import { ChangeDetectorRef, Component, Input, OnChanges, OnInit } from '@angular/core';
import cloneDeep from 'lodash-es/cloneDeep';
import { JsonSchemaFormService } from '../../json-schema-form.service';
import { isDefined } from '../../shared';
@Component({
// tslint:disable-next-line:component-selector
selector: 'material-design-framework',
template: `
`,
styles: [`
.array-item {
border-radius: 2px;
box-shadow: 0 3px 1px -2px rgba(0,0,0,.2),
0 2px 2px 0 rgba(0,0,0,.14),
0 1px 5px 0 rgba(0,0,0,.12);
padding: 6px;
position: relative;
transition: all 280ms cubic-bezier(.4, 0, .2, 1);
}
.close-button {
cursor: pointer;
position: absolute;
top: 6px;
right: 6px;
fill: rgba(0,0,0,.4);
visibility: hidden;
z-index: 500;
}
.close-button:hover { fill: rgba(0,0,0,.8); }
.array-item:hover > .close-button { visibility: visible; }
.spacer { margin: 6px 0; }
[draggable=true]:hover {
box-shadow: 0 5px 5px -3px rgba(0,0,0,.2),
0 8px 10px 1px rgba(0,0,0,.14),
0 3px 14px 2px rgba(0,0,0,.12);
cursor: move;
z-index: 10;
}
[draggable=true].drag-target-top {
box-shadow: 0 -2px 0 #000;
position: relative; z-index: 20;
}
[draggable=true].drag-target-bottom {
box-shadow: 0 2px 0 #000;
position: relative; z-index: 20;
}
`],
})
export class MaterialDesignFrameworkComponent implements OnInit, OnChanges {
frameworkInitialized = false;
inputType: string;
options: any; // Options used in this framework
widgetLayoutNode: any; // layoutNode passed to child widget
widgetOptions: any; // Options passed to child widget
formControl: any = null;
parentArray: any = null;
isOrderable = false;
dynamicTitle: string = null;
@Input() layoutNode: any;
@Input() layoutIndex: number[];
@Input() dataIndex: number[];
constructor(
private changeDetector: ChangeDetectorRef,
private jsf: JsonSchemaFormService
) { }
get showRemoveButton(): boolean {
if (!this.layoutNode || !this.widgetOptions.removable ||
this.widgetOptions.readonly || this.layoutNode.type === '$ref'
) { return false; }
if (this.layoutNode.recursiveReference) { return true; }
if (!this.layoutNode.arrayItem || !this.parentArray) { return false; }
// If array length <= minItems, don't allow removing any items
return this.parentArray.items.length - 1 <= this.parentArray.options.minItems ? false :
// For removable list items, allow removing any item
this.layoutNode.arrayItemType === 'list' ? true :
// For removable tuple items, only allow removing last item in list
this.layoutIndex[this.layoutIndex.length - 1] === this.parentArray.items.length - 2;
}
ngOnInit() {
this.initializeFramework();
}
ngOnChanges() {
if (!this.frameworkInitialized) { this.initializeFramework(); }
if (this.dynamicTitle) { this.updateTitle(); }
}
initializeFramework() {
if (this.layoutNode) {
this.options = cloneDeep(this.layoutNode.options || {});
this.widgetLayoutNode = {
...this.layoutNode,
options: cloneDeep(this.layoutNode.options || {})
};
this.widgetOptions = this.widgetLayoutNode.options;
this.formControl = this.jsf.getFormControl(this);
if (
isDefined(this.widgetOptions.minimum) &&
isDefined(this.widgetOptions.maximum) &&
this.widgetOptions.multipleOf >= 1
) {
this.layoutNode.type = 'range';
}
if (
!['$ref', 'advancedfieldset', 'authfieldset', 'button', 'card',
'checkbox', 'expansion-panel', 'help', 'message', 'msg', 'section',
'submit', 'tabarray', 'tabs'].includes(this.layoutNode.type) &&
/{{.+?}}/.test(this.widgetOptions.title || '')
) {
this.dynamicTitle = this.widgetOptions.title;
this.updateTitle();
}
if (this.layoutNode.arrayItem && this.layoutNode.type !== '$ref') {
this.parentArray = this.jsf.getParentNode(this);
if (this.parentArray) {
this.isOrderable =
this.parentArray.type.slice(0, 3) !== 'tab' &&
this.layoutNode.arrayItemType === 'list' &&
!this.widgetOptions.readonly &&
this.parentArray.options.orderable;
}
}
this.frameworkInitialized = true;
} else {
this.options = {};
}
}
updateTitle() {
this.widgetLayoutNode.options.title = this.jsf.parseText(
this.dynamicTitle,
this.jsf.getFormControlValue(this),
this.jsf.getFormControlGroup(this).value,
this.dataIndex[this.dataIndex.length - 1]
);
}
removeItem() {
this.jsf.removeItem(this);
}
}