Palette visuals for no matches. Filter text placeholder binding.

This commit is contained in:
BoykoAlex
2019-12-03 20:29:31 -05:00
parent 5434d7797c
commit a3269fc8bf
5 changed files with 113 additions and 16 deletions

View File

@@ -7,7 +7,9 @@
Spring Flo Sample
</div>
<div id="flo-container">
<flo-editor (floApi)="editorContext = $event" [metamodel]="metamodel" [renderer]="renderer" [editor]="editor" [paletteSize]="paletteSize" [paletteEntryPadding]="{width: 4, height: 4}" [(dsl)]="dsl" [paperPadding]="20" (validationMarkers)="markersChanged($event)">
<flo-editor (floApi)="editorContext = $event" [metamodel]="metamodel" [renderer]="renderer" [editor]="editor"
[paletteSize]="paletteSize" [paletteEntryPadding]="{width: 4, height: 4}" [(dsl)]="dsl"
[paperPadding]="20" (validationMarkers)="markersChanged($event)" searchFilterPlaceHolder="Apps...">
<div header>
<div id="controls" class="controls">
<button class="button" id="clearGraph" (click)="editorContext.clearGraph()">Create New Flow</button>
@@ -15,27 +17,42 @@
<button class="button" id="deleteSelectedNode" ng-click="flo.deleteSelectedNode()">Delete Selected Node</button>
-->
<button class="button" id="performLayout" (click)="arrangeAll()">Reset Layout</button>
<button class="button" id="sync" (click)="editorContext.graphToTextSync = !editorContext.graphToTextSync" [ngClass]="{on:editorContext.graphToTextSync}">Synchronize</button>
<button class="button" id="readOnly" (click)="editorContext.readOnlyCanvas = !editorContext.readOnlyCanvas" [ngClass]="{on:editorContext.readOnlyCanvas}">Read-Only</button>
<button class="button" id="noPalette" (click)="editorContext.noPalette = !editorContext.noPalette" [ngClass]="{on:!editorContext.noPalette}">Palette</button>
<button class="button" id="editor" (click)="dslEditor = !dslEditor" [ngClass]="{on:dslEditor}">{{dslEditor ? 'TextArea' : 'Editor'}}</button>
<button class="button" id="sync" (click)="editorContext.graphToTextSync = !editorContext.graphToTextSync"
[ngClass]="{on:editorContext.graphToTextSync}">Synchronize
</button>
<button class="button" id="readOnly" (click)="editorContext.readOnlyCanvas = !editorContext.readOnlyCanvas"
[ngClass]="{on:editorContext.readOnlyCanvas}">Read-Only
</button>
<button class="button" id="noPalette" (click)="editorContext.noPalette = !editorContext.noPalette"
[ngClass]="{on:!editorContext.noPalette}">Palette
</button>
<button class="button" id="editor" (click)="dslEditor = !dslEditor" [ngClass]="{on:dslEditor}">{{dslEditor ?
'TextArea' : 'Editor'}}
</button>
<span class="button">
<label>Zoom: </label>
<input id="zoomInput" type="text" [(ngModel)]="editorContext.zoomPercent" size="3">
<label>%</label>
<input type="range" [(ngModel)]="editorContext.zoomPercent" [step]="editorContext.getZoomStep()" [max]="editorContext.getMaxZoom()" [min]="editorContext.getMinZoom()" data-type="range" name="range" class="range">
<input type="range" [(ngModel)]="editorContext.zoomPercent" [step]="editorContext.getZoomStep()"
[max]="editorContext.getMaxZoom()" [min]="editorContext.getMinZoom()" data-type="range" name="range"
class="range">
</span>
<span class="button">
<label>Grid Size: </label>
<input id="gridSizeInput" type="text" [(ngModel)]="editorContext.gridSize" size="2">
<label>pixels</label>
<input type="range" [(ngModel)]="editorContext.gridSize" step="1" max="50" min="1" data-type="range" name="range" class="range">
<input type="range" [(ngModel)]="editorContext.gridSize" step="1" max="50" min="1" data-type="range"
name="range" class="range">
</span>
</div>
<div class="flow-definition-container">
<dsl-editor *ngIf="dslEditor" [(dsl)]="dsl" line-numbers="true" line-wrapping="true" (blur)="editorContext.graphToTextSync=true" (focus)="editorContext.graphToTextSync=false" placeholder="Enter stream definition..."></dsl-editor>
<textarea *ngIf="!dslEditor" id="flow-definition" class="flow-definition" placeholder="Enter stream definition..."
[value]="dsl" (keyup)="dsl=$event.target.value" (blur)="editorContext.graphToTextSync=true" (focus)="editorContext.graphToTextSync=false"></textarea>
<dsl-editor *ngIf="dslEditor" [(dsl)]="dsl" line-numbers="true" line-wrapping="true"
(blur)="editorContext.graphToTextSync=true" (focus)="editorContext.graphToTextSync=false"
placeholder="Enter stream definition..."></dsl-editor>
<textarea *ngIf="!dslEditor" id="flow-definition" class="flow-definition"
placeholder="Enter stream definition..."
[value]="dsl" (keyup)="dsl=$event.target.value" (blur)="editorContext.graphToTextSync=true"
(focus)="editorContext.graphToTextSync=false"></textarea>
</div>
</div>
</flo-editor>

