UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

319 lines (312 loc) 23.9 kB
import * as i2 from '@c8y/ngx-components'; import { IconDirective, C8yTranslatePipe, CoreModule, EmptyComponent, BuiltInActionType, Status, DataGridModule, TitleComponent, C8yTranslateDirective, ActionBarItemComponent, EmptyStateComponent, hookRoute, ViewContext } from '@c8y/ngx-components'; import { gettext } from '@c8y/ngx-components/gettext'; import * as i0 from '@angular/core'; import { input, signal, effect, Optional, Component } from '@angular/core'; import * as i2$1 from '@angular/router'; import { RouterLinkWithHref } from '@angular/router'; import * as i1 from '@c8y/ngx-components/remote-access/data'; import { canActivateRemoteAccess } from '@c8y/ngx-components/remote-access/data'; import * as i3 from '@angular/common'; import { NgIf } from '@angular/common'; import * as i1$1 from 'ngx-bootstrap/modal'; import { IconDeviceGridColumn } from '@c8y/ngx-components/device-grid'; import * as i5 from '@ngx-translate/core'; class RemoteAccessConnectButtonComponent { constructor(remoteAccess, context) { this.remoteAccess = remoteAccess; this.context = context; this.deviceId = input(null, ...(ngDevMode ? [{ debugName: "deviceId" }] : [])); this.configurationId = input(null, ...(ngDevMode ? [{ debugName: "configurationId" }] : [])); this.protocol = input(null, ...(ngDevMode ? [{ debugName: "protocol" }] : [])); this.protocolProviders = []; this.protocolProviders = this.remoteAccess.getProtocolProviders(); this.connectHref = this.getEndpointHref(); } getEndpointHref() { const resultSignal = signal(null, ...(ngDevMode ? [{ debugName: "resultSignal" }] : [])); effect(async () => { let deviceId = this.deviceId(); let configurationId = this.configurationId(); let protocol = this.protocol(); if (this.context) { if (!deviceId) { deviceId = this.context.property?.target; } if (!configurationId) { configurationId = this.context.item.id; } if (!protocol) { protocol = this.context.item.protocol; } } if (!deviceId || !configurationId || !protocol) { resultSignal.set(null); return; } const provider = this.protocolProviders.find(p => p.protocolName === protocol); if (!provider || !provider.connectEndpointHref) { resultSignal.set(null); return; } const href = await provider.connectEndpointHref(deviceId, this.context.item || { id: configurationId }); resultSignal.set(href); }, { allowSignalWrites: true }); return resultSignal.asReadonly(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: RemoteAccessConnectButtonComponent, deps: [{ token: i1.RemoteAccessService }, { token: i2.CellRendererContext, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.19", type: RemoteAccessConnectButtonComponent, isStandalone: true, selector: "c8y-remote-access-connect-button", inputs: { deviceId: { classPropertyName: "deviceId", publicName: "deviceId", isSignal: true, isRequired: false, transformFunction: null }, configurationId: { classPropertyName: "configurationId", publicName: "configurationId", isSignal: true, isRequired: false, transformFunction: null }, protocol: { classPropertyName: "protocol", publicName: "protocol", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<a\n *ngIf=\"connectHref() as endpointHref\"\n [title]=\"'Connect' | translate\"\n [routerLink]=\"endpointHref\"\n [attr.data-cy]=\"'remoteAccessConnectButton'\"\n>\n <i [c8yIcon]=\"'connected'\"></i>\n</a>\n", dependencies: [{ kind: "directive", type: RouterLinkWithHref, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: RemoteAccessConnectButtonComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-remote-access-connect-button', standalone: true, imports: [RouterLinkWithHref, IconDirective, NgIf, C8yTranslatePipe], template: "<a\n *ngIf=\"connectHref() as endpointHref\"\n [title]=\"'Connect' | translate\"\n [routerLink]=\"endpointHref\"\n [attr.data-cy]=\"'remoteAccessConnectButton'\"\n>\n <i [c8yIcon]=\"'connected'\"></i>\n</a>\n" }] }], ctorParameters: () => [{ type: i1.RemoteAccessService }, { type: i2.CellRendererContext, decorators: [{ type: Optional }] }], propDecorators: { deviceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "deviceId", required: false }] }], configurationId: [{ type: i0.Input, args: [{ isSignal: true, alias: "configurationId", required: false }] }], protocol: [{ type: i0.Input, args: [{ isSignal: true, alias: "protocol", required: false }] }] } }); class RemoteAccessPickProtocolModalComponent { constructor(bsModalRef) { this.bsModalRef = bsModalRef; this.title = gettext('Select a protocol'); this.result = new Promise((resolve, reject) => { this._resolve = resolve; this._reject = reject; }); // set via initialState this.protocolProviders = []; } cancel() { this._reject(); } selectProtocol(protocol) { this.bsModalRef.hide(); this._resolve(protocol); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: RemoteAccessPickProtocolModalComponent, deps: [{ token: i1$1.BsModalRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: RemoteAccessPickProtocolModalComponent, isStandalone: true, selector: "c8y-remote-access-pick-protocol-modal", ngImport: i0, template: "<c8y-modal\n [title]=\"title\"\n [headerClasses]=\"'dialog-header'\"\n (onDismiss)=\"cancel()\"\n [labels]=\"{ cancel: 'Cancel' }\"\n>\n <ng-container c8y-modal-title>\n <span [c8yIcon]=\"'laptop'\"></span>\n </ng-container>\n <div class=\"p-24\">\n <c8y-li *ngFor=\"let provider of protocolProviders\">\n <c8y-li-icon>\n <i [c8yIcon]=\"provider.protocolIcon\"></i>\n </c8y-li-icon>\n <c8y-li-body>\n <div class=\"d-flex j-c-between\">\n <div>\n <p>{{ provider.protocolLabel | translate }}</p>\n <p>\n <small>{{ provider.protocolDescription | translate }}</small>\n </p>\n </div>\n <div>\n <button\n class=\"btn btn-primary\"\n (click)=\"selectProtocol(provider)\"\n [attr.data-cy]=\"'remoteAccessPickProtocolModal--select-' + provider.protocolName\"\n >\n <span translate>Select</span>\n </button>\n </div>\n </div>\n </c8y-li-body>\n </c8y-li>\n </div>\n</c8y-modal>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: i2.ModalComponent, selector: "c8y-modal", inputs: ["disabled", "close", "dismiss", "title", "body", "customFooter", "headerClasses", "labels"], outputs: ["onDismiss", "onClose"] }, { kind: "component", type: i2.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i2.ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: i2.ListItemBodyComponent, selector: "c8y-list-item-body, c8y-li-body", inputs: ["body"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: RemoteAccessPickProtocolModalComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-remote-access-pick-protocol-modal', standalone: true, imports: [CoreModule], template: "<c8y-modal\n [title]=\"title\"\n [headerClasses]=\"'dialog-header'\"\n (onDismiss)=\"cancel()\"\n [labels]=\"{ cancel: 'Cancel' }\"\n>\n <ng-container c8y-modal-title>\n <span [c8yIcon]=\"'laptop'\"></span>\n </ng-container>\n <div class=\"p-24\">\n <c8y-li *ngFor=\"let provider of protocolProviders\">\n <c8y-li-icon>\n <i [c8yIcon]=\"provider.protocolIcon\"></i>\n </c8y-li-icon>\n <c8y-li-body>\n <div class=\"d-flex j-c-between\">\n <div>\n <p>{{ provider.protocolLabel | translate }}</p>\n <p>\n <small>{{ provider.protocolDescription | translate }}</small>\n </p>\n </div>\n <div>\n <button\n class=\"btn btn-primary\"\n (click)=\"selectProtocol(provider)\"\n [attr.data-cy]=\"'remoteAccessPickProtocolModal--select-' + provider.protocolName\"\n >\n <span translate>Select</span>\n </button>\n </div>\n </div>\n </c8y-li-body>\n </c8y-li>\n </div>\n</c8y-modal>\n" }] }], ctorParameters: () => [{ type: i1$1.BsModalRef }] }); class RemoteAccessConfigurationListComponent { constructor(remoteAccess, activatedRoute, modalService, alert, bsModalService, translateService, ctx) { this.remoteAccess = remoteAccess; this.activatedRoute = activatedRoute; this.modalService = modalService; this.alert = alert; this.bsModalService = bsModalService; this.translateService = translateService; this.ctx = ctx; this.rows = []; this.columns = [ new IconDeviceGridColumn({ headerCellRendererComponent: EmptyComponent }, context => { const provider = this.protocolProviders.find(p => p.protocolName === context.item.protocol); return provider?.protocolIcon || 'laptop'; }), { name: 'name', header: gettext('Endpoint'), path: 'name' }, { name: 'hostname', header: gettext('Host'), path: 'hostname' }, { name: 'port', header: gettext('Port'), path: 'port' }, { name: 'protocol', header: gettext('Protocol'), path: 'protocol' }, { name: 'connect', header: gettext('Connect'), cellRendererComponent: RemoteAccessConnectButtonComponent } ]; this.actionControls = [ { type: BuiltInActionType.Edit, callback: async (entry) => { const provider = this.getProtocolProviderForConfiguration(entry); try { let result; if (provider.editEndpoint) { result = await provider.editEndpoint(this.deviceId, entry); } else { result = await this.defaultEditEndpoint(this.deviceId, entry); } if (!result) { return; } this.alert.success(gettext('Endpoint saved.')); } catch (e) { console.warn(e); this.alert.danger(gettext('Failed to save endpoint.'), e); } this.reload(); } }, { type: BuiltInActionType.Delete, callback: async (entry) => { const result = await this.modalService.confirm(gettext('Delete endpoint'), this.translateService.instant(gettext(`You are about to delete endpoint "{{ endpointName }}". Do you want to proceed?`), { endpointName: entry.name }), Status.DANGER, { cancel: gettext('Cancel'), ok: gettext('Delete') }); if (!result) { return; } const provider = this.getProtocolProviderForConfiguration(entry); try { await provider.removeEndpoint(this.deviceId, entry); this.alert.success(gettext('Endpoint deleted.')); } catch (e) { console.warn(e); this.alert.danger(gettext('Failed to delete endpoint.'), e); } this.reload(); } } ]; this.pagination = { pageSize: 10, currentPage: 1 }; this.displayOptions = { bordered: false, striped: true, filter: true, gridHeader: true, hover: true }; this.protocolProviders = []; this.gridTitle = gettext('Remote access endpoints'); this.device = this.ctx.getContextData(this.activatedRoute)?.contextData; this.deviceId = this.device?.id; this.protocolProviders = this.remoteAccess.getSupportedProtocolProvidersFor(this.device); const connectColum = this.columns.find(c => c.name === 'connect'); if (connectColum) { connectColum.target = this.deviceId; } } ngOnInit() { this.reload(); } async reload() { const configurations = await this.remoteAccess.listConfigurations(this.deviceId); const supportedProtocols = this.remoteAccess.getSupportedProtocolProvidersFor(this.device); const supportedProtocolsNames = supportedProtocols.map(p => p.protocolName); this.rows = configurations.filter(c => supportedProtocolsNames.includes(c.protocol.toUpperCase())); } async addEndpoint() { let provider = null; if (this.protocolProviders.length > 1) { try { const modalRef = this.bsModalService.show(RemoteAccessPickProtocolModalComponent, { initialState: { protocolProviders: this.protocolProviders } }); provider = await modalRef.content.result; } catch (e) { // modal closed return; } } else if (this.protocolProviders.length === 1) { provider = this.protocolProviders[0]; } else { return; } try { let addModalResult = null; if (provider.addEndpoint) { addModalResult = await provider.addEndpoint(this.deviceId); } else { addModalResult = await this.defaultAddEndpoint(this.deviceId, provider); } if (!addModalResult) { return; } this.alert.success(gettext('Endpoint added.')); } catch (e) { console.warn(e); this.alert.danger(gettext('Failed to add endpoint.'), e); } this.reload(); } getProtocolProviderForConfiguration(configuration) { return this.protocolProviders.find(p => p.protocolName === configuration.protocol); } async defaultEditEndpoint(deviceId, configuration) { const modalResult = await this.openBasicEndpointModal(configuration); if (!modalResult) { return modalResult; } return this.remoteAccess.updateConfiguration(deviceId, modalResult); } async defaultAddEndpoint(deviceId, provider) { let defaultConfig = { protocol: provider.protocolName }; if (provider.getDefaultEndpointConfiguration) { const defaultConfigFromProvider = await provider.getDefaultEndpointConfiguration(); defaultConfig = { ...defaultConfig, ...defaultConfigFromProvider }; } const modalResult = await this.openBasicEndpointModal(defaultConfig); if (!modalResult) { return modalResult; } return this.remoteAccess.addConfiguration(deviceId, modalResult); } async openBasicEndpointModal(currentConfiguration) { const { RemoteAccessBasicEndpointModalComponent } = await import('@c8y/ngx-components/remote-access/shared'); try { const modalRef = this.bsModalService.show(RemoteAccessBasicEndpointModalComponent, { initialState: { currentValue: currentConfiguration } }); return (await modalRef.content.result); } catch (e) { // modal closed return null; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: RemoteAccessConfigurationListComponent, deps: [{ token: i1.RemoteAccessService }, { token: i2$1.ActivatedRoute }, { token: i2.ModalService }, { token: i2.AlertService }, { token: i1$1.BsModalService }, { token: i5.TranslateService }, { token: i2.ContextRouteService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: RemoteAccessConfigurationListComponent, isStandalone: true, selector: "c8y-remote-access-configuration-list", ngImport: i0, template: "<c8y-title>{{ 'Remote access' | translate }}</c8y-title>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n (click)=\"addEndpoint()\"\n [disabled]=\"!protocolProviders?.length\"\n [attr.data-cy]=\"'remoteAccessConfigurationList--add-endpoint'\"\n >\n <i [c8yIcon]=\"'plus-circle'\"></i>\n <span translate>Add endpoint</span>\n </button>\n</c8y-action-bar-item>\n\n<div class=\"content-fullpage d-flex d-col border-top\">\n <c8y-data-grid\n [title]=\"gridTitle\"\n [rows]=\"rows\"\n [columns]=\"columns\"\n [pagination]=\"pagination\"\n (onReload)=\"reload()\"\n [actionControls]=\"actionControls\"\n [displayOptions]=\"displayOptions\"\n >\n <c8y-ui-empty-state\n [icon]=\"'window-restore'\"\n [title]=\"'No endpoints configured.' | translate\"\n [subtitle]=\"'Click below to add your first endpoint.' | translate\"\n [horizontal]=\"false\"\n >\n <button\n class=\"btn btn-default\"\n (click)=\"addEndpoint()\"\n translate\n >\n Add endpoint\n </button>\n </c8y-ui-empty-state>\n </c8y-data-grid>\n</div>\n", dependencies: [{ kind: "ngmodule", type: DataGridModule }, { kind: "component", type: i2.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "loading", "columns", "rows", "pagination", "childNodePagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows", "treeGrid", "hideReload", "childNodesProperty", "parentNodeLabelProperty"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "component", type: TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: RemoteAccessConfigurationListComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-remote-access-configuration-list', standalone: true, imports: [ DataGridModule, TitleComponent, C8yTranslateDirective, ActionBarItemComponent, IconDirective, EmptyStateComponent, C8yTranslatePipe ], template: "<c8y-title>{{ 'Remote access' | translate }}</c8y-title>\n\n<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n (click)=\"addEndpoint()\"\n [disabled]=\"!protocolProviders?.length\"\n [attr.data-cy]=\"'remoteAccessConfigurationList--add-endpoint'\"\n >\n <i [c8yIcon]=\"'plus-circle'\"></i>\n <span translate>Add endpoint</span>\n </button>\n</c8y-action-bar-item>\n\n<div class=\"content-fullpage d-flex d-col border-top\">\n <c8y-data-grid\n [title]=\"gridTitle\"\n [rows]=\"rows\"\n [columns]=\"columns\"\n [pagination]=\"pagination\"\n (onReload)=\"reload()\"\n [actionControls]=\"actionControls\"\n [displayOptions]=\"displayOptions\"\n >\n <c8y-ui-empty-state\n [icon]=\"'window-restore'\"\n [title]=\"'No endpoints configured.' | translate\"\n [subtitle]=\"'Click below to add your first endpoint.' | translate\"\n [horizontal]=\"false\"\n >\n <button\n class=\"btn btn-default\"\n (click)=\"addEndpoint()\"\n translate\n >\n Add endpoint\n </button>\n </c8y-ui-empty-state>\n </c8y-data-grid>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.RemoteAccessService }, { type: i2$1.ActivatedRoute }, { type: i2.ModalService }, { type: i2.AlertService }, { type: i1$1.BsModalService }, { type: i5.TranslateService }, { type: i2.ContextRouteService }] }); const remoteAccessConfigurationListProviders = [ hookRoute({ component: RemoteAccessConfigurationListComponent, label: gettext('Remote access'), path: 'remote_access', icon: 'window-restore', context: ViewContext.Device, canActivate: [canActivateRemoteAccess] }) ]; /** * Generated bundle index. Do not edit. */ export { RemoteAccessConfigurationListComponent, remoteAccessConfigurationListProviders }; //# sourceMappingURL=c8y-ngx-components-remote-access-configurations.mjs.map