diff --git a/docs/README.md b/docs/README.md index b3d90a78e8..1d04ba330d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,3 +1,18 @@ + + # Luigi Documentation If you are new to Luigi, read the [Getting started guide](getting-started.md) to learn more about its structure and key features. diff --git a/docs/application-setup.md b/docs/application-setup.md index ce42ccee52..80b22f5877 100644 --- a/docs/application-setup.md +++ b/docs/application-setup.md @@ -1,3 +1,18 @@ + + # Application setup Prior to start developing with Luigi, you need to set up your application. This document shows you how to set up a web application using the Luigi micro frontend framework. @@ -48,32 +63,19 @@ or execute these commands manually to get the same result: ```bash mkdir my-new-app && cd my-new-app - npm init -y - sed 's/"scripts": {/"scripts": {\ \ "buildConfig":"webpack --entry .\/src\/luigi-config\/basic\/basicConfiguration.js -o .\/public\/assets\/sampleconfig.js --mode production",/1' package.json > p.tmp.json && mv p.tmp.json package.json - npm i -save @kyma-project/luigi-core @kyma-project/luigi-client fiori-fundamentals webpack webpack-cli @babel/core @babel/preset-env babel-loader - mkdir -p public/assets - mkdir -p src/luigi-config/basic - curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/index.html > public/index.html - curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/assets/sampleexternal.html > public/assets/basicexternal.html - curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/luigi-config/basic/basicConfiguration.js > src/luigi-config/basic/basicConfiguration.js - sed "s|extendedConfiguration.bundle.js|sampleconfig.js|g" public/index.html > public/index.tmp.html && mv public/index.tmp.html public/index.html - cp -r node_modules/\@kyma-project/luigi-* public - cp -r node_modules/fiori-fundamentals/dist public/fiori-fundamentals - npm run buildConfig - live-server --entry-file=index.html public ``` @@ -93,33 +95,19 @@ bash <(curl -s https://raw.githubusercontent.com/SAP/luigi/master/scripts/setup/ or execute these commands manually to get the same result: ```bash ng new my-angular-app --routing && cd my-angular-app - npm i -P @kyma-project/luigi-core @kyma-project/luigi-client fiori-fundamentals webpack webpack-cli @babel/core @babel/preset-env babel-loader - sed 's/"scripts": {/"scripts": {\ \ "buildConfig":"webpack --entry .\/src\/luigi-config\/basic\/basicConfiguration.js -o .\/src\/assets\/sampleconfig.js --mode production",/1' package.json > p.tmp.json && mv p.tmp.json package.json - mkdir -p src/luigi-config/basic - mv src/index.html src/angular.html - curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/index.html > src/index.html - curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/luigi-config/basic/basicConfiguration.js > src/luigi-config/basic/basicConfiguration.js - curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/assets/sampleexternal.html > src/assets/basicexternal.html - - sed 's/extendedConfiguration.bundle.js/sampleconfig.js/g' src/index.html > src/index.tmp.html && mv src/index.tmp.html src/index.html - sed 's#"src/index.html"#"src/angular.html"#g' angular.json > tmp.json && mv tmp.json angular.json - sed 's#"src/styles.css"#"src/styles.css", "node_modules/fiori-fundamentals/dist/fiori-fundamentals.min.css"#g' angular.json > tmp.json && mv tmp.json angular.json - sed 's#"src/assets"#"src/assets","src/index.html","src/logout.html",{"glob": "fiori-fundamentals.min.css","input": "node_modules/fiori-fundamentals/dist","output": "/fiori-fundamentals"},{"glob": "fonts/**","input": "node_modules/fiori-fundamentals/dist","output": "/fiori-fundamentals"},{"glob": "SAP-icons.*","input": "node_modules/fiori-fundamentals/dist","output": "/fiori-fundamentals"},{"glob": "**","input": "node_modules/@kyma-project/luigi-core","output": "/luigi-core"},{"glob": "luigi-client.js","input": "node_modules/@kyma-project/luigi-client","output": "/luigi-client"}#g' angular.json > tmp.json && mv tmp.json angular.json - npm run buildConfig - npm run start ``` diff --git a/docs/authorization-configuration.md b/docs/authorization-configuration.md index c312506923..10643c72de 100644 --- a/docs/authorization-configuration.md +++ b/docs/authorization-configuration.md @@ -1,3 +1,18 @@ + + # Authorization configuration To configure authorization in Luigi, go to the `auth:` section of your project's `basicConfiguration.js` file. To see how authorization works, you can also go to the [Luigi Fiddle](https://fiddle.luigi-project.io) site and configure a sample application. diff --git a/docs/authorization-events.md b/docs/authorization-events.md index c3157fdbb7..0c4d8c385e 100644 --- a/docs/authorization-events.md +++ b/docs/authorization-events.md @@ -1,3 +1,18 @@ + + # Authorization events >**NOTE:** For learning and testing purposes, use the [Luigi Fiddle](https://fiddle.luigi-project.io) page where you can configure a sample Luigi application. diff --git a/docs/communication.md b/docs/communication.md index 661b00f2cb..b2e44e1beb 100644 --- a/docs/communication.md +++ b/docs/communication.md @@ -1,3 +1,18 @@ + + # Communication >**NOTE:** For learning and testing purposes, use the [Luigi Fiddle](https://fiddle.luigi-project.io) page where you can configure a sample Luigi application. diff --git a/docs/general-settings.md b/docs/general-settings.md index b29dfa7c85..22da59bf13 100644 --- a/docs/general-settings.md +++ b/docs/general-settings.md @@ -1,3 +1,18 @@ + + # General settings diff --git a/docs/getting-started.md b/docs/getting-started.md index 3c36f2e0a1..5d40755fff 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,3 +1,18 @@ + + # Getting started ## What is Luigi? diff --git a/docs/lifecycle-hooks.md b/docs/lifecycle-hooks.md index 3c105f047c..51aa95da34 100644 --- a/docs/lifecycle-hooks.md +++ b/docs/lifecycle-hooks.md @@ -1,3 +1,18 @@ + + # Lifecycle hooks You can use any of the Luigi lifecycle hooks by adding additional setup to the root of the Luigi configuration object. Here is an example: diff --git a/docs/luigi-architecture.md b/docs/luigi-architecture.md index 25fbefb83f..5c99f624ff 100644 --- a/docs/luigi-architecture.md +++ b/docs/luigi-architecture.md @@ -1,3 +1,20 @@ + + +# Luigi Architecture + This diagram represents an overview of Luigi's architecture. It shows the relationship between the Luigi framework, the web application, and the external micro frontends and authorization providers: ![Architecture](assets/architecture.png) diff --git a/docs/luigi-client-api.md b/docs/luigi-client-api.md index 66e5cc7546..e6b64c7c4d 100644 --- a/docs/luigi-client-api.md +++ b/docs/luigi-client-api.md @@ -1,3 +1,18 @@ + + # Luigi Client API diff --git a/docs/luigi-client-setup.md b/docs/luigi-client-setup.md index f396827b1e..2c3028e011 100644 --- a/docs/luigi-client-setup.md +++ b/docs/luigi-client-setup.md @@ -1,3 +1,18 @@ + + # Luigi Client Installation Luigi Client contains a library that allows your application to use all features of the Luigi framework. diff --git a/docs/luigi-core-api.md b/docs/luigi-core-api.md index e1e79cf526..9d48dd6887 100644 --- a/docs/luigi-core-api.md +++ b/docs/luigi-core-api.md @@ -1,3 +1,18 @@ + + # Luigi Core API ## Luigi Config diff --git a/docs/luigi-ux-features.md b/docs/luigi-ux-features.md index 91807b2c92..f6889b14a1 100644 --- a/docs/luigi-ux-features.md +++ b/docs/luigi-ux-features.md @@ -1,3 +1,18 @@ + + # Luigi UX features diff --git a/docs/navigation-advanced.md b/docs/navigation-advanced.md index 0c17de2bc0..8943e186b6 100644 --- a/docs/navigation-advanced.md +++ b/docs/navigation-advanced.md @@ -1,3 +1,18 @@ + + # Advanced navigation This document shows you how to configure the following Luigi features: diff --git a/docs/navigation-configuration-example.md b/docs/navigation-configuration-example.md index f68906635f..cbe165136b 100644 --- a/docs/navigation-configuration-example.md +++ b/docs/navigation-configuration-example.md @@ -1,3 +1,19 @@ + + # Navigation configuration example This example represents a sample Luigi navigation configuration including parameters described in the [navigation parameters reference](navigation-parameters-reference.md). diff --git a/docs/navigation-configuration.md b/docs/navigation-configuration.md index 3a5da98065..5d8c7d7983 100644 --- a/docs/navigation-configuration.md +++ b/docs/navigation-configuration.md @@ -1,3 +1,18 @@ + + # Basic navigation configuration Read these guides to get started with configuring your navigation: diff --git a/docs/navigation-parameters-reference.md b/docs/navigation-parameters-reference.md index 599c2ea8bc..3eda87a1f1 100644 --- a/docs/navigation-parameters-reference.md +++ b/docs/navigation-parameters-reference.md @@ -1,3 +1,18 @@ + + # Navigation parameters reference diff --git a/website/docs/.gitignore b/website/docs/.gitignore index 35cad95c5e..823e714a68 100644 --- a/website/docs/.gitignore +++ b/website/docs/.gitignore @@ -13,6 +13,7 @@ luigi-client public/* static/assets *coreStyles* +navigation-generated.json # Debug yarn-error.log diff --git a/website/docs/package-lock.json b/website/docs/package-lock.json index f3d5a14797..aac5e831b0 100644 --- a/website/docs/package-lock.json +++ b/website/docs/package-lock.json @@ -3203,7 +3203,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3224,12 +3225,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3244,17 +3247,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -3371,7 +3377,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -3383,6 +3390,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3397,6 +3405,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3404,12 +3413,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3428,6 +3439,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3508,7 +3520,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3520,6 +3533,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3605,7 +3619,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3641,6 +3656,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3660,6 +3676,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3703,12 +3720,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -4942,6 +4961,12 @@ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, + "lodash.orderby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.orderby/-/lodash.orderby-4.6.0.tgz", + "integrity": "sha1-5pfwTOXXhSL1TZM4syuBozk+TrM=", + "dev": true + }, "longest-streak": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.3.tgz", @@ -6842,6 +6867,16 @@ "unified": "^8.2.0" } }, + "remark-frontmatter": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-1.3.2.tgz", + "integrity": "sha512-2eayxITZ8rezsXdgcXnYB3iLivohm2V/ZT4Ne8uhua6A4pk6GdLE2ZzJnbnINtD1HRLaTdB7RwF9sgUbMptJZA==", + "dev": true, + "requires": { + "fault": "^1.0.1", + "xtend": "^4.0.1" + } + }, "remark-html": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-10.0.0.tgz", diff --git a/website/docs/package.json b/website/docs/package.json index cd1b072fe2..45f2718fc4 100644 --- a/website/docs/package.json +++ b/website/docs/package.json @@ -16,7 +16,7 @@ "cy:run": "cypress run", "cy:open": "cypress open", "mock:develop-plugins": "NODE_ENV=debug node -r esm scripts/markdown.unified-preview.js", - "mock:develop-plugins:watch": "NODE_ENV=debug nodemon -r esm scripts/markdown.unified-preview.js" + "mock:develop-plugins:watch": "NODE_ENV=debug nodemon --ignore 'static/**' -r esm scripts/markdown.unified-preview.js" }, "dependencies": { "@kyma-project/luigi-client": "^0.6.0", @@ -44,6 +44,7 @@ "css-loader": "^3.2.0", "esm": "^3.2.25", "fiori-fundamentals": "^1.7.1", + "lodash.orderby": "^4.6.0", "mini-css-extract-plugin": "^0.8.0", "node-sass": "^4.12.0", "npm-run-all": "^4.1.5", @@ -55,6 +56,7 @@ "rehype-slug": "^2.0.3", "rehype-stringify": "^6.0.0", "remark": "^11.0.1", + "remark-frontmatter": "^1.3.2", "remark-html": "^10.0.0", "remark-parse": "^7.0.1", "remark-preset-lint-markdown-style-guide": "^2.1.3", diff --git a/website/docs/public/navigation-children.json b/website/docs/public/navigation-children.json deleted file mode 100644 index 12e7f98a1f..0000000000 --- a/website/docs/public/navigation-children.json +++ /dev/null @@ -1,152 +0,0 @@ -[ - { - "label": "README", - "pathSegment": "README", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/README", - "context": { - "doc": "README" - } - }, - { - "label": "application-setup", - "pathSegment": "application-setup", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/application-setup", - "context": { - "doc": "application-setup" - } - }, - { - "label": "authorization-configuration", - "pathSegment": "authorization-configuration", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/authorization-configuration", - "context": { - "doc": "authorization-configuration" - } - }, - { - "label": "authorization-events", - "pathSegment": "authorization-events", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/authorization-events", - "context": { - "doc": "authorization-events" - } - }, - { - "label": "communication", - "pathSegment": "communication", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/communication", - "context": { - "doc": "communication" - } - }, - { - "label": "general-settings", - "pathSegment": "general-settings", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/general-settings", - "context": { - "doc": "general-settings" - } - }, - { - "label": "getting-started", - "pathSegment": "getting-started", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/getting-started", - "context": { - "doc": "getting-started" - } - }, - { - "label": "lifecycle-hooks", - "pathSegment": "lifecycle-hooks", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/lifecycle-hooks", - "context": { - "doc": "lifecycle-hooks" - } - }, - { - "label": "luigi-client-api", - "pathSegment": "luigi-client-api", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/luigi-client-api", - "context": { - "doc": "luigi-client-api" - } - }, - { - "label": "luigi-core-api", - "pathSegment": "luigi-core-api", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/luigi-core-api", - "context": { - "doc": "luigi-core-api" - } - }, - { - "label": "luigi-ux-features", - "pathSegment": "luigi-ux-features", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/luigi-ux-features", - "context": { - "doc": "luigi-ux-features" - } - }, - { - "label": "navigation-advanced", - "pathSegment": "navigation-advanced", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/navigation-advanced", - "context": { - "doc": "navigation-advanced" - } - }, - { - "label": "navigation-configuration-example", - "pathSegment": "navigation-configuration-example", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/navigation-configuration-example", - "context": { - "doc": "navigation-configuration-example" - } - }, - { - "label": "navigation-configuration", - "pathSegment": "navigation-configuration", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/navigation-configuration", - "context": { - "doc": "navigation-configuration" - } - }, - { - "label": "navigation-parameters-reference", - "pathSegment": "navigation-parameters-reference", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/navigation-parameters-reference", - "context": { - "doc": "navigation-parameters-reference" - } - } -] \ No newline at end of file diff --git a/website/docs/scripts/markdown.unified-preview.js b/website/docs/scripts/markdown.unified-preview.js index 139555512a..52d13b807f 100644 --- a/website/docs/scripts/markdown.unified-preview.js +++ b/website/docs/scripts/markdown.unified-preview.js @@ -1,12 +1,15 @@ import { MarkdownSvc } from '../src/services/markdown.service'; -import { readdirSync, readFileSync } from 'fs'; +import { readFileSync } from 'fs'; const filesToProcess = [ // 'plain.md', // 'links.md', // 'link.md', // 'codeblocks.md', - 'custom-attributes.md', + // 'custom-attributes.md', + 'frontmatter-3.md', + 'frontmatter-2.md', + 'frontmatter.md' ]; filesToProcess.forEach(async (name) => { diff --git a/website/docs/scripts/mocks/frontmatter-2.md b/website/docs/scripts/mocks/frontmatter-2.md new file mode 100644 index 0000000000..245ff1648f --- /dev/null +++ b/website/docs/scripts/mocks/frontmatter-2.md @@ -0,0 +1,12 @@ + +# Frontmatter Testing + +[Link](some-file.md)
\ No newline at end of file diff --git a/website/docs/scripts/mocks/frontmatter-3.md b/website/docs/scripts/mocks/frontmatter-3.md new file mode 100644 index 0000000000..25337e6fa2 --- /dev/null +++ b/website/docs/scripts/mocks/frontmatter-3.md @@ -0,0 +1,12 @@ + +# Frontmatter Testing + +[Link](some-file.md)
\ No newline at end of file diff --git a/website/docs/scripts/mocks/frontmatter.md b/website/docs/scripts/mocks/frontmatter.md new file mode 100644 index 0000000000..a6f3ddd594 --- /dev/null +++ b/website/docs/scripts/mocks/frontmatter.md @@ -0,0 +1,13 @@ + + +# Frontmatter Testing + +[Link](some-file.md)
\ No newline at end of file diff --git a/website/docs/scripts/move-export.sh b/website/docs/scripts/move-export.sh index 07e025a97c..173952c3b0 100755 --- a/website/docs/scripts/move-export.sh +++ b/website/docs/scripts/move-export.sh @@ -18,6 +18,9 @@ mv $EXPORT_DIR/luigi/* $LUIGI_DIR mkdir -p $LUIGI_DIR/docu-microfrontend mv $EXPORT_DIR/* $LUIGI_DIR/docu-microfrontend +# copy generated-json afterwards, since static files are only copied once by sapper in the beginning +cp $BASE_DIR/../static/luigi/navigation-generated.json $LUIGI_DIR/ + # copy redirects file for netlify cp $LUIGI_DIR/../src/_redirects $LUIGI_DIR/ diff --git a/website/docs/src/client.js b/website/docs/src/client.js index a366d70939..51dc47ce92 100644 --- a/website/docs/src/client.js +++ b/website/docs/src/client.js @@ -20,6 +20,7 @@ const selectText = (node) => { console.warn("Could not select text in node: Unsupported browser."); } } + window.copyCode = (evt, elem) => { evt.preventDefault(); evt.stopPropagation(); @@ -41,4 +42,10 @@ LuigiClient.addInitListener((ctx) => { } }); } + + window.navigateInternal = (evt, elem) => { + evt.preventDefault(); + evt.stopPropagation(); + LuigiClient.linkManager().navigate(elem.getAttribute('href').replace(ctx.coreBaseUrl, '').replace('.md', '').replace('/docu-microfrontend', '')); + } }); diff --git a/website/docs/src/docs/README.md b/website/docs/src/docs/README.md deleted file mode 100644 index 45c633f8ad..0000000000 --- a/website/docs/src/docs/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# Luigi Documentation - -Read the documentation to explore the features of Luigi Core and Luigi Client. - -## Luigi Core - -Set up and configure the main application. - -* [Application setup](application-setup.md) shows you the first steps to prepare your application for development. -* [Navigation configuration](navigation-configuration.md) shows you how to configure navigation in Luigi. -* [Navigation parameters reference](navigation-parameters-reference.md) lists the parameters you can use to configure the top and side navigation. -* [Authorization configuration](authorization-configuration.md) guides you through the configuration to secure Luigi. -* [Authorization events](authorization-events.md) guides you through the event configuration to react to Luigi authorization events. -* [General settings](general-settings.md) provides you with additional configuration parameters for Luigi. -* [Luigi lifecycle hooks](lifecycle-hooks.md) allows you to execute custom logic on any of the Luigi lifecycle steps. -* [Core API](luigi-core-api.md) provides you with API features that help you enrich and use Luigi Core. -* [Luigi UI features](luigi-ux-features.md) provides different possibilities of customizing some of the Luigi UI components. - - -## Luigi Client - -Use the Luigi Client API documentation to learn more about the functions and parameters you can use to communicate with the core application to define lifecycle, links, and the appearance of the application. - -* [Lifecycle](luigi-client-api.md#lifecycle) gives you details on the lifecycle of listeners, navigation nodes, and Event data. -* [Link Manager](luigi-client-api.md#linkmanager) allows you to navigate to a specific route. -* [UX Manager](luigi-client-api.md#uxmanager) helps you to manage the appearance features in Luigi, such as the behavior of backdrop or loading indictors. - -## Common -* [Communication](communication.md) describes how to configure features related to communication between Luigi Core and Client. diff --git a/website/docs/src/docs/application-setup.md b/website/docs/src/docs/application-setup.md deleted file mode 100644 index b721027820..0000000000 --- a/website/docs/src/docs/application-setup.md +++ /dev/null @@ -1,187 +0,0 @@ -# Application setup - -Prior to start developing with Luigi, you need to set up your application. This document shows you how to set up a web application using the Luigi micro frontend framework. - -Choose the framework to build your application: - -[Application setup without a framework](#noframework)
-[Angular 6](#angular6)
-[SAPUI5/OpenUI5](#sapui5)
-[VUE.JS](#vuejs) - -## Basic application setup - -Follow these steps to build a web application based on Luigi: - -1. Add Luigi npm packages to your project dependencies. - -```` -npm install --save @kyma-project/luigi-core -npm install --save @kyma-project/luigi-client -```` - -2. Give Luigi exclusive control over the entry `index.html` file. If you have a single page application, transfer it to a two-page application. Your app should run to make sure the existing router doesn't interfere. -3. Define your Luigi [navigation configuration](navigation-configuration.md). -4. Start your server to run the application. - -## Command examples - -The examples on this page demonstrate commands that perform each of the necessary steps to set up your application. Each set of commands is grouped by the framework on which you execute it. - - -### Application setup for an application not using a framework - ->**NOTE:** You need a development server capable of hosting Single Page Applications. The recommended server is Live Server. - -1. If you do not have Live Server installed, use this command to install it. - -```` -npm install -g live-server -```` - -2. Use the following installer to create a directory for your application, install Luigi, make assets available, and start your local server - -``` -bash <(curl -s https://raw.githubusercontent.com/SAP/luigi/master/scripts/setup/no-framework.sh) -```` -or execute these commands manually to get the same result: - -```bash -mkdir my-new-app && cd my-new-app - -npm init -y - -sed 's/"scripts": {/"scripts": {\ -\ "buildConfig":"webpack --entry .\/src\/luigi-config\/basic\/basicConfiguration.js -o .\/public\/assets\/sampleconfig.js --mode production",/1' package.json > p.tmp.json && mv p.tmp.json package.json - -npm i -save @kyma-project/luigi-core @kyma-project/luigi-client fiori-fundamentals webpack webpack-cli @babel/core @babel/preset-env babel-loader - -mkdir -p public/assets - -mkdir -p src/luigi-config/basic - -curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/index.html > public/index.html - -curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/assets/sampleexternal.html > public/assets/basicexternal.html - -curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/luigi-config/basic/basicConfiguration.js > src/luigi-config/basic/basicConfiguration.js - -sed "s|extendedConfiguration.bundle.js|sampleconfig.js|g" public/index.html > public/index.tmp.html && mv public/index.tmp.html public/index.html - -cp -r node_modules/\@kyma-project/luigi-* public - -cp -r node_modules/fiori-fundamentals/dist public/fiori-fundamentals - -npm run buildConfig - -live-server --entry-file=index.html public -``` - - - -### Application setup for Angular 6 - ->**NOTE:** The Angular CLI is a prerequisite for this example. - -1. If you do not have the Angular CLI installed, download and install it from [this URL](https://cli.angular.io/). - -2. Use the installer to create your application, install Luigi, make assets available, and serve your application: - -```` -bash <(curl -s https://raw.githubusercontent.com/SAP/luigi/master/scripts/setup/angular.sh) -```` -or execute these commands manually to get the same result: -```bash -ng new my-angular-app --routing && cd my-angular-app - -npm i -P @kyma-project/luigi-core @kyma-project/luigi-client fiori-fundamentals webpack webpack-cli @babel/core @babel/preset-env babel-loader - -sed 's/"scripts": {/"scripts": {\ -\ "buildConfig":"webpack --entry .\/src\/luigi-config\/basic\/basicConfiguration.js -o .\/src\/assets\/sampleconfig.js --mode production",/1' package.json > p.tmp.json && mv p.tmp.json package.json - -mkdir -p src/luigi-config/basic - -mv src/index.html src/angular.html - -curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/index.html > src/index.html - -curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/luigi-config/basic/basicConfiguration.js > src/luigi-config/basic/basicConfiguration.js - -curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/assets/sampleexternal.html > src/assets/basicexternal.html - - -sed 's/extendedConfiguration.bundle.js/sampleconfig.js/g' src/index.html > src/index.tmp.html && mv src/index.tmp.html src/index.html - -sed 's#"src/index.html"#"src/angular.html"#g' angular.json > tmp.json && mv tmp.json angular.json - -sed 's#"src/styles.css"#"src/styles.css", "node_modules/fiori-fundamentals/dist/fiori-fundamentals.min.css"#g' angular.json > tmp.json && mv tmp.json angular.json - -sed 's#"src/assets"#"src/assets","src/index.html","src/logout.html",{"glob": "fiori-fundamentals.min.css","input": "node_modules/fiori-fundamentals/dist","output": "/fiori-fundamentals"},{"glob": "fonts/**","input": "node_modules/fiori-fundamentals/dist","output": "/fiori-fundamentals"},{"glob": "SAP-icons.*","input": "node_modules/fiori-fundamentals/dist","output": "/fiori-fundamentals"},{"glob": "**","input": "node_modules/@kyma-project/luigi-core","output": "/luigi-core"},{"glob": "luigi-client.js","input": "node_modules/@kyma-project/luigi-client","output": "/luigi-client"}#g' angular.json > tmp.json && mv tmp.json angular.json - -npm run buildConfig - -npm run start -``` - - - -### Application setup for SAPUI5/OpenUI5 - ->**NOTE:** Live Server must be installed as your development server. - -1. If you do not have Live Server installed, use this command to install it. - -```` -npm install -g live-server -```` - -2. Use the installer to create a directory for your application, install Luigi, make assets available, and start your local server: - -```` -bash <(curl -s https://raw.githubusercontent.com/SAP/luigi/master/scripts/setup/openui5.sh) -```` -or execute these commands manually to get the same result: - -```` -$ mkdir my-ui5-app && cd my-ui5-app -$ npm init -y -$ npm i -save @kyma-project/luigi-core @kyma-project/luigi-client fiori-fundamentals -$ mkdir -p public/assets -$ curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/index.html > public/index.html -$ sed 's/extendedConfiguration.bundle.js/sampleconfig.js/g' public/index.html > public/index.tmp.html && mv public/index.tmp.html public/index.html -$ curl https://raw.githubusercontent.com/SAP/openui5/master/src/sap.m/test/sap/m/demokit/tutorial/quickstart/01/webapp/index.html | sed 's/src="..\/..\/..\/..\/..\/..\/..\/..\/resources\/sap-ui-core.js"/src="https:\/\/openui5.hana.ondemand.com\/resources\/sap-ui-core.js"/g' > public/ui5.html -$ curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/luigi-config/basic/basicConfiguration.js > public/assets/sampleconfig.js -$ curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/assets/sampleexternal.html > public/assets/basicexternal.html -$ cp -r node_modules/\@kyma-project/luigi-* public -$ live-server --entry-file=index.html public -```` - - - -### Application setup for VUE.JS - ->**NOTE:** The VUE CLI is a prerequisite for this example. - -1. If you do not have VUE CLI installed, use this command to install it. - -```` -npm install -g @vue/cli -```` - -2. Use the installer to create your application, install Luigi, make assets available, and serve your application: -```` -bash <(curl -s https://raw.githubusercontent.com/SAP/luigi/master/scripts/setup/vue.sh) -```` -or execute these commands manually to get the same result: -```` -$ vue create -d my-original-vue-app && cd my-original-vue-app -$ npm i -save @kyma-project/luigi-core @kyma-project/luigi-client fiori-fundamentals -$ mkdir -p public/assets -$ mv public/index.html public/vue.html -$ curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/index.html > public/index.html -$ sed 's/extendedConfiguration.bundle.js/sampleconfig.js/g' public/index.html > public/index.tmp.html && mv public/index.tmp.html public/index.html -$ curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/luigi-config/basic/basicConfiguration.js > public/assets/sampleconfig.js -$ curl https://raw.githubusercontent.com/SAP/luigi/master/core/examples/luigi-sample-angular/src/assets/sampleexternal.html > public/assets/basicexternal.html -$ echo "const webpack=require('webpack');const CopyWebpackPlugin=require('copy-webpack-plugin');module.exports={pages:{sampleapp:{entry:'src/main.js',template:'public/vue.html',filename:'vue.html'}},lintOnSave:true,runtimeCompiler:true,outputDir:'dist',configureWebpack:{plugins:[new CopyWebpackPlugin([{context:'public',to:'index.html',from:'index.html'},{context:'node_modules/@kyma-project/luigi-core',to:'./luigi-core',from:{glob:'**',dot:true}},{context:'node_modules/@kyma-project/luigi-client',to:'./luigi-client',from:{glob:'**',dot:true}}],{ignore:['.gitkeep','**/.DS_Store','**/Thumbs.db'],debug:'warning'})]}};" > vue.config.js -$ npm run serve -```` \ No newline at end of file diff --git a/website/docs/src/docs/assets/favicon-sap.ico b/website/docs/src/docs/assets/favicon-sap.ico deleted file mode 100644 index 5975b8922e..0000000000 Binary files a/website/docs/src/docs/assets/favicon-sap.ico and /dev/null differ diff --git a/website/docs/src/docs/assets/navigation-structure.png b/website/docs/src/docs/assets/navigation-structure.png deleted file mode 100644 index 0ca0f86b20..0000000000 Binary files a/website/docs/src/docs/assets/navigation-structure.png and /dev/null differ diff --git a/website/docs/src/docs/authorization-configuration.md b/website/docs/src/docs/authorization-configuration.md deleted file mode 100644 index 51c52fa525..0000000000 --- a/website/docs/src/docs/authorization-configuration.md +++ /dev/null @@ -1,162 +0,0 @@ -# Authorization configuration - -Luigi provides OpenID Connect and OAuth2 Implicit Grant authorization out of the box. The **use** key defines the active authorization provider and the **disableAutoLogin** key allows you to disable the automatic login flow that is provided by default. - -```` -auth: { - use: 'openIdConnect', - openIdConnect: { - ... - }, - disableAutoLogin: true -} -```` - -## OpenID Connect configuration - -The following code snippet demonstrates how to configure authorization using OpenID Connect in Luigi. - -```` -auth: { - use: 'openIdConnect', - openIdConnect: { - authority: 'https://example-authority.com', - client_id: 'client', - scope: 'audience:server:client_id:client openid profile email groups', - redirect_uri: '', - post_logout_redirect_uri: '/logout.html', - automaticSilentRenew: true, - userInfoFn:()=>{}, - accessTokenExpiringNotificationTime: 60 - }, - disableAutoLogin: false -} -```` - -- **authority** contains the OpenID Connect server address used to authenticate. -- **client_id** contains your app client ID. -- **scope** defines the permissions to request at login. -- **redirect_uri** sets the URL to return to after login. The default application root is `/`. -- **post_logout_redirect_uri** sets the URL to return after logout. The default URL is `/logout.html`. -- **automaticSilentRenew** enables the automatic silent renewal of the token if it is supported by the server. The default value is `false`. For this mechanism to work, the browser must have third-party cookies support enabled. -- **accessTokenExpiringNotificationTime** is the number of seconds before an access token is to expire and triggers silent token refresh. The default value is `60` seconds. -- **thirdPartyCookiesScriptLocation** is the URL to the page containing third-party cookies support check. For details, see [Third-party cookies and silent token refresh section](#Third-party-cookies-and-silent-token-refresh). -- **userInfoFn** provides a function to get user information. It returns a promise of a **userinfo** object which can contain **name**, **email** and **picture** (value is a URL to the image). **Name** or **email** are displayed in the profile drop-down menu and the user’s profile picture is displayed in the top navigation. - -## OAuth2 Implicit Grant configuration - -The following code snippet demonstrates how to configure authorization using OAuth2 Implicit Grant in Luigi. - -```` -auth: { - use: 'oAuth2ImplicitGrant', - oAuth2ImplicitGrant: { - authorizeUrl: 'https://example-url.com/authorize', - logoutUrl: 'https://example-url.com/logout', - oAuthData: { - client_id: 'egDuozijY5SVr0NSIowUP1dT6RVqHnlp' - scope: '', - // optional parameters - redirect_uri: '/luigi-core/auth/oauth2/callback.html' - response_type: 'id_token token', - // all specified values inside oAuthData will be added to the oauth call, i.e display="popup", - } - // optional functions - nonceFn: () => {}, - logoutFn: (settings, authData, logoutCallback) => {}, - userInfoFn:()=>{}, - accessTokenExpiringNotificationTime: 60, - expirationCheckInterval: 5 - }, - disableAutoLogin: false -```` - -- **authorizeUrl** contains the URL or address of the OAuth2 authorization server. -- **logoutUrl** contains the endpoint to terminate the authorization session. -- **oAuthData** comprises the object with data sent to the **authorizeUrl**. -- **client_id** holds your application client ID. -- **scope** defines permissions that are requested at login. -- **redirect_uri** contains the URL to return to after login. The default application root is `/`. -- **response_type** defaults to the **id_token**. Any other parameter that is added to oAuthData is also added to the authorization payload. -- **nonceFn** provides a function that returns a string in order to override the default **nonce**. -- **logoutFn** provides the function to override the **logoutUrl** functionality for a custom logout. It needs to execute the **logoutCallback()** function after logout. -- **userInfoFn** provides a function to get user information. It returns a promise of a **userinfo** object which can contain **name**, **email** and **picture** (value is a URL to the image). **Name** or **email** are displayed in the profile drop-down menu and the user’s profile picture is displayed in the top navigation. -- **accessTokenExpiringNotificationTime** number of seconds that pass before an access token expires and the **onAuthExpireSoon** event is fired. The default value is `60` seconds. -- **expirationCheckInterval** the number of seconds to pass between each check if the token is about to expire. The default value is `5` seconds. - - -### Custom Authentication Provider - -If you are using any authentication provider you can also implement the following functions for Luigi. - -```` -export class CustomAuthenticationProvider { - - login(){ - // logic to handle the login mechanism - // returns a promise which contains an error message if something went wrong - } - - logout(authData, logoutCallback){ - // logic to handle the logout mechanism - } - - setTokenExpirationAction(){ - } - - setTokenExpireSoonAction() {} - - generateNonce(){ - //returns a string - } - - userInfo(){ - // logic to get some user information - // returns a promise of a userinfo object which contains a user name and/or email to display in the profile dropdown menu - } -} -```` - - -### Third-party cookies and silent token refresh - -The OpenID Connect configuration allows you to specify the **automaticSilentRenew** option. When set to `true`, Luigi attempts to automatically renew the token in the background before it expires. Be aware that this mechanism requires the browser to support [third-party cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#Third-party_cookies). -It is possible to detect whether the user's browser supports the mechanism by using the script in [`third-party-cookies`](https://github.com/SAP/luigi/tree/master/core/third-party-cookies) catalog. Deploy these files on a **different domain** than your main application and set **thirdPartyCookiesScriptLocation** to `init.html` file. During initialization, Luigi detects the cookies support and produces a warning in the console if cookies are disabled in the user's browser. - -When Luigi fails to renew the token and then logs out the user, it adds the following query parameters to the logout page redirect URL: `?reason=tokenExpired&thirdPartyCookies=[VALUE]`. Luigi replaces the **VALUE** with one of the following: -- `disabled` means that third party cookies is disabled. -- `enabled` means third party cookies are supported by the browser. -- `not_checked` means that the script was not provided in **thirdPartyCookiesScriptLocation** or it could not be loaded. - -The application developer can read these parameters and set a logout page based on them. - -### Implement a Custom Authentication Provider - -You can write your own authentication provider that meets your requirements. - -[oAuth2ImplicitGrant.js](https://github.com/SAP/luigi/blob/master/core/src/providers/auth/oAuth2ImplicitGrant.js) is a good starting point if you don't use an external authentication library. -After authorization is successful on the auth provider's side it redirects back to `Luigi callback.html` **redirect_uri**. The auth provider verifies the authentication data, saves it in **localStorage** for Luigi, and redirects to the Luigi main page. - -[openIdConnect.js](https://github.com/SAP/luigi/blob/master/core/src/providers/auth/openIdConnect.js) lazy loads the official `oidc-client` library and is a good starting point if you also depend on external authentication libraries. - -Make sure to set the following data in your Authentication Provider implementation, so that it is used after successful authentication. -``` -const data = { - accessToken: hashParams['access_token'], - accessTokenExpirationDate: hashParams['expiry_timestamp'], - scope: hashParams['scope'], - idToken: hashParams['id_token'] -}; - -localStorage.setItem('luigi.auth', JSON.stringify(data)); -localStorage.setItem('luigi.newlyAuthorized', true); -``` - -Additionally, if you process authentication data during Luigi runtime (inside the custom provider, similarly to using the`openIdConnect` provider), dispatch the `luigi.auth.tokenIssued` Event to update the currently opened micro frontends with the latest authentication data. This is not required when processing authentication outside Luigi, for example when `oAuth2ImplicitGrant` provider processes the data in `callback.html` and redirects to Luigi afterward. - -``` -window.postMessage( - { msg: 'luigi.auth.tokenIssued', authData: data }, - '*' -); -``` diff --git a/website/docs/src/docs/authorization-events.md b/website/docs/src/docs/authorization-events.md deleted file mode 100644 index 70ac1ad0a0..0000000000 --- a/website/docs/src/docs/authorization-events.md +++ /dev/null @@ -1,36 +0,0 @@ -# Authorization events - -Luigi provides life cycle events which it can trigger internally or by authorization providers. -Events are part of the **auth** configuration object and have to be functions. They can be executed asynchronously. - -An example events configuration looks as follows: - -``` -auth: { - events: { - onAuthSuccessful: (settings, authData) => {}, - onAuthError: (settings, err) => {} - onAuthExpired: (settings) => {}, - onLogout: (settings) => {}, - onAuthExpireSoon: (settings) => {} - } -} -``` - -The first parameter is always the current **settings** object of the currently active authorization provider. This object contains the user provider configuration with the default values. -The second parameter is optional and it is either **authData** or **error**. - -You can disable the default behavior of `onAuthExpired` and `onAuthError` by making the function return `false`. As a result, the lifecycle execution stops with this function. This, however, may lead to blank pages after the user logs out since typically the page redirects to a logout, login or home page. - -## Events - -- `onAuthSuccessful` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** is executed after logging in with the **authData** object parameter. If valid authorization data was found in the local storage, the function is not executed. -- `onAuthError` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** is executed: - - by Luigi **reason** URL parameter with optional **error** URL parameter for detailed description was found on Luigi initialization. The OAuth2Provider uses this approach by redirecting from the authorization provider to `luigi.domain/?reason=someError&error=Error detail describe`. - - by the OIDC provider if silent access token renewal fails - - Return `false` to prevent redirecting to `logoutUrl` after executing this function. It goes to the Luigi main route `/` instead. -- `onAuthExpired` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** is executed if the token expires during runtime, or if Luigi is opened with outdated authorization data in the local storage. Return `false` to prevent redirecting to `logoutUrl` after executing this function. -- `onLogout` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** is executed after the user logs out. -- `onAuthExpireSoon` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** is executed before the token expires. For OAuth2 and OIDC you can set the **accessTokenExpiringNotificationTime** to specify the number of seconds required to pass before the event is fired. The default value is `60` seconds. - - by using oAuth2ImplicitGrant you can specify **expirationCheckInterval** which is the number of seconds to pass between each check if the token is about to expire. The default value is `5` seconds. diff --git a/website/docs/src/docs/communication.md b/website/docs/src/docs/communication.md deleted file mode 100644 index 0bf19c4509..0000000000 --- a/website/docs/src/docs/communication.md +++ /dev/null @@ -1,35 +0,0 @@ -# Communication - -## Custom messages - -Luigi Core and Luigi Client can exchange custom messages in both directions. - -### Luigi Client to Luigi Core - -For Luigi Client to send messages to Luigi Core, use the [*sendCustomMessage*](luigi-client-api.md#sendCustomMessage) method from Client API. - -For Luigi Core to process custom messages, define a configuration similar to the following at the root level of your Luigi configuration object: - -```javascript -{ - ... - communication: { - customMessagesListeners: { - 'my-custom-message.update-top-nav': () => { - Luigi.navigation().updateTopNavigation(); - } - } - } - ... -} -``` -where the `my-custom-message.update-top-nav` key is the message id, and the value is the listener function for the custom message. The listener receives the following input parameters: -- **customMessage** the [*message*](luigi-client-api.md#sendCustomMessage) sent by Luigi Client. -- **microfrontend** a micro frontend object as specified [here](luigi-core-api.md#getMicrofrontends). -- **navigation node** a [navigation node object](navigation-parameters-reference.md#Node-parameters). - -### Luigi Core to Luigi Client - -For Luigi Core to send messages, use the [*customMessages*](luigi-core-api.md#customMessages) section from Core API. You can send a custom message to all rendered micro frontends, or to a specific one. For the latter, use the Core API [*elements*](luigi-core-api.md#elements) methods to retrieve micro frontends and select the one you want to send the custom message to. - -For Luigi Client to process the message, add and remove message listeners as described [here](luigi-client-api.md#addCustomMessageListener). diff --git a/website/docs/src/docs/lifecycle-hooks.md b/website/docs/src/docs/lifecycle-hooks.md deleted file mode 100644 index 3c105f047c..0000000000 --- a/website/docs/src/docs/lifecycle-hooks.md +++ /dev/null @@ -1,24 +0,0 @@ -# Lifecycle hooks - -You can use any of the Luigi lifecycle hooks by adding additional setup to the root of the Luigi configuration object. Here is an example: - -```javascript -{ - ... - lifecycleHooks: { - luigiAfterInit: () => { - const newCustomMessage = { - id: 'luigi.my-custom-message-for-client', - description: 'here goes the message description' - }; - Luigi.customMessages().send('MY_MICRO_FRONTEND_ID', newCustomMessage); - } - } - ... -} -``` - -### luigiAfterInit() - -This method will be called after `Luigi.setConfig({})` is executed. - diff --git a/website/docs/src/docs/luigi-client-api.md b/website/docs/src/docs/luigi-client-api.md deleted file mode 100644 index 43e418fc50..0000000000 --- a/website/docs/src/docs/luigi-client-api.md +++ /dev/null @@ -1,617 +0,0 @@ -# Luigi Client API - - - - - -## Lifecycle - -Use the functions and parameters to define the Lifecycle of listeners, navigation nodes, and Event data. - -### addInitListener - -Registers a listener called with the context object and the Luigi Core domain as soon as Luigi is instantiated. Defer your application bootstrap if you depend on authentication data coming from Luigi. - -#### Parameters - -- `initFn` **[Lifecycle~initListenerCallback](#lifecycleinitlistenercallback)** the function that is called once Luigi is initialized, receives current context and origin as parameters. - -### removeInitListener - -Removes an init listener. - -#### Parameters - -- `id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the id that was returned by the `addInitListener` function - -### addContextUpdateListener - -Registers a listener called with the context object upon any navigation change. - -#### Parameters - -- `contextUpdatedFn` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** the listener function called each time Luigi context changes - -### removeContextUpdateListener - -Removes a context update listener. - -#### Parameters - -- `id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the id that was returned by the `addContextUpdateListener` function - -### addCustomMessageListener - -Registers a listener called when the micro frontend receives a custom message. - -#### Parameters - -- `customMessageId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the custom message id -- `customMessageListener` **[Lifecycle~customMessageListenerCallback](#lifecyclecustommessagelistenercallback)** the function that is called when the micro frontend receives the corresponding event. - -**Meta** - -- **since**: 0.6.2 - -### removeCustomMessageListener - -Removes a custom message listener. - -#### Parameters - -- `id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the id that was returned by the `addInitListener` function - -**Meta** - -- **since**: 0.6.2 - -### getToken - -Returns the currently valid access token. - -Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** current access token - -### getEventData - -Returns the context object. Typically it is not required as the [addContextUpdateListener()](#addContextUpdateListener) receives the same values. - -Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** current context data - -### getContext - -Returns the context object. It is an alias function for getEventData(). - -Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** current context data - -### getNodeParams - -Returns the node parameters of the active URL. -Node parameters are defined like URL query parameters but with a specific prefix allowing Luigi to pass them to the micro frontend view. The default prefix is **~** and you can use it in the following way: `https://my.luigi.app/home/products?~sort=asc~page=3`. - -> **NOTE:** some special characters (`<`, `>`, `"`, `'`, `/`) in node parameters are HTML-encoded. - -Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** node parameters, where the object property name is the node parameter name without the prefix, and its value is the value of the node parameter. For example `{sort: 'asc', page: 3}` - -### getPathParams - -Returns the dynamic path parameters of the active URL. -Path parameters are defined by navigation nodes with a dynamic **pathSegment** value starting with **:**, such as **productId**. -All path parameters in the current navigation path (as defined by the active URL) are returned. - -> **NOTE:** some special characters (`<`, `>`, `"`, `'`, `/`) in path parameters are HTML-encoded. - -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. - -### sendCustomMessage - -Sends a custom message to the Luigi Core application. - -#### Parameters - -- `message` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** an object containing data to be sent to the Luigi Core to process it further. This object is set as an input parameter of the custom message listener on the Luigi Core side. - - `message.id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** a string containing the message id - - `message.MY_DATA_FIELD` **any** any other message data field - -#### Examples - -```javascript -import LuigiClient from '@kyma-project/luigi-client'; -LuigiClient.sendCustomMessage({id: 'environment.created', production: false}) -``` - -**Meta** - -- **since**: 0.6.2 - -## Lifecycle~initListenerCallback - -Callback of the addInitListener - -Type: [Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function) - -### Parameters - -- `context` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** current context data -- `origin` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Luigi Core URL - -## Lifecycle~customMessageListenerCallback - -Callback of the customMessageListener - -Type: [Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function) - -### Parameters - -- `customMessage` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** custom message object - - `customMessage.id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** message id - - `customMessage.MY_DATA_FIELD` **any** any other message data field -- `listenerId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** custom message listener id to be used for unsubscription - -## linkManager - -The Link Manager allows you to navigate to another route. Use it instead of an internal router to: - -- Provide routing inside micro frontends. -- Reflect the route. -- Keep the navigation state in Luigi. - -### navigate - -Navigates to the given path in the application hosted by Luigi. It contains either a full absolute path or a relative path without a leading slash that uses the active route as a base. This is the standard navigation. - -#### Parameters - -- `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** path to be navigated to -- `sessionId` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** current Luigi **sessionId** -- `preserveView` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** preserve a view by setting it to `true`. It keeps the current view opened in the background and opens the new route in a new frame. Use the [goBack()](#goBack) function to navigate back. You can use this feature across different levels. Preserved views are discarded as soon as you use the standard [navigate()](#navigate) function instead of [goBack()](#goBack) -- `modalSettings` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** opens a view in a modal. Use these settings to configure the modal's title and size - - `modalSettings.title` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** modal title. By default, it is the node label. If there is no label, it is left empty - - `modalSettings.size` **(`"l"` \| `"m"` \| `"s"`)** size of the modal (optional, default `"l"`) -- `splitViewSettings` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** opens a view in a split view. Use these settings to configure the split view's behaviour - - `splitViewSettings.title` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** split view title. By default, it is the node label. If there is no label, it is left empty - - `splitViewSettings.size` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** height of the split view in percent (optional, default `40`) - - `splitViewSettings.collapsed` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** creates split view but leaves it closed initially (optional, default `false`) - -#### Examples - -```javascript -LuigiClient.linkManager().navigate('/overview') -LuigiClient.linkManager().navigate('users/groups/stakeholders') -LuigiClient.linkManager().navigate('/settings', null, true) // preserve view -``` - -### openAsModal - -Opens a view in a modal. You can specify the modal's title and size. If you don't specify the title, it is the node label. If there is no node label, the title remains empty. The default size of the modal is `l`, which means 80%. You can also use `m` (60%) and `s` (40%) to set the modal size. Optionally, use it in combination with any of the navigation functions. - -#### Parameters - -- `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** navigation path -- `modalSettings` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)?** opens a view in a modal. Use these settings to configure the modal's title and size - - `modalSettings.title` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** modal title. By default, it is the node label. If there is no label, it is left empty - - `modalSettings.size` **(`"l"` \| `"m"` \| `"s"`)** size of the modal (optional, default `"l"`) - -#### Examples - -```javascript -LuigiClient.linkManager().openAsModal('projects/pr1/users', {title:'Users', size:'m'}); -``` - -### openAsSplitView - -- **See: [splitView](#splitview) for further documentation about the returned instance** - -Opens a view in a split view. You can specify the split view's title and size. If you don't specify the title, it is the node label. If there is no node label, the title remains empty. The default size of the split view is `40`, which means 40% height of the split view. - -#### Parameters - -- `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** navigation path -- `splitViewSettings` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** opens a view in a split view. Use these settings to configure the split view's behaviour (optional, default `{}`) - - `splitViewSettings.title` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** split view title. By default, it is the node label. If there is no label, it is left empty - - `splitViewSettings.size` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** height of the split view in percent (optional, default `40`) - - `splitViewSettings.collapsed` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** opens split view in collapsed state (optional, default `false`) - -#### Examples - -```javascript -const splitViewHandle = LuigiClient.linkManager().openAsSplitView('projects/pr1/logs', {title: 'Logs', size: 40, collapsed: true}); -``` - -Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** instance of the SplitView. It provides Event listeners and you can use the available functions to control its behavior. - -**Meta** - -- **since**: 0.6.0 - -### fromContext - -Sets the current navigation context to that of a specific parent node which has the [navigationContext](navigation-configuration.md) field declared in the navigation configuration. This navigation context is then used by the `navigate` function. - -#### Parameters - -- `navigationContext` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -#### Examples - -```javascript -LuigiClient.linkManager().fromContext('project').navigate('/settings') -``` - -Returns **[linkManager](#linkmanager)** link manager instance - -### fromClosestContext - -Sets the current navigation context which is then used by the `navigate` function. This has to be a parent navigation context, it is not possible to use the child navigation contexts. - -#### Examples - -```javascript -LuigiClient.linkManager().fromClosestContext().navigate('/users/groups/stakeholders') -``` - -Returns **[linkManager](#linkmanager)** link manager instance - -### withParams - -Sends node parameters to the route. The parameters are used by the `navigate` function. Use it optionally in combination with any of the navigation functions and receive it as part of the context object in Luigi Client. - -#### Parameters - -- `nodeParams` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** - -#### Examples - -```javascript -LuigiClient.linkManager().withParams({foo: "bar"}).navigate("path") - -// Can be chained with context setting functions such as: -LuigiClient.linkManager().fromContext("currentTeam").withParams({foo: "bar"}).navigate("path") -``` - -Returns **[linkManager](#linkmanager)** link manager instance - -### pathExists - -Checks if the path you can navigate to exists in the main application. For example, you can use this helper method conditionally to display a DOM element like a button. - -#### Parameters - -- `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** path which existence you want to check - -#### Examples - -```javascript -let pathExists; - LuigiClient - .linkManager() - .pathExists('projects/pr2') - .then( - (pathExists) => { } - ); -``` - -Returns **[promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)** a promise which resolves to a Boolean variable specifying whether the path exists or not - -### hasBack - -Checks if there is one or more preserved views. You can use it to show a **back** button. - -Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** indicating if there is a preserved view you can return to - -### goBack - -Discards the active view and navigates back to the last visited view. Works with preserved views, and also acts as the substitute of the browser **back** button. **goBackContext** is only available when using preserved views. - -#### Parameters - -- `goBackValue` **any** data that is passed in the **goBackContext** field to the last visited view when using preserved views. - -#### Examples - -```javascript -LuigiClient.linkManager().goBack({ foo: 'bar' }); -LuigiClient.linkManager().goBack(true); -``` - -## splitView - -Split view -Allows to open a micro frontend in a split screen in the lower part of the content area. Open it by calling `const splitViewHandle = LuigiClient.linkManager().openAsSplitView`. -At a given time, you can open only one split view. It closes automatically when you navigate to a different route. -When you call `handle.collapse()`, the split view gets destroyed. It recreates when you use `handle.expand()`. -`openAsSplitView` returns an instance of the split view handle. The functions, actions, and event handlers listed below allow you to control and manage the split view. - -**Meta** - -- **since**: 0.6.0 - -### collapse - -Collapses the split view - -#### Examples - -```javascript -splitViewHandle.collapse(); -``` - -**Meta** - -- **since**: 0.6.0 - -### expand - -Expands the split view - -#### Examples - -```javascript -splitViewHandle.expand(); -``` - -**Meta** - -- **since**: 0.6.0 - -### close - -Closes and destroys the split view - -#### Examples - -```javascript -splitViewHandle.close(); -``` - -**Meta** - -- **since**: 0.6.0 - -### setSize - -Sets the height of the split view - -#### Parameters - -- `value` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** lower height in percent - -#### Examples - -```javascript -splitViewHandle.setSize(60); -``` - -**Meta** - -- **since**: 0.6.0 - -### on - -Registers a listener for split view events - -#### Parameters - -- `name` **(`"expand"` \| `"collapse"` \| `"resize"` \| `"close"`)** event name -- `callback` **[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** gets called when this event gets triggered by Luigi - -#### Examples - -```javascript -const listenerId = splitViewHandle.on('expand', () => {}); -const listenerId = splitViewHandle.on('collapse', () => {}); -const listenerId = splitViewHandle.on('resize', () => {}); -const listenerId = splitViewHandle.on('close', () => {}); -* -``` - -Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** listener id - -**Meta** - -- **since**: 0.6.0 - -### removeEventListener - -Unregisters a split view listener - -#### Parameters - -- `id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** listener id - -#### Examples - -```javascript -splitViewHandle.removeEventListener(listenerId); -``` - -**Meta** - -- **since**: 0.6.0 - -### exists - -Gets the split view status - -#### Examples - -```javascript -splitViewHandle.exists(); -``` - -Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** true if a split view is loaded - -**Meta** - -- **since**: 0.6.0 - -### getSize - -Reads the size of the split view - -#### Examples - -```javascript -splitViewHandle.getSize(); -``` - -Returns **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** height in percent - -**Meta** - -- **since**: 0.6.0 - -### isCollapsed - -Reads the collapse status - -#### Examples - -```javascript -splitViewHandle.isCollapsed(); -``` - -Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** true if the split view is currently collapsed - -**Meta** - -- **since**: 0.6.0 - -### isExpanded - -Reads the expand status - -#### Examples - -```javascript -splitViewHandle.isExpanded(); -``` - -Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** true if the split view is currently expanded - -**Meta** - -- **since**: 0.6.0 - -## uxManager - -Use the UX Manager to manage the appearance features in Luigi. - -### showLoadingIndicator - -Adds a backdrop with a loading indicator for the micro frontend frame. This overrides the [loadingIndicator.enabled](navigation-configuration.md#nodes) setting. - -### hideLoadingIndicator - -Removes the loading indicator. Use it after calling [showLoadingIndicator()](#showLoadingIndicator) or to hide the indicator when you use the [loadingIndicator.hideAutomatically: false](navigation-configuration.md#nodes) node configuration. - -### addBackdrop - -Adds a backdrop to block the top and side navigation. It is based on the Fundamental UI Modal, which you can use in your micro frontend to achieve the same behavior. - -### removeBackdrop - -Removes the backdrop. - -### setDirtyStatus - -This method informs the main application that there are unsaved changes in the current view in the iframe. For example, that can be a view with form fields which were edited but not submitted. - -#### Parameters - -- `isDirty` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** indicates if there are any unsaved changes on the current page or in the component - -### showConfirmationModal - -Shows a confirmation modal. - -#### Parameters - -- `settings` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** the settings of the confirmation modal. If you don't provide any value for any of the fields, a default value is used - - `settings.header` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the content of the modal header (optional, default `"Confirmation"`) - - `settings.body` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the content of the modal body (optional, default `"Are you sure you want to do this?"`) - - `settings.buttonConfirm` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the label for the modal confirm button (optional, default `"Yes"`) - - `settings.buttonDismiss` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the label for the modal dismiss button (optional, default `"No"`) - -Returns **[promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)** which is resolved when accepting the confirmation modal and rejected when dismissing it - -### showAlert - -Shows an alert. - -#### Parameters - -- `settings` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** the settings for the alert - - `settings.text` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the content of the alert. To add a link to the content, you have to set up the link in the `links` object. The key(s) in the `links` object must be used in the text to reference the links, wrapped in curly brackets with no spaces. If you don't specify any text, the alert is not displayed - - `settings.type` **(`"info"` \| `"success"` \| `"warning"` \| `"error"`)** sets the type of alert - - `settings.links` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** provides links data - - `settings.links.LINK_KEY` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** object containing the data for a particular link. To properly render the link in the alert message refer to the description of the **settings.text** parameter - - `settings.links.LINK_KEY.text` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** text which replaces the link identifier in the alert content - - `settings.links.LINK_KEY.url` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** url to navigate when you click the link. Currently, only internal links are supported in the form of relative or absolute paths. - - `settings.closeAfter` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (optional) time in milliseconds that tells Luigi when to close the Alert automatically. If not provided, the Alert will stay on until closed manually. It has to be greater than `100`. - -#### Examples - -```javascript -import LuigiClient from '@kyma-project/luigi-client'; -const settings = { - text: Ut enim ad minim veniam, {goToHome} quis nostrud exercitation ullamco {relativePath} laboris nisi ut aliquip ex ea commodo consequat. - Duis aute irure dolor {goToOtherProject}, - type: 'info', - links: { - goToHome: { text: 'homepage', url: '/overview' }, - goToOtherProject: { text: 'other project', url: '/projects/pr2' }, - relativePath: { text: 'relative hide side nav', url: 'hideSideNav' } - }, -closeAfter: 3000 -} -LuigiClient - .uxManager() - .showAlert(settings) - .then(() => { - // Logic to execute when the alert is dismissed -}); -``` - -Returns **[promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)** which is resolved when the alert is dismissed. - -### getCurrentLocale - -Gets the current locale. - -Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** current locale - -### setCurrentLocale - -Sets current locale to the specified one. - -**NOTE:** this must be explicitly allowed on the navigation node level by setting `clientPermissions.changeCurrentLocale` to `true`. (See [Node parameters](navigation-parameters-reference.md).) - -#### Parameters - -- `locale` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** locale to be set as the current locale - -### isSplitView - -Checks if the current micro frontend is displayed inside a split view - -Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** indicating if it is loaded inside a split view - -**Meta** - -- **since**: 0.6.0 - -### isModal - -Checks if the current micro frontend is displayed inside a modal - -Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** indicating if it is loaded inside a modal - -**Meta** - -- **since**: 0.6.0 diff --git a/website/docs/src/docs/luigi-core-api.md b/website/docs/src/docs/luigi-core-api.md deleted file mode 100644 index 517b4e0042..0000000000 --- a/website/docs/src/docs/luigi-core-api.md +++ /dev/null @@ -1,415 +0,0 @@ -# Luigi Core API - -## Luigi Config - - - -### Configuration - -#### setConfig - -Sets the configuration for Luigi initially. Can also be called at a later point in time again to update the configuration. - -##### Parameters - -- `configInput` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** the Luigi Core configuration object - -##### Examples - -```javascript -Luigi.setConfig({ - navigation: { - nodes: () => [ - { - pathSegment: 'home', - label: 'Home', - children: [ - { - pathSegment: 'hello', - label: 'Hello Luigi!', - viewUrl: '/assets/basicexternal.html' - } - ] - } - ] - }, - routing: { - useHashRouting: true - } -}) -``` - -#### getConfig - -Returns the current active configuration - -##### Examples - -```javascript -Luigi.getConfig() -``` - -Returns **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** configuration object - -#### configChanged - -Tells Luigi that the configuration has been changed. Luigi will update the application or parts of it based on the specified scope. - -##### Parameters - -- `scope` **...[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** one or more scope selectors specifying what parts of the configuration were changed. If no scope selector is provided, the whole configuration is considered changed.

