This is an automated email from the ASF dual-hosted git repository.
zehnder pushed a commit to branch rel/0.98.0
in repository https://gitbox.apache.org/repos/asf/streampipes.git
The following commit(s) were added to refs/heads/rel/0.98.0 by this push:
new 0261a9bdf0 Role Management for Assets in create Tasks (#3897)
0261a9bdf0 is described below
commit 0261a9bdf0ffb3def7736917a49ff0b5b93e1b9f
Author: Jacqueline Höllig <[email protected]>
AuthorDate: Tue Nov 11 16:36:41 2025 +0100
Role Management for Assets in create Tasks (#3897)
Co-authored-by: Philipp Zehnder <[email protected]>
---
ui/cypress/support/utils/UserUtils.ts | 17 +++
ui/cypress/support/utils/connect/ConnectBtns.ts | 4 +
.../support/utils/dataExplorer/DataExplorerBtns.ts | 10 +-
ui/cypress/support/utils/pipeline/PipelineBtns.ts | 12 ++
.../{pipeline/PipelineBtns.ts => user/UserBtns.ts} | 22 ++--
.../tests/userManagement/testUserRoleAsset.spec.ts | 139 +++++++++++++++++++++
.../security-user-config.component.html | 6 +-
.../start-adapter-configuration.component.html | 108 ++++++++--------
.../start-adapter-configuration.component.ts | 21 +++-
.../edit-dashboard-dialog.component.html | 67 +++++-----
.../edit-dashboard-dialog.component.ts | 15 ++-
...data-explorer-chart-view-toolbar.component.html | 22 ++--
.../data-explorer-chart-view-toolbar.component.ts | 26 +++-
.../save-pipeline-settings.component.html | 38 +++---
.../save-pipeline-settings.component.ts | 12 ++
.../save-pipeline/save-pipeline.component.html | 1 +
16 files changed, 396 insertions(+), 124 deletions(-)
diff --git a/ui/cypress/support/utils/UserUtils.ts
b/ui/cypress/support/utils/UserUtils.ts
index 26802e32ea..ff660fae37 100644
--- a/ui/cypress/support/utils/UserUtils.ts
+++ b/ui/cypress/support/utils/UserUtils.ts
@@ -19,6 +19,7 @@
import { User } from '../model/User';
import { UserBuilder } from '../builder/UserBuilder';
import { UserRole } from '../../../src/app/_enums/user-role.enum';
+import { UserBtns } from './user/UserBtns';
export class UserUtils {
public static adminUser =
UserBuilder.create('[email protected]')
@@ -42,6 +43,7 @@ export class UserUtils {
public static goToUserConfiguration() {
cy.visit('#/configuration/security');
+ cy.dataCy('add-new-user', { timeout: 10000 }).should('exist');
}
public static addUser(user: User) {
@@ -66,6 +68,21 @@ export class UserUtils {
cy.dataCy('sp-element-edit-user-save').click();
}
+ public static toggleUserRole(user: User, role: UserRole) {
+ this.switchUser(this.adminUser);
+ this.goToUserConfiguration();
+ cy.get('table tbody tr', { timeout: 10000 }).should(
+ 'have.length.greaterThan',
+ 0,
+ );
+
+ UserBtns.editUserBtn(user.email);
+
+ UserBtns.userRoleCheckbox(role).click();
+
+ UserBtns.saveEditUserBtn().click();
+ }
+
/**
* Create a new user with the specified roles and a default password to
the system.
*
diff --git a/ui/cypress/support/utils/connect/ConnectBtns.ts
b/ui/cypress/support/utils/connect/ConnectBtns.ts
index 8319dab829..c0940f8c16 100644
--- a/ui/cypress/support/utils/connect/ConnectBtns.ts
+++ b/ui/cypress/support/utils/connect/ConnectBtns.ts
@@ -93,6 +93,10 @@ export class ConnectBtns {
return cy.dataCy('show-code-checkbox');
}
+ public static assetCheckbox() {
+ return cy.dataCy('show-asset-checkbox');
+ }
+
// ========================================================================
// ===================== Event Schema buttons ==========================
diff --git a/ui/cypress/support/utils/dataExplorer/DataExplorerBtns.ts
b/ui/cypress/support/utils/dataExplorer/DataExplorerBtns.ts
index e18474ac40..275a1d9a77 100644
--- a/ui/cypress/support/utils/dataExplorer/DataExplorerBtns.ts
+++ b/ui/cypress/support/utils/dataExplorer/DataExplorerBtns.ts
@@ -38,7 +38,7 @@ export class DataExplorerBtns {
}
public static chartAssetCheckboxBtn() {
- return cy.dataCy('sp-show-chart-asset-checkbox');
+ return cy.dataCy('add-to-Asset-data-view-btn');
}
public static confirmAssetSelectionBtn() {
return cy
@@ -51,4 +51,12 @@ export class DataExplorerBtns {
.dataCy('edit-data-view-' + widgetName.replaceAll(' ', ''))
.click();
}
+
+ public static dashboardAssetCheckboxBtn() {
+ return cy.dataCy('sp-show-dashboard-asset-checkbox');
+ }
+
+ public static closeDashboardCreate() {
+ return cy.dataCy('close-data-view');
+ }
}
diff --git a/ui/cypress/support/utils/pipeline/PipelineBtns.ts
b/ui/cypress/support/utils/pipeline/PipelineBtns.ts
index faece471a5..a79e14dccf 100644
--- a/ui/cypress/support/utils/pipeline/PipelineBtns.ts
+++ b/ui/cypress/support/utils/pipeline/PipelineBtns.ts
@@ -28,4 +28,16 @@ export class PipelineBtns {
public static deletePipeline() {
return cy.dataCy('delete-pipeline', { timeout: 10000 });
}
+
+ public static pipelineEditorSave() {
+ return cy.dataCy('sp-editor-save-pipeline');
+ }
+
+ public static pipelineAssetCheckbox() {
+ return cy.dataCy('sp-show-pipeline-asset-checkbox');
+ }
+
+ public static pipelineEditorCancel() {
+ return cy.dataCy('sp-editor-cancel');
+ }
}
diff --git a/ui/cypress/support/utils/pipeline/PipelineBtns.ts
b/ui/cypress/support/utils/user/UserBtns.ts
similarity index 59%
copy from ui/cypress/support/utils/pipeline/PipelineBtns.ts
copy to ui/cypress/support/utils/user/UserBtns.ts
index faece471a5..b3cfb8525f 100644
--- a/ui/cypress/support/utils/pipeline/PipelineBtns.ts
+++ b/ui/cypress/support/utils/user/UserBtns.ts
@@ -16,16 +16,24 @@
*
*/
-export class PipelineBtns {
- public static statusPipeline() {
- return cy.dataCy('status-pipeline-green', { timeout: 10000 });
+export class UserBtns {
+ public static editUserBtn(username) {
+ cy.get('[data-cy="security-user-config"]')
+ .find('tr')
+ .contains('b', username)
+ .closest('tr')
+ .within(() => {
+ cy.get('[data-cy="user-edit-btn"]')
+ .should('be.visible')
+ .click();
+ });
}
- public static stopPipeline() {
- return cy.dataCy('stop-pipeline-button', { timeout: 10000 });
+ public static userRoleCheckbox(role) {
+ return cy.dataCy('role-' + role).children();
}
- public static deletePipeline() {
- return cy.dataCy('delete-pipeline', { timeout: 10000 });
+ public static saveEditUserBtn() {
+ return cy.dataCy('sp-element-edit-user-save');
}
}
diff --git a/ui/cypress/tests/userManagement/testUserRoleAsset.spec.ts
b/ui/cypress/tests/userManagement/testUserRoleAsset.spec.ts
new file mode 100644
index 0000000000..ece8fba06d
--- /dev/null
+++ b/ui/cypress/tests/userManagement/testUserRoleAsset.spec.ts
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 { UserRole } from '../../../src/app/_enums/user-role.enum';
+import { UserUtils } from '../../support/utils/UserUtils';
+import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
+import { PipelineBtns } from '../../support/utils/pipeline/PipelineBtns';
+import { AssetUtils } from '../../support/utils/asset/AssetUtils';
+import { AdapterBuilder } from '../../support/builder/AdapterBuilder';
+import { DataExplorerUtils } from
'../../support/utils/dataExplorer/DataExplorerUtils';
+import { DataExplorerBtns } from
'../../support/utils/dataExplorer/DataExplorerBtns';
+import { ConnectBtns } from '../../support/utils/connect/ConnectBtns';
+
+describe('Test User Roles for Pipelines', () => {
+ let newUser;
+ beforeEach('Setup Test', () => {
+ cy.initStreamPipesTest();
+ newUser = UserUtils.createUser(
+ 'user',
+ UserRole.ROLE_PIPELINE_ADMIN,
+ UserRole.ROLE_ASSET_ADMIN,
+ UserRole.ROLE_CONNECT_ADMIN,
+ UserRole.ROLE_DATA_EXPLORER_ADMIN,
+ UserRole.ROLE_DASHBOARD_ADMIN,
+ );
+
+ AssetUtils.goToAssets();
+ AssetUtils.addAndSaveAsset('Asset');
+ });
+
+ it('Check Role Asset Admin in Connect', () => {
+ UserUtils.switchUser(newUser);
+
+ ConnectUtils.goToConnect();
+
+ ConnectUtils.addAdapter(
+ AdapterBuilder.create('Machine_Data_Simulator')
+ .setName('Machine Data Simulator Test 1')
+ .addInput('input', 'wait-time-ms', '1000')
+ .setStartAdapter(false)
+ .build(),
+ );
+ ConnectBtns.assetCheckbox().should('exist');
+
+ UserUtils.toggleUserRole(newUser, UserRole.ROLE_ASSET_ADMIN);
+
+ UserUtils.switchUser(newUser);
+
+ ConnectUtils.goToConnect();
+
+ ConnectUtils.addAdapter(
+ AdapterBuilder.create('Machine_Data_Simulator')
+ .setName('Machine Data Simulator Test2')
+ .addInput('input', 'wait-time-ms', '1000')
+ .setStartAdapter(false)
+ .build(),
+ );
+ ConnectBtns.assetCheckbox().should('not.exist');
+ });
+
+ it('Check Role Asset Admin in Pipeline', () => {
+ UserUtils.switchUser(newUser);
+
+ PipelineUtils.goToPipelines();
+
+ PipelineUtils.addSampleAdapterAndPipeline();
+
+ PipelineUtils.editPipeline('Pipeline Test');
+
+ PipelineBtns.pipelineEditorSave().click();
+
+ PipelineBtns.pipelineAssetCheckbox().should('exist');
+
+ PipelineBtns.pipelineEditorCancel().click();
+
+ UserUtils.toggleUserRole(newUser, UserRole.ROLE_ASSET_ADMIN);
+
+ UserUtils.switchUser(newUser);
+
+ PipelineUtils.goToPipelines();
+
+ PipelineUtils.editPipeline('Pipeline Test');
+
+ PipelineBtns.pipelineEditorSave().click();
+
+ PipelineBtns.pipelineAssetCheckbox().should('not.exist');
+ });
+
+ it('Check Role Asset Admin in Charts', () => {
+ UserUtils.switchUser(newUser);
+
+ DataExplorerUtils.goToDatalake();
+ DataExplorerUtils.createAndEditDataView();
+
+ DataExplorerBtns.chartAssetCheckboxBtn().should('exist');
+
+ UserUtils.toggleUserRole(newUser, UserRole.ROLE_ASSET_ADMIN);
+
+ UserUtils.switchUser(newUser);
+
+ DataExplorerUtils.goToDatalake();
+ DataExplorerUtils.createAndEditDataView();
+
+ DataExplorerBtns.chartAssetCheckboxBtn().should('not.exist');
+ });
+
+ it('Check Role Asset Admin in Dashboard', () => {
+ UserUtils.switchUser(newUser);
+ DataExplorerUtils.goToDashboard();
+ DataExplorerUtils.createDashboard('Test');
+
+ DataExplorerBtns.dashboardAssetCheckboxBtn().should('exist');
+ DataExplorerBtns.closeDashboardCreate().click();
+
+ UserUtils.toggleUserRole(newUser, UserRole.ROLE_ASSET_ADMIN);
+
+ UserUtils.switchUser(newUser);
+
+ DataExplorerUtils.goToDashboard();
+ DataExplorerUtils.createDashboard('Test');
+ DataExplorerBtns.dashboardAssetCheckboxBtn().should('not.exist');
+ });
+});
diff --git
a/ui/src/app/configuration/security-configuration/security-user-configuration/security-user-config.component.html
b/ui/src/app/configuration/security-configuration/security-user-configuration/security-user-config.component.html
index 9e17796d6e..a7cb3e39cf 100644
---
a/ui/src/app/configuration/security-configuration/security-user-configuration/security-user-config.component.html
+++
b/ui/src/app/configuration/security-configuration/security-user-configuration/security-user-config.component.html
@@ -112,7 +112,7 @@
class="mat-basic"
[matTooltip]="'Edit user' | translate"
matTooltipPosition="above"
- data-cy="user-edit-btn"
+ [attr.data-cy]="'user-edit-btn'"
(click)="editUser(account)"
>
<i class="material-icons">edit</i>
@@ -124,9 +124,7 @@
mat-flat-button
[matTooltip]="'Delete user' | translate"
matTooltipPosition="above"
- [attr.data-cy]="
- 'user-delete-btn-' + account.fullName
- "
+ [attr.data-cy]="'user-delete-btn'"
(click)="deleteUser(account)"
>
<i class="material-icons">delete</i>
diff --git
a/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.html
b/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.html
index 20b14171b6..442b1fdf49 100644
---
a/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.html
+++
b/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.html
@@ -103,26 +103,30 @@
>
</sp-adapter-options-panel>
- <sp-adapter-options-panel
- [optionTitle]="'Add to Asset' | translate"
- [optionDescription]="'Add Adapter to an existing Asset' |
translate"
- optionIcon="precision_manufacturing"
- dataCy="show-asset-checkbox"
- [isChecked]="
- showAsset && (!isEditMode || originalAssets.length > 0)
- "
- (optionSelectedEmitter)="showAsset = $event"
- >
- <sp-asset-link-configuration
- *ngIf="showAsset"
- [isEdit]="isEditMode"
- [itemId]="adapterDescription.elementId"
- (selectedAssetsChange)="onSelectedAssetsChange($event)"
- (deselectedAssetsChange)="onDeselectedAssetsChange($event)"
- (originalAssetsEmitter)="onOriginalAssetsEmitted($event)"
+ @if (isAssetAdmin) {
+ <sp-adapter-options-panel
+ [optionTitle]="'Add to Asset' | translate"
+ [optionDescription]="
+ 'Add Adapter to an existing Asset' | translate
+ "
+ optionIcon="precision_manufacturing"
+ dataCy="show-asset-checkbox"
+ [isChecked]="
+ showAsset && (!isEditMode || originalAssets.length > 0)
+ "
+ (optionSelectedEmitter)="showAsset = $event"
>
- </sp-asset-link-configuration>
- </sp-adapter-options-panel>
+ <sp-asset-link-configuration
+ *ngIf="showAsset"
+ [isEdit]="isEditMode"
+ [itemId]="adapterDescription.elementId"
+ (selectedAssetsChange)="onSelectedAssetsChange($event)"
+ (deselectedAssetsChange)="onDeselectedAssetsChange($event)"
+ (originalAssetsEmitter)="onOriginalAssetsEmitted($event)"
+ >
+ </sp-asset-link-configuration>
+ </sp-adapter-options-panel>
+ }
<sp-adapter-options-panel
[optionTitle]="'Remove Duplicates' | translate"
@@ -197,38 +201,44 @@
</sp-adapter-options-panel>
<!-- Start pipeline template to store raw events in data lake -->
- <sp-adapter-options-panel
- [optionTitle]="'Persist events' | translate"
- [optionDescription]="
- 'Store all events of this source in the internal data store'
- | translate
- "
- optionIcon="save"
- dataCy="sp-store-in-datalake"
- *ngIf="!isEditMode"
- (optionSelectedEmitter)="handlePersistOption($event)"
- >
- <mat-form-field *ngIf="saveInDataLake" color="accent"
class="mt-10">
- <mat-label>{{ 'Select Time Field' | translate }}</mat-label>
- <mat-select
- [(ngModel)]="dataLakeTimestampField"
- [ngModelOptions]="{ standalone: true }"
- data-cy="sp-store-in-datalake-timestamp"
+ @if (isPipelineAdmin) {
+ <sp-adapter-options-panel
+ [optionTitle]="'Persist events' | translate"
+ [optionDescription]="
+ 'Store all events of this source in the internal data
store'
+ | translate
+ "
+ optionIcon="save"
+ dataCy="sp-store-in-datalake"
+ *ngIf="!isEditMode"
+ (optionSelectedEmitter)="handlePersistOption($event)"
+ >
+ <mat-form-field
+ *ngIf="saveInDataLake"
+ color="accent"
+ class="mt-10"
>
- <mat-option
- class="md-elevation-z1"
- style="background: white"
- *ngFor="
- let timestampField of eventSchema.eventProperties
- | timestampFilter
- "
- [value]="timestampField.runtimeName"
+ <mat-label>{{ 'Select Time Field' | translate
}}</mat-label>
+ <mat-select
+ [(ngModel)]="dataLakeTimestampField"
+ [ngModelOptions]="{ standalone: true }"
+ data-cy="sp-store-in-datalake-timestamp"
>
- {{ timestampField.runtimeName }}
- </mat-option>
- </mat-select>
- </mat-form-field>
- </sp-adapter-options-panel>
+ <mat-option
+ class="md-elevation-z1"
+ style="background: white"
+ *ngFor="
+ let timestampField of
eventSchema.eventProperties
+ | timestampFilter
+ "
+ [value]="timestampField.runtimeName"
+ >
+ {{ timestampField.runtimeName }}
+ </mat-option>
+ </mat-select>
+ </mat-form-field>
+ </sp-adapter-options-panel>
+ }
<sp-adapter-options-panel
[optionTitle]="'Show code' | translate"
diff --git
a/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.ts
b/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.ts
index 6c69a048f6..eda1100774 100644
---
a/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.ts
+++
b/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.ts
@@ -22,6 +22,7 @@ import {
EventSchema,
SpAssetTreeNode,
RemoveDuplicatesTransformationRuleDescription,
+ UserInfo,
} from '@streampipes/platform-services';
import {
UntypedFormBuilder,
@@ -31,12 +32,17 @@ import {
} from '@angular/forms';
import { MatStepper } from '@angular/material/stepper';
import { AdapterStartedDialog } from
'../../../dialog/adapter-started/adapter-started-dialog.component';
-import { DialogService, PanelType } from '@streampipes/shared-ui';
+import {
+ CurrentUserService,
+ DialogService,
+ PanelType,
+} from '@streampipes/shared-ui';
import { ShepherdService } from '../../../../services/tour/shepherd.service';
import { TimestampPipe } from '../../../filter/timestamp.pipe';
import { TransformationRuleService } from
'../../../services/transformation-rule.service';
import { ValidateName } from
'../../../../core-ui/static-properties/input.validator';
import { TranslateService } from '@ngx-translate/core';
+import { UserRole } from 'src/app/_enums/user-role.enum';
@Component({
selector: 'sp-start-adapter-configuration',
@@ -85,6 +91,8 @@ export class StartAdapterConfigurationComponent implements
OnInit {
startAdapterSettingsFormValid = false;
+ currentUser: UserInfo;
+
// preprocessing rule variables
removeDuplicates = false;
removeDuplicatesTime: number;
@@ -103,6 +111,9 @@ export class StartAdapterConfigurationComponent implements
OnInit {
deselectedAssets = [];
originalAssets = [];
+ isAssetAdmin = false;
+ isPipelineAdmin = false;
+
constructor(
private dialogService: DialogService,
private shepherdService: ShepherdService,
@@ -110,10 +121,18 @@ export class StartAdapterConfigurationComponent
implements OnInit {
private timestampPipe: TimestampPipe,
private transformationRuleService: TransformationRuleService,
private translateService: TranslateService,
+ private currentUserService: CurrentUserService,
) {}
ngOnInit(): void {
this.showAsset = this.isEditMode;
+ this.currentUser = this.currentUserService.getCurrentUser();
+ this.isAssetAdmin = this.currentUserService.hasRole(
+ UserRole.ROLE_ASSET_ADMIN,
+ );
+ this.isPipelineAdmin = this.currentUserService.hasRole(
+ UserRole.ROLE_PIPELINE_ADMIN,
+ );
this.startAdapterForm = this._formBuilder.group({});
this.startAdapterForm.addControl(
'adapterName',
diff --git
a/ui/src/app/dashboard/dialogs/edit-dashboard/edit-dashboard-dialog.component.html
b/ui/src/app/dashboard/dialogs/edit-dashboard/edit-dashboard-dialog.component.html
index 8c2f062889..ae95727681 100644
---
a/ui/src/app/dashboard/dialogs/edit-dashboard/edit-dashboard-dialog.component.html
+++
b/ui/src/app/dashboard/dialogs/edit-dashboard/edit-dashboard-dialog.component.html
@@ -98,39 +98,43 @@
</mat-checkbox>
</div>
- <div class="mt-10" fxLayout="column">
- <label>{{ 'Add Dashboard to Assets' | translate }}</label>
+ @if (isAssetAdmin) {
+ <div class="mt-10" fxLayout="column">
+ <label>{{
+ 'Add Dashboard to Assets' | translate
+ }}</label>
- <mat-checkbox
- [(ngModel)]="addToAssets"
- color="accent"
- data-cy="sp-show-dashboard-asset-checkbox"
- >
- {{
- 'Add the current dashboard to an existing asset'
- | translate
- }}
- </mat-checkbox>
+ <mat-checkbox
+ [(ngModel)]="addToAssets"
+ color="accent"
+ data-cy="sp-show-dashboard-asset-checkbox"
+ >
+ {{
+ 'Add the current dashboard to an existing
asset'
+ | translate
+ }}
+ </mat-checkbox>
- @if (addToAssets) {
- <div class="mt-10">
- <sp-asset-link-configuration
- [isEdit]="!createMode"
- [itemId]="dashboard.elementId"
- (selectedAssetsChange)="
- onSelectedAssetsChange($event)
- "
- (deselectedAssetsChange)="
- onDeselectedAssetsChange($event)
- "
- (originalAssetsEmitter)="
- onOriginalAssetsEmitted($event)
- "
- >
- </sp-asset-link-configuration>
- </div>
- }
- </div>
+ @if (addToAssets) {
+ <div class="mt-10">
+ <sp-asset-link-configuration
+ [isEdit]="!createMode"
+ [itemId]="dashboard.elementId"
+ (selectedAssetsChange)="
+ onSelectedAssetsChange($event)
+ "
+ (deselectedAssetsChange)="
+ onDeselectedAssetsChange($event)
+ "
+ (originalAssetsEmitter)="
+ onOriginalAssetsEmitted($event)
+ "
+ >
+ </sp-asset-link-configuration>
+ </div>
+ }
+ </div>
+ }
<!--<mat-checkbox [(ngModel)]="dashboard.displayHeader">Show
name and description in dashboard</mat-checkbox>-->
</div>
@@ -153,6 +157,7 @@
mat-flat-button
class="mat-basic mr-10"
(click)="onCancel()"
+ data-cy="close-data-view"
>
{{ 'Close' | translate }}
</button>
diff --git
a/ui/src/app/dashboard/dialogs/edit-dashboard/edit-dashboard-dialog.component.ts
b/ui/src/app/dashboard/dialogs/edit-dashboard/edit-dashboard-dialog.component.ts
index 426b676362..554e65cdd9 100644
---
a/ui/src/app/dashboard/dialogs/edit-dashboard/edit-dashboard-dialog.component.ts
+++
b/ui/src/app/dashboard/dialogs/edit-dashboard/edit-dashboard-dialog.component.ts
@@ -29,8 +29,14 @@ import {
DashboardService,
LinkageData,
SpAssetTreeNode,
+ UserInfo,
} from '@streampipes/platform-services';
-import { AssetSaveService, DialogRef } from '@streampipes/shared-ui';
+import {
+ AssetSaveService,
+ CurrentUserService,
+ DialogRef,
+} from '@streampipes/shared-ui';
+import { UserRole } from 'src/app/_enums/user-role.enum';
@Component({
selector: 'sp-edit-dashboard-dialog-component',
@@ -52,10 +58,17 @@ export class EditDashboardDialogComponent implements OnInit
{
private dialogRef = inject(DialogRef<EditDashboardDialogComponent>);
private dashboardService = inject(DashboardService);
private assetSaveService = inject(AssetSaveService);
+ private readonly currentUserService = inject(CurrentUserService);
+ currentUser: UserInfo;
+ isAssetAdmin = false;
addToAssets: boolean = false;
ngOnInit() {
+ this.currentUser = this.currentUserService.getCurrentUser();
+ this.isAssetAdmin = this.currentUserService.hasRole(
+ UserRole.ROLE_ASSET_ADMIN,
+ );
if (!this.dashboard.dashboardGeneralSettings.defaultViewMode) {
this.dashboard.dashboardGeneralSettings.defaultViewMode = 'grid';
}
diff --git
a/ui/src/app/data-explorer/components/chart-view/toolbar/data-explorer-chart-view-toolbar.component.html
b/ui/src/app/data-explorer/components/chart-view/toolbar/data-explorer-chart-view-toolbar.component.html
index 680c07a36f..739d94cbd1 100644
---
a/ui/src/app/data-explorer/components/chart-view/toolbar/data-explorer-chart-view-toolbar.component.html
+++
b/ui/src/app/data-explorer/components/chart-view/toolbar/data-explorer-chart-view-toolbar.component.html
@@ -67,16 +67,18 @@
<mat-icon>save</mat-icon>
{{ 'Save' | translate }}
</button>
- <button
- mat-flat-button
- [matTooltip]="'Add to Asset' | translate"
- class="edit-menu-btn"
- (click)="addToAssetEmitter.emit()"
- data-cy="add-to-Asset-data-view-btn"
- >
- <mat-icon>precision_manufacturing</mat-icon>
- {{ 'Add To Asset' | translate }}
- </button>
+ @if (isAssetAdmin) {
+ <button
+ mat-flat-button
+ [matTooltip]="'Add to Asset' | translate"
+ class="edit-menu-btn"
+ (click)="addToAssetEmitter.emit()"
+ data-cy="add-to-Asset-data-view-btn"
+ >
+ <mat-icon>precision_manufacturing</mat-icon>
+ {{ 'Add To Asset' | translate }}
+ </button>
+ }
<button
mat-flat-button
[matTooltip]="'Discard' | translate"
diff --git
a/ui/src/app/data-explorer/components/chart-view/toolbar/data-explorer-chart-view-toolbar.component.ts
b/ui/src/app/data-explorer/components/chart-view/toolbar/data-explorer-chart-view-toolbar.component.ts
index 085271665e..dbc232a765 100644
---
a/ui/src/app/data-explorer/components/chart-view/toolbar/data-explorer-chart-view-toolbar.component.ts
+++
b/ui/src/app/data-explorer/components/chart-view/toolbar/data-explorer-chart-view-toolbar.component.ts
@@ -16,11 +16,21 @@
*
*/
-import { Component, EventEmitter, Input, Output } from '@angular/core';
+import {
+ Component,
+ EventEmitter,
+ inject,
+ Input,
+ OnInit,
+ Output,
+} from '@angular/core';
import {
DataExplorerWidgetModel,
TimeSettings,
+ UserInfo,
} from '@streampipes/platform-services';
+import { CurrentUserService } from '@streampipes/shared-ui';
+import { UserRole } from 'src/app/_enums/user-role.enum';
@Component({
selector: 'sp-data-explorer-data-view-toolbar',
@@ -28,7 +38,9 @@ import {
styleUrls: ['../data-explorer-chart-view.component.scss'],
standalone: false,
})
-export class DataExplorerChartViewToolbarComponent {
+export class DataExplorerChartViewToolbarComponent implements OnInit {
+ private readonly currentUserService = inject(CurrentUserService);
+
@Input()
editMode = true;
@@ -54,4 +66,14 @@ export class DataExplorerChartViewToolbarComponent {
@Output()
downloadFileEmitter: EventEmitter<void> = new EventEmitter();
+
+ currentUser: UserInfo;
+ isAssetAdmin = false;
+
+ ngOnInit() {
+ this.currentUser = this.currentUserService.getCurrentUser();
+ this.isAssetAdmin = this.currentUserService.hasRole(
+ UserRole.ROLE_ASSET_ADMIN,
+ );
+ }
}
diff --git
a/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.html
b/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.html
index cb88a730c0..f0898df853 100644
---
a/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.html
+++
b/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.html
@@ -122,24 +122,26 @@
>
Navigate to pipeline overview afterwards
</mat-checkbox>
- <mat-checkbox
- [(ngModel)]="addToAssets"
- color="accent"
- data-cy="sp-show-pipeline-asset-checkbox"
- >
- Add Pipeline to Assets
- </mat-checkbox>
- @if (addToAssets) {
- <div class="mt-10">
- <sp-asset-link-configuration
- [isEdit]="storageOptions.updateMode === 'update'"
- [itemId]="pipeline._id"
- (selectedAssetsChange)="onSelectedAssetsChange($event)"
- (deselectedAssetsChange)="onDeselectedAssetsChange($event)"
- (originalAssetsEmitter)="onOriginalAssetsEmitted($event)"
- >
- </sp-asset-link-configuration>
- </div>
+ @if (isAssetAdmin) {
+ <mat-checkbox
+ [(ngModel)]="addToAssets"
+ color="accent"
+ data-cy="sp-show-pipeline-asset-checkbox"
+ >
+ Add Pipeline to Assets
+ </mat-checkbox>
+ @if (addToAssets) {
+ <div class="mt-10">
+ <sp-asset-link-configuration
+ [isEdit]="storageOptions.updateMode === 'update'"
+ [itemId]="pipeline._id"
+ (selectedAssetsChange)="onSelectedAssetsChange($event)"
+ (deselectedAssetsChange)="onDeselectedAssetsChange($event)"
+ (originalAssetsEmitter)="onOriginalAssetsEmitted($event)"
+ >
+ </sp-asset-link-configuration>
+ </div>
+ }
}
<div class="mt-10">
<mat-expansion-panel class="mat-elevation-z0 border-1">
diff --git
a/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.ts
b/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.ts
index b8b5284f16..f9cb65100b 100644
---
a/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.ts
+++
b/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.ts
@@ -19,6 +19,7 @@
import {
Component,
EventEmitter,
+ Inject,
inject,
Input,
OnInit,
@@ -35,9 +36,12 @@ import {
Pipeline,
PipelineService,
SpAssetTreeNode,
+ UserInfo,
} from '@streampipes/platform-services';
import { PipelineStorageOptions } from '../../../model/editor.model';
import { ValidateName } from
'../../../../core-ui/static-properties/input.validator';
+import { CurrentUserService } from '@streampipes/shared-ui';
+import { UserRole } from 'src/app/_enums/user-role.enum';
@Component({
selector: 'sp-save-pipeline-settings',
@@ -46,6 +50,8 @@ import { ValidateName } from
'../../../../core-ui/static-properties/input.valida
standalone: false,
})
export class SavePipelineSettingsComponent implements OnInit {
+ private readonly currentUserService = inject(CurrentUserService);
+
@Input()
submitPipelineForm: UntypedFormGroup = new UntypedFormGroup({});
@@ -62,6 +68,8 @@ export class SavePipelineSettingsComponent implements OnInit {
private pipelineService = inject(PipelineService);
compactPipeline: CompactPipeline;
+ currentUser: UserInfo;
+ isAssetAdmin = false;
addToAssets: boolean = false;
@Input()
@@ -76,6 +84,10 @@ export class SavePipelineSettingsComponent implements OnInit
{
@Output() originalAssetsChange = new EventEmitter<SpAssetTreeNode[]>();
ngOnInit() {
+ this.currentUser = this.currentUserService.getCurrentUser();
+ this.isAssetAdmin = this.currentUserService.hasRole(
+ UserRole.ROLE_ASSET_ADMIN,
+ );
this.submitPipelineForm.addControl(
'pipelineName',
new UntypedFormControl(this.pipeline.name, [
diff --git
a/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.html
b/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.html
index 75ffc1fecb..2a1138adb7 100644
--- a/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.html
+++ b/ui/src/app/editor/dialog/save-pipeline/save-pipeline.component.html
@@ -88,6 +88,7 @@
mat-flat-button
class="mat-basic"
(click)="hide(true)"
+ data-cy="sp-editor-cancel"
>
{{ 'Cancel' }}
</button>