--- /dev/null
+import {Component, Input, Output, EventEmitter, Host, OnInit} from '@angular/core';
+import {FmRecordEditorComponent} from './fm-editor.component';
+
+@Component({
+ selector: 'eg-fm-record-editor-action',
+ template: '<ng-template></ng-template>' // no-op
+})
+
+export class FmRecordEditorActionComponent implements OnInit {
+
+ // unique identifier
+ @Input() key: string;
+
+ @Input() label: string;
+
+ @Input() buttonCss = 'btn-outline-dark';
+
+ // Emits the 'key' of the clicked action.
+ @Output() actionClick: EventEmitter<string>;
+
+ @Input() disabled: boolean;
+
+ constructor(@Host() private editor: FmRecordEditorComponent) {
+ this.actionClick = new EventEmitter<string>();
+ }
+
+ ngOnInit() {
+ this.editor.actions.push(this);
+ }
+}
+
<eg-string #successStr text="Update Succeeded" i18n-text></eg-string>
<eg-string #failStr text="Update Failed" i18n-text></eg-string>
+<eg-confirm-dialog #confirmDel
+ dialogTitle="Delete?" i18n-dialogTitle
+ dialogBody="Delete {{recordLabel}}?" i18n-dialogBody>
+</eg-confirm-dialog>
+
<ng-template #dialogContent>
<div class="modal-header bg-info" *ngIf="!hideBanner">
<h4 class="modal-title" i18n>Record Editor: {{recordLabel}}</h4>
[required]="field.isRequired()"
[entries]="field.linkedValues"
[asyncDataSource]="field.linkedValuesSource"
- [startId]="record[field.name]()"
+ [selectedId]="record[field.name]()"
(onChange)="record[field.name]($event ? $event.id : null)">
</eg-combobox>
</ng-container>
</form>
</div>
<div class="modal-footer">
+ <button type="button" class="btn {{action.buttonCss}}"
+ *ngFor="let action of actions" [disabled]="action.disabled"
+ (click)="action.actionClick.emit({action: action.key, record: record})">
+ {{action.label}}
+ </button>
<ng-container *ngIf="isDialog()">
<button type="button" class="btn btn-success" *ngIf="mode == 'view'"
(click)="close()" i18n>Close</button>
<button type="button" class="btn btn-warning ml-2" *ngIf="mode != 'view'"
(click)="cancel()" i18n>Cancel</button>
</ng-container>
+
+ <ng-container *ngIf="showDelete && mode != 'view'">
+ <button type="button" class="btn btn-warning" (click)="remove()"
+ [disabled]="record && record.isnew()" i18n>Delete</button>
+ </ng-container>
+
<button type="button" class="btn btn-info"
[disabled]="fmEditForm.invalid" *ngIf="mode != 'view'"
(click)="save()" i18n>Save</button>
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
import {TranslateComponent} from '@eg/share/translate/translate.component';
+import {FmRecordEditorActionComponent} from './fm-editor-action.component';
+import {ConfirmDialogComponent} from '@eg/share/dialog/confirm.component';
interface CustomFieldTemplate {
// Emit the modified object when the save action completes.
@Output() recordSaved = new EventEmitter<IdlObject>();
+ // Emit the modified object when the save action completes.
+ @Output() recordDeleted = new EventEmitter<IdlObject>();
+
// Emit the original object when the save action is canceled.
@Output() recordCanceled = new EventEmitter<IdlObject>();
@ViewChild('translator') private translator: TranslateComponent;
@ViewChild('successStr') successStr: StringComponent;
@ViewChild('failStr') failStr: StringComponent;
+ @ViewChild('confirmDel') confirmDel: ConfirmDialogComponent;
// IDL info for the the selected IDL class
idlDef: any;
// is actionable. This allows the caller to use both @Input()'s
// without each clobbering the other.
- // Record ID to view/update.
+ // Record ID to view/update.
_recordId: any = null;
@Input() set recordId(id: any) {
if (id) {
return this._record;
}
+ actions: FmRecordEditorActionComponent[] = [];
+
initDone: boolean;
// Comma-separated list of field names defining the order in which
// will be rendered alphabetically by label after the named fields.
@Input() fieldOrder: string;
+ // When true, show a delete button and support delete operations.
+ @Input() showDelete: boolean;
+
constructor(
private modal: NgbModal, // required for passing to parent
private idl: IdlService,
// Modifies the provided FM record in place, replacing JS values
// with IDL-compatible values.
convertDatatypesToIdl(rec: IdlObject) {
- const fields = this.idlDef.fields;
+ const fields = this.idlDef.fields.filter(f => !f.virtual);
+
fields.forEach(field => {
if (field.datatype === 'bool') {
if (rec[field.name]() === true) {
);
}
+ remove() {
+ this.confirmDel.open().subscribe(confirmed => {
+ if (!confirmed) { return; }
+ const recToRemove = this.idl.clone(this.record);
+ this.pcrud.remove(recToRemove).toPromise().then(
+ result => {
+ this.recordDeleted.emit(result);
+ this.successStr.current().then(msg => this.toast.success(msg));
+ if (this.isDialog()) { this.close(result); }
+ },
+ error => {
+ this.recordError.emit(error);
+ this.failStr.current().then(msg => this.toast.warning(msg));
+ if (this.isDialog()) { this.error(error); }
+ }
+ );
+ });
+ }
+
cancel() {
this.recordCanceled.emit(this.record);
this.close();
import {StringModule} from '@eg/share/string/string.module';
import {TranslateModule} from '@eg/share/translate/translate.module';
import {FmRecordEditorComponent} from './fm-editor.component';
+import {FmRecordEditorActionComponent} from './fm-editor-action.component';
@NgModule({
declarations: [
- FmRecordEditorComponent
+ FmRecordEditorComponent,
+ FmRecordEditorActionComponent
],
imports: [
EgCommonModule,
CommonWidgetsModule
],
exports: [
- FmRecordEditorComponent
+ FmRecordEditorComponent,
+ FmRecordEditorActionComponent
],
providers: [
]