View File

@@ -6,7 +6,9 @@
[paletteEntryPadding]="paletteEntryPadding || {width: 12, height: 12}"
(onPaletteEntryDrop)="handleDnDFromPalette($event)"
(paletteReady)="updatePaletteReadyState($event)"
(paletteFocus)="graphToTextSync=true"></flo-palette>
(paletteFocus)="graphToTextSync=true"
[searchFilterPlaceHolder]="searchFilterPlaceHolder">
</flo-palette>
</div>
<div id="sidebar-resizer" *ngIf="!noPalette"

View File

@@ -113,6 +113,9 @@ export class EditorComponent implements OnInit, OnDestroy {
this.paletteSizeChange.emit(newSize);
}
@Input()
searchFilterPlaceHolder = 'Search...';
/**
* Palette entry padding
*/

View File

@@ -1,6 +1,6 @@
<div id="palette-filter" class="palette-filter">
<label class="palette-filter-label" for="palette-filter-textfield">
<input type="search" id="palette-filter-textfield" class="palette-filter-textfield" [(ngModel)]="filterText" (focus)="onFocus()" placeholder="Applications"/>
<input type="search" id="palette-filter-textfield" class="palette-filter-textfield" [(ngModel)]="filterText" (focus)="onFocus()" [placeholder]="searchFilterPlaceHolder"/>
</label>
</div>
<div id="palette-paper-container">

View File

