import { nameof, assign, XParam, isFunction, XResourceIDs, XModelProperty, XModalButtonRole, XModelKeyProvider, isNullOrUndefined, isNullOrEmptyString, } from 'x-framework-core'; import { Subject } from 'rxjs'; import { XListItem, XIconNames, XPopoverComponent, XListItemSlideOption, XModelPresenterAction, XModelPresenterActionModel, } from 'x-framework-components'; import { Component } from '@angular/core'; import { XMarkdownMode } from 'x-framework-components'; import { VPageComponent } from '../../../views/v-page/v-page.component'; import { AppResourceIDs } from 'src/app/config/app.localization.config'; export interface DataMODEL { firstName: string; lastName: string; email: string; contacts: Array<{ type: 'mobile' | 'phone'; title: string; number: string; }>; checkList: { todo1: boolean; todo2: boolean; todo3: boolean; todo4: Array<{ action: string; dueData: Date; }>; }; } @Component({ selector: 'app-model-presenter', templateUrl: './model-presenter.page.html', styleUrls: ['./model-presenter.page.scss'], }) // tslint:disable-next-line:component-class-suffix export class ModelPresenterPage extends VPageComponent { // //#region Props ... // //#region Page Props ... titleRes = AppResourceIDs.model_presenter; toolbarTitle = this.resourceProvider(this.titleRes); toolbarSubTitle = this.resourceProvider( AppResourceIDs.model_presenter_description ); toolbarShowSubTitle = true; //#endregion // // Prepare All Resource IDs ... readonly ResourceIDs = Object.assign( Object.assign({}, XResourceIDs), AppResourceIDs ) as any; // readonly IconNames = Object.assign({}, XIconNames); //#endregion // readonly MarkdownModes = Object.assign({}, XMarkdownMode); // //#region Model Presenter ... dataModel: DataMODEL = { firstName: 'Hadi', lastName: 'Khazaee Asl', email: 'hadi_khazaee_asl@yahoo.com', contacts: [ { type: 'mobile', title: 'Personal', number: '09121694056', }, { type: 'phone', title: 'saherelm office', number: '02632757987', }, ], checkList: { todo1: true, todo2: false, todo3: true, todo4: [ { action: 'start', dueData: new Date(), }, { action: 'end', dueData: new Date(), }, ], }, }; actionProvider = new Subject(); availableModelKeys: string[] = [ nameof('lastName'), nameof('firstName'), nameof('email'), nameof('contacts'), nameof('checkList'), // // Contacts ... // `${nameof('contacts')}.type`, `${nameof('contacts')}.title`, // `${nameof('contacts')}.number`, // // Checklist ... `${nameof('checkList')}.todo1`, `${nameof('checkList')}.todo2`, `${nameof('checkList')}.todo3`, `${nameof('checkList')}.todo4`, // `${nameof('checkList')}.todo4.action`, `${nameof('checkList')}.todo4.dueData`, ]; hiddenModelKeys: string[] = [`${nameof('contacts')}.type`]; hiddenLabelModelKeys: string[] = [`${nameof('contacts')}.number`]; // sortOrederModelKeys: string[] = [ nameof('firstName'), nameof('lastName'), nameof('email'), nameof('contacts'), nameof('checkList'), // // Contacts ... `${nameof('contacts')}.number`, `${nameof('contacts')}.title`, // // Checklist ... `${nameof('checkList')}.todo4.dueData`, `${nameof('checkList')}.todo4.action`, ]; // modelKeyProvider: XModelKeyProvider = (key) => { // let result = key as string; // switch (key) { // case nameof('firstName'): result = this.resourceProvider(this.AppResourceIDs.first_name); break; // case nameof('lastName'): result = this.resourceProvider(this.AppResourceIDs.last_name); break; // case nameof('contacts'): result = this.resourceProvider(this.AppResourceIDs.content); break; // default: result = key as string; break; } // return result; }; //#endregion // // Content ... readonly contentFa = ` # ${this.toolbarTitle} این مولفه جهت نمایش و ویرایش یک شی یا مدل در نمایی ساختار یافته بکار می رود. `; readonly contentEn = ` # ${this.toolbarTitle} this component used to view and edit data models in an structural view. `; // readonly sample1 = '```html' + ` ` + '```'; readonly sample2 = '```html' + ` ` + '```'; readonly sample3 = '```javascript' + ` export interface DataMODEL { firstName: string; lastName: string; email: string; contacts: Array<{ type: 'mobile' | 'phone'; title: string; number: string; }>; checkList: { todo1: boolean; todo2: boolean; todo3: boolean; todo4: Array<{ action: string; dueData: Date; }>; }; } ` + '```'; readonly sample4 = '```javascript' + ` dataModel: DataMODEL = { firstName: 'Hadi', lastName: 'Khazaee Asl', email: 'hadi_khazaee_asl@yahoo.com', contacts: [ { type: 'mobile', title: 'Personal', number: '09121694056', }, { type: 'phone', title: 'saherelm office', number: '02632757987', }, ], checkList: { todo1: true, todo2: false, todo3: true, todo4: [ { action: 'start', dueData: new Date(), }, { action: 'end', dueData: new Date(), }, ], }, }; actionProvider = new Subject(); availableModelKeys: string[] = [ nameof('lastName'), nameof('firstName'), nameof('email'), nameof('contacts'), nameof('checkList'), // // Contacts ... \`\${nameof('contacts')}.type\`, \`\${nameof('contacts')}.title\`, \`\${nameof('contacts')}.number\`, // // Checklist ... \`\${nameof('checkList')}.todo1\`, \`\${nameof('checkList')}.todo2\`, \`\${nameof('checkList')}.todo3\`, \`\${nameof('checkList')}.todo4\`, // \`\${nameof('checkList')}.todo4.action\`, \`\${nameof('checkList')}.todo4.dueData\`, ]; hiddenModelKeys: string[] = [\`\${nameof('contacts')}.type\`]; hiddenLabelModelKeys: string[] = [\`\${nameof('contacts')}.number\`]; // sortOrederModelKeys: string[] = [ nameof('firstName'), nameof('lastName'), nameof('email'), nameof('contacts'), nameof('checkList'), // // Contacts ... \`\${nameof('contacts')}.number\`, \`\${nameof('contacts')}.title\`, // // Checklist ... \`\${nameof('checkList')}.todo4.dueData\`, \`\${nameof('checkList')}.todo4.action\`, ]; // modelKeyProvider: XModelPresenterModelKeyProvider = (key) => { // let result = key as string; // switch (key) { // case nameof('firstName'): result = this.resourceProvider(this.AppResourceIDs.first_name); break; // case nameof('lastName'): result = this.resourceProvider(this.AppResourceIDs.last_name); break; // case nameof('contacts'): result = this.resourceProvider(this.AppResourceIDs.content); break; // default: result = key as string; break; } // return result; }; ` + '```'; readonly sample5 = '```javascript' + ` async handlePropertyActionMenuClicked( key: string, prefix: string, value: any ) { // if (isNullOrEmptyString(key)) { return; } // const onlyIcon = false; const slideOptions: XListItemSlideOption[] = []; // // Edit ... slideOptions.push({ id: 'property_edit', icon: this.IconNames.edit, title: this.ResourceIDs.edit, color: isNullOrUndefined(value) ? this.ColorNames.Danger : this.ColorNames.Tertiary, slot: 'start', onlyIcon, handler: async () => { await this.handlePropertyEdit(key, prefix, value); }, }); // // Clear ... slideOptions.push({ id: 'property_clear', icon: this.IconNames.clear, title: this.ResourceIDs.clear, color: this.ColorNames.Danger, slot: 'start', disabled: isNullOrUndefined(value), onlyIcon, handler: async () => { await this.handlePropertyClear(key, prefix, value); }, }); // // Menu Items ... const item: XListItem = { data: '', slideOptions, }; // const popOver = await this.managerService.dialogService.presentPopover({ component: XPopoverComponent, componentProps: assign({}, { key: XParam.Item, value: item }), translucent: true, showBackdrop: true, event, }); // const { data } = await popOver.onWillDismiss(); if (!data || !data.id || !data.data) { return; } // const optionId = data.id.toString() as string; const option = item && item.slideOptions ? item.slideOptions.find((so) => so.id === optionId) : null; if (!option) { return; } // const handler = option.handler; if (!handler || !isFunction(handler)) { return; } // // Run Handler ... await handler(); } async handlePropertyEdit(key: string, prefix: string, value: any) { // if (isNullOrEmptyString(key)) { return; } // await this.managerService.dialogService.presentAlert({ header: 'Change Value:', message: 'Enter new Value:', inputs: [ { type: 'text', name: 'value', label: 'Value', placeholder: isNullOrUndefined(value) ? '' : \`\${value.toString()}\`, }, ], buttons: [ { text: 'Change', role: XModalButtonRole.Selected, cssClass: ['btn-selected'], handler: async (value) => { // let newValue = ''; if (value && value.value) { newValue = value.value; } // console.log('new value to set: ', newValue); // this.actionProvider.next({ action: XModelPresenterAction.SetProperty, payload: { key: key, value: newValue, keyPrefix: prefix, } as XModelPresenterProperty, }); }, }, { text: 'Cancel', role: XModalButtonRole.Cancel, cssClass: ['btn-cancel'], }, ], }); } async handlePropertyClear(key: string, prefix: string, value: any) { // if (isNullOrEmptyString(key) || isNullOrUndefined(value)) { return; } // await this.managerService.dialogService.presentAreYouSureYesNoDialog(() => { // this.actionProvider.next({ action: XModelPresenterAction.ClearProperty, payload: { key, keyPrefix: prefix, } as XModelPresenterProperty, }); }); } async handleModelChanged(event: any) { console.log('handle model changed: ', event); } ` + '```'; // readonly sample3 = // '```html' + // ` // ` + // '```'; // //#region UI Providers ... // // Provide content based on current locale ... getContent(title: string) { // if (isNullOrEmptyString(title)) { return ''; } // const currentLocale = this.managerService.currentLocale; // const varName = title + (currentLocale === 'en-US' ? 'En' : currentLocale === 'fa-IR' ? 'Fa' : ''); const result = this[`${varName}`]; // return result || ''; } //#endregion // //#region UI Handlers ... // //#region Model Presenter Handlers ... async handlePropertyActionMenuClicked( key: string, prefix: string, value: any ) { // if (isNullOrEmptyString(key)) { return; } // const onlyIcon = false; const slideOptions: XListItemSlideOption[] = []; // // Edit ... slideOptions.push({ id: 'property_edit', icon: this.IconNames.edit, title: this.ResourceIDs.edit, color: isNullOrUndefined(value) ? this.ColorNames.Danger : this.ColorNames.Tertiary, slot: 'start', onlyIcon, handler: async () => { await this.handlePropertyEdit(key, prefix, value); }, }); // // Clear ... slideOptions.push({ id: 'property_clear', icon: this.IconNames.clear, title: this.ResourceIDs.clear, color: this.ColorNames.Danger, slot: 'start', disabled: isNullOrUndefined(value), onlyIcon, handler: async () => { await this.handlePropertyClear(key, prefix, value); }, }); // // Menu Items ... const item: XListItem = { data: '', slideOptions, }; // const popOver = await this.managerService.dialogService.presentPopover({ component: XPopoverComponent, componentProps: assign({}, { key: XParam.Item, value: item }), translucent: true, showBackdrop: true, event, }); // const { data } = await popOver.onWillDismiss(); if (!data || !data.id || !data.data) { return; } // const optionId = data.id.toString() as string; const option = item && item.slideOptions ? item.slideOptions.find((so) => so.id === optionId) : null; if (!option) { return; } // const handler = option.handler; if (!handler || !isFunction(handler)) { return; } // // Run Handler ... await handler(); } async handlePropertyEdit(key: string, prefix: string, value: any) { // if (isNullOrEmptyString(key)) { return; } // await this.managerService.dialogService.presentAlert({ header: 'Change Value:', message: 'Enter new Value:', inputs: [ { type: 'text', name: 'value', label: 'Value', placeholder: isNullOrUndefined(value) ? '' : `${value.toString()}`, }, ], buttons: [ { text: 'Change', role: XModalButtonRole.Selected, cssClass: ['btn-selected'], handler: async (value) => { // let newValue = ''; if (value && value.value) { newValue = value.value; } // console.log('new value to set: ', newValue); // this.actionProvider.next({ action: XModelPresenterAction.SetProperty, payload: { prefix, key: key, value: newValue, } as XModelProperty, }); }, }, { text: 'Cancel', role: XModalButtonRole.Cancel, cssClass: ['btn-cancel'], }, ], }); } async handlePropertyClear(key: string, prefix: string, value: any) { // if (isNullOrEmptyString(key) || isNullOrUndefined(value)) { return; } // await this.managerService.dialogService.presentAreYouSureYesNoDialog(() => { // this.actionProvider.next({ action: XModelPresenterAction.ClearProperty, payload: { key, prefix, } as XModelProperty, }); }); } async handleModelChanged(event: any) { console.log('handle model changed: ', event); } //#endregion //#endregion }