Files
start-os/ui/src/app/components/form-object/form-object.component.html
Drew Ansbacher 83f0f13df5 drew-err=logs
2021-09-03 16:05:15 -06:00

195 lines
9.2 KiB
HTML

<ion-item-group [formGroup]="formGroup">
<div *ngFor="let entry of formGroup.controls | keyvalue : asIsOrder">
<!-- union enum -->
<ng-container *ngIf="unionSpec && entry.key === unionSpec.tag.id">
<p class="input-label">{{ unionSpec.tag.name }}</p>
<ion-item>
<ion-label>{{ unionSpec.tag.name }}</ion-label>
<ion-select [interfaceOptions]="{ message: getWarningText(unionSpec.warning) }" slot="end" placeholder="Select" [formControlName]="unionSpec.tag.id" [selectedText]="unionSpec.tag['variant-names'][entry.value.value]" (ionChange)="updateUnion($event)">
<ion-select-option *ngFor="let option of Object.keys(unionSpec.variants)" [value]="option">
{{ unionSpec.tag['variant-names'][option] }}
</ion-select-option>
</ion-select>
</ion-item>
</ng-container>
<ng-container *ngIf="objectSpec[entry.key] as spec">
<!-- primitive -->
<ng-container *ngIf="['string', 'number', 'boolean', 'enum'] | includes : spec.type">
<!-- label -->
<h4 class="input-label">
<form-label [data]="{
spec: spec,
isNew: current && current[entry.key] === undefined,
isEdited: entry.value.dirty
}"></form-label>
</h4>
<!-- string -->
<ion-item color="dark" *ngIf="spec.type === 'string'">
<ion-input [type]="spec.masked && !unmasked[entry.key] ? 'password' : 'text'" [placeholder]="'Enter ' + spec.name" [formControlName]="entry.key" (ionFocus)="presentAlertChangeWarning(entry.key, spec)" (ionChange)="handleInputChange(spec)"></ion-input>
<ion-button *ngIf="spec.masked" fill="clear" color="light" (click)="unmasked[entry.key] = !unmasked[entry.key]">
<ion-icon slot="icon-only" [name]="unmasked[entry.key] ? 'eye-off-outline' : 'eye-outline'" size="small"></ion-icon>
</ion-button>
</ion-item>
<!-- number -->
<ion-item color="dark" *ngIf="spec.type === 'number'">
<ion-input type="tel" [placeholder]="'Enter ' + spec.name" [formControlName]="entry.key" (ionFocus)="presentAlertChangeWarning(entry.key, spec)" (ionChange)="handleInputChange(spec)"></ion-input>
<ion-note *ngIf="spec.units" slot="end" color="light" style="font-size: medium;">{{ spec.units }}</ion-note>
</ion-item>
<!-- boolean -->
<ion-item *ngIf="spec.type === 'boolean'">
<ion-label>{{ spec.name }}</ion-label>
<ion-toggle slot="end" [formControlName]="entry.key" (ionChange)="handleBooleanChange(entry.key, spec)"></ion-toggle>
</ion-item>
<!-- enum -->
<ion-item *ngIf="spec.type === 'enum'">
<ion-label>{{ spec.name }}</ion-label>
<ion-select [interfaceOptions]="{ message: getWarningText(spec.warning) }" slot="end" placeholder="Select" [formControlName]="entry.key" [selectedText]="spec['value-names'][formGroup.get(entry.key).value]" (ionChange)="handleInputChange(spec)">
<ion-select-option *ngFor="let option of spec.values" [value]="option">
{{ spec['value-names'][option] }}
</ion-select-option>
</ion-select>
</ion-item>
</ng-container>
<!-- object or union -->
<ng-container *ngIf="spec.type === 'object' || spec.type ==='union'">
<!-- label -->
<ion-item-divider>
<form-label [data]="{
spec: spec,
isNew: current && current[entry.key] === undefined,
isEdited: entry.value.dirty
}"></form-label>
</ion-item-divider>
<!-- body -->
<div class="nested-wrapper">
<form-object
[objectSpec]="
spec.type === 'union' ?
spec.variants[entry.value.controls[spec.tag.id].value] :
spec.spec"
[formGroup]="entry.value"
[current]="current ? current[entry.key] : undefined"
[unionSpec]="spec.type === 'union' ? spec : undefined"
></form-object>
</div>
</ng-container>
<!-- list (not enum) -->
<ng-container *ngIf="spec.type === 'list' && spec.subtype !== 'enum'">
<ng-container *ngIf="formGroup.get(entry.key) as formArr" [formArrayName]="entry.key">
<!-- label -->
<ion-item-divider>
<form-label [data]="{
spec: spec,
isNew: current && current[entry.key] === undefined,
isEdited: entry.value.dirty
}"></form-label>
<ion-button fill="clear" color="primary" slot="end" (click)="addListItemWrapper(entry.key, spec)">
<ion-icon slot="start" name="add"></ion-icon>
Add
</ion-button>
</ion-item-divider>
<!-- body -->
<div class="nested-wrapper">
<div
*ngFor="let abstractControl of formArr.controls; let i = index;"
class="ion-padding-top"
>
<!-- nested -->
<ng-container *ngIf="spec.subtype === 'object' || spec.subtype === 'union'">
<!-- nested label -->
<ion-item button (click)="toggleExpand(entry.key, i)">
<form-label [data]="{
spec: { name: objectListInfo[entry.key][i].displayAs || 'Entry ' + (i + 1) },
isNew: false,
isEdited: abstractControl.dirty
}"></form-label>
<ion-icon
slot="end"
name="chevron-up"
[ngStyle]="{
'transform': objectListInfo[entry.key][i].expanded ? 'rotate(0deg)' : 'rotate(180deg)',
'transition': 'transform 0.4s ease-out'
}"
></ion-icon>
</ion-item>
<!-- nested body -->
<div
[id]="entry.key"
[ngStyle]="{
'max-height': objectListInfo[entry.key][i].height,
'overflow': 'hidden',
'transition-property': 'max-height',
'transition-duration': '.5s',
'transition-delay': '.05s'
}"
>
<!-- [hidden]="objectListInfo[entry.key][i].expanded ? false : true" -->
<form-object
[objectSpec]="
spec.subtype === 'union' ?
spec.spec.variants[abstractControl.controls[spec.spec.tag.id].value] :
spec.spec.spec"
[formGroup]="abstractControl"
[current]="current && current[entry.key] ? current[entry.key][i] : undefined"
[unionSpec]="spec.subtype === 'union' ? spec.spec : undefined"
(onInputChange)="updateLabel(entry.key, i, spec.spec['display-as'])"
></form-object>
<div style="text-align: right; padding-top: 12px;">
<ion-button fill="clear" (click)="presentAlertDelete(entry.key, i)" color="danger">
<ion-icon slot="start" name="close"></ion-icon>
Delete
</ion-button>
</div>
</div>
</ng-container>
<!-- string or number -->
<ion-item-group *ngIf="spec.subtype === 'string' || spec.subtype === 'number'">
<ion-item color="dark">
<ion-input type="spec.spec.masked ? 'password' : 'text'" [placeholder]="'Enter ' + spec.name" [formControlName]="i"></ion-input>
<ion-button slot="end" color="danger" (click)="presentAlertDelete(entry.key, i)">
<ion-icon slot="icon-only" name="close"></ion-icon>
</ion-button>
</ion-item>
<form-error
*ngIf="abstractControl.errors"
[control]="abstractControl"
[spec]="spec.spec"
>
</form-error>
</ion-item-group>
</div>
</div>
</ng-container>
</ng-container>
<!-- list (enum) -->
<ng-container *ngIf="spec.type === 'list' && spec.subtype === 'enum'">
<ng-container *ngIf="formGroup.get(entry.key) as formArr" [formArrayName]="entry.key">
<!-- label -->
<p class="input-label">
<form-label [data]="{
spec: spec,
isNew: current && current[entry.key] === undefined,
isEdited: entry.value.dirty
}"></form-label>
</p>
<!-- list -->
<ion-item button detail="false" color="dark" (click)="presentModalEnumList(entry.key, spec, formArr.value)">
<ion-label>
<h2>{{ getEnumListDisplay(formArr.value, spec.spec) }}</h2>
</ion-label>
<ion-button slot="end" fill="clear" color="light">
<ion-icon slot="icon-only" name="chevron-down"></ion-icon>
</ion-button>
</ion-item>
</ng-container>
</ng-container>
<form-error
*ngIf="formGroup.get(entry.key).errors"
[control]="formGroup.get(entry.key)"
[spec]="spec"
>
</form-error>
</ng-container>
</div>
</ion-item-group>