- The supported scope selectors are: -

-

- -#### getConfigValue - -Gets value of the given property on Luigi config object. Target can be a value or a synchronous function. - -##### Parameters - -- `property` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the object traversal path - -##### Examples - -```javascript -Luigi.getConfigValue('auth.use') -Luigi.getConfigValue('settings.sideNavFooterText') -``` - -#### getConfigBooleanValue - -Gets boolean value of the given property on Luigi config object. -Function return true if the property value is equal true or 'true'. Otherwise the function returns false. - -##### Parameters - -- `property` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the object traversal path - -##### Examples - -```javascript -Luigi.getConfigBooleanValue('settings.hideNavigation') -``` - -#### getConfigValueAsync - -Gets value of the given property on the Luigi config object. -If the value is a Function it is called (with the given parameters) and the result of that call is the value. -If the value is not a Promise it is wrapped to a Promise so that the returned value is definitely a Promise. - -##### Parameters - -- `property` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the object traversal path -- `parameters` **any** optional parameters that are used if the target is a function - -##### Examples - -```javascript -Luigi.getConfigValueAsync('navigation.nodes') -Luigi.getConfigValueAsync('navigation.profile.items') -Luigi.getConfigValueAsync('navigation.contextSwitcher.options') -``` - -#### isAuthorizationEnabled - -Detects if authorization is enabled via configuration. - -Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** returns true if authorization is enabled. Otherwise returns false. - -**Meta** - -- **deprecated**: now located in Luigi.auth() instead of Luigi - -## Luigi.elements() - - - -### Elements - -Use these functions to get DOM elements. - -#### getLuigiContainer - -Returns the container of the Luigi content. - -##### Examples - -```javascript -Luigi.elements().getLuigiContainer(); -``` - -Returns **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)** the DOM element that wraps the Luigi content. - -**Meta** - -- **since**: 0.6.0 - -#### getShellbar - -Returns the shellbar component. - -##### Examples - -```javascript -Luigi.elements().getShellbar(); -``` - -Returns **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)** the shellbar DOM element. - -**Meta** - -- **since**: 0.4.12 - -#### getShellbarActions - -Returns the shellbar actions component. - -##### Examples - -```javascript -Luigi.elements().getShellbarActions(); -``` - -Returns **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)** the shellbar actions DOM element. - -**Meta** - -- **since**: 0.4.12 - -#### getMicrofrontends - -Returns a list of all available micro frontends. - -##### Examples - -```javascript -Luigi.elements().getMicrofrontends(); -``` - -Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<{id: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), active: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean), container: [HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element), type: (`"main"` \| `"split-view"` \| `"modal"`)}>** list of objects defining all micro frontends from the DOM - -**Meta** - -- **since**: 0.6.2 - -#### getMicrofrontendIframes - -Returns all micro frontend iframes including the iframe from the modal if it exists. - -##### Examples - -```javascript -Luigi.elements().getMicrofrontendIframes(); -``` - -Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)>** an array of all micro frontend iframes from the DOM. - -**Meta** - -- **since**: 0.4.12 - -#### getCurrentMicrofrontendIframe - -Returns the active micro frontend iframe. -If there is a modal, which includes the micro frontend iframe, the function returns this iframe. - -##### Examples - -```javascript -Luigi.elements().getCurrentMicrofrontendIframe(); -``` - -Returns **[HTMLElement](https://developer.mozilla.org/docs/Web/HTML/Element)** the active micro frontend iframe DOM element. - -**Meta** - -- **since**: 0.4.12 - -## Luigi.auth() - - - -### Authorization - -Authorization helpers - -#### isAuthorizationEnabled - -Detects if authorization is enabled via configuration. - -##### Examples - -```javascript -Luigi.auth().isAuthorizationEnabled(); -``` - -Returns **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** true if authorization is enabled. Otherwise returns false. - -## Luigi.navigation() - - - -### LuigiNavigation - -Use these functions for navigation-related features. - -#### updateTopNavigation - -Refreshes top navigation badge counters by rendering the navigation again. - -##### Examples - -```javascript -Luigi.navigation().updateTopNavigation(); -``` - -## Luigi.i18n() - - - -### LuigiI18N - -Localization-related functions. - -#### getCurrentLocale - -Gets the current locale. - -Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** current locale - -**Meta** - -- **since**: 0.5.3 - -#### setCurrentLocale - -Sets current locale to the specified one. - -##### Parameters - -- `locale` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** locale to be set as the current locale - -**Meta** - -- **since**: 0.5.3 - -#### addCurrentLocaleChangeListener - -Registers a listener for locale changes. - -##### Parameters - -- `listener` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** function called on every locale change with the new locale as argument - -Returns **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** listener ID associated with the given listener; use it when removing the listener - -**Meta** - -- **since**: 0.5.3 - -#### removeCurrentLocaleChangeListener - -Unregisters a listener for locale changes. - -##### Parameters - -- `listenerId` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** listener ID associated with the listener to be removed, returned by addCurrentLocaleChangeListener - -**Meta** - -- **since**: 0.5.3 - -#### getTranslation - -Gets translated text for the specified key in the current locale or in the specified one. -Property values for token replacement in the localization key will be taken from the specified interpolations object. - -##### Parameters - -- `key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** key to be translated -- `interpolations` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** objects with properties that will be used for token replacements in the localization key -- `locale` **locale** optional locale to get the translation for; default is the current locale - -## Luigi.customMessages() - - - -### CustomMessages - -Functions related to custom messages. - -#### sendToAll - -Sends a custom message to all opened micro frontends. - -##### Parameters - -- `message` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** an object containing data to be sent to the micro frontend to process it further. This object is set as an input parameter of the custom message listener on the micro frontend side. - - `message.id` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the id of the message - - `message.MY_DATA_FIELD` **any** any other message data field - -##### Examples - -```javascript -Luigi.customMessages().sendToAll({ - id: 'myprefix.my-custom-message-for-client', - dataField1: 'here goes some data', - moreData: 'here goes some more' -}); -``` - -**Meta** - -- **since**: 0.6.2 - -#### send - -Sends a message to specific micro frontend identified with an id. -Use Luigi.elements().getMicrofrontends() to get the iframe id. - -##### Parameters - -- `microfrontendId` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the id of the micro frontend -- `message` **[Object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** an object containing data to be sent to the micro frontend to process it further. This object is set as an input parameter of the custom message listener on the micro frontend side. - - `message.id` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the id of the message - - `message.MY_DATA_FIELD` **any** any other message data field - -##### Examples - -```javascript -Luigi.customMessages().send(microfrontend.id, { - id: 'myprefix.my-custom-message-for-client', - dataField1: 'here goes some data', - moreData: 'here goes some more' -}); -``` - -**Meta** - -- **since**: 0.6.2 - -## Luigi.ux() - - - -### UX - -Functions to use Luigi Core UX features. - -#### hideAppLoadingIndicator - -Hides the app loading indicator. - -**Meta** - -- **since**: 0.6.4 diff --git a/website/docs/src/docs/luigi-ux-features.md b/website/docs/src/docs/luigi-ux-features.md deleted file mode 100644 index 97e7e5ccfd..0000000000 --- a/website/docs/src/docs/luigi-ux-features.md +++ /dev/null @@ -1,54 +0,0 @@ - -# Luigi UX features - -### Rendering of Luigi application in the DOM - -By default, the Luigi content, including the top navigation, the left navigation, and the content iframed area, are rendered in the body tag of your Luigi Core application. As a result, the Luigi content takes the whole space from your browser window. - -However, you can render the Luigi content in any other HTML container. It can be useful if you want to add a header or a footer on top of the Luigi content. To use this feature, add the `luigi-app-root` custom HTML attribute to the HTML tag in which you want to render the Luigi content. - ->**NOTE:** If you render the Luigi content in a custom container, the container is positioned relatively when you apply your own CSS. Also, set the height of the Luigi custom container either in **px** or **vh**. - - -### Responsive application setup - -You can quickly adjust the Luigi application to improve user experience on mobile devices, such as smartphones or tablets. Here are some examples: - -* Add the following line to your `index.html` file for the Luigi application to render well on a mobile device: - -```html - -``` - -* Define and apply [responsiveNavigation](./general-settings.md) settings to make the left navigation responsive. - -### App loading indicator - -To show a loading indicator before Luigi Core or your first micro frontend is ready, add a container with the `luigi-app-loading-indicator` attribute to your _index.html_ body or inside your [`luigi-app-root`](#rendering-of-luigi-application-in-the-dom) container. - -```html -
-
-
-
-
-``` - -By default, the loading indicator is removed after `Luigi.setConfig({})` has been executed. - -Alternatively, to keep the loading indicator until the first micro frontend is usable, follow these steps: - -1. Set the app loading indicator parameter `hideAutomatically` to `false` - -```javascript -{ - ... - settings: { - appLoadingIndicator: { - hideAutomatically: false - } - } - ... -} -``` -2. Call [`Luigi.ux().hideAppLoadingIndicator()`](./luigi-core-api.md#hideAppLoadingIndicator) in the Luigi Core once your initial micro frontend has finished loading to remove the loading indicator. You can, for example, use the [custom messages](./communication.md#custom-messages) feature to allow the Luigi Client micro frontend to communicate with the Core when this function should be executed. diff --git a/website/docs/src/docs/navigation-configuration.md b/website/docs/src/docs/navigation-configuration.md deleted file mode 100644 index 209a430f17..0000000000 --- a/website/docs/src/docs/navigation-configuration.md +++ /dev/null @@ -1,282 +0,0 @@ -# Navigation configuration - -Navigation parameters allow you to specify routing configuration, set the appearance of navigation, and define navigation structure. - -## Navigation elements - -The image shows the elements of Luigi navigation: - -1. Top navigation which displays the main navigation path. -2. Side navigation which displays the defined applications. -3. Main content window which renders the micro frontend. - - -![Navigation layout](assets/navigation-structure.png) - - -## Navigation structure - -The navigation structure is a recursive tree-like data structure that defines all possible navigation paths within the application. - ->**NOTE:** This document describes the navigation structure along with the options you can use to create it. For a full list of available parameters, see the [parameter reference](navigation-parameters-reference.md) document. - -A navigation path is any existing path in the navigation tree. It connects the following elements together: - -- The path of the main application, that is, the path in the browser URL. The path is defined in a Luigi navigation node through one of the following parameters, listed in order of precedence: **externalLink**, **link**, and **pathSegment**. -- The **viewUrl** property of a micro frontend rendered in the content area of the main application. - -If you set the **hideSideNav** property to `true`, the left navigation disappears when you click the affected node. It is set to `false` by default. - -If you want to group some navigation nodes into a separate parent node, you can use the **category** property. The grouped navigation nodes are rendered in a dropdown. The **category** property needs a **label** and, optionally, an **icon**. - -A sample navigation structure looks as follows: - -```` -{ - navigation: { - nodes: [ - { - pathSegment: 'home', - label: 'Home', - viewUrl: 'https://my.microfrontend.com/', - children: [ - { - link: '/home', - label: 'Go back home' - }, - { - link: 'projects/pr2/settings', - label: 'Go to Project 2 Settings' - }, - { - pathSegment: 'settings', - label: 'Settings', - viewUrl: 'https://my.microfrontend.com/general/settings.html' - }, - { - pathSegment: 'projects', - label: 'Projects', - viewGroup: 'projectsGroup', - viewUrl: 'https://my.microfrontend.com/projects/list.html', - children: [ - { - pathSegment: 'pr1', - label: 'Project one', - viewUrl: 'https://my.microfrontend.com/projects/details.html#id=pr1', - hideSideNav: true - }, - { - pathSegment: 'pr2', - label: 'Project two', - viewUrl: 'https://my.microfrontend.com/projects/details.html#id=pr2' - } - ] - }, - { - category: {label:'Misc', icon:'miscellaneous'}, - pathSegment: 'miscellaneous', - label: 'Miscellaneous', - viewUrl: 'https://my.microfrontend.com/general/miscellaneous.html' - }, - { - category:'Misc', - pathSegment: 'miscellaneous2', - label: 'Miscellaneous2', - viewUrl: 'https://my.microfrontend.com/general/miscellaneous2.html' - } - ] - } - ] - } -} -```` - - -## Node navigation - -When you navigate between nodes that are located in the same domain, Luigi triggers a hash or path change. Then it sends the updated context in order not to fully reload the view for a single-page application based micro frontend. Navigation between domains triggers a full page load in order to comply with cross-domain security concepts. - -If you start navigating from a child node level, navigate to the specific product route using the [Luigi Client API](luigi-client-api.md) as shown in the example: - -```` -LuigiClient.linkManager().fromContext('project').withParam({sort: 'asc'}).navigate('/products'); -```` - -You can also navigate directly from any other node: - -```` -LuigiClient.linkManager().withParam({sort: 'asc'}).navigate('/something/sample_1/products'); -```` - -## Application path - -The main application path is built from **pathSegment** values in the navigation path, joined with the **/** character. You can override this setting using either **externalLink** or **link** parameters. - -The micro frontend view URL is the value of the **viewUrl** property of the last node in the navigation path. - -The following example shows the structure of different navigation paths. If the URL of the main application is `https://luigiexample.com`, then: - -- `https://luigiexample.com/home/projects/pr1` reflects the `home/projects/pr1` navigation path. It is a valid navigation path as it exists in the defined navigation tree structure. The micro frontend view URL rendered in the content area is `https://my.microfrontend.com/projects/details.html#id=pr1`. - -- `https://luigiexample.com/home/maskopatol` defines an invalid `home/maskopatol` navigation path. - -- `https://luigiexample.com/projects/pr1` defines the `projects/pr1` navigation path. It is not a valid navigation path, since a valid navigation path always starts from the root. - - -## Path parameters - -Use path parameter values to define the **pathSegment** in your configuration. You can either use a static value for your **pathSegment**, or add a colon to this value as in `:projectId`, to make it act as a parameter. This tells Luigi to accept any value for this **pathSegment** of the main application URL. The value replaces the parameter when it is further processed by the application. - -A sample structure with a parametrized **pathSegment** is as follows: -``` -{ - navigation: { - nodes: [ - { - pathSegment: 'home', - label: 'Home', - viewUrl: 'https://my.microfrontend.com/', - children: [ - { - pathSegment: 'projects', - label: 'Projects', - viewUrl: 'https://my.microfrontend.com/projects/list.html', - children: [ - { - pathSegment: ':projectId', - label: 'Project Details', - viewUrl: 'https://my.microfrontend.com/projects/details.html#id=:projectId;' - } - ] - } - ] - } - ] - } -} - -``` - - Use the following options to work with path parameters: - -- Add the parameters to the **viewUrl** by placing them anywhere in the **viewUrl** value. For example, if the main application URL is `https://luigiexample.com/home/projects/pr23`, then the **viewUrl** of the micro frontend in the content area is `https://my.microfrontend.com/projects/details.html#id=pr23`. -- Use the [Luigi Client API](luigi-client-api.md) to access the node parameter values from the micro frontend. Use the `LuigiClient.getPathParams()` function. -For example, to get the value of the sample project parameter, use `LuigiClient.getPathParams().projectId`. -- Add a parameter to the context part of your configuration: - ``` - { - pathSegment: ':projectId', - label: 'Project Details', - viewUrl: 'https://my.microfrontend.com/projects/details.html#id=:projectId;', - context: { - project: ':projectId' - } - } - ``` -In all cases, the parameter is automatically replaced by the real value. - - -## Node parameters - -You can use node parameters to build the **viewUrl** and pass them to the micro frontend specified in the navigation node selected in the navigation path. -You can specify them in the main application URL, similarly to URL query parameters with a specific prefix. The prefix is `~` by default, but you can reconfigure it using the global **nodeParamPrefix** setting. - -All parameters without the prefix are not passed to the micro frontend and are consumed by the main application. - -A sample **viewUrl** `https://luigiexample.com/home/projects/pr23?~sorting=asc&~page=2` supports sorting and paging by introducing the **sort** and **page** node parameters. - -The navigation structure with the project list view using such sample node parameters looks as follows: - -```` -{ - navigation: { - nodes: [ - { - pathSegment: 'home', - label: 'Home', - viewUrl: 'https://my.microfrontend.com/', - children: [ - { - pathSegment: 'projects', - label: 'Projects', - viewGroup: 'projectsGroup', - viewUrl: 'https://my.microfrontend.com/projects/list.html#pagenr={nodeParams.page};sort={nodeParams.sorting}', - children: [ - { - pathSegment: ':projectId', - label: 'Project Details', - viewUrl: 'https://my.microfrontend.com/projects/details.html#id=:projectId;' - } - ] - } - ] - } - ] - } -} - -```` - - Use the following options to work with node parameters: - -- Build the **viewUrl** by placing them anywhere in the **viewUrl** value using the following syntax: `nodeParams.{node param name}`. For example, if the main application URL is `https://luigiexample.com/home/projects/?~sorting=asc&~page=2` then the **viewUrl** of a micro frontend is `https://my.microfrontend.com/projects/list.html#pagenr=2;sort=asc`. - -- Use the [Luigi Client API](luigi-client-api.md) to access the node parameter values from within the micro frontend. Use the `LuigiClient.getNodeParams()` function. -For example, to get the value of the sorting parameter, use `LuigiClient.getNodeParams().sorting`. - - -## Dynamic viewUrl - -Use the node parameters and path parameters to build a dynamic **viewUrl**. - -In this example, the web application URL is `https://Luigi.corp/something/sample_1/products?~sort=asc`. The micro frontend loads using a different URL, such as `https://admin.my.test/project/sample_1/products?sort=asc`. - -When loading, the **viewUrl** uses the following dynamic URL parameters: - -- `:projectId = sample_1` -- `sort = asc` - -``` -Luigi.setConfig({ - routing: { - nodeParamPrefix: '~' - }, - navigation: { - nodes: [ - { - pathSegment: 'something', - label: 'Something', - viewUrl: 'https://admin.my.test/project', - children: [{ - navigationContext: 'project', - pathSegment: ':projectId', - viewUrl: 'https://admin.my.test/project/:projectId', - // Optional, you can always call LuigiClient.getPathParams() to get the parameters - // context: { - // currentProject: ':projectId' - // }, - children: [ - { - pathSegment: 'products', - label: 'Products', - viewUrl: 'https://admin.my.test/project/:projectId/products' - } - ] - } - } - ] - } -}); -``` - -## View groups - -The view groups feature allows you to override the default iframes management policy. Imagine your application hosts two micro frontend views: `http://mysite.com/a#e` and `http://mysite.com/b#f`. Due to hash routing and a different path up to `#`, they are, by default, rendered in different iframes. However, as they both have the **same origin**, such as`mysite.com`, and belong to the **same micro frontend** you want to render them in the same iframe. To achieve that, use the view groups feature. Define the **viewGroup** parameter for top navigation nodes. The children nodes will automatically be considered as part of the same view group. - -Nodes belonging to the same view group are always rendered in their own view group iframe. Nodes not belonging to any view group follow the same-origin iframe rendering policy. - -The view groups feature also offers out-of-the-box caching. Each time you navigate to another view group, either a new iframe is created or it is reused if already exists. In both cases, the iframe you are navigating from becomes hidden and is available for you to use again. If you navigate back to the first iframe and it should be updated with new data, such when a new entry was added in the second iframe and you want to display it in a table in the first iframe, you must define a **preloadUrl** parameter for a given view in the view group to ensure that the view is refreshed when you navigate back to it. - -You can also preload view groups. You just need to define which URL you want to preload, and Luigi will preload the view after some user interactions when the browser is most likely to be idle. This option is active by default, but you can deactivate it with a [configuration flag](navigation-parameters-reference.md#node-parameters). - -For more information on setting caching with view refreshing and preloading for view groups, read [this document](navigation-parameters-reference.md#node-parameters). diff --git a/website/docs/src/docs/navigation-parameters-reference.md b/website/docs/src/docs/navigation-parameters-reference.md deleted file mode 100644 index 38c2f7f69e..0000000000 --- a/website/docs/src/docs/navigation-parameters-reference.md +++ /dev/null @@ -1,281 +0,0 @@ -# Navigation parameters reference -You can use the listed parameters and functions to configure your navigation structure. The examples show how to use selected options. - -## Navigation configuration example - -This code sample demonstrates a sample structure with the parameters you can use when configuring navigation for Luigi. - -``` -Luigi.setConfig({ - routing: { - // uses hash-based navigation if set to true - useHashRouting: true, - nodeParamPrefix: '~', - skipRoutingForUrlPatterns: [/access_token=/, /id_token=/] - }, - // navigation structure and settings - navigation: { - nodeAccessibilityResolver: function (nodeToCheckPermissionFor, parentNode, currentContext) {}, - viewGroupSettings: { - main: { - preloadUrl: 'https://my-site.com/index.html#/preload', - }, - projects: { - preloadUrl: 'https://my-site.com/projects.html#/preloading', - }, - envs: { - preloadUrl: 'https://my-site.com/environments-details.html#/preload-view', - } - }, - nodes: [ - // STATIC navigation node - { - pathSegment: 'settings', - label: 'Settings', - viewUrl: 'https://admin.mydomain.com/settings', - viewGroup: 'settingsGroup', - // optional - children: [node, node, node], - hideFromNav: false, - isolateView: false, - icon: 'settings', - testId: 'myTestId' - category: { - label: 'General', - testId: 'myTestId', - icon: 'general' - }, // OR - category: 'General' - }, - // DYNAMIC navigation node - { - navigationContext: 'contextName', - pathSegment: ':projectId', - testId: 'myTestId', - viewUrl: '/some/path/:projectId', - context: { - projectId: ':projectId' - }, - children: [node, node, node] - }, - // View groups nodes - { - viewGroup: 'main', - pathSegment: 'overview', - label: 'Overview', - viewUrl: 'https://my-site.com/index.html#/overview' - }, - { - viewGroup: 'main', - pathSegment: 'preload', - viewUrl: 'https://my-site.com/index.html#/preload' - }, - { - viewGroup: 'projects', - pathSegment: 'projects', - label: 'Projects', - viewUrl: 'https://my-site.com/projects.html#/list', - children: [ - { - pathSegment: 'preloading', - viewUrl: 'https://my-site.com/projects.html#/preloading' - } - ] - }, - { - viewGroup: 'envs', - pathSegment: 'create-environment', - viewUrl: 'https://my-site.com/environments.html#/create', - context: { - label: 'Create Environment' - } - }, - { - viewGroup: 'envs', - pathSegment: 'environments', - viewUrl: 'https://my-site.com/environments-details.html#/list', - children: [ - { - pathSegment: 'preload', - viewUrl: 'https://my-site.com/environments-details.html#/preload-view' - }, - { - pathSegment: 'env1', - viewUrl: 'https://my-site.com/environments-details.html#/details/env1' - } - ] - } - ], - contextSwitcher: { - defaultLabel: 'Select Environment ...', - testId: 'myTestId', - parentNodePath: '/environments', - lazyloadOptions: false, - fallbackLabelResolver: (id) => (id.toUpperCase()), - options: [{label,pathValue}, {label,pathValue}], - actions: [{label,link,position,clickHandler?}] - }, - profile: { - logout: { - label: 'End session' - // icon: "sys-cancel", - testId: 'myTestId', - }, - items: [ - { - icon: '', - testId: 'myTestId', - label: 'Luigi in Github', - externalLink: { - url: 'https://github.com/SAP/luigi', - sameWindow: false - } - }, - { - icon: '', - label: 'Project 1', - link: '/projects/pr1' - } - ] - }, - productSwitcher: { - label: 'My Products', - testId: 'myTestId', - icon: 'grid', - items: [ - { - icon: '', - label: 'Luigi in Github', - testId: 'myTestId', - externalLink: { - url: 'https://github.com/SAP/luigi', - sameWindow: false - } - }, - { - icon: '', - label: 'Project 1', - testId: 'myTestId', - link: '/projects/pr1' - } - ] - }, - } -}); -``` - -## Routing - -You can configure the way Luigi tackles routing in your application in the **Routing** section of the configuration file. For example, you can choose the routing strategy to apply in your application as either hash or path location routing. - -- **useHashRouting** defines either hash-based (`url.com/#/yourpath`) or path-based (`url.com/yourpath`) routing. -- **nodeParamPrefix** sets the prefix character when using the `LuigiClient.linkManager().withParam()` function, which provides a way to simply attach query parameters to the view URL for activities such as sorting and filtering. The URL contains the parameters to allow deep linking. If you want to use a different character prefix, define yours here. The default character is `~`. -- **skipRoutingForUrlPatterns** defines regex patterns to be skipped by the router when listening for path changes. This parameter is used for excluding **redirect_uri** parameters. Default patterns are `[/access_token=/, '/id_token=/]`. -- **pageNotFoundHandler** is a function defining custom behavior when the 404 (page not found) error occurs. Luigi handles it by default. Leave its body empty if you have an external 404 handling. This function takes the following parameters: - - **wrongPath**(string): the path that user tried to navigate to - - **wasAnyPathFitted**(bool): it is true if Luigi managed to fit a valid path which means **wrongPath** was only partially wrong. Otherwise it is false. - -## Node navigation parameters - -The node navigation parameters are as follows: - -- **nodeAccessibilityResolver** receives all values defined in the node configuration. It allows you to define a permission checker function that gets executed on every node. If it returns `false`, Luigi removes the node and its children from the navigation structure. -See [angular navigation.js](https://github.com/SAP/luigi/blob/master/core/examples/luigi-sample-angular/src/luigi-config/extended/navigation.js) for an example. -- **defaults.isolateView** renders all views in new frames. This setting overrides the same-domain frame reuse. The **defaults.isolateView** is disabled by default, and you can overwrite it using the **isolateView** value on a single node level. -- **preloadViewGroups**(bool) allows deactivating the default preloading of [view groups](navigation-configuration.md#view-groups) iframes. -- **viewGroupsSettings** is an object containing key-object pairs, where the key is the view group name as specified in the node parameters, and the object contains key-value pairs. In each key-value pair, the key is the feature name and the value is the actual setting. The following options are supported: - - **preloadUrl**(string): needs to be an absolute URL for a node from the view group. It is recommended that you use a dedicated small, visually empty view, which imports Luigi Client and is fine with getting an empty context, for example, without an access token. The **preloadUrl** parameter is also required for view group caching in case you need a view group iframe to refresh whenever you navigate back to it. - -## Node parameters - -The node parameters are as follows: - -- **pathSegment** specifies the partial URL of the current segment. **pathSegment** must not contain slashes. - - A static settings example reflects `luigidomain.test/settings`. - - A dynamic settings example, prefixed with a colon, loads on any other value. -- **link** is a string which refers to an absolute path in the navigation structure or a relative path to a grandchild of the current path. If this parameter is defined, **pathSegment** is ignored. - - **externalLink** is an object which indicates that the node links to an external URL. If this parameter is defined, **pathSegment** and **link** parameters are ignored. It has the following properties: - - **sameWindow** defines if the external URL is opened in a new or current tab. The default value for this parameter is `false`. - - **url** is the external URL that the node leads to. -- **label** contains the display name of the navigation node. -- **testId** is a string where you can define your own custom `testId`. If there is nothing specified, it is a combination of the node's pathsegment followed by a dash (if pathsegment exists) and the label written as one word and lower case (e.g. `pathsegment_label` or `label`). -- **hideFromNav** shows or hides a navigation node. You can still navigate to the node but it does not show up in the top or left pane. -- **viewUrl** contains the URL or path to a view which renders when you click the navigation node. Use either a full URL or a relative path. This value may consist of variables if you have specified a **navigationContext** with a dynamic **pathSegment**. If **viewUrl** is undefined, Luigi activates the child node specified in **defaultChildNode**. When both **viewUrl** and **defaultChildNode** are undefined, Luigi opens the first child of the current node. -- **navigationContext** contains a named node that is mainly for use in combination with a dynamic **pathSegment** to start navigation from a dynamic node using ` LuigiClient.linkManager().fromContext('contextname')`. -- **context** sends the specified object as context to the view. Use this parameter in combination with the dynamic **pathSegment** to receive the context through the context listeners of **Luigi Client**. This is an alternative to using the dynamic value in the **viewUrl**. -- **defaultChildNode** sets the child node that Luigi activates automatically if the current node has no **viewUrl** defined. Provide **pathSegment** of the child node you want to activate as a string. -- **isolateView** renders the view in a new frame when you enter and leave the node. This setting overrides the same-domain frame re-usage. The **isolateView** is disabled by default. -- **viewGroup** allows you to associate nodes to be rendered in the same iframe, as long as they belong to the same origin. The value of this parameter is considered as the view group id. For further explanations, see [this section](navigation-configuration.md#view-groups). -- **keepSelectedForChildren** focuses the navigation on its current hierarchy, omitting the display of children. -- **loadingIndicator.enabled** shows a loading indicator when switching between micro frontends. If you have a fast micro frontend, you can disable this feature to prevent flickering of the loading indicator. This parameter is enabled by default. -- **loadingIndicator.hideAutomatically** disables the automatic hiding of the loading indicator once the micro frontend is loaded. It is only considered if the loading indicator is enabled. It does not apply if the loading indicator is activated manually with the `LuigiClient.uxManager().showLoadingIndicator()` function. If the loading indicator is enabled and automatic hiding is disabled, use `LuigiClient.uxManager().hideLoadingIndicator()` to hide it manually in your micro frontend during the startup. This parameter is enabled by default. -- **viewGroup** defines a group of views in the same domain sharing a common security context. This improves performance through reusing the frame. Use **viewGroup** only for the views that use path routing internally. -- **icon** is the name of an icon, without the `sap-icon--` prefix. Its source may be [OpenUI](https://openui5.hana.ondemand.com/1.40.10/iconExplorer.html) or a custom link (relative or absolute) to an image. The icon is displayed next to the node label in the side navigation or instead of the label in the top navigation. -- **hideSideNav** if set to `true`, the left navigation disappears when you click the affected node. It is set to `false` by default. -- **badgeCounter** adds a badge with a number and a label to a node. Nodes that are part of a category show a cumulated number of all badges in this category. **badgeCounter** is only available for top navigation items. - - **label** is the label of the badge. - - **count** is a function or asynchronous function that returns a number. - Gets updated when you click the navigation. Use `Luigi.navigation().updateTopNavigation()` in Luigi Core or trigger it in Luigi Client by using the custom message feature. -- **category** defines a group of views separated with a headline and an icon. You should define at least one node in a group should as an Object with **label** and **icon** properties. For all other nodes, you can set **category** as a string with the `label` value. - - **label** is a string that represents the title of the category - - **icon** is the name of an icon, without the `sap-icon--` prefix. Its source may be [OpenUI](https://openui5.hana.ondemand.com/1.40.10/iconExplorer.html) or a custom link (relative or absolute) to an image. The icon is displayed next to the node label in the side navigation or instead of the label in the top navigation. In case you accidentally define different icons in a category group, only the first one is used. - - **collapsible** if set to `true`, category items are hidden at first. To expand them, click the main category node. - - **testId** is a string where you can define your own custom `testId`. If nothing is specified, it is the node's label written as one word and lower case (e.g. `label`). -- **openNodeInModal** configures the settings of the view which opens in a modal. You can specify the modal's title and size. If you don't specify the title, the node label is used. If there is no node label, the title remains empty. The default size of the modal is `l`, which means 80%. You can also use `m` (60%) and `s` (40%) to set the modal size.
Optionally you can set the **openNodeInModal** property to `true` to use default title and size. - - **title** modal title. By default, it is the node label. If there is no label, it is left empty - - **size** **(`"l"` \| `"m"` \| `"s"`)** size of the modal (optional, default `"l"`) -- **onNodeActivation** is an optional function executed when a request to navigate to the node occurs. As an input parameter, the function receives the node object as described in the configuration. This function can return results synchronously or asynchronously. If the function returns boolean `false`, the navigation is not triggered, otherwise, navigation renders as usual. -- **clientPermissions.changeCurrentLocale** current locale can be changed from client using the corresponding API if this is set to `true` - -## Context switcher - -The context switcher is a drop-down list available in the top navigation bar. It allows you to switch between a curated list of navigation elements such as Environments. To do so, add the **contextSwitcher** property to the **navigation** object using the following optional properties: - -- **defaultLabel** specifies the default label that is shown if no context is selected. -- **parentNodePath** specifies the base path, that is prepended to **options[].pathValue**. It must be an absolute path. -- **lazyloadOptions** defines when to fetch **options**. When set to `true`, loads **options** when you click the context switcher. It doesn't involve any caching. When set to `false`, loads **options** once the page loads. The default value is `true`. -- **options** defines the list of context element. Context element properties are: - - **label** defines the context element label. If not defined, the **pathValue** is passed to **fallbackLabelResolver** to set its value. The default value is **pathValue**, if **fallbackLabelResolver** is not defined. - - **pathValue** defines the context element path that is appended to **parentNodePath** and reflects a **pathSegment**. -- **actions** defines a list of additional elements that are shown on above or below the context switcher **options**. Each action contains the following parameters: - - **label** defines the action element label. - - **testId** is a string where you can define your own custom `testId`. If nothing is specified, it is the node's label written as one word and lower case (e.g. `label`). - - **position** defines the action element position. Can be `top` or `bottom`. The default value is `top`. This parameter is optional. - - **link** defines an absolute Link to a **node**. This parameter is optional. - - **clickHandler** specifies a function and is executed on click and should return a boolean. If it returns `true`, **link** is opened afterwards. -- **fallbackLabelResolver** specifies a function used to fetch the **label** for **options** with no **label** defined. Additionally, it fetches the drop-down label for non-existing **options**. - - -## Profile - -The profile section is a configurable drop-down list available in the top navigation bar. Within the configuration, you can override the logout item content (if authorization is configured) and/or add links to Luigi navigation nodes. To do so, add the **profile** property to the **navigation** object using the following optional properties: - -- **logout** overrides the content of the logout item. - - **label** overrides the text for the logout item. The default value is "Sign Out". - - **testId** is a string where you can define your own custom `testId`. If nothing is specified, it is the node's label written as one word and lower case (e.g. `label`). - - **icon** overrides the icon for the logout item. The default value is [SAP UI5 log icon](https://sapui5.hana.ondemand.com/test-resources/sap/m/demokit/iconExplorer/webapp/index.html#/overview/SAP-icons/?tag=logout). -- **items** is an array of objects, each one being a link to a Luigi navigation node or an external URL. An item can have the following parameters: - - **label** defines the text for the link. - - **testId** is a string where you can define your own custom `testId`. If nothing is specified, it is the node's label written as one word and lower case (e.g. `label`). - - **icon** is the name of an icon from the [OpenUI](https://openui5.hana.ondemand.com/1.40.10/iconExplorer.html) or a custom link (relative or absolute) to an image displayed next to the label or instead of it. - - **link** defines an absolute link to a **node**. - - **externalLink** is an object which indicates that the node links to an external URL. If this parameter is defined, the **link** parameter is ignored. It has the following properties: - - **sameWindow** defines if the external URL is opened in the current tab or in a new one. The default value for this parameter is `false`. - - **url** is the external URL that the link leads to. ->**NOTE:** Neither authorization nor profile property are configured if the profile section in the top navigation bar is not visible. - -## Product switcher - -The product switcher is a pop-up window available in the top navigation bar. It allows you to switch between the navigation elements displayed in the pop-up. To do so, add the **productSwitcher** property to the **navigation** object using the following optional properties: - -- **label** defines the label of the product switcher. It is displayed as a title attribute on hover in the top navigation and as a headline in the mobile pop-up. -- **testId** is a string where you can define your own custom `testId`. If nothing is specified, it is the node's label written as one word and lower case (e.g. `label`). -- **icon** is the name of an icon, without the `sap-icon--` prefix. Its source may be [OpenUI](https://openui5.hana.ondemand.com/1.40.10/iconExplorer.html) or a custom link (relative or absolute) to an image. The icon is displayed without label in the top navigation. -- **items** is an array of objects, each one being a link to a Luigi navigation node or an external URL. An item can have the following parameters: - - **label** defines the text for the link. - - **testId** is a string where you can define your own custom `testId`. If nothing is specified, it is the node's label written as one word and lower case (e.g. `label`). - - **icon** is the name of an icon from the [OpenUI](https://openui5.hana.ondemand.com/1.40.10/iconExplorer.html) or a custom link (relative or absolute) to an image displayed next to the label or instead of it. - - **link** defines an absolute link to a **node**. - - **externalLink** is an object which indicates that the node links to an external URL. If this parameter is defined, the **link** parameter is ignored. It has the following properties: - - **sameWindow** defines if the external URL is opened in the current tab or in a new one. The default value for this parameter is `false`. - - **url** is the external URL that the link leads to. \ No newline at end of file diff --git a/website/docs/src/luigi-config/extended/navigation.js b/website/docs/src/luigi-config/extended/navigation.js index 1c422d5316..ea5625271e 100644 --- a/website/docs/src/luigi-config/extended/navigation.js +++ b/website/docs/src/luigi-config/extended/navigation.js @@ -5,7 +5,7 @@ if (location.port == '4000') { baseUrl = '/docu-microfrontend'; } const getDocuItems = () => { - return fetch('/navigation-nodes.json', { + return fetch('/navigation-generated.json', { headers: { 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains; preload' } @@ -22,119 +22,48 @@ const getDocuItems = () => { } class Navigation { - nodes = [ - { - pathSegment: 'docs', - label: 'Documentation', - viewUrl: baseUrl + '/docs', - children: getDocuItems(), - context: { - coreBaseUrl: window.location.origin - } - }, - { - label: 'About Luigi', - defaultChildNode: 'docs', - externalLink: { - url: 'https://luigi-project.io/about', - sameWindow: true - } - }, - { - label: 'Twitter', - externalLink: { - url: 'https://twitter.com/luigiprojectio' + nodes = { + defaultChildNode: 'docs', + children: [ + { + label: 'About Luigi', + externalLink: { + url: 'https://luigi-project.io/about', + sameWindow: true + } }, - icon: 'twitter' - }, - { - label: 'Slack', - externalLink: { - url: 'https://slack.luigi-project.io' + { + pathSegment: 'docs', + label: 'Documentation', + viewUrl: baseUrl + '/docs', + children: getDocuItems(), + context: { + coreBaseUrl: window.location.origin + } }, - icon: 'slack' - }, - { - label: 'Github', - externalLink: { - url: 'https://github.com/SAP/luigi' + { + label: 'Twitter', + externalLink: { + url: 'https://twitter.com/luigiprojectio' + }, + icon: 'twitter' }, - icon: 'github' - } - // { - // pathSegment: 'docs', - // label: 'Overview', - // viewUrl: baseUrl + '/docs', - // children: getDocuItems() - // } - ]; - - // getContextSwitcherActions = () => { - // const actions = [ - // { - // label: '+ New Environment (top)', - // link: '/create-environment' - // }, - // { - // label: '+ New Project', - // link: '/projects', - // position: 'bottom', - // clickHandler: node => { - // const p = addProject(); - // Luigi.setConfig(Luigi.getConfig()); - // Luigi.showAlert({ - // text: `${p.name} created.`, - // type: 'info', - // closeAfter: 3000 - // }); - // return true; - // } - // } - // ]; - - // if (getProjectCount() > 0) { - // actions.push({ - // label: '\u2212 Remove Project', - // link: '/projects', - // position: 'bottom', - // clickHandler: node => { - // const p = removeProject(); - // Luigi.setConfig(Luigi.getConfig()); - // Luigi.showAlert({ - // text: `${p.name} removed.`, - // type: 'info', - // closeAfter: 3000 - // }); - // return true; - // } - // }); - // } - - // return actions; - // }; - - // The following configuration will be used to render the context switcher component - // contextSwitcher = { - // defaultLabel: 'Select Environment ...', - // parentNodePath: '/environments', // absolute path - // lazyloadOptions: true, // load options on click instead on page load - // options: () => - // [...Array(10).keys()] - // .filter(n => n !== 0) - // .map(n => ({ - // label: 'Environment ' + n, // (i.e mapping between what the user sees and what is taken to replace the dynamic part for the dynamic node) - // pathValue: 'env' + n // will be used to replace dynamic part - // })), - // actions: this.getContextSwitcherActions, - - // /** - // * fallbackLabelResolver - // * Resolve what do display in the context switcher (Label) in case the activated - // * context (option) is not listed in available options (eg kyma-system namespace), - // * or if options have not been fetched yet - // */ - // fallbackLabelResolver: id => id.replace(/\b\w/g, l => l.toUpperCase()) - // }; + { + label: 'Slack', + externalLink: { + url: 'https://slack.luigi-project.io' + }, + icon: 'slack' + }, + { + label: 'Github', + externalLink: { + url: 'https://github.com/SAP/luigi' + }, + icon: 'github' + } + ] + }; getProductSwitcherItems = () => { const items = [ @@ -151,11 +80,6 @@ class Navigation { return items; }; - // The following configuration will be used to render a product switcher component - // productSwitcher = { - // items: this.getProductSwitcherItems - // }; - getProfileItems = () => { const items = [ { @@ -168,14 +92,6 @@ class Navigation { ]; return items; }; - - // profile = { - // logout: { - // label: 'End session' - // // icon: "sys-cancel", - // }, - // items: this.getProfileItems - // }; } export const navigation = new Navigation(); diff --git a/website/docs/src/routes/docs/_parser.js b/website/docs/src/routes/docs/_parser.js index 50b0e3bb89..3e237aede4 100644 --- a/website/docs/src/routes/docs/_parser.js +++ b/website/docs/src/routes/docs/_parser.js @@ -11,16 +11,6 @@ export function getParsedDocs() { return Promise.resolve(JSON.stringify(parsedDocs)); }); } -// let parsedReadMeDoc; -// export function getParsedReadMeDoc() { -// if (parsedReadMeDoc) { -// return Promise.resolve(JSON.stringify(parsedReadMeDoc)); -// } -// return setParsedReadMeDoc().then((doc) => { -// parsedReadMeDoc = doc; -// return Promise.resolve(JSON.stringify(parsedReadMeDoc)); -// }); -// } function setParsedDocs() { const dir = './../../docs'; @@ -43,45 +33,5 @@ function setParsedDocs() { })); }); - return Promise.all(parsingArr) - .then((files) => { - // write Luigi navigation tree for our config - const navChildren = files - .map((fileObj) => (fileObj.shortName)) - .map((name) => ({ - label: name, - pathSegment: name, - navigationContext: 'doc', - keepSelectedForChildren: true, - viewUrl: `__BASE_URL__/docs/${name}` - })); - writeFileSync('./static/luigi/navigation-children-raw.json', JSON.stringify(navChildren, null, 2)); - - // return for sapper - return Promise.resolve(files); - }); + return Promise.all(parsingArr); } - -// function setParsedReadMeDoc() { -// const dir = './../../docs'; -// let parsingArr; -// readdirSync(dir) -// .find(name => { -// if(name == 'README.md') { -// const mdContent = readFileSync(dir + '/' + name); -// parsingArr = new Promise((resolve) => { -// MarkdownSvc.process(mdContent).then((contents) => { -// resolve({ -// contents -// }); -// }) -// }); -// } -// }); - -// return parsingArr -// .then((file) => { -// // return for sapper -// return file; -// }); -// } \ No newline at end of file diff --git a/website/docs/src/services/markdown.service.js b/website/docs/src/services/markdown.service.js index 49c4209462..1f59fa2db9 100644 --- a/website/docs/src/services/markdown.service.js +++ b/website/docs/src/services/markdown.service.js @@ -5,10 +5,12 @@ import raw from 'rehype-raw'; import format from 'rehype-format'; import html from 'rehype-stringify'; import addIdsToHeadings from 'rehype-slug'; +import frontmatter from 'remark-frontmatter'; import luigiLinkParser from '../unified-plugins/rehype-luigi-linkparser'; import addCopyToClipboard from '../unified-plugins/rehype-copy-to-clipboard'; import addCustomAttributes from '../unified-plugins/rehype-add-custom-attributes'; +import luigiNavigationBuilder from '../unified-plugins/remark-generate-luigi-navigation'; // import highlight from 'rehype-highlight' // syntax highlight code blocks with lowlight: https://github.com/wooorm/lowlight import rehypeSection from '@agentofuser/rehype-section'; @@ -19,12 +21,14 @@ class MarkdownService { return new Promise((resolve, reject) => { unified() .use(markdown) + .use(frontmatter, {type: 'json', fence: {open: ''}}) + // .use(logger) + .use(luigiNavigationBuilder, data) .use(remark2rehype, {allowDangerousHTML: true}) .use(raw) .use(addCustomAttributes) .use(luigiLinkParser, data) .use(section) - // .use(highlight) .use(addIdsToHeadings) .use(addCopyToClipboard) .use(format) @@ -37,6 +41,10 @@ class MarkdownService { resolve(file.contents); }); }); + + function logger() { + return console.dir; + } } } diff --git a/website/docs/src/unified-plugins/remark-generate-luigi-navigation.js b/website/docs/src/unified-plugins/remark-generate-luigi-navigation.js new file mode 100644 index 0000000000..515686da4a --- /dev/null +++ b/website/docs/src/unified-plugins/remark-generate-luigi-navigation.js @@ -0,0 +1,61 @@ +import visit from 'unist-util-visit'; +import { writeFileSync, readFileSync, readdirSync } from 'fs'; +import orderBy from 'lodash.orderby'; + +const staticLuigiFolder = 'static/luigi/'; +const navigationFile = staticLuigiFolder + 'navigation-generated.json'; +const staticNavigation = readFileSync(staticLuigiFolder + 'navigation-nodes.json'); + +// initially write static navigation items to file +writeFileSync(navigationFile, String(staticNavigation)); + +export default function luigiNavigationBuilder(data = {}) { + + return function transformer(tree) { + const navItems = JSON.parse(readFileSync(navigationFile)); + visit(tree, ['json'], function (node) { + const navData = Object.assign({}, data, parseFrontmatter(node.value)); + navItems.push(generateNavItem(navData)); + node.value = ''; // clear, to not produce html output + }); + + // sort by metaData.categoryPosition AND metaData.position + const navItemsSorted = orderBy(navItems, ['metaData.categoryPosition', 'metaData.position']); + + // write to navigationFile + writeFileSync(navigationFile, JSON.stringify(navItemsSorted, null, 2)); + } + + function generateNavItem(d) { + if(!d.node || !d.node.label) { + console.warn('WARNING: possible invalid frontmatter data', d); + } + + const navItem = Object.assign({}, + d.node, + { + label: d.node && d.node.label || d.shortName, + pathSegment: d.shortName, + navigationContext: 'doc', + keepSelectedForChildren: true, + viewUrl: `__BASE_URL__/docs/${d.shortName}` + }); + return navItem; + } + + function IsJsonString(str) { + try { + JSON.parse(str); + } catch (e) { + return false; + } + return true; + } + + function parseFrontmatter(str) { + if(!IsJsonString(str)) { + console.error('ERROR, invalid json', str); + } + return JSON.parse(str); + } +} \ No newline at end of file diff --git a/website/docs/static/luigi/navigation-nodes.json b/website/docs/static/luigi/navigation-nodes.json index 4477e08696..29fae55905 100644 --- a/website/docs/static/luigi/navigation-nodes.json +++ b/website/docs/static/luigi/navigation-nodes.json @@ -1,215 +1,4 @@ [ - - - { - "label": "Getting started", - "pathSegment": "getting-started", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/getting-started", - "context": { - "doc": "getting-started" - }, - "category": { - "label": "Basics" - } - }, - { - "label": "Architecture", - "pathSegment": "", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/", - "context": { - "doc": "" - }, - "category": { - "label": "Basics" - } - }, - { - "label": "Installation", - "pathSegment": "application-setup", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/application-setup", - "context": { - "doc": "application-setup" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "Basic navigation", - "pathSegment": "navigation-configuration", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/navigation-configuration", - "context": { - "doc": "navigation-configuration" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "Configuration Example", - "pathSegment": "navigation-configuration-example", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "hideFromNav": true, - "viewUrl": "__BASE_URL__/docs/navigation-configuration-example", - "context": { - "doc": "navigation-configuration-example" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "Advanced navigation", - "pathSegment": "navigation-advanced", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/navigation-advanced", - "context": { - "doc": "navigation-advanced" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "Routing", - "pathSegment": "navigation-parameters-reference", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/navigation-parameters-reference", - "context": { - "doc": "navigation-parameters-reference" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "Authorization", - "pathSegment": "authorization-configuration", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/authorization-configuration", - "context": { - "doc": "authorization-configuration" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "Authorization events", - "pathSegment": "authorization-events", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/authorization-events", - "context": { - "doc": "authorization-events" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "General settings", - "pathSegment": "general-settings", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/general-settings", - "context": { - "doc": "general-settings" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "Lifecycle hooks", - "pathSegment": "lifecycle-hooks", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/lifecycle-hooks", - "context": { - "doc": "lifecycle-hooks" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "UI features", - "pathSegment": "luigi-ux-features", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/luigi-ux-features", - "context": { - "doc": "luigi-ux-features" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "API", - "pathSegment": "luigi-core-api", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/luigi-core-api", - "context": { - "doc": "luigi-core-api" - }, - "category": { - "label": "Luigi Core" - } - }, - { - "label": "Installation", - "pathSegment": "", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/", - "context": { - "doc": "" - }, - "category": { - "label": "Luigi Client" - } - }, - { - "label": "API", - "pathSegment": "luigi-client-api", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/luigi-client-api", - "context": { - "doc": "luigi-client-api" - }, - "category": { - "label": "Luigi Client" - } - }, - { - "label": "Custom messages", - "pathSegment": "communication", - "navigationContext": "doc", - "keepSelectedForChildren": true, - "viewUrl": "__BASE_URL__/docs/communication", - "context": { - "doc": "communication" - }, - "category": { - "label": "Advanced" - } - }, { "label": "Angular", "pathSegment": "", @@ -224,6 +13,10 @@ }, "externalLink": { "url": "https://github.com/SAP/luigi/tree/master/core/examples/luigi-example-angular" + }, + "metaData": { + "categoryPosition": 5, + "position": 0 } }, { @@ -240,6 +33,10 @@ }, "externalLink": { "url": "https://github.com/SAP/luigi/tree/master/core/examples/luigi-example-vue" + }, + "metaData": { + "categoryPosition": 5, + "position": 1 } }, { @@ -256,6 +53,10 @@ }, "externalLink": { "url": "https://github.com/SAP/luigi/tree/master/core/examples/luigi-example-react" + }, + "metaData": { + "categoryPosition": 5, + "position": 2 } } ] \ No newline at end of file