UNPKG

@bd-innovations/abstract-section

Version:

A bunch of abstract logic for the section

1,054 lines (1,029 loc) 36.7 kB
import { Optional, Directive, Input, Inject, InjectionToken, NgModule, EventEmitter } from '@angular/core'; import { MatDialog, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { HttpClient } from '@angular/common/http'; import { TranslateService } from '@ngx-translate/core'; import { Subject } from 'rxjs'; import { NavigationEnd, Router, ActivatedRoute } from '@angular/router'; import { takeUntil, filter, map, switchMap, tap } from 'rxjs/operators'; import { __awaiter } from 'tslib'; /** * @deprecated * */ class AbstractNotifierService { constructor() { } } /** * @deprecated * */ class AbstractService { constructor(http, translate, config, notifier) { this.http = http; this.translate = translate; this.config = config; this.notifier = notifier; /** * by default keyValue is uuId, override if need other */ this.keyValue = 'uuId'; } /** * @param key - uuId or ObjectId or... */ getOneByKeyValue(key) { const path = `${this.config.apiPrefix}${this.config.apiPath.getOne}${key}`; return this.http.get(path); } /** * @param parentKey - provide when request is send for child entity */ getAll(parentKey) { const path = `${this.config.apiPrefix}${this.config.apiPath.getAll}${parentKey ? '/' + parentKey : ''}`; return this.http.get(path); } /** * * @param apiCall paginator & search settings * @param parentKey - provide when request is send for child entity */ getAllPaginated(apiCall, parentKey) { const { apiPrefix, apiPath } = this.config; const { paginator: { pageIndex, pageSize }, search, sort, filters } = apiCall; const path = `${apiPrefix}${apiPath.getPaginated}/${pageIndex}/${pageSize}${parentKey ? '/' + parentKey : ''}`; const params = Object.assign({}, filters); search && (params.search = search); sort && sort.direction && sort.active && (params.sort = `${sort.active},${sort.direction}`); const stringifiedParams = {}; Object.keys(params).forEach(key => { if (params[key] instanceof Date) { stringifiedParams[key] = (params[key]).toISOString(); } else if (params[key] !== '' && params[key] !== null && params[key] !== undefined) { stringifiedParams[key] = params[key]; } }); return this.http.get(path, { params: stringifiedParams }); } /** * @deprecated use getAllPaginated instead * @param apiCall paginator & search settings * @param parentKey - provide when request is send for child entity */ getAllPaginatedBody(apiCall, parentKey) { const { apiPrefix, apiPath } = this.config; const path = `${apiPrefix}${apiPath.getPaginated}${parentKey ? '/' + parentKey : ''}`; const body = Object.keys(apiCall).reduce((res, key) => key === 'filters' ? Object.assign(Object.assign({}, res), apiCall.filters) : Object.assign(Object.assign({}, res), { [key]: apiCall[key] }), {}); return this.http.post(path, body); } /** * @deprecated use getAllPaginated instead * @param apiCall paginator & search settings * @param parentKey - provide when request is send for child entity */ getAllPaginatedPath(apiCall, parentKey) { const { apiPrefix, apiPath } = this.config; const { paginator: { pageIndex, pageSize }, search } = apiCall; const path = `${apiPrefix}${apiPath.getPaginated}${parentKey ? '/' + parentKey : ''}/${pageIndex}/${pageSize}/${search}`; const body = Object.keys(apiCall).reduce((res, key) => key === 'filters' ? Object.assign(Object.assign({}, res), apiCall.filters) : Object.assign(Object.assign({}, res), { [key]: apiCall[key] }), {}); delete body['paginator']; return this.http.post(path, body); } /** * @param newObject: create new element */ post(newObject) { const { apiPrefix, apiPath } = this.config; const path = `${apiPrefix}${apiPath.post}`; return this.http.post(path, newObject); } /** * @param editedObject: edit element */ put(editedObject) { const { apiPrefix, apiPath } = this.config; const path = `${apiPrefix}${apiPath.put}`; return this.http.put(path, editedObject); } /** * @param key: delete element by keyValue */ delete(key) { const { apiPrefix, apiPath } = this.config; const path = `${apiPrefix}${apiPath.delete}${key}`; return this.http.delete(path); } } AbstractService.ctorParameters = () => [ { type: HttpClient }, { type: TranslateService }, { type: undefined }, { type: AbstractNotifierService, decorators: [{ type: Optional }] } ]; /** * @deprecated * */ class AbstractComponent { constructor(service, dialog) { this.service = service; this.dialog = dialog; this.dialog_config = {}; this.abstract_dialog_config = {}; /** * by default true, override with false when data already exist */ this.requestInitialData = true; /** DIALOGS SETTINGS */ this.dialogPanelClass = 'bd-dialog'; this.editDialogWidth = '700px'; this.editDialogPanelClass = 'bd-edit-dialog'; this.newDialogWidth = undefined; this.newDialogPanelClass = undefined; this.deleteDialogWidth = '500px'; this.deleteDialogPanelClass = 'bd-delete-dialog'; this.onDestroy$ = new Subject(); } /** * calls getData() if requestInitData is true (by default it is) */ ngOnInit() { if (this.requestInitialData) { this.getData(); } } ngOnDestroy() { this.onDestroy$.next(); this.onDestroy$.complete(); } onSuccessfulDataInit(res) { } afterDataInit() { } onDataInitError(error) { } /** EDIT DIALOG */ /** * calls onBeforeEditOpen() * opens dialog * subscribe on dialog afterClosed and emits value into afterEditClosed() * @param t: element */ openEdit(t) { this.onBeforeEditOpen(t); const dialogRef = this.dialog.open(this.returnEditComponentType(), this.dialog_config); dialogRef.afterClosed().subscribe(res => this.afterEditClose(res)); } /** * setup dialog data with t, dialog width with editDialogWidth & dialog panelClasses with dialogPanelClass & editDialogPanelClass * @param t: element */ onBeforeEditOpen(t) { this.abstract_dialog_config.element = t; this.dialog_config.data = this.abstract_dialog_config; this.dialog_config.width = this.editDialogWidth; this.dialog_config.panelClass = [this.dialogPanelClass, this.editDialogPanelClass]; } /** * if submit true calls onSuccessfulEdit() * when false onEditCancel() * @param submit: true when edited/false when canceled */ afterEditClose(submit) { submit ? this.onSuccessfulEdit(submit) : this.onEditCancel(); } onSuccessfulEdit(submit) { this.getData(); } onEditCancel() { } /** DELETE DIALOG */ /** * calls onBeforeDeleteOpen() * opens dialog * subscribe on dialog afterClosed and emits value into afterDeleteClose() * @param t: element */ openDelete(t) { this.onBeforeDeleteOpen(t); const dialogRef = this.dialog.open(this.returnDeleteComponentType(), this.dialog_config); dialogRef.afterClosed().subscribe(submit => this.afterDeleteClose(submit, t)); } /** * setup dialog data with t, dialog width with deleteDialogWidth & dialog panelClasses with dialogPanelClass & deleteDialogPanelClass * @param t: element */ onBeforeDeleteOpen(t) { this.abstract_dialog_config.element = t; this.dialog_config.data = this.abstract_dialog_config; this.dialog_config.width = this.deleteDialogWidth; this.dialog_config.panelClass = [this.dialogPanelClass, this.deleteDialogPanelClass]; } /** * if submit true calls onSuccessfulDelete() * when false onDeleteCancel() * @param submit: true when edited/false when canceled * @param t: element to delete */ afterDeleteClose(submit, t) { submit ? this.onSuccessfulDelete(submit, t) : this.onDeleteCancel(); } onDeleteCancel() { } } AbstractComponent.decorators = [ { type: Directive } ]; AbstractComponent.ctorParameters = () => [ { type: AbstractService }, { type: MatDialog } ]; AbstractComponent.propDecorators = { requestInitialData: [{ type: Input }] }; /** * @deprecated * */ class AbstractDetailsComponent extends AbstractComponent { constructor(service, dialog, router, route) { super(service, dialog); this.service = service; this.dialog = dialog; this.router = router; this.route = route; } get _pathParamName() { return this.pathParamName || this.service.keyValue; } /** * calls setPreviousUrl(), setPathParamName() * gets keyValue from route & emits it into getData */ ngOnInit() { this.setPreviousUrl(); super.ngOnInit(); } setPreviousUrl() { this.router.events.pipe(takeUntil(this.onDestroy$), filter(event => event instanceof NavigationEnd)).subscribe((event) => { this.previousUrl = event.url; }); } /** * calls getRequest(key) if requestInitialData != false * on response calls onSuccessfulDataInit() * on error - onDataInitError() * @param key: keyValue of element */ getData(key) { this.route.params.pipe(takeUntil(this.onDestroy$), filter(params => params && params[this._pathParamName]), map(params => params[this._pathParamName]), switchMap(paramKey => this.getRequest(paramKey)), tap(() => this.service.notifier && this.service.notifier.openGetOneNotification(this.service.config.modelName), (e) => this.service.notifier && this.service.notifier.openErrorNotification(e))).subscribe(res => this.onSuccessfulDataInit(res), error => this.onDataInitError(error)); } getRequest(key) { return this.service.getOneByKeyValue(key); } /** * puts API response into element; * then calls afterDataInit() * @param res - API response */ onSuccessfulDataInit(res) { this.element = res; this.afterDataInit(); } openEdit(t) { super.openEdit(t || this.element); } onSuccessfulEdit(res) { this.element = res; } openDelete(t) { super.openDelete(t || this.element); } /** * calls back() * @param res: deleted element */ onSuccessfulDelete(res) { this.back(); } back() { this.router.navigate([this.previousUrl]); } } /** * @deprecated * */ var ResponseTypeEnum; (function (ResponseTypeEnum) { ResponseTypeEnum["all"] = "all"; ResponseTypeEnum["paginated"] = "paginated"; /** * @deprecated */ ResponseTypeEnum["paginated_post"] = "post"; /** * @deprecated */ ResponseTypeEnum["paginated_path"] = "path"; })(ResponseTypeEnum || (ResponseTypeEnum = {})); /** * @deprecated * */ class AbstractListComponent extends AbstractComponent { constructor(service, dialog, router, route) { super(service, dialog); this.service = service; this.dialog = dialog; this.router = router; this.route = route; /** * data: by default empty array, if Inputted from other component override ngOnInit, to disable get All request */ this.data = []; /** * listType: By default gets all, if need paginated override with ResponseTypeEnum.paginated/paginated_body/paginated_path */ this.listType = ResponseTypeEnum.all; /** * filters - object {key: value} that will be mapped into request * for paginated: &key=value */ this.filters = {}; /** * TABLE SETTINGS * sort - true by default, if sort is available * apiable - true by default, if search & pages change will call API * search - true by default, if search is available in table * paginator - by default pageSize = 25, pageIndex = 0, length = null */ this.sort = true; this.apiable = true; this.search = true; this.paginator = { pageSize: 25, pageIndex: 0, length: null }; } /** * override for child entities used for list & details * @example * ``` * get newElement() { * return {someoneUuId: this.parentUuId} * } * ``` */ get newElement() { return {}; } ngOnDestroy() { super.ngOnDestroy(); this.data = undefined; } returnNewComponentType() { return undefined; } /** * combines this.paginator, this filters & apiCallModel from arguments * @param obj - optional ApiCallModel */ getApiCallModel(obj) { return Object.assign({ paginator: this.paginator, filters: this.filters }, obj); } /** * use for dynamic table @Output(apiRequest) * @param apiCall: ApiCallModel */ onApiRequestEmitted(apiCall) { this.getData(Object.assign({}, apiCall)); } /** * calls getAllRequest() maps it with mapListResponse() and subscribes on result. * If request successful calls onSuccessfulDataInit(res), * on error calls onDataInitError(error) * @param apiCall: optional ApiCallModel */ getData(apiCall) { this.getAllRequest(this.getApiCallModel(apiCall)) .subscribe(res => this.onSuccessfulDataInit(res), error => this.onDataInitError(error)); } /** * depending on listType calls service's getAll() or one of getAllPaginated() * @param apiCall: ApiCallModel better format throw getApiCallModel(apiCall) before */ getAllRequest(apiCall) { switch (this.listType) { case ResponseTypeEnum.paginated: return this.service.getAllPaginated(apiCall, this.parentUuId).pipe(tap(({ list, totalItems }) => this.service.notifier && this.service.notifier.openGetListNotification(this.service.config.modelName, list.length, totalItems), (e) => this.service.notifier && this.service.notifier.openErrorNotification(e)), map(res => this.mapPaginatedResponse(res, apiCall))); case ResponseTypeEnum.paginated_path: return this.service.getAllPaginatedPath(apiCall, this.parentUuId).pipe(tap(({ list, numberOfEntities }) => this.service.notifier && this.service.notifier.openGetListNotification(this.service.config.modelName, list.length, numberOfEntities), (e) => this.service.notifier && this.service.notifier.openErrorNotification(e)), map(res => this.mapPaginatedResponse(res, apiCall))); case ResponseTypeEnum.paginated_post: return this.service.getAllPaginatedBody(apiCall, this.parentUuId).pipe(tap(({ list, numberOfEntities }) => this.service.notifier && this.service.notifier.openGetListNotification(this.service.config.modelName, list.length, numberOfEntities), (e) => this.service.notifier && this.service.notifier.openErrorNotification(e)), map(res => this.mapPaginatedResponse(res, apiCall))); case ResponseTypeEnum.all: default: return this.service.getAll(this.parentUuId) .pipe(tap(response => this.service.notifier && this.service.notifier.openGetListNotification(this.service.config.modelName, response.length), (e) => this.service.notifier && this.service.notifier.openErrorNotification(e))); } } /** * sets up length of received array & returns data list * is arrow function to survive this * @param pagination: Paginated Response Model * @param apiCall: Api call model */ mapPaginatedResponse(pagination, apiCall) { this.paginator = Object.assign(Object.assign({}, this.paginator), { length: pagination.totalItems || pagination.numberOfEntities || 0, pageIndex: apiCall.paginator.pageIndex, pageSize: apiCall.paginator.pageSize }); return pagination.list; } /** * puts API response into data; * then calls afterDataInit() * @param res - API response */ onSuccessfulDataInit(res) { this.data = res; this.afterDataInit(); } /** * DETAILS */ /** * navigates to this.route/{element[keyValue]} * @param t: list element */ openDetails(t) { this.router.navigate([t[this.service.keyValue]], { relativeTo: this.route }); } /** NEW DIALOG */ /** * calls onBeforeOpen(), opens dialog & subscribes on result. Result is send to afterNewClosed() * */ openNew() { this.onBeforeNewOpen(); const dialogRef = this.dialog.open(this.returnNewComponentType() || this.returnEditComponentType(), this.dialog_config); dialogRef.afterClosed().subscribe(res => this.afterNewClosed(res)); } /** * calls from openNew() * setups dialog data, panelClasses & width * if newDialogWidth is undefined takes editDialogWidth * if newDialogPanelClass is undefined takes editDialogPanelClass */ onBeforeNewOpen() { this.abstract_dialog_config.element = Object.assign({}, this.newElement); this.dialog_config.data = this.abstract_dialog_config; this.dialog_config.width = this.newDialogWidth || this.editDialogWidth; this.dialog_config.panelClass = [this.dialogPanelClass, this.newDialogPanelClass || this.editDialogPanelClass]; } /** * if submit true calls onSuccessfulCreateNew() * when false onNewCreateNewCancel() * @param submit: true when created/false when canceled */ afterNewClosed(submit) { submit ? this.onSuccessfulCreateNew() : this.onCreateNewCancel(); } /** * calls getData() */ onSuccessfulCreateNew() { this.getData(); } onCreateNewCancel() { } /** EDIT DIALOG */ /** * calls onBeforeEditOpen() * opens dialog * subscribe on dialog afterClosed and emits value into afterEditClosed() * @param t: element */ openEdit(t) { this.onBeforeEditOpen(t); const dialogRef = this.dialog.open(this.returnEditComponentType(), this.dialog_config); dialogRef.afterClosed().subscribe(res => this.afterEditClose(res)); } /** * if submit true calls onSuccessfulCreateNew() * when false onNewCreateNewCancel() * @param submit: true when edited/false when canceled */ afterEditClose(submit) { submit ? this.onSuccessfulEdit(submit) : this.onEditCancel(); } /** * if submit true calls onSuccessfulDelete() * when false onDeleteCancel() * @param submit: true when edited/false when canceled * @param t: element to delete */ afterDeleteClose(submit, t) { submit ? this.onSuccessfulDelete(submit, t) : this.onDeleteCancel(); } /** * calls getData() * @param submit: true when edited/false when canceled * @param t: element to delete */ onSuccessfulDelete(submit, t) { this.getData(); } /** * use for dynamic table @Output(actionRequest) * handles dynamic table events: edit, delete, open; * if do not need open override this way: * @example * > if ($event.type === 'open) return; * > super.actionHandler($event); * @param $event: dynamic table event: {type: string, entity: element} */ actionHandler($event) { switch ($event.type) { case ('delete'): this.openDelete($event.entity); break; case ('edit'): this.openEdit($event.entity); break; case ('open'): this.openDetails($event.entity); break; } } } AbstractListComponent.decorators = [ { type: Directive } ]; AbstractListComponent.ctorParameters = () => [ { type: AbstractService }, { type: MatDialog }, { type: Router }, { type: ActivatedRoute } ]; AbstractListComponent.propDecorators = { data: [{ type: Input }], parentUuId: [{ type: Input }] }; /** * @deprecated * */ class AbstractDialogComponent { constructor(data, dialogRef) { this.data = data; this.dialogRef = dialogRef; this.close = (val) => this.dialogRef.close(val || null); } } AbstractDialogComponent.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }, { type: MatDialogRef } ]; /** * @deprecated * */ class AbstractEditComponent extends AbstractDialogComponent { constructor(data, service, dialogRef) { super(data, dialogRef); this.data = data; this.service = service; this.dialogRef = dialogRef; /** * by default true, override with false when data already exist */ this.requestInitialData = true; /** * is truly while http requests are pending */ this.pending = false; } /** * if element has a keyValue & requestInitialData is true sets pending as true * & calls getInitData() & subscribes on it * - on response calls onSuccessfulDataInit() * - on error calls onDataInitError() * else calls onNullElementOrKeyValue() */ ngOnInit() { if (this.data.element && this.data.element[this.service.keyValue] && this.requestInitialData) { this.pending = true; this.getInitData() .subscribe(res => this.onSuccessfulDataInit(res), error => this.onDataInitError(error)); } else { this.onNullElementOrKeyValue(); } } /** * returns service's getOneByKeyValue(keyValue) */ getInitData() { return this.service.getOneByKeyValue(this.data.element[this.service.keyValue]); } /** * puts API response into data.element * creates form with API response value * sets pending as false * calls afterDataInit() * @param res: API response */ onSuccessfulDataInit(res) { this.data.element = res; this.form = this.returnForm(res); this.pending = false; this.afterDataInit(); } /** * closes dialog * @param error: API error */ onDataInitError(error) { this.close(); } /** * creates form with data.element * calls afterDataInit() */ onNullElementOrKeyValue() { this.form = this.returnForm(this.data.element); this.afterDataInit(); } /** * use for any custom logic after getting data from API */ afterDataInit() { } /** * sets pending as true * check keyValue of element, if it's true will call putRequest() else will call postRequest() * @param submit: optional - will call API with provided submit value or take form value */ submit(val) { const isExisting = !!this.data.element[this.service.keyValue]; this.pending = true; (isExisting ? this.putRequest(val || this.form.value) : this.postRequest(val || this.form.value)).pipe(tap(() => (isExisting ? this.service.notifier && this.service.notifier.openPutNotification(this.service.config.modelName) : this.service.notifier && this.service.notifier.openPostNotification(this.service.config.modelName)), (e) => this.service.notifier && this.service.notifier.openErrorNotification(e))).subscribe(res => this.close(res), err => this.onRequestError(err)); } /** * returns service's post method * @param submit: any value to send into post */ postRequest(submit) { return this.service.post(submit); } /** * returns service's put method * @param submit: any value to send into put */ putRequest(submit) { return this.service.put(submit); } /** * handle request error if needed * sets pending as false * @param err: API response error */ onRequestError(err) { this.pending = false; } } AbstractEditComponent.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }, { type: AbstractService }, { type: MatDialogRef } ]; /** * @deprecated * */ class AbstractDeleteComponent extends AbstractDialogComponent { constructor(data, service, dialogRef) { super(data, dialogRef); this.data = data; this.service = service; this.dialogRef = dialogRef; /** * is truly while http requests are pending */ this.pending = false; } /** * sets pending as true; * calls deleteRequest() & subscribes on result * when ok: calls onSuccessfulDelete(response), * on error: calls onDeleteFail(error) */ submit() { this.pending = true; this.deleteRequest().pipe(tap(() => this.service.notifier && this.service.notifier.openDeleteNotification(this.service.config.modelName), (e) => this.service.notifier && this.service.notifier.openErrorNotification(e))).subscribe(res => this.onSuccessfulDelete(res), err => this.onDeleteFail(err)); } /** * calls service's delete() */ deleteRequest() { return this.service.delete(this.data.element[this.service.keyValue]); } /** * closes dialog with http response * @param res http response */ onSuccessfulDelete(res) { this.pending = false; this.close(res); } /** * sets pending as false * @param err - http error */ onDeleteFail(err) { this.pending = false; } } AbstractDeleteComponent.ctorParameters = () => [ { type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }, { type: AbstractService }, { type: MatDialogRef } ]; const ABSTRACT_SECTION_CONFIG = new InjectionToken('ABSTRACT_SECTION_CONFIG'); class AbstractSectionModule { static forRoot(config) { return { ngModule: AbstractSectionModule, providers: [ { provide: ABSTRACT_SECTION_CONFIG, useValue: config.defaultDialogConfig } ] }; } } AbstractSectionModule.decorators = [ { type: NgModule } ]; class DialogComponentFasade { constructor() { this.cancel$ = new EventEmitter(); this.submit$ = new EventEmitter(); } ngOnInit() { this.loaderConfigurator && this.loaderConfigurator.initLoader(); } ngOnDestroy() { this.loaderConfigurator && this.loaderConfigurator.destroyLoader(); } } function mixinHasSubs(base) { return class extends base { constructor(...args) { super(args); this.subs$ = []; } clearSubscriptions() { this.subs$.forEach(sub => sub.unsubscribe()); } }; } class RoutedComponentFasade extends mixinHasSubs(class { }) { constructor() { super(); } ngOnInit() { this.loaderConfigurator && this.loaderConfigurator.initLoader(); this.formConfigurator && this.initDataReloadOnSuccessNewOrEdit(); this.deleteConfigurator && this.initDataReloadOnSuccessDelete(); } ngOnDestroy() { this.clearSubscriptions(); this.loaderConfigurator && this.loaderConfigurator.destroyLoader(); this.formConfigurator && this.formConfigurator.clearSubscriptions(); this.deleteConfigurator && this.deleteConfigurator.clearSubscriptions(); } initDataReloadOnSuccessNewOrEdit() { this.subs$.push(this.formConfigurator.onSuccess$ .subscribe(() => this.loaderConfigurator.loadData())); } initDataReloadOnSuccessDelete() { this.subs$.push(this.deleteConfigurator.onSuccess$ .subscribe(() => this.loaderConfigurator.loadData())); } } class DeleteDialogConfigurator extends mixinHasSubs(class { }) { constructor(owner) { super(); this.owner = owner; this.onSuccess$ = new Subject(); this.onCancel$ = new Subject(); } openDialog(instance) { const dialogConfig = { data: { element: instance } }; this.dialogRef = this.owner.dialog.open(this.owner.deleteComponentType, dialogConfig); const dialogComponent = this.dialogRef.componentInstance; this.subs$.push(dialogComponent.submit$ .subscribe(() => this.onDialogSubmit(instance)), dialogComponent.cancel$ .subscribe(() => this.onDialogCancel())); } onDialogSubmit(res) { this.subs$.push(this.owner.service.delete(res[this.owner.logic.primaryKey]) .subscribe(() => { this.dialogRef.close(); this.onSuccess$.next(); })); } onDialogCancel() { this.dialogRef.close(); } } class FormDialogConfigurator extends mixinHasSubs(class { }) { constructor(owner) { super(); this.owner = owner; this.onSuccess$ = new Subject(); this.onCancel$ = new Subject(); } openDialog(instance) { return __awaiter(this, void 0, void 0, function* () { if (this.owner.dialogConfig && this.owner.dialogConfig.reloadData && instance && instance[this.owner.logic.primaryKey]) { instance = yield this.owner.service.getOne(instance[this.owner.logic.primaryKey]).toPromise(); } const dialogConfig = { data: Object.assign({ element: instance }, (this.owner.dialogConfig && this.owner.dialogConfig.additionalDialogData)) }; this.dialogRef = this.owner.dialog.open(this.owner.formComponentType, dialogConfig); const dialogComponent = this.dialogRef.componentInstance; this.subs$.push(dialogComponent.submit$ .subscribe(res => this.onDialogSubmit(res)), dialogComponent.cancel$ .subscribe(() => this.onDialogCancel())); }); } onDialogSubmit(res) { this.subs$.push((res[this.owner.logic.primaryKey] ? this.owner.service.put(res) : this.owner.service.post(res)) .subscribe(() => { this.dialogRef.close(); this.onSuccess$.next(); })); } onDialogCancel() { this.dialogRef.close(); } } class FormLoaderConfigurator { constructor(owner) { this.owner = owner; this.onDataLoaded$ = new Subject(); } initLoader() { this.form = this.owner.logic.form(this.owner.data.element); this.onDataLoaded$.next(this.owner.data.element); } ; loadData() { } destroyLoader() { } } class ListLoaderConfigurator extends mixinHasSubs(class { }) { constructor(owner) { super(); this.owner = owner; this.onDataLoaded$ = new Subject(); } initLoader() { this.loadData(this.owner.parentPrimaryKey); } loadData(parentPrimaryKey) { this.parentPrimaryKey = parentPrimaryKey !== undefined ? parentPrimaryKey : this.parentPrimaryKey; this.subs$.push(this.owner.service.getList(this.parentPrimaryKey) .subscribe(next => { this.data = next; this.onDataLoaded$.next(this.data); })); } destroyLoader() { this.clearSubscriptions(); } } class OneLoaderConfigurator extends mixinHasSubs(class { }) { constructor(owner) { super(); this.owner = owner; this.onDataLoaded$ = new Subject(); } initLoader() { this.loadData(); } loadData() { this.subs$.push(this.owner.primaryKeyFactory().pipe(switchMap(primaryKey => this.owner.service.getOne(primaryKey))).subscribe(next => { this.element = next; this.onDataLoaded$.next(this.element); })); } destroyLoader() { this.clearSubscriptions(); } } class PaginatedListLoaderConfigurator extends mixinHasSubs(class { }) { constructor(owner) { super(); this.owner = owner; this.onDataLoaded$ = new Subject(); this.requestParams = { pagination: { pageSize: 25, pageIndex: 0 } }; } initLoader() { this.requestParams = Object.assign(Object.assign({}, this.requestParams), this.owner.requestParams); this.loadData(this.requestParams); } loadData(requestParams) { this.requestParams = Object.assign(Object.assign({}, this.requestParams), requestParams); this.subs$.push(this.owner.service.getPaginatedList(this.requestParams) .subscribe(next => { this.data = next; this.onDataLoaded$.next(this.data); })); } destroyLoader() { this.clearSubscriptions(); } } class CrudService { constructor(http, config) { this.http = http; this.config = config; } getOne(primaryKey) { if (!primaryKey || (typeof primaryKey !== 'number' && typeof primaryKey !== 'string')) { throw new Error('CrudService #getOne() primaryKey is falsy or neither number or string'); } return this.http.get(`${this.config.apiPrefix}/${this.config.apiPath.getOne}/${primaryKey}`); } getList(parentPrimaryKey) { if (!!parentPrimaryKey && (typeof parentPrimaryKey !== 'number' && typeof parentPrimaryKey !== 'string')) { throw new Error('CrudService #getList() parentPrimaryKey was passed but it is neither number or string'); } let path = `${this.config.apiPrefix}/${this.config.apiPath.getMany}`; if (!!parentPrimaryKey) { path += `/${parentPrimaryKey}`; } return this.http.get(path); } getPaginatedList(requestParams = { pagination: { pageIndex: 0, pageSize: 25 } }) { let path = `${this.config.apiPrefix}/${this.config.apiPath.getMany}`; if (!!requestParams.parentPrimaryKey) { path += `/${requestParams.parentPrimaryKey}`; } path += `/${requestParams.pagination.pageIndex}/${requestParams.pagination.pageSize}`; const queryParams = Object.assign({}, requestParams.filters); if (!!requestParams.indexSearch) { queryParams.search = requestParams.indexSearch; } if (requestParams.sort && requestParams.sort.active && requestParams.sort.direction) { queryParams.sort = `${requestParams.sort.active},${requestParams.sort.direction}`; } Object.keys(queryParams).forEach(key => { if (queryParams[key] instanceof Date) { queryParams[key] = (queryParams[key]).toISOString(); } else if (queryParams[key] === '' || queryParams[key] === null || queryParams[key] === undefined) { delete queryParams[key]; } }); return this.http.get(path, { params: queryParams }); } post(body) { return this.http.post(`${this.config.apiPrefix}/${this.config.apiPath.post}`, body); } put(body) { return this.http.put(`${this.config.apiPrefix}/${this.config.apiPath.put}`, body); } delete(primaryKey) { if (!primaryKey || (typeof primaryKey !== 'number' && typeof primaryKey !== 'string')) { throw new Error('CrudService #delete() primaryKey is falsy or neither number or string'); } return this.http.delete(`${this.config.apiPrefix}/${this.config.apiPath.delete}/${primaryKey}`); } } /* * Public API Surface of bd-abstract-section */ /** * Generated bundle index. Do not edit. */ export { ABSTRACT_SECTION_CONFIG, AbstractComponent, AbstractDeleteComponent, AbstractDetailsComponent, AbstractDialogComponent, AbstractEditComponent, AbstractListComponent, AbstractNotifierService, AbstractSectionModule, AbstractService, CrudService, DeleteDialogConfigurator, DialogComponentFasade, FormDialogConfigurator, FormLoaderConfigurator, ListLoaderConfigurator, OneLoaderConfigurator, PaginatedListLoaderConfigurator, ResponseTypeEnum, RoutedComponentFasade }; //# sourceMappingURL=bd-innovations-abstract-section.js.map