@@ -35,6 +35,39 @@ joint.shapes.flo.PaletteGroupHeader = joint.shapes.basic.Generic.extend({
}, joint.shapes.basic.Generic.prototype.defaults)
});
joint.shapes.flo.NoMatchesFound = joint.shapes.basic.Generic.extend({
// The path is the open/close arrow, defaults to vertical (open)
markup: '<g class="scalable"><rect class="no-matches-label-border"/></g><rect class="no-mathes-label-bg"/><text class="no-matches-label"/>',
defaults: joint.util.deepSupplement({
size: {width: 170, height: 30},
position: {x: 0, y: 0},
attrs: {
'.no-matches-label-border': {
refWidth: 1,
refHeight: 1,
refX: 0,
refY: 0,
},
'.no-macthes-label-bg': {
ref: '.no-matches-label',
refWidth: 10,
refHeight: 2,
'follow-scale': true
},
'.no-matches-label': {
text: 'No Matches Found...',
ref: '.no-matches-label-border',
refX: 0.5,
refY: 0.5,
xAlignment: 'middle',
yAlignment: 'middle',
'fill': '#777777',
'font-style': 'italic'
},
},
}, joint.shapes.basic.Generic.prototype.defaults)
});
@Component({
selector: 'flo-palette',
templateUrl: './palette.component.html',
@@ -79,6 +112,8 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
private filterTextModel = new Subject<string>();
private noMacthesFoundNode: dia.Cell;
@Input()
metamodel: Flo.Metamodel;
@@ -88,6 +123,9 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
@Input()
paletteEntryPadding: dia.Size = {width: 12, height: 12};
@Input()
searchFilterPlaceHolder = 'Search...';
@Output()
onPaletteEntryDrop = new EventEmitter<Flo.DnDEvent>();
@@ -292,7 +330,7 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
this.createPaletteGroup(group, !this.closedGroups.has(group));
groupAdded.add(group);
}
if (!this.closedGroups.has(group)) {
if (!(node.metadata && node.metadata.noPaletteEntry)) {
this.createPaletteEntry(name, node);
}
}
@@ -300,6 +338,9 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
}
});
this.noMacthesFoundNode = new joint.shapes.flo.NoMatchesFound();
this.palette.model.addCell(this.noMacthesFoundNode);
this.layout();
this.paletteReady.emit(true);
@@ -321,16 +362,36 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
this.palette.model.getCells().forEach((cell: dia.Cell) => {
const metadata: Flo.ElementMetadata = cell.attr('metadata');
if (cell.get('header') || metadata && metadata.group && metadata.name && !this.closedGroups.has(metadata.group)
&& (!filterText || metadata.group.indexOf(filterText) >= 0 || metadata.group.indexOf(filterText) >= 0)) {
if (cell.get('header')) {
const previous = paletteNodes.length > 0 ? paletteNodes[paletteNodes.length - 1] : undefined;
// If previous is a paletter header node as well then the previous header had no nodes under it and we can hide it and remove from paletteNodes aeeay
if (previous && previous.get('header') && !this.closedGroups.has(previous.get('header'))) {
paletteNodes.pop().attr('./display', 'none');
}
cell.attr('./display', 'block');
cell.removeAttr('./display');
paletteNodes.push(cell);
} else if (metadata && metadata.group && metadata.name && !this.closedGroups.has(metadata.group)
&& (!filterText || metadata.group.indexOf(filterText) >= 0 || metadata.name.indexOf(filterText) >= 0)) {
cell.attr('./display', 'block');
cell.removeAttr('./display');
paletteNodes.push(cell);
} else {
cell.attr('./display', 'none');
if (cell === this.noMacthesFoundNode) {
} else {
cell.attr('./display', 'none');
}
}
});
// Check if last group is empty
const previous = paletteNodes.length > 0 ? paletteNodes[paletteNodes.length - 1] : undefined;
// If previous is a paletter header node as well then the previous header had no nodes under it and we can hide it and remove from paletteNodes aeeay
if (previous && previous.get('header') && !this.closedGroups.has(previous.get('header'))) {
paletteNodes.pop().attr('./display', 'none');
}
let cellWidth = 0, cellHeight = 0;
// Determine the size of the palette entry cell (width and height)
paletteNodes.forEach(pnode => {
@@ -394,6 +455,20 @@ export class Palette implements OnInit, OnDestroy, OnChanges {
}
prevNode = pnode;
});
this.noMacthesFoundNode.set('size', {width: parentWidth, height: this.noMacthesFoundNode.get('size').height || 30});
this.noMacthesFoundNode.set('position', {x: 0, y: 0});
if (paletteNodes.length === 0 && filterText) {
// There is a filter present but everything is filtered out
// Show no matches found node
this.noMacthesFoundNode.attr('./display', 'block');
this.noMacthesFoundNode.removeAttr('./display');
ypos = this.noMacthesFoundNode.get('size').height;
} else {
// Hide no matches node in all other cases
this.noMacthesFoundNode.attr('./display', 'none');
}
this.palette.setDimensions(parentWidth, ypos);
console.debug('buildPalette layout ' + (new Date().getTime() - startTime) + 'ms');