diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index 49f1f57fd1..38cf85e72c 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -153,10 +153,10 @@ import { TenantProfileQueuesComponent } from '@home/components/profile/queue/ten import { QueueFormComponent } from '@home/components/queue/queue-form.component'; import { WidgetSettingsModule } from '@home/components/widget/lib/settings/widget-settings.module'; import { WidgetSettingsComponent } from '@home/components/widget/widget-settings.component'; -import { VcEntityExportDialogComponent } from '@home/components/vc/vc-entity-export-dialog.component'; import { VersionControlSettingsComponent } from '@home/components/vc/version-control-settings.component'; import { VersionControlComponent } from '@home/components/vc/version-control.component'; import { EntityVersionsTableComponent } from '@home/components/vc/entity-versions-table.component'; +import { EntityVersionExportComponent } from '@home/components/vc/entity-version-export.component'; @NgModule({ declarations: @@ -281,10 +281,10 @@ import { EntityVersionsTableComponent } from '@home/components/vc/entity-version DisplayWidgetTypesPanelComponent, TenantProfileQueuesComponent, QueueFormComponent, - VcEntityExportDialogComponent, VersionControlSettingsComponent, VersionControlComponent, - EntityVersionsTableComponent + EntityVersionsTableComponent, + EntityVersionExportComponent ], imports: [ CommonModule, @@ -403,10 +403,10 @@ import { EntityVersionsTableComponent } from '@home/components/vc/entity-version DisplayWidgetTypesPanelComponent, TenantProfileQueuesComponent, QueueFormComponent, - VcEntityExportDialogComponent, VersionControlSettingsComponent, VersionControlComponent, - EntityVersionsTableComponent + EntityVersionsTableComponent, + EntityVersionExportComponent ], providers: [ WidgetComponentService, diff --git a/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html b/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html index 57286fd7ee..f5b9c15a0f 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/device-profile.component.html @@ -34,12 +34,6 @@ [fxShow]="!isEdit && !entity?.default"> {{'device-profile.set-default' | translate }} - + + + diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-version-export.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-version-export.component.ts new file mode 100644 index 0000000000..368a4bf441 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/vc/entity-version-export.component.ts @@ -0,0 +1,84 @@ +/// +/// Copyright © 2016-2022 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, Input, OnInit } from '@angular/core'; +import { PageComponent } from '@shared/components/page.component'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { + SingleEntityVersionCreateRequest, + VersionCreateRequestType, + VersionCreationResult +} from '@shared/models/vc.models'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { EntitiesVersionControlService } from '@core/http/entities-version-control.service'; +import { EntityId } from '@shared/models/id/entity-id'; + +@Component({ + selector: 'tb-entity-version-export', + templateUrl: './entity-version-export.component.html', + styleUrls: [] +}) +export class EntityVersionExportComponent extends PageComponent implements OnInit { + + @Input() + branch: string; + + @Input() + entityId: EntityId; + + @Input() + onClose: (result: VersionCreationResult | null, branch: string | null) => void; + + exportFormGroup: FormGroup; + + constructor(protected store: Store, + private entitiesVersionControlService: EntitiesVersionControlService, + private fb: FormBuilder) { + super(store); + } + + ngOnInit(): void { + this.exportFormGroup = this.fb.group({ + branch: [this.branch, [Validators.required]], + versionName: [null, [Validators.required]], + saveRelations: [false, []] + }); + } + + cancel(): void { + if (this.onClose) { + this.onClose(null, null); + } + } + + export(): void { + const request: SingleEntityVersionCreateRequest = { + entityId: this.entityId, + branch: this.exportFormGroup.get('branch').value, + versionName: this.exportFormGroup.get('versionName').value, + config: { + saveRelations: this.exportFormGroup.get('saveRelations').value + }, + type: VersionCreateRequestType.SINGLE_ENTITY + }; + this.entitiesVersionControlService.saveEntitiesVersion(request).subscribe((result) => { + if (this.onClose) { + this.onClose(result, request.branch); + } + }); + } +} diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.html b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.html index f5aa4a04d2..11d8b2a2e2 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.html @@ -31,10 +31,12 @@ - diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.scss b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.scss index 9017de60b8..ec5cb02256 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.scss +++ b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.scss @@ -78,7 +78,7 @@ tb-branch-autocomplete { mat-form-field { font-size: 16px; - width: 200px; + width: 250px; .mat-form-field-wrapper { padding-bottom: 0; diff --git a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts index 884bab417b..436267fe2f 100644 --- a/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/entity-versions-table.component.ts @@ -21,8 +21,8 @@ import { ElementRef, Input, OnDestroy, - OnInit, - ViewChild + OnInit, Renderer2, + ViewChild, ViewContainerRef } from '@angular/core'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; @@ -33,7 +33,7 @@ import { BehaviorSubject, merge, Observable, of, ReplaySubject } from 'rxjs'; import { emptyPageData, PageData } from '@shared/models/page/page-data'; import { PageLink } from '@shared/models/page/page-link'; import { catchError, map, tap } from 'rxjs/operators'; -import { EntityVersion } from '@shared/models/vc.models'; +import { EntityVersion, VersionCreationResult } from '@shared/models/vc.models'; import { EntitiesVersionControlService } from '@core/http/entities-version-control.service'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; @@ -42,6 +42,10 @@ import { hidePageSizePixelValue } from '@shared/models/constants'; import { Direction, SortOrder } from '@shared/models/page/sort-order'; import { BranchAutocompleteComponent } from '@shared/components/vc/branch-autocomplete.component'; import { isNotEmptyStr } from '@core/utils'; +import { TbPopoverService } from '@shared/components/popover.service'; +import { EntityVersionExportComponent } from '@home/components/vc/entity-version-export.component'; +import { MatButton } from '@angular/material/button'; +import { TbPopoverComponent } from '@shared/components/popover.component'; @Component({ selector: 'tb-entity-versions-table', @@ -68,6 +72,8 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni viewsInited = false; + vcExportPopover: TbPopoverComponent; + private componentResize$: ResizeObserver; @Input() @@ -94,12 +100,18 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni } } + @Input() + entityId: EntityId; + @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; constructor(protected store: Store, private entitiesVersionControlService: EntitiesVersionControlService, + private popoverService: TbPopoverService, + private renderer: Renderer2, private cd: ChangeDetectorRef, + private viewContainerRef: ViewContainerRef, private elementRef: ElementRef) { super(store); this.dirtyValue = !this.activeValue; @@ -148,10 +160,36 @@ export class EntityVersionsTableComponent extends PageComponent implements OnIni } } - vcExport($event: Event) { + toggleVcExport($event: Event, exportButton: MatButton) { if ($event) { $event.stopPropagation(); } + const trigger = exportButton._elementRef.nativeElement; + if (this.popoverService.hasPopover(trigger)) { + this.popoverService.hidePopover(trigger); + } else { + this.vcExportPopover = this.popoverService.displayPopover(trigger, this.renderer, + this.viewContainerRef, EntityVersionExportComponent, 'bottom', true, null, + { + branch: this.branch, + entityId: this.entityId, + onClose: (result: VersionCreationResult | null, branch: string | null) => { + this.vcExportPopover.hide(); + if (result) { + if (this.branch !== branch) { + this.branchChanged(branch); + } else { + this.updateData(); + } + } + } + }, {}, {}, {}, false); + this.vcExportPopover.tbVisibleChange.subscribe((visible: boolean) => { + if (!visible) { + this.vcExportPopover = null; + } + }); + } } versionIdContent(entityVersion: EntityVersion): string { diff --git a/ui-ngx/src/app/modules/home/components/vc/vc-entity-export-dialog.component.html b/ui-ngx/src/app/modules/home/components/vc/vc-entity-export-dialog.component.html deleted file mode 100644 index e7ea79cd73..0000000000 --- a/ui-ngx/src/app/modules/home/components/vc/vc-entity-export-dialog.component.html +++ /dev/null @@ -1,77 +0,0 @@ - -
- -

{{ (createResult ? 'version-control.entity-version-exported' : 'version-control.export-entity-version') | translate }}

- - -
- - -
-
-
-
- - - - version-control.version-name - - - {{ 'version-control.version-name-required' | translate }} - - - - {{ 'version-control.export-entity-relations' | translate }} - -
-
-
-
-
-
-
-
- - -
-
- -
-
diff --git a/ui-ngx/src/app/modules/home/components/vc/vc-entity-export-dialog.component.ts b/ui-ngx/src/app/modules/home/components/vc/vc-entity-export-dialog.component.ts deleted file mode 100644 index 9d3affea42..0000000000 --- a/ui-ngx/src/app/modules/home/components/vc/vc-entity-export-dialog.component.ts +++ /dev/null @@ -1,105 +0,0 @@ -/// -/// Copyright © 2016-2022 The Thingsboard Authors -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -import { Component, Inject, OnInit, SkipSelf } from '@angular/core'; -import { ErrorStateMatcher } from '@angular/material/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; -import { Store } from '@ngrx/store'; -import { AppState } from '@core/core.state'; -import { FormBuilder, FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms'; -import { Router } from '@angular/router'; -import { DialogComponent } from '@app/shared/components/dialog.component'; -import { EntityId } from '@shared/models/id/entity-id'; -import { - SingleEntityVersionCreateRequest, - VersionCreateRequestType, - VersionCreationResult -} from '@shared/models/vc.models'; -import { EntitiesVersionControlService } from '@core/http/entities-version-control.service'; -import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; -import { TranslateService } from '@ngx-translate/core'; - -export interface VcEntityExportDialogData { - entityId: EntityId; -} - -@Component({ - selector: 'tb-vc-entity-export-dialog', - templateUrl: './vc-entity-export-dialog.component.html', - providers: [{provide: ErrorStateMatcher, useExisting: VcEntityExportDialogComponent}], - styleUrls: [] -}) -export class VcEntityExportDialogComponent extends DialogComponent - implements OnInit, ErrorStateMatcher { - - exportFormGroup: FormGroup; - - submitted = false; - - createResult: VersionCreationResult; - - createResultMessage: SafeHtml; - - constructor(protected store: Store, - protected router: Router, - @Inject(MAT_DIALOG_DATA) public data: VcEntityExportDialogData, - @SkipSelf() private errorStateMatcher: ErrorStateMatcher, - public dialogRef: MatDialogRef, - private entitiesVersionControlService: EntitiesVersionControlService, - private translate: TranslateService, - private domSanitizer: DomSanitizer, - private fb: FormBuilder) { - super(store, router, dialogRef); - - this.exportFormGroup = this.fb.group({ - branch: [null, [Validators.required]], - versionName: [null, [Validators.required]], - saveRelations: [false, []] - }); - } - - ngOnInit(): void { - } - - isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { - const originalErrorState = this.errorStateMatcher.isErrorState(control, form); - const customErrorState = !!(control && control.invalid && this.submitted); - return originalErrorState || customErrorState; - } - - cancel(): void { - this.dialogRef.close(); - } - - export(): void { - this.submitted = true; - const request: SingleEntityVersionCreateRequest = { - entityId: this.data.entityId, - branch: this.exportFormGroup.get('branch').value, - versionName: this.exportFormGroup.get('versionName').value, - config: { - saveRelations: this.exportFormGroup.get('saveRelations').value - }, - type: VersionCreateRequestType.SINGLE_ENTITY - }; - this.entitiesVersionControlService.saveEntitiesVersion(request).subscribe((result) => { - this.createResult = result; - const message = this.translate.instant('version-control.export-entity-version-result-message', - {name: result.version.name, commitId: result.version.id}); - this.createResultMessage = this.domSanitizer.bypassSecurityTrustHtml(message); - }); - } -} diff --git a/ui-ngx/src/app/modules/home/components/vc/version-control.component.html b/ui-ngx/src/app/modules/home/components/vc/version-control.component.html index 903460054b..c631819128 100644 --- a/ui-ngx/src/app/modules/home/components/vc/version-control.component.html +++ b/ui-ngx/src/app/modules/home/components/vc/version-control.component.html @@ -21,5 +21,6 @@ diff --git a/ui-ngx/src/app/modules/home/components/vc/version-control.component.ts b/ui-ngx/src/app/modules/home/components/vc/version-control.component.ts index 07bdbcba25..2ca68255ae 100644 --- a/ui-ngx/src/app/modules/home/components/vc/version-control.component.ts +++ b/ui-ngx/src/app/modules/home/components/vc/version-control.component.ts @@ -44,6 +44,9 @@ export class VersionControlComponent implements OnInit, HasConfirmForm { @Input() externalEntityId: EntityId; + @Input() + entityId: EntityId; + hasVersionControl$ = this.store.pipe(select(selectHasVersionControl)); constructor(private store: Store) { diff --git a/ui-ngx/src/app/modules/home/dialogs/home-dialogs.service.ts b/ui-ngx/src/app/modules/home/dialogs/home-dialogs.service.ts index 1730c69084..ff08af8039 100644 --- a/ui-ngx/src/app/modules/home/dialogs/home-dialogs.service.ts +++ b/ui-ngx/src/app/modules/home/dialogs/home-dialogs.service.ts @@ -22,11 +22,6 @@ import { ImportDialogCsvComponent, ImportDialogCsvData } from '@home/components/import-export/import-dialog-csv.component'; -import { EntityId } from '@shared/models/id/entity-id'; -import { - VcEntityExportDialogComponent, - VcEntityExportDialogData -} from '@home/components/vc/vc-entity-export-dialog.component'; @Injectable() export class HomeDialogsService { @@ -46,17 +41,6 @@ export class HomeDialogsService { } } - public exportVcEntity(entityId: EntityId): Observable { - return this.dialog.open(VcEntityExportDialogComponent, - { - disableClose: true, - panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], - data: { - entityId - } - }).afterClosed(); - } - private openImportDialogCSV(entityType: EntityType, importTitle: string, importFileLabel: string): Observable { return this.dialog.open(ImportDialogCsvComponent, { diff --git a/ui-ngx/src/app/modules/home/pages/asset/asset-tabs.component.html b/ui-ngx/src/app/modules/home/pages/asset/asset-tabs.component.html index e5accc15a9..3a3f2dda92 100644 --- a/ui-ngx/src/app/modules/home/pages/asset/asset-tabs.component.html +++ b/ui-ngx/src/app/modules/home/pages/asset/asset-tabs.component.html @@ -49,3 +49,8 @@ label="{{ 'audit-log.audit-logs' | translate }}" #auditLogsTab="matTab"> + + + diff --git a/ui-ngx/src/app/modules/home/pages/asset/asset.component.html b/ui-ngx/src/app/modules/home/pages/asset/asset.component.html index 75171b4532..00ed882cd9 100644 --- a/ui-ngx/src/app/modules/home/pages/asset/asset.component.html +++ b/ui-ngx/src/app/modules/home/pages/asset/asset.component.html @@ -46,12 +46,6 @@ [fxShow]="!isEdit && assetScope === 'edge'"> {{ 'edge.unassign-from-edge' | translate }} - - - - -