From 2157d3ba20c43ff9d3aa23b87f4b6eccb99807db Mon Sep 17 00:00:00 2001 From: JohannesDoberer Date: Mon, 29 Jul 2019 16:54:49 +0200 Subject: [PATCH] Client permissions available in the client (#678) client permissions --- client/luigi-client.d.ts | 12 ++++++++++++ client/src/lifecycleManager.js | 9 +++++++++ client/src/luigi-client.js | 3 +++ .../luigi-client-ux-manager-features.spec.js | 15 +++++++++++++++ .../src/app/project/project.component.html | 2 ++ .../src/app/project/project.component.ts | 4 ++++ .../src/luigi-config/extended/projectDetailNav.js | 6 ++++++ core/package.json | 2 +- core/src/App.html | 7 +++++-- core/src/services/iframe.js | 2 +- core/src/services/routing.js | 6 +----- docs/luigi-client-api.md | 6 ++++++ 12 files changed, 65 insertions(+), 9 deletions(-) diff --git a/client/luigi-client.d.ts b/client/luigi-client.d.ts index ac566026b1..3471b830a0 100644 --- a/client/luigi-client.d.ts +++ b/client/luigi-client.d.ts @@ -57,6 +57,10 @@ export declare interface NodeParams { [key: string]: string; } +export declare interface ClientPermissions { + [key: string]: any; +} + export declare interface AlertSettings { text?: string; type: 'info' | 'success' | 'warning' | 'error'; @@ -357,6 +361,14 @@ export type getNodeParams = () => NodeParams; export function getPathParams(): PathParams; export type getPathParams = () => PathParams; +/** + * Returns the current client permissions as specified in the navigation node or an empty object. For details, see [Node parameters](navigation-parameters-reference.md). + * @returns {Object} client permissions as specified in the navigation node. + * @memberof Lifecycle + */ +export function getClientPermissions(): ClientPermissions; +export type getClientPermissions = () => ClientPermissions; + /** * The Link Manager allows you to navigate to another route. Use it instead of an internal router to: - Route inside micro front-ends. diff --git a/client/src/lifecycleManager.js b/client/src/lifecycleManager.js index 7429229c2c..2bfbe50633 100644 --- a/client/src/lifecycleManager.js +++ b/client/src/lifecycleManager.js @@ -235,5 +235,14 @@ class LifecycleManager extends LuigiClientBase { getPathParams() { return this.currentContext.pathParams; } + + /** + * Returns the current client permissions as specified in the navigation node or an empty object. For details, see [Node parameters](navigation-parameters-reference.md). + * @returns {Object} client permissions as specified in the navigation node. + * @memberof Lifecycle + */ + getClientPermissions() { + return this.currentContext.internal.clientPermissions || {}; + } } export const lifecycleManager = new LifecycleManager(); diff --git a/client/src/luigi-client.js b/client/src/luigi-client.js index 91ea790559..10775e1645 100644 --- a/client/src/luigi-client.js +++ b/client/src/luigi-client.js @@ -34,6 +34,9 @@ class LuigiClient { getPathParams() { return lifecycleManager.getPathParams(); } + getClientPermissions() { + return lifecycleManager.getClientPermissions(); + } /** * @private */ diff --git a/core/examples/luigi-sample-angular/e2e/tests/luigi-client-ux-manager-features.spec.js b/core/examples/luigi-sample-angular/e2e/tests/luigi-client-ux-manager-features.spec.js index 66d67683c1..904772d9de 100644 --- a/core/examples/luigi-sample-angular/e2e/tests/luigi-client-ux-manager-features.spec.js +++ b/core/examples/luigi-sample-angular/e2e/tests/luigi-client-ux-manager-features.spec.js @@ -316,6 +316,7 @@ describe('Luigi client ux manager features', () => { cy.get('[data-cy=luigi-alert]').should('not.exist'); }); }); + describe('Luigi Client Localization', () => { it('set localization in client', () => { cy.goToUxManagerMethods($iframeBody); @@ -336,6 +337,20 @@ describe('Luigi client ux manager features', () => { .find('[data-cy=luigi-current-locale]') .should('contain', "'pl_PL'"); }); + + it('clientPermissions: check if set localization in client is disabled', () => { + cy.visit('/projects/pr1/clientPermissionsTets') + .getIframeBody() + .then(body => { + cy.wrap(body) + .find('[data-cy=luigi-input-locale]') + .should('be.disabled'); + + cy.wrap(body) + .find('[data-cy=set-current-locale]') + .should('be.disabled'); + }); + }); }); }); }); diff --git a/core/examples/luigi-sample-angular/src/app/project/project.component.html b/core/examples/luigi-sample-angular/src/app/project/project.component.html index bf510df6c4..ae166fa02c 100644 --- a/core/examples/luigi-sample-angular/src/app/project/project.component.html +++ b/core/examples/luigi-sample-angular/src/app/project/project.component.html @@ -146,6 +146,7 @@

LuigiClient uxManager methods

name="locale" placeholder="" data-cy="luigi-input-locale" + [disabled]="!canChangeLocale" /> @@ -155,6 +156,7 @@

LuigiClient uxManager methods

class="fd-button" data-cy="set-current-locale" (click)="setCurrentLocale()" + [disabled]="!canChangeLocale" > Set Current Locale diff --git a/core/examples/luigi-sample-angular/src/app/project/project.component.ts b/core/examples/luigi-sample-angular/src/app/project/project.component.ts index 72de317b7e..9311dd1376 100644 --- a/core/examples/luigi-sample-angular/src/app/project/project.component.ts +++ b/core/examples/luigi-sample-angular/src/app/project/project.component.ts @@ -10,6 +10,7 @@ import { Subscription } from 'rxjs'; import { linkManager, uxManager, + getClientPermissions, addContextUpdateListener, removeContextUpdateListener } from '@kyma-project/luigi-client'; @@ -41,6 +42,7 @@ export class ProjectComponent implements OnInit, OnDestroy { public isDirty = false; public splitViewHandle; public currentLocale = ''; + public canChangeLocale = false; public constructor( private activatedRoute: ActivatedRoute, @@ -85,6 +87,7 @@ export class ProjectComponent implements OnInit, OnDestroy { this.projectId = ctx.context.currentProject; this.preservedViewCallbackContext = ctx.context.goBackContext; this.currentLocale = uxManager().getCurrentLocale(); + this.canChangeLocale = getClientPermissions().changeCurrentLocale; // Since Luigi runs outside of Zone.js, changes need // to be updated manually // Be sure to check for destroyed ChangeDetectorRef, @@ -105,6 +108,7 @@ export class ProjectComponent implements OnInit, OnDestroy { // this.projectId = updatedContext.currentProject; // this.preservedViewCallbackContext = updatedContext.goBackContext; this.currentLocale = uxManager().getCurrentLocale(); + this.canChangeLocale = getClientPermissions().changeCurrentLocale; console.log('context updated', this.currentLocale, updatedContext); // Be sure to check for destroyed ChangeDetectorRef, // else you get runtime Errors diff --git a/core/examples/luigi-sample-angular/src/luigi-config/extended/projectDetailNav.js b/core/examples/luigi-sample-angular/src/luigi-config/extended/projectDetailNav.js index 30dbe2a3d2..c9e7f9ca54 100644 --- a/core/examples/luigi-sample-angular/src/luigi-config/extended/projectDetailNav.js +++ b/core/examples/luigi-sample-angular/src/luigi-config/extended/projectDetailNav.js @@ -64,6 +64,12 @@ export const projectDetailNavStructure = projectId => [ viewUrl: '/sampleapp.html#/projects/' + projectId + '/developers', icon: '/assets/favicon-sap.ico' }, + { + pathSegment: 'clientPermissionsTets', + label: 'ClientPermissionsTets', + viewUrl: '/sampleapp.html#/projects/pr1', + hideFromNav: true + }, { pathSegment: 'on-node-activation', label: 'Node with node activation hook', diff --git a/core/package.json b/core/package.json index 805775a7c5..f536e72b51 100644 --- a/core/package.json +++ b/core/package.json @@ -53,7 +53,7 @@ "test:watch": "npm run test -- --watch", "bundlesize": "npm run bundle && bundlesize", "docu": "npm run docu:validate && npm run docu:generate:config && npm run docu:generate:dom-elements && npm run docu:generate:auth && npm run docu:generate:navigation && npm run docu:generate:i18n", - "docu:validate": "documentation lint --shallow src/core-api/config.js src/core-api/elements.js src/core-api/auth.js src/core-api/navigation.js src/core-api/i18n.j", + "docu:validate": "documentation lint --shallow src/core-api/config.js src/core-api/elements.js src/core-api/auth.js src/core-api/navigation.js src/core-api/i18n.js", "docu:generate:config": "documentation readme src/core-api/config.js --shallow -f md --section='Luigi Config' --readme-file=../docs/luigi-core-api.md --markdown-toc=false --github false --quiet", "docu:generate:dom-elements": "documentation readme src/core-api/dom-elements.js --shallow -f md --section='Luigi.elements()' --readme-file=../docs/luigi-core-api.md --markdown-toc=false --github false --quiet", "docu:generate:auth": "documentation readme src/core-api/auth.js --shallow -f md --section='Luigi.auth()' --readme-file=../docs/luigi-core-api.md --markdown-toc=false --github false --quiet", diff --git a/core/src/App.html b/core/src/App.html index 3e49028294..36b7fc181b 100644 --- a/core/src/App.html +++ b/core/src/App.html @@ -616,11 +616,14 @@ addPreserveView(this, data, config); Routing.navigateTo(path); //navigate to the raw path. Any errors/alerts are handled later }, - prepareInternalData(config = {}) { + prepareInternalData(config) { const internalData = { isNavigateBack: this.get().isNavigateBack, viewStackSize: this.get().preservedViews.length, - currentLocale: LuigiI18N.getCurrentLocale() + currentLocale: LuigiI18N.getCurrentLocale(), + clientPermissions: config.iframe.luigi.nextViewUrl + ? config.iframe.luigi.nextClientPermissions + : config.iframe.luigi.clientPermissions }; IframeHelpers.specialIframeTypes .map(o => o.iframeConfigKey) diff --git a/core/src/services/iframe.js b/core/src/services/iframe.js index 199c631b4b..4f5070dae5 100644 --- a/core/src/services/iframe.js +++ b/core/src/services/iframe.js @@ -278,7 +278,7 @@ class IframeClass { ), nodeParams: JSON.stringify(Object.assign({}, componentData.nodeParams)), pathParams: JSON.stringify(Object.assign({}, componentData.pathParams)), - internal: JSON.stringify(component.prepareInternalData()) + internal: JSON.stringify(component.prepareInternalData(config)) }; IframeHelpers.sendMessageToIframe(config.iframe, message); // clear goBackContext and reset navigateBack after sending it to the client diff --git a/core/src/services/routing.js b/core/src/services/routing.js index 4585edee77..77936ed2a6 100644 --- a/core/src/services/routing.js +++ b/core/src/services/routing.js @@ -1,11 +1,7 @@ // Methods related to the routing. They mostly end up changing the iframe view which is handled by `iframe.js` file; // Please consider adding any new methods to 'routing-helpers' if they don't require anything from this file. import { Navigation } from '../navigation/services/navigation'; -import { - GenericHelpers, - IframeHelpers, - RoutingHelpers -} from '../utilities/helpers'; +import { GenericHelpers, RoutingHelpers } from '../utilities/helpers'; import { LuigiConfig } from '../core-api'; import { Iframe } from './iframe'; import { NAVIGATION_DEFAULTS } from './../utilities/luigi-config-defaults'; diff --git a/docs/luigi-client-api.md b/docs/luigi-client-api.md index fd45b85be1..c322aaf20a 100644 --- a/docs/luigi-client-api.md +++ b/docs/luigi-client-api.md @@ -75,6 +75,12 @@ All path parameters in the current navigation path (as defined by the active URL Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** path parameters, where the object property name is the path parameter name without the prefix, and its value is the actual value of the path parameter. For example `{productId: 1234, ...}` +### getClientPermissions + +Returns the current client permissions as specified in the navigation node or an empty object. For details, see [Node parameters](navigation-parameters-reference.md). + +Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** client permissions as specified in the navigation node. + ## linkManager The Link Manager allows you to navigate to another route. Use it instead of an internal router to: