import { Component, ViewChild, TemplateRef, ChangeDetectionStrategy, } from '@angular/core'; import { XFileDto, XPersonDto, XReferenceDto, defaultFileDto, fileEntityToDto, } from 'x-mabsut-api-sdk'; import { XRef, nameof, isFunction, getFieldNames, isNullOrUndefined, isNullOrEmptyString, XResourceIdentifier, getComponentSelector, XFileType, } from 'x-framework-core'; import { XListItem, XSlotName, XButtonType, XListItemOptionSlot, XActionBarActionFiredModel, defaultActionBarUploadItem, } from 'x-framework-components'; import { Observable, Subject } from 'rxjs'; import { VBaseDtoAction, VModelFieldTypes, VBaseDtoActionModel, VBaseDtoModelAction, VBaseDtoPresentType, VModelFieldDescriptor, VBaseDtoModelFiredActionModel, } from 'src/app/views/v-dto/v-dto.typings'; import { defaultEditFabButton, defaultOptionsFabItem, defaultRemoveFabButton, } from 'src/app/views/constants/fab.defaults'; import { toSimpleFabItems, XSimpleFabButton, } from 'src/app/views/typings/simple.fab.typings'; import { defaultEditSlideOption, defaultRemoveSlideOption, defaultDetailsSlideOption, } from 'src/app/views/constants/slide.options.defaults'; import { processFilledItems, VQueryPresenterTabs, VQueryPresenterAction, VQueryPresenterActionModel, VQueryPresenterActionIdentifier, VQueryFilledItemsProcessingResult, } from 'src/app/views/v-query-presenter/v-query-presenter.typings'; import { XQueryDto, XQueryResultDto } from 'x-framework-identity-sdk'; import { sendAction } from 'src/app/views/tools/action-provider.tools'; import { getFileTypeResourceID } from 'src/app/views/files/v-file.tools'; import { getPersonFullName } from 'src/app/views/v-person/v-person.tools'; import { PersonPresentType } from 'src/app/views/v-person/v-person.typings'; import { VFileComponent } from 'src/app/views/files/v-file/v-file.component'; import { VFilePresentType } from 'src/app/views/files/v-file/v-file.typings'; import { VDtoCommonProperties } from 'src/app/views/typings/dto.common.typings'; import { VMediaPresentType } from 'src/app/views/files/v-media/v-media.typings'; import { VPagePresenter } from 'src/app/views/v-page-presenter/v-page-presenter.component'; import { getQuerySelectorOfSpecifiedAttribute } from 'src/app/views/typings/common.typings'; import { XSimpleListItemSlideOption } from 'src/app/views/typings/simple.list-item.typings'; import { VQueryPresenterBasePage } from 'src/app/views/v-query-presenter/v-query-presenter.base.page'; @Component({ template: '', changeDetection: ChangeDetectionStrategy.OnPush, }) export abstract class FilesBaseProviderPage extends VQueryPresenterBasePage { // //#region Props ... toolbarShowTitle = true; toolbarShowSubTitle = true; titleRes = this.ResourceIDs.app_name; toolbarSubTitle = this.resourceProvider( this.AppResourceIDs.files_management_page_title ); toolbarTitle = this.resourceProvider(this.titleRes); // @ViewChild('pagePresenter') pagePresenter!: VPagePresenter; // @ViewChild('fileNameRef') fileNameRef!: TemplateRef; // readonly ButtonTypes = Object.assign(XButtonType, {}); readonly ModelFieldNames = getFieldNames(defaultFileDto); readonly ModelFieldTypes = Object.assign(VModelFieldTypes); readonly FilePresentTypes = Object.assign(VFilePresentType, {}); readonly MediaPresentTypes = Object.assign(VMediaPresentType, {}); readonly PersonPresentTypes = Object.assign(PersonPresentType, {}); readonly BasePresentTypes = Object.assign(VBaseDtoPresentType, {}); // // Prepare Commonly Used Properties for Dto Actions ... // we can Override this for other Purposes ... commonViewsProperties: VDtoCommonProperties = { isInPage: false, wrapWithCard: false, labelColor: undefined, valueColor: undefined, fieldFormButtonPosition: undefined, fieldFormIcon: undefined, fieldFormIconColor: undefined, fieldFormApplyIcon: undefined, fieldFormApplyIconColor: undefined, fieldFormCancelIcon: undefined, fieldFormCancelIconColor: undefined, removeCardMargin: undefined, cardForegroundColor: undefined, cardCssClass: undefined, cardColor: undefined, cardActionProvider: undefined, formAppearance: undefined, formActionProvider: undefined, formRegularColor: undefined, formAccentColor: undefined, formHintColor: undefined, formActiveColor: undefined, formValidColor: undefined, formInvalidColor: undefined, formPendingColor: undefined, formFillColor: undefined, formDisabledColor: undefined, formDisabledFillColor: undefined, showFormCancelButton: undefined, formCancelButtonResource: undefined, formCancelButtonColor: undefined, formResetButtonResource: undefined, formResetButtonColor: undefined, formActionButtonAddResource: undefined, formActionButtonUpdateResource: undefined, formActionButtonColor: undefined, }; // //#region Query Presenter Props ... modelIdentifier: string = nameof('id'); listTabCardTitle: XResourceIdentifier = this.AppResourceIDs.files; /** * Presenter Component Action Provider ... */ queryPresenterActionProvider = new Subject(); //#endregion //#endregion /** * Specified How to get Specific Item using Model Identifier ... */ abstract getModelTask(identifier: string): Observable; /** * Specified How to Query Items ... */ abstract queryModelTask(query: XQueryDto): Observable>; /** * Param Recieved Action ... */ paramAction: string = undefined; // //#region LifeCycles ... async afterViewInit(): Promise { await super.afterViewInit(); // this.applyTakeUntilWrapper( this.managerService.settingsService.isMobile$ ).subscribe((res) => { // if (!isNullOrUndefined(this.activeTab)) { // switch (this.activeTab) { // case VQueryPresenterTabs.List: sendAction({ provider: this.listItemActionProvider, action: VBaseDtoAction.Refresh, }); break; } } }); // this.handleAttachTemplates(); await this.handleConnectPushService(); } //#endregion // //#region Providers ... //#endregion // //#region List ... /** * Provides List Item Template ... */ @ViewChild('itemTemplate') itemTemplate!: TemplateRef; /** * Provides List Item Template ... */ @ViewChild('listItemTemplate') listItemTemplate!: TemplateRef; // //#region Owner Custom Template for List Item View ... private LIST_OWNER_REF: TemplateRef; @ViewChild('listOwnerRef') set listOwnerRef(v: TemplateRef) { // this.LIST_OWNER_REF = v; this.applyListOwnerRef(); } get listOwnerRef() { return this.LIST_OWNER_REF; } //#endregion /** * Query Object for Fetching Data ... */ query: XQueryDto = { page: 1, filter: '', pageSize: this.config.defaultPageSize, sortBy: nameof('uploadedOn'), }; /** * a Flag for Detect Has Query result or not ... */ hasQueryResultError: boolean = false; /** * Fetching Data Result Model ... */ dtoQueryResult: XQueryResultDto = undefined; /** * Specified Action Provider ... */ listItemActionProvider = new Subject(); /** * Specified View Properties ... */ listItemViewProperties: VDtoCommonProperties = { ...this.commonViewsProperties, }; /** * Specified Field Descriptors for List Items ... */ listItemViewFieldDescriptors: VModelFieldDescriptor[] = [ // // Type ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.type, label: this.ResourceIDs.type, key: this.ModelFieldNames.type, type: this.ModelFieldTypes.Number, valueProvider: (value) => { return this.applyLocale( this.resourceProvider(getFileTypeResourceID(value)) ); }, } as VModelFieldDescriptor, // // FileName ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.fileName, type: this.ModelFieldTypes.String, key: this.ModelFieldNames.fileName, label: this.AppResourceIDs.file_name, valueProvider: (value) => { return this.applyLocale(value); }, } as VModelFieldDescriptor, // // Name ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.name, key: this.ModelFieldNames.name, label: this.AppResourceIDs.name, type: this.ModelFieldTypes.String, } as VModelFieldDescriptor, // // UploadedOn ... { hide: false, hideLabel: false, allowFieldForm: false, type: this.ModelFieldTypes.Date, value: defaultFileDto.uploadedOn, key: this.ModelFieldNames.uploadedOn, label: this.AppResourceIDs.uploaded_on, valueProvider: (value: Date) => { // if (isNullOrUndefined(value)) { return ''; } // return this.applyDefaultDate(value); }, } as VModelFieldDescriptor, // // Path ... { hide: false, hideLabel: true, allowFieldForm: false, hasCustomTemplate: true, value: defaultFileDto.path, key: this.ModelFieldNames.path, label: this.AppResourceIDs.path, type: this.ModelFieldTypes.String, } as VModelFieldDescriptor, // // Owner ... { hide: false, hideLabel: false, hasCustomTemplate: true, showContentBelowLabel: true, value: defaultFileDto.owner, key: this.ModelFieldNames.owner, label: this.AppResourceIDs.author, type: this.ModelFieldTypes.Object, } as VModelFieldDescriptor, // // // // References ... // { // hide: false, // hideLabel: false, // allowFieldForm: false, // value: defaultFileDto.references, // type: this.ModelFieldTypes.Array, // key: this.ModelFieldNames.references, // label: this.AppResourceIDs.references, // hasCustomTemplate: true, // showContentBelowLabel: true, // pushArrayChildsOnceToTemplate: true, // } as VModelFieldDescriptor>>, ]; /** * Get File Owner Full Name ... * * @param model * @returns */ getOwnerFullName(model: XPersonDto) { return getPersonFullName(model); } /** * Hold each Items Provided Actions based on Identifier ... */ itemsActions = new Map>>(); /** * Prepare Item Actions based on Slot ... */ getSlottedItemActions(slot: XSlotName, model: XFileDto) { // let result: Array = []; // if ( isNullOrUndefined(model) || isNullOrEmptyString(slot) || isNullOrEmptyString(model.id) || isNullOrUndefined(this.itemsActions) || !this.itemsActions.has(model.id) ) { return result; } // let _slot: XListItemOptionSlot = slot === XSlotName.START || slot === XSlotName.TOP ? 'start' : 'end'; // result = this.itemsActions .get(model.id) .value.filter((a) => a.slot === _slot); // return result; } /** * Handle Non As List Item's Action ... * * @param id * @param data */ async handleItemAction(id: string, data: XFileDto) { // // Validate ... if ( this.loading || this.uiDisabled || isNullOrEmptyString(id) || isNullOrUndefined(data) ) { return; } // await this.doItemActions({ id, data }); } /** * Apply List Owner Template to Descriptors ... * * @returns */ applyListOwnerRef() { // if (isNullOrUndefined(this.LIST_OWNER_REF)) { return; } // this.listItemViewFieldDescriptors = this.listItemViewFieldDescriptors.map( (fd) => { // return { ...fd, template: fd.key === this.ModelFieldNames.owner ? this.LIST_OWNER_REF : fd.template, }; } ); } /** * Handle Retrieve Data based on XQuery ... * * @param query * @returns */ async handleGetQueryResult( query: XQueryDto ): Promise> { // let result: XQueryResultDto = undefined; // // Start Loading ... this.hasQueryResultError = false; await this.setLoadingState(true); // // Try to Prepare Result ... try { // // Retrieve File Dto Result ... this.dtoQueryResult = await this.getValueAsync( this.queryModelTask(query) ); // // Prepare Result ... result = { ...result, page: this.dtoQueryResult.page, pageSize: this.dtoQueryResult.pageSize, totalItems: this.dtoQueryResult.totalItems, totalPages: this.dtoQueryResult.totalPages, totalFilteredItems: this.dtoQueryResult.totalFilteredItems, totalFilteredPages: this.dtoQueryResult.totalFilteredPages, }; // // Converts XFileDto to XFileDto ... result.items = this.dtoQueryResult.items.map((i) => i); // // Remove Scrolling Info ... if ( !isNullOrUndefined(this.query) && this.query.filter !== query.filter ) { // this.removeScrollingInfo(); this.infinityScrollDisabled = true; } // this.query = query; } catch { // this.hasQueryResultError = true; await this.handleCustomError('QueryFilesError'); return result; } // // Stop Loading ... await this.setLoadingState(false); // return result; } /** * Get Specified Model Based on Identifier ... * * @param identifier * @param applyState * @returns */ async handleGetSpecifiedModel(identifier: string, applyState = false) { // if (isNullOrEmptyString(identifier)) { return; } // let response: any = undefined; try { // if (applyState) { await this.setLoadingState(true); } // response = await this.getValueAsync(this.getModelTask(identifier)); // } catch { // await this.handleCustomError('GetFileError'); return; } // if (applyState) { await this.setLoadingState(false); } // return response; } /** * Provide List Actions for Specific Model ... * * @param model * @returns */ async prepareListActions(model: XFileDto) { // const userId = await this.getValueAsync(this.sharedService.userId$); const isAdmin = await this.getValueAsync(this.sharedService.isAdmin$); // return this.provideItemOptions(userId, isAdmin, model); } /** * Validate List Items ... * * @param items * @returns */ async validateAndPrepareListItems( items: Array> ): Promise>> { // let result: Array> = []; // // Preparing Slide Options ... result = await Promise.all([ ...items.map(async (i) => { return { ...i, slideOptions: [...(await this.prepareListActions(i.data))], }; }), ]); // return result; } /** * Prepare Result for Non As List Presenting Items ... * * @param current * @param recieved */ async requestFillingItems( exists: Array, recieved: Array ): Promise> { // let result: VQueryFilledItemsProcessingResult = processFilledItems(exists, recieved, 'id'); // // Filling Actions ... if (!isNullOrUndefined(result)) { // // News Items Actions ... if (!isNullOrUndefined(result.news) && this.hasChild(result.news)) { // result.news.forEach(async (i) => { // const actions = await this.prepareListActions(i); this.itemsActions.set(i.id, { value: actions }); }); } // // Changed Items Actions ... if (!isNullOrUndefined(result.changed) && this.hasChild(result.changed)) { // result.changed.forEach(async (i) => { // if (this.itemsActions.has(i.identifier)) { // const actions = await this.prepareListActions(i.data); this.itemsActions.set(i.identifier, { value: actions }); } }); } } // return result; } /** * When Non as List Items Filled, this method call for Change Detection ... * * @param ids */ async handleRefreshViews(ids: Array): Promise { await super.handleRefreshViews(ids); // if (isNullOrUndefined(ids) || !this.hasChild(ids)) { return; } // const selector = getComponentSelector(VFileComponent); ids.forEach((id) => { // const iSelector = `${selector}[${nameof( 'id' )}="${id}"][${nameof('presentType')}="${ VBaseDtoPresentType.AsView }"]`; this.waitForElement(iSelector).then((el) => { this.listItemActionProvider.next({ action: VBaseDtoAction.Refresh }); }); }); } //#endregion // //#region Add ... /** * Provides Template for Adding Items ... */ @ViewChild('addItemTemplate') addItemTemplate!: TemplateRef; /** * a Model for Providing to Add ... */ addModel: XFileDto = { ...defaultFileDto, }; /** * Specified Action Provider ... */ addItemActionProvider = new Subject(); /** * Specify View Properties for Add ... */ addModelViewProperties: VDtoCommonProperties = { ...this.commonViewsProperties, isInPage: true, wrapWithCard: true, }; /** * Describe Add Model Fields ... */ addModelViewFieldDescriptors: VModelFieldDescriptor[] = [ // // Type ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.type, label: this.ResourceIDs.type, key: this.ModelFieldNames.type, type: this.ModelFieldTypes.Number, valueProvider: (value) => { return this.applyLocale( this.resourceProvider(getFileTypeResourceID(value)) ); }, } as VModelFieldDescriptor, // // FileName ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.fileName, type: this.ModelFieldTypes.String, key: this.ModelFieldNames.fileName, label: this.AppResourceIDs.file_name, valueProvider: (value) => { return this.applyLocale(value); }, } as VModelFieldDescriptor, // // Name ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.name, key: this.ModelFieldNames.name, label: this.AppResourceIDs.name, type: this.ModelFieldTypes.String, } as VModelFieldDescriptor, // // UploadedOn ... { hide: false, hideLabel: false, allowFieldForm: false, type: this.ModelFieldTypes.Date, value: defaultFileDto.uploadedOn, key: this.ModelFieldNames.uploadedOn, label: this.AppResourceIDs.uploaded_on, valueProvider: (value: Date) => { // if (isNullOrUndefined(value)) { return ''; } // return this.applyDefaultDate(value); }, } as VModelFieldDescriptor, // // Path ... { hide: false, hideLabel: true, allowFieldForm: false, hasCustomTemplate: true, value: defaultFileDto.path, key: this.ModelFieldNames.path, label: this.AppResourceIDs.path, type: this.ModelFieldTypes.String, } as VModelFieldDescriptor, // // Owner ... { hide: false, hideLabel: false, hasCustomTemplate: true, showContentBelowLabel: true, value: defaultFileDto.owner, key: this.ModelFieldNames.owner, label: this.AppResourceIDs.author, type: this.ModelFieldTypes.Object, } as VModelFieldDescriptor, // // // // References ... // { // hide: false, // hideLabel: false, // allowFieldForm: false, // value: defaultFileDto.references, // type: this.ModelFieldTypes.Array, // key: this.ModelFieldNames.references, // label: this.AppResourceIDs.references, // hasCustomTemplate: true, // showContentBelowLabel: true, // pushArrayChildsOnceToTemplate: true, // } as VModelFieldDescriptor>>, ]; /** * Handle Locking Page when a Form Lock Content ... * * @param event */ handleAddViewLockNotifier(event: { id: string; state: boolean }) { this.lock = event.state; } /** * Handle Actiond Fired form FileUpload ... * * @param event * @returns */ async handleFileUploadActionFired(event: XActionBarActionFiredModel) { // // Validate ... if (isNullOrUndefined(event) || isNullOrEmptyString(event.action)) { return; } // // Upload ... if (event.action === defaultActionBarUploadItem.id) { // await this.handleAddModel({ ...defaultFileDto }); } } /** * Holding File(s) for Upload ... */ filesForUpload: Array = []; handleFileUploadFilesChanged(event: Array) { // // Update Files For Upload List ... if (isNullOrUndefined(event)) { this.filesForUpload = []; } else { this.filesForUpload = [...event]; } } /** * Handle Cancel Add Form View ... * * @param event */ async handleAddViewActionFired(event: VBaseDtoModelFiredActionModel) { // // Cancel Form ... if (event.action === VBaseDtoModelAction.Cancel) { // // Since Cancel only Fired when Lock Breaked, here we do not need to handle it ... this.sendQueryPresenterAction( VQueryPresenterAction.ChangeTab, this.prevTab || VQueryPresenterTabs.List ); } // // Reset Form ... else if (event.action === VBaseDtoModelAction.Reset) { } // // Add Or Update Form ... else if (event.action === VBaseDtoModelAction.AddOrUpdate) { // const pModel: Required = { ...event.payload.model, } as Required; await this.handleAddModel(pModel); } } /** * Do Add Model ... * * @param model * @returns */ async handleAddModel(model: XFileDto) { // if (isNullOrUndefined(model) || !this.hasChild(this.filesForUpload)) { return; } // await this.setLoadingState(true); // let response: Array = undefined; try { // // Retrieve Connection ID ... const connectionId = this.sharedService.mabsutAPIService.files.fileEntityPushService .connectionId; // // Issue Task ... response = await this.getValueAsync( this.sharedService.mabsutAPIService.files.fileProviderService.upload( [...this.filesForUpload], // Model ... connectionId // Connection Id ... ) ); } catch (ex) { // await this.handleCustomError('AddModelError'); return; } // this.lock = false; this.filesForUpload = []; this.addModel = undefined; this.showSuccess(); await this.setLoadingState(false); this.sendQueryPresenterAction(VQueryPresenterAction.ResetQuery, true); } //#endregion // //#region Update ... /** * Provides Template for Update Items ... */ @ViewChild('updateItemTemplate') updateItemTemplate!: TemplateRef; /** * a Model for Providing to Update ... */ updateModel: XFileDto = undefined; /** * Specified Action Provider ... */ updateItemActionProvider = new Subject(); /** * Specify View Properties for Update ... */ updateModelViewProperties: VDtoCommonProperties = { ...this.commonViewsProperties, isInPage: true, wrapWithCard: true, }; /** * Describe Update Model Fields ... */ updateModelViewFieldDescriptors: VModelFieldDescriptor[] = [ // // Type ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.type, label: this.ResourceIDs.type, key: this.ModelFieldNames.type, type: this.ModelFieldTypes.Number, valueProvider: (value) => { return this.applyLocale( this.resourceProvider(getFileTypeResourceID(value)) ); }, } as VModelFieldDescriptor, // // FileName ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.fileName, type: this.ModelFieldTypes.String, key: this.ModelFieldNames.fileName, label: this.AppResourceIDs.file_name, valueProvider: (value) => { return this.applyLocale(value); }, } as VModelFieldDescriptor, // // Name ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.name, key: this.ModelFieldNames.name, label: this.AppResourceIDs.name, type: this.ModelFieldTypes.String, } as VModelFieldDescriptor, // // UploadedOn ... { hide: false, hideLabel: false, allowFieldForm: false, type: this.ModelFieldTypes.Date, value: defaultFileDto.uploadedOn, key: this.ModelFieldNames.uploadedOn, label: this.AppResourceIDs.uploaded_on, valueProvider: (value: Date) => { // if (isNullOrUndefined(value)) { return ''; } // return this.applyDefaultDate(value); }, } as VModelFieldDescriptor, // // Path ... { hide: false, hideLabel: true, allowFieldForm: false, hasCustomTemplate: true, value: defaultFileDto.path, key: this.ModelFieldNames.path, label: this.AppResourceIDs.path, type: this.ModelFieldTypes.String, } as VModelFieldDescriptor, // // Owner ... { hide: false, hideLabel: false, hasCustomTemplate: true, showContentBelowLabel: true, value: defaultFileDto.owner, key: this.ModelFieldNames.owner, label: this.AppResourceIDs.author, type: this.ModelFieldTypes.Object, } as VModelFieldDescriptor, // // // // References ... // { // hide: false, // hideLabel: false, // allowFieldForm: false, // value: defaultFileDto.references, // type: this.ModelFieldTypes.Array, // key: this.ModelFieldNames.references, // label: this.AppResourceIDs.references, // hasCustomTemplate: true, // showContentBelowLabel: true, // pushArrayChildsOnceToTemplate: true, // } as VModelFieldDescriptor>>, ]; /** * Handle Locking Page when a Form Lock Content ... * * @param event */ handleUpdateViewLockNotifier(event: { id: string; state: boolean }) { this.lock = event.state; } /** * Tags Actions Provider for Details Section ... * * @param t * @returns */ detailsTagsActionsProvider: (t: string) => Array = (t) => { return []; }; /** * Files Actions Provider for Details Section ... * * @param f * @returns */ detailsFilesActionsProvider: ( f: XFileDto | File ) => Array = (f) => { return []; }; /** * Handle Cancel Update Form View ... * * @param event */ async handleUpdateViewActionFired(event: VBaseDtoModelFiredActionModel) { // // Cancel Form ... if (event.action === VBaseDtoModelAction.Cancel) { // // Since Cancel only Fired when Lock Breaked, here we do not need to handle it ... this.sendQueryPresenterAction( VQueryPresenterAction.ChangeTab, this.prevTab || VQueryPresenterTabs.List ); } // // Reset Form ... else if (event.action === VBaseDtoModelAction.Reset) { } // // Add Or Update Form ... else if (event.action === VBaseDtoModelAction.AddOrUpdate) { // const pModel: Required = { ...event.payload.model, } as Required; await this.handleUpdateModel(pModel); } } /** * Do Update Model ... * * @param model * @returns */ async handleUpdateModel(model: XFileDto) { // const prevTab = this.prevTab; // if (isNullOrUndefined(model)) { return; } // await this.setLoadingState(true); // let response: XFileDto = undefined; try { // // Prepare Dto Model to Add ... const dto = !isNullOrUndefined(this.dtoQueryResult) && !isNullOrUndefined(this.dtoQueryResult.items) && this.hasChild(this.dtoQueryResult.items) ? this.dtoQueryResult.items.find((i) => i.id === model.id) : undefined; if (isNullOrUndefined(dto)) { throw 'UpdateModelError'; } // // Preparing Update Model ... const dtoModel = { ...model }; // // Retrieve Connection ID ... const connectionId = this.sharedService.mabsutAPIService.files.fileEntityPushService .connectionId; // // Filling Owner ID ... dtoModel.ownerId = await this.getValueAsync(this.sharedService.userId$); // // Issue Task ... // response = await this.getValueAsync( // this.sharedService.mabsutAPIService.files.fileProviderService.update( // dtoModel.id, // dtoModel, // connectionId // ) // ); } catch (ex) { // await this.handleCustomError('UpdateModelError'); return; } // if (isNullOrUndefined(response)) { // await this.handleCustomError('UpdateModelError'); return; } // this.lock = false; this.updateModel = undefined; await this.setLoadingState(false); this.showSuccess(); // this.prevTab = prevTab; model = { ...response }; const actions = await this.prepareListActions(model); // if (this.prevTab === VQueryPresenterTabs.Details) { // this.detailsModel = { ...model, }; } // this.sendQueryPresenterAction(VQueryPresenterAction.UpdateModel, { model, actions, key: nameof('id'), }); // // Check Handle Back ... if ( this.toolbarHasBack && this.toolbarShowBack && isFunction(this.toolbarBackHandler) ) { await this.toolbarBackHandler(); } } //#endregion // //#region Details ... /** * Provides Template for Details Items ... */ @ViewChild('detailsItemTemplate') detailsItemTemplate!: TemplateRef; /** * a Model for Providing to Details ... */ detailsModel: XFileDto = undefined; /** * Specified Action Provider ... */ detailsItemActionProvider = new Subject(); /** * Specify View Properties for Details ... */ detailsModelViewProperties: VDtoCommonProperties = { ...this.commonViewsProperties, isInPage: true, wrapWithCard: true, }; /** * Describe Details Model Fields ... */ detailsModelViewFieldDescriptors: VModelFieldDescriptor[] = [ // // Type ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.type, label: this.ResourceIDs.type, key: this.ModelFieldNames.type, type: this.ModelFieldTypes.Number, valueProvider: (value) => { return this.applyLocale( this.resourceProvider(getFileTypeResourceID(value)) ); }, } as VModelFieldDescriptor, // // FileName ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.fileName, type: this.ModelFieldTypes.String, key: this.ModelFieldNames.fileName, label: this.AppResourceIDs.file_name, valueProvider: (value) => { return this.applyLocale(value); }, } as VModelFieldDescriptor, // // Name ... { hide: false, hideLabel: false, allowFieldForm: false, value: defaultFileDto.name, key: this.ModelFieldNames.name, label: this.AppResourceIDs.name, type: this.ModelFieldTypes.String, } as VModelFieldDescriptor, // // UploadedOn ... { hide: false, hideLabel: false, allowFieldForm: false, type: this.ModelFieldTypes.Date, value: defaultFileDto.uploadedOn, key: this.ModelFieldNames.uploadedOn, label: this.AppResourceIDs.uploaded_on, valueProvider: (value: Date) => { // if (isNullOrUndefined(value)) { return ''; } // return this.applyDefaultDate(value); }, } as VModelFieldDescriptor, // // Path ... { hide: false, hideLabel: true, allowFieldForm: false, hasCustomTemplate: true, value: defaultFileDto.path, key: this.ModelFieldNames.path, label: this.AppResourceIDs.path, type: this.ModelFieldTypes.String, } as VModelFieldDescriptor, // // Owner ... { hide: false, hideLabel: false, hasCustomTemplate: true, showContentBelowLabel: true, value: defaultFileDto.owner, key: this.ModelFieldNames.owner, label: this.AppResourceIDs.author, type: this.ModelFieldTypes.Object, } as VModelFieldDescriptor, // // // // References ... // { // hide: false, // hideLabel: false, // allowFieldForm: false, // value: defaultFileDto.references, // type: this.ModelFieldTypes.Array, // key: this.ModelFieldNames.references, // label: this.AppResourceIDs.references, // hasCustomTemplate: true, // showContentBelowLabel: true, // pushArrayChildsOnceToTemplate: true, // } as VModelFieldDescriptor>>, ]; /** * Provides Card Title for Specified Model ... * * @param model * @returns */ getModelCardTitle(model: XFileDto) { // // Since card title's are Rescource ID's ... return this.applyLocale(`${model.fileName} `); } //#endregion // //#region Handlers ... /** * Handle Errors ... * * @param error */ async handleCustomError( error?: VQueryPresenterActionIdentifier ): Promise { // await this.setLoadingState(false); // // TODO: Implement this ... console.log('handle Custom Error: ', error); } /** * Override this for adding additional futures ... * * @param tab */ async handleStateAfterTabOpen(tab: number) { await super.handleStateAfterTabOpen(tab); // let selector: string = undefined; let fabs: XSimpleFabButton[] = []; let model: XFileDto = undefined; // // Remove Edit From Fab Actions ... let actions = await toSimpleFabItems(this.actions); if (!isNullOrUndefined(actions) && this.hasChild(actions.childs)) { actions = { ...actions, childs: [ ...actions.childs.filter((ch) => ch.id !== defaultEditFabButton.id), ], }; } this.closeActions(); this.actions = undefined; // const userId = await this.getValueAsync(this.sharedService.userId$); const isAdmin = await this.getValueAsync(this.sharedService.isAdmin$); const isAgent = await this.getValueAsync(this.sharedService.isAgent$); const isAdminAgent = isAdmin || isAgent; // switch (tab) { // case VQueryPresenterTabs.List: // // if Show Items as List ... if (this.showItemsAsList) { // sendAction({ provider: this.listItemActionProvider, action: VBaseDtoAction.SetProperties, payload: { props: { ...this.listItemViewProperties }, }, }); } else { // // Call each Items Action Provider Separately ... // // Prepare Non As List Items Properties ... const properties: VDtoCommonProperties = { ...this.listItemViewProperties, isInPage: true, wrapWithCard: true, cardShowActions: true, // Since Each Items has Separate Actions ... }; // sendAction({ provider: this.listItemActionProvider, action: VBaseDtoAction.SetProperties, payload: { props: { ...properties }, }, }); } // break; // case VQueryPresenterTabs.Add: // this.addModel = { ...defaultFileDto, }; // sendAction({ provider: this.addItemActionProvider, action: VBaseDtoAction.SetProperties, payload: { props: { ...this.addModelViewProperties }, }, }); break; // case VQueryPresenterTabs.Update: // model = { ...this.updateModel }; // sendAction({ provider: this.updateItemActionProvider, action: VBaseDtoAction.SetProperties, payload: { props: { ...this.updateModelViewProperties }, }, }); break; // case VQueryPresenterTabs.Details: // model = { ...this.detailsModel }; // sendAction({ provider: this.detailsItemActionProvider, action: VBaseDtoAction.SetProperties, payload: { props: { ...this.detailsModelViewProperties }, }, }); // // Adding Custom Actions ... // let isOwner = this.detailsModel.ownerId === userId; // // Actions Preparing ... actions = { ...(!isNullOrUndefined(actions) ? actions : defaultOptionsFabItem), childs: [ ...(!isNullOrUndefined(actions) && this.hasChild(actions.childs) ? actions.childs : []), ...fabs, ], }; // // Issue Action if Waiting for Details ... if (!isNullOrEmptyString(this.paramAction)) { // const action = this.paramAction; this.paramAction = undefined; // await this.doItemActions({ id: action, data: { ...this.detailsModel }, }); } break; } // // Here can Handle Actions Permissions and States ... if (!isNullOrUndefined(actions)) { // // Only if model Exists ... if (!isNullOrUndefined(model)) { // // Retrieve Requirements ... // const isOwner = model.ownerId === userId; // const canRemove = isOwner || isAdmin; // // Remove ... if ( actions.id === defaultRemoveFabButton.id || (!isNullOrUndefined(actions.childs) && this.hasChild(actions.childs) && actions.childs.findIndex( (a) => a.id === defaultRemoveFabButton.id )) >= 0 ) { // if (actions.id === defaultRemoveFabButton.id) { actions.disabled = !canRemove || actions.disabled || this.loading || this.uiDisabled; } else { // actions.childs = [ ...actions.childs.map((ch) => { return { ...ch, disabled: ch.id === defaultRemoveFabButton.id ? !canRemove || ch.disabled || this.loading || this.uiDisabled : ch.disabled, }; }), ]; } } } // // Update Actions ... this.actions = { ...actions, }; } } /** * Override this for adding additional futures ... * * @param from * @param to */ async handleStateBeforeTabOpen(from: number, to: number) { await super.handleStateBeforeTabOpen(from, to); // this.closeActions(); // switch (to) { // case VQueryPresenterTabs.List: // this.addModel = undefined; this.updateModel = undefined; this.detailsModel = undefined; break; // case VQueryPresenterTabs.Add: // this.updateModel = undefined; this.detailsModel = undefined; break; // case VQueryPresenterTabs.Update: // this.addModel = undefined; this.detailsModel = undefined; break; // case VQueryPresenterTabs.Details: // if ( isNullOrUndefined(this.detailsModel) && !isNullOrUndefined(this.updateModel) && from === VQueryPresenterTabs.Update ) { // this.detailsModel = { ...this.updateModel, }; } // this.addModel = undefined; this.updateModel = undefined; break; } } /** * Here We Do All Items Based Actions ... * * @param info * @returns */ async doItemActions(info: { id: string; data: XFileDto }): Promise { // if (isNullOrUndefined(info) || isNullOrEmptyString(info.id)) { return; } // let isKnown = false; // // Details ... isKnown = info.id === defaultDetailsSlideOption.id; if (isKnown) { // this.detailsModel = { ...info.data, }; // this.sendQueryPresenterAction( VQueryPresenterAction.ChangeTab, VQueryPresenterTabs.Details ); } // // Edit ... isKnown = info.id === defaultEditSlideOption.id || info.id === defaultEditFabButton.id; if (isKnown) { // if (!isNullOrUndefined(info.data)) { // this.updateModel = { ...info.data, }; } else if ( !isNullOrUndefined(this.detailsModel) && this.activeTab === VQueryPresenterTabs.Details ) { // this.updateModel = { ...this.detailsModel, }; } // if (!isNullOrUndefined(this.updateModel)) { // this.sendQueryPresenterAction( VQueryPresenterAction.ChangeTab, VQueryPresenterTabs.Update ); } } // // Remove ... isKnown = info.id === defaultRemoveSlideOption.id || info.id === defaultRemoveFabButton.id; if (isKnown) { // if ( isNullOrUndefined(info.data) && !isNullOrUndefined(this.detailsModel) && this.activeTab === VQueryPresenterTabs.Details ) { // info.data = { ...this.detailsModel, }; } // if (!isNullOrUndefined(info.data)) { await this.handleRemoveFile(info.data); } } } /** * Handle Specified Param ... * * @param identifier * @param acttion */ async handleParamAction(identifier: string, action: string): Promise { await super.handleParamAction(identifier, action); // if (isNullOrEmptyString(identifier) || isNullOrEmptyString(action)) { // this.hasParams = false; return; } // let model = await this.handleGetSpecifiedModel(identifier, true); if (!isNullOrUndefined(model)) { // this.paramAction = action; this.detailsModel = { ...model }; this.activeTab = VQueryPresenterTabs.Details; this.sendQueryPresenterAction( VQueryPresenterAction.ChangeTab, this.activeTab ); } else { this.hasParams = false; } } /** * Handle Removing File ... * * @param model */ async handleRemoveFile(model: XFileDto) { // await this.doConfirmedAction(async () => { // await this.setLoadingState(true); // try { // const connectionId = this.sharedService.mabsutAPIService.files.fileEntityPushService .connectionId; // await this.getValueAsync( this.sharedService.mabsutAPIService.files.fileProviderService.remove( model.id, connectionId ) ); } catch { // await this.handleCustomError('RemoveModelError'); return; } // this.sendQueryPresenterAction(VQueryPresenterAction.RemoveModel, { model, actions: [], key: nameof('id'), }); // this.showSuccess(); await this.setLoadingState(false); // // Handle Change Tabs if in Details ... if ( this.activeTab === VQueryPresenterTabs.List || this.activeTab === VQueryPresenterTabs.Details ) { // this.prevTab = undefined; this.sendQueryPresenterAction( VQueryPresenterAction.ChangeTab, VQueryPresenterTabs.List ); } }); } /** * Handle Running toolbar Back Handler on Specified Case * when User Pressed Escape Button ... * * @param event * @returns */ async handleGlobalEscapePressed(event: any) { // if ( this.lock || !this.toolbarHasBack || !this.toolbarShowBack || !isFunction(this.toolbarBackHandler) || [VQueryPresenterTabs.Add, VQueryPresenterTabs.Update].includes( this.activeTab ) ) { return; } // await this.toolbarBackHandler(); } //#endregion // //#region Private ... private provideItemOptions(userId: string, isAdmin: boolean, item: XFileDto) { // let result: Array = []; // // Validate ... if (!isNullOrUndefined(item) && !isNullOrEmptyString(userId)) { // const isOwner = item.ownerId === userId; // const canRemove = isOwner || isAdmin; // // Details ... result.push({ ...defaultDetailsSlideOption, slot: 'start', disabled: this.loading || this.uiDisabled, } as XSimpleListItemSlideOption); // // Remove ... result.push({ ...defaultRemoveSlideOption, slot: 'end', disabled: this.loading || this.uiDisabled || !canRemove, } as XSimpleListItemSlideOption); } // return result; } private handleAttachTemplates() { // // List Item ... let hasTemplate = !isNullOrUndefined( this.listItemViewFieldDescriptors.find( (fd) => fd.key === this.ModelFieldNames.path && !!fd.hasCustomTemplate && !isNullOrUndefined(fd.template) ) ); if (!hasTemplate && !isNullOrUndefined(this.fileNameRef)) { // this.listItemViewFieldDescriptors = this.listItemViewFieldDescriptors.map( (fd) => { // return { ...fd, template: fd.key === this.ModelFieldNames.path && !!fd.hasCustomTemplate && isNullOrUndefined(fd.template) ? this.fileNameRef : fd.template, }; } ); } // // Add Item ... hasTemplate = !isNullOrUndefined( this.addModelViewFieldDescriptors.find( (fd) => fd.key === this.ModelFieldNames.path && !!fd.hasCustomTemplate && !isNullOrUndefined(fd.template) ) ); if (!hasTemplate && !isNullOrUndefined(this.fileNameRef)) { // this.addModelViewFieldDescriptors = this.addModelViewFieldDescriptors.map( (fd) => { // return { ...fd, template: fd.key === this.ModelFieldNames.path && !!fd.hasCustomTemplate && isNullOrUndefined(fd.template) ? this.fileNameRef : fd.template, }; } ); } // // Update Item ... hasTemplate = !isNullOrUndefined( this.updateModelViewFieldDescriptors.find( (fd) => fd.key === this.ModelFieldNames.path && !!fd.hasCustomTemplate && !isNullOrUndefined(fd.template) ) ); if (!hasTemplate && !isNullOrUndefined(this.fileNameRef)) { // this.updateModelViewFieldDescriptors = this.updateModelViewFieldDescriptors.map((fd) => { // return { ...fd, template: fd.key === this.ModelFieldNames.path && !!fd.hasCustomTemplate && isNullOrUndefined(fd.template) ? this.fileNameRef : fd.template, }; }); } // // Details ... hasTemplate = !isNullOrUndefined( this.detailsModelViewFieldDescriptors.find( (fd) => fd.key === this.ModelFieldNames.path && !!fd.hasCustomTemplate && !isNullOrUndefined(fd.template) ) ); if (!hasTemplate && !isNullOrUndefined(this.fileNameRef)) { // this.detailsModelViewFieldDescriptors = this.detailsModelViewFieldDescriptors.map((fd) => { // return { ...fd, template: fd.key === this.ModelFieldNames.path && !!fd.hasCustomTemplate && isNullOrUndefined(fd.template) ? this.fileNameRef : fd.template, }; }); } } isPushServiceConnected = false; private async handleConnectPushService() { // // Preparing Connections ... try { // // Check Connected Before ... if ( this.sharedService.mabsutAPIService.files.fileEntityPushService.isConnected() ) { this.isPushServiceConnected = true; } else { // this.isPushServiceConnected = true; await this.sharedService.mabsutAPIService.files.fileEntityPushService.connect(); } } catch { // await this.handleCustomError('PushServiceConnection'); return; } // // Check Connected ... if (!this.isPushServiceConnected) { return; } // // On Added ... this.applyTakeUntilWrapper( this.sharedService.mabsutAPIService.files.fileEntityPushService.onAdded$ ).subscribe(async (event) => { // if (isNullOrUndefined(event)) { return; } }); // // On Removed ... this.applyTakeUntilWrapper( this.sharedService.mabsutAPIService.files.fileEntityPushService.onDeleted$ ).subscribe(async (event) => { // if (isNullOrUndefined(event) && isNullOrUndefined(this.dtoQueryResult)) { return; } // // Check if Model Exists in Current Context or not ... let model = this.dtoQueryResult.items.find( (i) => i.id === event.model.id ); const modelP = fileEntityToDto(event.model, model.owner); if (!isNullOrUndefined(model) && !isNullOrUndefined(modelP)) { // const actions = await this.prepareListActions(modelP); // this.sendQueryPresenterAction(VQueryPresenterAction.RemoveModel, { actions, model: modelP, key: nameof('id'), }); } // // Check Details or Edit Tab ... if ( (!isNullOrUndefined(model) && !isNullOrUndefined(this.detailsModel) && this.detailsModel.id === model.id && this.activeTab === VQueryPresenterTabs.Details) || (!isNullOrUndefined(model) && !isNullOrUndefined(this.updateModel) && this.updateModel.id === model.id && this.activeTab === VQueryPresenterTabs.Update) ) { // // Force Unlock ... this.lock = false; // this.sendQueryPresenterAction( VQueryPresenterAction.ChangeTab, VQueryPresenterTabs.List ); } }); // // On Updated ... this.applyTakeUntilWrapper( this.sharedService.mabsutAPIService.files.fileEntityPushService.onUpdated$ ).subscribe(async (event) => { // if (isNullOrUndefined(event) || isNullOrUndefined(this.dtoQueryResult)) { return; } // // Check if Model Exists in Current Context or not ... let model = this.dtoQueryResult.items.find( (i) => i.id === event.model.id ); if (isNullOrUndefined(model)) { return; } // let fromEntity: XFileDto = undefined; try { fromEntity = await this.getValueAsync( this.sharedService.mabsutAPIService.files.fileProviderService.get( event.model.id ) ); } catch { return; } // if (isNullOrUndefined(fromEntity)) { return; } // const modelP = fileEntityToDto(event.model, fromEntity.owner); // if (isNullOrUndefined(modelP)) { return; } // // Preparing Model List Actions ... const actions = await this.prepareListActions(modelP); // // Updating Model on Query Presenter ... this.sendQueryPresenterAction(VQueryPresenterAction.UpdateModel, { actions, model: { ...modelP }, key: nameof('id'), }); // // Update Tab ... if ( !isNullOrUndefined(this.updateModel) && modelP.id === this.updateModel.id && this.activeTab === VQueryPresenterTabs.Update ) { // this.updateModel = { ...modelP, }; // const selector = getQuerySelectorOfSpecifiedAttribute( VFileComponent, this.ModelFieldNames.id, this.updateModel.id ); await this.waitForElement(selector).then(async (el) => { // this.updateItemActionProvider.next({ action: VBaseDtoAction.RenewModel, payload: { ...this.updateModel }, }); // const prevTab = this.prevTab; await this.handleStateAfterTabOpen(this.activeTab); this.prevTab = prevTab; }); } // // Details Tab ... if ( !isNullOrUndefined(this.detailsModel) && modelP.id === this.detailsModel.id && this.activeTab === VQueryPresenterTabs.Details ) { // this.detailsModel = { ...modelP, }; // const selector = getQuerySelectorOfSpecifiedAttribute( VFileComponent, this.ModelFieldNames.id, this.detailsModel.id ); await this.waitForElement(selector).then(async (el) => { // this.detailsItemActionProvider.next({ action: VBaseDtoAction.RenewModel, payload: { ...this.detailsModel }, }); // const prevTab = this.prevTab; await this.handleStateAfterTabOpen(this.activeTab); this.prevTab = prevTab; }); } }); } //#endregion }