You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
314 lines
14 KiB
314 lines
14 KiB
import {Component, Input, OnInit} from '@angular/core';
|
|
import {EditorService} from '../../../../service/editor.service';
|
|
import {ModalController} from '@ionic/angular';
|
|
import HostRecord from '../../../../structures/HostRecord';
|
|
import {debug} from '../../../../utility';
|
|
import {DbApiService} from '../../../../service/db-api.service';
|
|
import {Database, DatabaseColumn} from '../../../../structures/db-api';
|
|
import {NodeTypeIcons} from '../../../../structures/node-types';
|
|
|
|
@Component({
|
|
selector: 'noded-node-form-input-options',
|
|
template: `
|
|
<ion-header>
|
|
<ion-toolbar>
|
|
<ion-title>Edit Form Input</ion-title>
|
|
<ion-buttons slot="end">
|
|
<ion-button (click)="dismissModal(true)">
|
|
<ion-icon name="save"></ion-icon>
|
|
</ion-button>
|
|
<ion-button (click)="dismissModal(false)">
|
|
<ion-icon name="close"></ion-icon>
|
|
</ion-button>
|
|
</ion-buttons>
|
|
</ion-toolbar>
|
|
</ion-header>
|
|
|
|
<ion-content class="ion-padding">
|
|
<ion-grid>
|
|
<ion-row>
|
|
<ion-col size="12">
|
|
<ion-item>
|
|
<ion-label [position]="'floating'">Label Text</ion-label>
|
|
<ion-input [(ngModel)]="label"></ion-input>
|
|
</ion-item>
|
|
</ion-col>
|
|
</ion-row>
|
|
<ion-row>
|
|
<ion-col size="12">
|
|
<ion-item>
|
|
<ion-label [position]="'floating'">Placeholder Text</ion-label>
|
|
<ion-input [(ngModel)]="placeholder"></ion-input>
|
|
</ion-item>
|
|
</ion-col>
|
|
</ion-row>
|
|
<ion-row>
|
|
<ion-col size="12">
|
|
<ion-item>
|
|
<ion-checkbox slot="start" [(ngModel)]="required">
|
|
</ion-checkbox>
|
|
Required
|
|
</ion-item>
|
|
</ion-col>
|
|
</ion-row>
|
|
<ion-row *ngIf="node.type === 'form_input_select' || node.type === 'form_input_multiselect'">
|
|
<ion-col size="12" [title]="'Defines where the options for the select field should come from'">
|
|
<ion-item>
|
|
<ion-label [position]="'floating'">Select Options Source</ion-label>
|
|
<ion-select
|
|
[(ngModel)]="selectSource"
|
|
style="width: 100%;"
|
|
>
|
|
<ion-select-option value="local">Static Options</ion-select-option>
|
|
<ion-select-option value="database">Database Values</ion-select-option>
|
|
</ion-select>
|
|
</ion-item>
|
|
</ion-col>
|
|
</ion-row>
|
|
<ion-row
|
|
*ngIf="
|
|
(node.type === 'form_input_select' || node.type === 'form_input_multiselect')
|
|
&& this.selectSource === 'database'"
|
|
>
|
|
<ion-col size="12">
|
|
<ion-item>
|
|
<ion-label position="floating">Source Database</ion-label>
|
|
<ionic-selectable
|
|
[items]="databases"
|
|
itemTextField="name"
|
|
itemValueField="uuid"
|
|
[canSearch]="true"
|
|
[title]="'Select a source database'"
|
|
[(ngModel)]="selectedDatabase"
|
|
(onChange)="onSelectDatabaseChange()"
|
|
>
|
|
<ng-template ionicSelectableItemTemplate let-port="item" let-isPortSelected="itemIsSelected">
|
|
<div><i [ngClass]="typeIcons.db" style="margin-right: 15px;"></i>{{ port.name }}</div>
|
|
</ng-template>
|
|
</ionic-selectable>
|
|
</ion-item>
|
|
</ion-col>
|
|
</ion-row>
|
|
<ion-row
|
|
*ngIf="
|
|
(node.type === 'form_input_select' || node.type === 'form_input_multiselect')
|
|
&& this.selectSource === 'database' && this.selectedDatabase"
|
|
>
|
|
<ion-col size="6">
|
|
<ion-item>
|
|
<ion-label position="floating">Display Column</ion-label>
|
|
<ionic-selectable
|
|
[items]="selectedDatabaseColumns"
|
|
itemTextField="name"
|
|
itemValueField="uuid"
|
|
[canSearch]="true"
|
|
[title]="'Select the column to be used as the display value'"
|
|
[(ngModel)]="selectDatabaseDisplayColumn"
|
|
></ionic-selectable>
|
|
</ion-item>
|
|
</ion-col>
|
|
<ion-col size="6">
|
|
<ion-item>
|
|
<ion-label position="floating">Value Column</ion-label>
|
|
<ionic-selectable
|
|
[items]="selectedDatabaseColumns"
|
|
itemTextField="name"
|
|
itemValueField="uuid"
|
|
[canSearch]="true"
|
|
[title]="'Select the column to be used as the record value'"
|
|
[(ngModel)]="selectDatabaseValueColumn"
|
|
></ionic-selectable>
|
|
</ion-item>
|
|
</ion-col>
|
|
</ion-row>
|
|
<ion-row
|
|
*ngIf="
|
|
(node.type === 'form_input_select' || node.type === 'form_input_multiselect')
|
|
&& this.selectSource === 'local'"
|
|
>
|
|
<ion-header style="display: flex; padding-top: 20px;">
|
|
<h5 style="flex: 1;">Options</h5>
|
|
<button [title]="'Add new option'" (click)="onAddSelectOption()">
|
|
<i class="fa fa-plus"></i>
|
|
</button>
|
|
</ion-header>
|
|
<ion-grid>
|
|
<ion-row *ngFor="let option of selectStaticOptions">
|
|
<ion-col size="5">
|
|
<ion-item>
|
|
<ion-label position="floating">Display</ion-label>
|
|
<ion-input [(ngModel)]="option.display"></ion-input>
|
|
</ion-item>
|
|
</ion-col>
|
|
<ion-col size="5">
|
|
<ion-item>
|
|
<ion-label position="floating">Value</ion-label>
|
|
<ion-input [(ngModel)]="option.value"></ion-input>
|
|
</ion-item>
|
|
</ion-col>
|
|
<ion-col size="2">
|
|
<button [title]="'Remove this option'" style="height: 100px; padding: 10px; color: red;" (click)="onRemoveSelectOption(option)">
|
|
<i class="fa fa-trash"></i>
|
|
</button>
|
|
</ion-col>
|
|
</ion-row>
|
|
</ion-grid>
|
|
</ion-row>
|
|
<ion-row *ngIf="node.type === 'form_input_password' || node.type === 'form_input_text'">
|
|
<ion-col size="6">
|
|
<ion-item>
|
|
<ion-label [position]="'floating'">Min Length</ion-label>
|
|
<ion-input type="'number'" [(ngModel)]="minLength"></ion-input>
|
|
</ion-item>
|
|
</ion-col>
|
|
<ion-col size="6">
|
|
<ion-item>
|
|
<ion-label [position]="'floating'">Max Length</ion-label>
|
|
<ion-input type="'number'" [(ngModel)]="maxLength"></ion-input>
|
|
</ion-item>
|
|
</ion-col>
|
|
</ion-row>
|
|
<ion-row *ngIf="node.type === 'form_input_number'">
|
|
<ion-col size="6">
|
|
<ion-item>
|
|
<ion-label [position]="'floating'">Min</ion-label>
|
|
<ion-input type="'number'" [(ngModel)]="min"></ion-input>
|
|
</ion-item>
|
|
</ion-col>
|
|
<ion-col size="6">
|
|
<ion-item>
|
|
<ion-label [position]="'floating'">Max</ion-label>
|
|
<ion-input type="'number'" [(ngModel)]="max"></ion-input>
|
|
</ion-item>
|
|
</ion-col>
|
|
</ion-row>
|
|
</ion-grid>
|
|
</ion-content>
|
|
`,
|
|
})
|
|
export class FormInputOptionsComponent implements OnInit {
|
|
@Input() node: HostRecord;
|
|
@Input() editorUUID: string;
|
|
|
|
public typeIcons = NodeTypeIcons;
|
|
|
|
public label = '';
|
|
public placeholder = '';
|
|
public required = false;
|
|
|
|
public minLength?: number;
|
|
public maxLength?: number;
|
|
|
|
public min?: number;
|
|
public max?: number;
|
|
|
|
public selectSource?: 'local'|'database';
|
|
public selectDatabaseDisplayColumn?: DatabaseColumn;
|
|
public selectDatabaseValueColumn?: DatabaseColumn;
|
|
public selectStaticOptions: { display: string, value: string }[] = [];
|
|
|
|
public databases: Database[] = [];
|
|
public selectedDatabase?: Database;
|
|
public selectedDatabaseColumns: DatabaseColumn[] = [];
|
|
|
|
constructor(
|
|
public editorService: EditorService,
|
|
public readonly dbApi: DbApiService,
|
|
public readonly modal: ModalController,
|
|
) { }
|
|
|
|
async ngOnInit() {
|
|
debug('Form input options', this);
|
|
this.editorService = this.editorService.getEditor(this.editorUUID);
|
|
|
|
this.label = this.node.AdditionalData.label;
|
|
this.placeholder = this.node.AdditionalData.placeholder;
|
|
this.required = this.node.AdditionalData.required;
|
|
|
|
if ( this.node.type === 'form_input_password' || this.node.type === 'form_input_text' ) {
|
|
this.minLength = this.node.AdditionalData.minLength;
|
|
this.maxLength = this.node.AdditionalData.maxLength;
|
|
}
|
|
|
|
if ( this.node.type === 'form_input_number' ) {
|
|
this.min = this.node.AdditionalData.min;
|
|
this.max = this.node.AdditionalData.max;
|
|
}
|
|
|
|
if ( this.node.type === 'form_input_select' || this.node.type === 'form_input_multiselect' ) {
|
|
this.selectSource = this.node.AdditionalData.selectSource;
|
|
|
|
this.databases = await this.dbApi.getDatabases();
|
|
|
|
if ( this.selectSource === 'database' ) {
|
|
this.selectedDatabase = this.databases.find(x => x.uuid === this.node.AdditionalData.selectSourceDatabaseId);
|
|
await this.onSelectDatabaseChange();
|
|
|
|
this.selectDatabaseValueColumn = this.selectedDatabaseColumns.find(x => {
|
|
return x.field === this.node.AdditionalData.selectDatabaseValueColumnId;
|
|
});
|
|
|
|
this.selectDatabaseDisplayColumn = this.selectedDatabaseColumns.find(x => {
|
|
return x.field === this.node.AdditionalData.selectDatabaseDisplayColumnId;
|
|
});
|
|
} else if ( this.selectSource === 'local' ) {
|
|
this.selectStaticOptions = this.node.AdditionalData.selectStaticOptions || [];
|
|
}
|
|
}
|
|
}
|
|
|
|
dismissModal(success = true) {
|
|
if ( success ) {
|
|
this.node.AdditionalData.label = this.label;
|
|
this.node.AdditionalData.placeholder = this.placeholder;
|
|
this.node.AdditionalData.required = !!this.required;
|
|
}
|
|
|
|
if ( this.node.type === 'form_input_password' || this.node.type === 'form_input_text' ) {
|
|
this.node.AdditionalData.minLength = this.minLength;
|
|
this.node.AdditionalData.maxLength = this.maxLength;
|
|
}
|
|
|
|
if ( this.node.type === 'form_input_number' ) {
|
|
this.node.AdditionalData.min = this.min;
|
|
this.node.AdditionalData.max = this.max;
|
|
}
|
|
|
|
if ( this.node.type === 'form_input_select' || this.node.type === 'form_input_multiselect' ) {
|
|
this.node.AdditionalData.selectSource = this.selectSource;
|
|
|
|
if ( this.selectSource === 'database' ) {
|
|
this.node.AdditionalData.selectSourceDatabaseId = this.selectedDatabase?.uuid;
|
|
this.node.AdditionalData.selectDatabaseValueColumnId = this.selectDatabaseValueColumn?.field;
|
|
this.node.AdditionalData.selectDatabaseDisplayColumnId = this.selectDatabaseDisplayColumn?.field;
|
|
} else if ( this.selectSource === 'local' ) {
|
|
this.node.AdditionalData.selectStaticOptions = this.selectStaticOptions;
|
|
}
|
|
}
|
|
|
|
this.modal.dismiss(success);
|
|
}
|
|
|
|
async onSelectDatabaseChange() {
|
|
if ( this.selectedDatabase ) {
|
|
this.selectedDatabaseColumns = await this.selectedDatabase.columns();
|
|
} else {
|
|
this.selectedDatabaseColumns = [];
|
|
}
|
|
|
|
this.selectDatabaseDisplayColumn = undefined;
|
|
this.selectDatabaseValueColumn = undefined;
|
|
}
|
|
|
|
onAddSelectOption() {
|
|
this.selectStaticOptions.push({
|
|
display: '',
|
|
value: '',
|
|
});
|
|
}
|
|
|
|
onRemoveSelectOption(option: any) {
|
|
this.selectStaticOptions = this.selectStaticOptions.filter(x => x !== option);
|
|
}
|
|
}
|