From 420935834edfde6c074a024a564245e37a895b1f Mon Sep 17 00:00:00 2001 From: Richard Cox Date: Fri, 7 Aug 2020 18:43:05 +0100 Subject: [PATCH] Fix docs (#4497) * Fixes #4335: Create Stratos static web site with better documentation structure using docusaurus. Initial commit. * 1) Re-organize some more existing doc files. 2) Re-organize links in the doc file to refer to the new document hierarchy. * Landing Page WIP * Documentation tweaks * Use better action names * More visual improvements to landing page * More doc and landing page improvements * Remove publish workflow for now * Typo fix * Moer documentation improvements * Remove extra title from helm doc * Fix script when used from npm * Improve layout on mobile devices * More documentation improvements * Fix typo * Merge downstream (#4441) * Merge src/frontend from downstream * Merge src/jetstream from jetstream * Remove examples/custom-src * Merge deploy from downstream Does not include changes to - deploy/all-in-one/* - deploy/aio-entrypoint.sh - deploy/Dockerfile.all-in-one * Merge build from downstream * Add missing merge items from deploy * Updates to package-lock * Remove fdescribe * Fix e2e core tests * Remove favicon from packages/core/src * Changes following review * Show all favorites for an endpoint favorite if there is only one (#4440) * Show all favorites for the endpoint favorite if there is only one * Missing changes * Merge downstream - JSON Viewer with dark mode & Header Fixes (#4444) * Fix json-viewer dark mode * Fix profile page and side nav top position following header diet - Fix side nav top position - Update fix for profile page to also work in non-desktop mode * Fix issues with tests not running if build upload fails (#4453) * Fix issues with tests not running if build upload fails * Fix script * One more fix for script * Fix white space at start of file * Improve autoscaler e2e logging (#4456) * Improve autoscaler e2e logging - it looks like the AS returns scaling events 1-2 mins after they occur, which is too late for the test - add additional logging to print out event table data in case of alternative events being raised - fix logging if wait for events times out - add hint in later test that depends on AS scaling event * Ensure only the schedule rule results in scaling events * Fix check-e2e-pr.sh for pr's from other repos (#4459) - switch from TRAVIS_PULL_REQUEST_SLUG to TRAVIS_REPO_SLUG * Convert Client Secret Input Fields to `password` (#4455) * Insecure tlsv10 and tlsv11 ciphers in Stratos UI, bsc#1173295 (#411) (#4460) Co-authored-by: Michal Jura * [Security] Bump codecov from 3.7.0 to 3.7.1 (#4457) Bumps [codecov](https://github.com/codecov/codecov-node) from 3.7.0 to 3.7.1. **This update includes a security fix.** - [Release notes](https://github.com/codecov/codecov-node/releases) - [Commits](https://github.com/codecov/codecov-node/compare/v3.7.0...v3.7.1) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> * Bump lodash from 4.17.15 to 4.17.19 (#4452) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.19. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.19) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Website update: Wed 22 Jul 2020 21:55:00 BST * Website update: Wed 22 Jul 2020 21:56:45 BST * Website update: Wed 22 Jul 2020 21:58:22 BST * Remove dist * FIx deploy script to remove old files * Moer tidy ups * Add CNAME file when publishing * Add talks doc * * Fix broken links due to reorganization of documents * Move Troubleshooting content from cloud-foundry deployment doc to cf-troubleshooting * * Fix Getting Started broken link in page footer * Only publish if there are website changes * Remove old doc * Publish website on merge * Apply new theming process to acme example * First pass at customization docs, most of themeing done * Final pass at customization docs * Update base README, point to website * Update developer docs Still need an overhall, but updated to remove incorrect data and apply website context * Fix PR template Co-authored-by: Veerapuram Varadhan Co-authored-by: Neil MacDougall Co-authored-by: Neil MacDougall Co-authored-by: Neil MacDougall Co-authored-by: Michal Jura Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/pull_request_template.md | 6 - .../developer/developers-guide-env-tech.md | 152 +------ website/docs/developer/frontend.md | 2 +- website/docs/extensions/frontend.md | 382 +++++++++++++----- 4 files changed, 306 insertions(+), 236 deletions(-) diff --git a/docs/pull_request_template.md b/docs/pull_request_template.md index 11568562b2..e651b7af6d 100644 --- a/docs/pull_request_template.md +++ b/docs/pull_request_template.md @@ -1,9 +1,3 @@ ---- -id: pull_request_template -title: Pull request template for contributions to Stratos -sidebar_label: PR template ---- - ## Description diff --git a/website/docs/developer/developers-guide-env-tech.md b/website/docs/developer/developers-guide-env-tech.md index 76918f9fba..0b374c6c01 100644 --- a/website/docs/developer/developers-guide-env-tech.md +++ b/website/docs/developer/developers-guide-env-tech.md @@ -1,40 +1,42 @@ --- id: developers-guide-env-tech -title: Stratos Tech + Developer Environment -sidebar_label: Dev Environment +title: Developer Links + Environment +sidebar_label: Dev Links & Env --- -## ES6 +## Links + +Below is a collection of links that are can be useful when tackling some of the technology involved with Stratos + +### ES6 * [http://stack.formidable.com/es6-interactive-guide](http://stack.formidable.com/es6-interactive-guide) * [http://es6-features.org](http://es6-features.org) -## TypeScript +### TypeScript -* [https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/](https://www.sitepen.com/blog/2013/12/31/definitive-guide-to-typescript/) * [https://learnxinyminutes.com/docs/typescript/](https://learnxinyminutes.com/docs/typescript/) (cheat sheet) * [https://www.tutorialspoint.com/typescript/](https://www.tutorialspoint.com/typescript/) * [https://tutorialzine.com/2016/07/learn-typescript-in-30-minutes](https://tutorialzine.com/2016/07/learn-typescript-in-30-minutes) -* [https://www.sitepen.com/blog/2013/12/31/typescript-cheat-sheet/](https://www.sitepen.com/blog/2013/12/31/typescript-cheat-sheet/) (advanced cheat sheet) - -## Angular ### Angular +#### Angular + * [https://www.youtube.com/watch?v=KhzGSHNhnbI](https://www.youtube.com/watch?v=KhzGSHNhnbI) (very basic 1h video of angular covering basic app features in a demo) * [https://angular.io/guide/architecture](https://angular.io/guide/architecture) (official angular intro) * [https://angular.io/tutorial](https://angular.io/tutorial) (official angular tutorial. Basic to start with but good introduction to routing, http requests, promises, observables and observable event stream later on) -### Angular CLI +#### Angular CLI * [https://cli.angular.io/reference.pdf](https://cli.angular.io/reference.pdf) (cheat sheet) * [https://github.com/angular/angular-cli](https://github.com/angular/angular-cli) -### Example Apps +#### Example Apps * https://github.com/aviabird/angularspree (covers everything) -## Redux +### Redux * [http://redux.js.org](http://redux.js.org) * [https://gist.github.com/btroncone/a6e4347326749f938510](https://gist.github.com/btroncone/a6e4347326749f938510) @@ -42,27 +44,25 @@ sidebar_label: Dev Environment * [https://www.youtube.com/watch?v=WIqbzHdEPVM](https://www.youtube.com/watch?v=WIqbzHdEPVM) * [https://egghead.io/courses/getting-started-with-redux](https://egghead.io/courses/getting-started-with-redux) -### Observables +#### Observables * [http://reactivex.io/documentation/observable.html](http://reactivex.io/documentation/observable.html) ## VS Code Plug-ins -There's no mandated IDE, but if you choose VS Code here's some helpful plug-ins +There's no mandated IDE, but if you choose Visual Studio Code here's some helpful plug-ins -### Super Helpful +### Really Helpful * TSLint -* SassLint * TS Hero -* Beautify +* Git Lens * gitignore +* Move TS - Move files and automatically update imports ### Helpful -* Angular 2+ Snippets -* Angular v4 TypeScript Snippets -* Git Lens +* Beautify * Document This * Git History * TODO Parser @@ -76,122 +76,10 @@ There's no mandated IDE, but if you choose VS Code here's some helpful plug-ins ``` * F1 + `Parse TODOs (all files)` to see all TODOs -* Move TS - Move files and automatically update imports - -### Of Interest - -* Eclipse Keymap * Code Spell Checker * List of words to exclude coming soon +* Eclipse Keymap -Example settings - -``` -{ - "gitlens.blame.line.enabled": false, - "gitlens.codeLens.recentChange.enabled": false, - "gitlens.codeLens.authors.enabled": false, - "gitlens.blame.highlight.locations": [ - "gutter", - "overview" - ], - "gitlens.currentLine.enabled": false, - "gitlens.hovers.currentLine.enabled": false, - "editor.fontSize": 12, - "editor.formatOnSave": true, - "editor.rulers": [ - 140 - ], - "editor.renderLineHighlight": "none", - "search.exclude": { - "node_modules": true, - "**/node_modules": true, - "**/bower_components": true, - "coverage": true, - "components/*/backend/vendor": true, - "*.orig": true - }, - "search.useIgnoreFilesByDefault": true, - "tslint.validateWithDefaultConfig": true, - "tslint.configFile": "tslint.json", - "tslint.autoFixOnSave": true, - "tslint.alwaysShowStatus": true, - "tslint.alwaysShowRuleFailuresAsWarnings": true, - "explorer.autoReveal": false, - "extensions.ignoreRecommendations": false, - "TodoParser": { - "folderExclude": [ - "node_modules", - ".vscode" - ] - }, - "cSpell.userWords": [ - "Guids", - "action", - "api", - "cnsi", - "cnsis", - "confirmation", - "dialog", - "falsies", - "guid", - "iapi", - "initialise", - "initialised", - "injectable", - "memberof", - "ngrx", - "normalizr", - "strat", - "unsubscribe", - "vars" - ], - "cSpell.language": ",en-GB", - "cSpell.enabledLanguageIds": [ - "c", - "css", - "cpp", - "csharp", - "fonts", - "go", - "handlebars", - "javascript", - "javascriptreact", - "json", - "latex", - "markdown", - "php", - "plaintext", - "python", - "restructuredtext", - "text", - "typescript", - "typescriptreact", - "yml", - "html" - ], - "files.exclude": { - "**/.git": true, - "**/.svn": true, - "**/.hg": true, - "**/CVS": true, - "**/.DS_Store": true, - "**/tmp": true, - "**/node_modules": true, - "**/bower_components": true, - "**/dist": true, - "**/.orig": true - }, - "files.watcherExclude": { - "**/.git/objects/**": true, - "**/.git/subtree-cache/**": true, - "**/node_modules/**": true, - "**/tmp/**": true, - "**/bower_components/**": true, - "**/dist/**": true - }, -} -``` ## Guides diff --git a/website/docs/developer/frontend.md b/website/docs/developer/frontend.md index 17c1e7b037..572dd2032a 100644 --- a/website/docs/developer/frontend.md +++ b/website/docs/developer/frontend.md @@ -69,5 +69,5 @@ Configuration information can be found in two places * Informs the frontend where the backend is * `./src/frontend/packages/core/src/environments/environment.ts` for developer vs production like config * This contains more general settings for the frontend and does not usually need to be changed -* `config.properies` +* `config.properties` * Backend configuration diff --git a/website/docs/extensions/frontend.md b/website/docs/extensions/frontend.md index a253e906ef..6bed192aae 100644 --- a/website/docs/extensions/frontend.md +++ b/website/docs/extensions/frontend.md @@ -3,20 +3,42 @@ title: Frontend Extensions sidebar_label: Frontend Extensions --- -An example illustrating the various front-end extension points of Stratos is included in the folder `examples/custom-src`. +Stratos exposes the following extension points: -To include the customizations in this example, either copy or symlink the `examples/custom-src` to `custom-src` at the top-level of the Stratos repository. +- Adding new items to the side navigation menu +- Adding new tabs to the Application, Cloud Foundry, Organization and Space views +- Adding new action buttons to the Application Wall, Application, Cloud Foundry, Organization and Space and Endpoint views +- Replace the loading page +- Replace the login page -Next, run the customization script (this is done automatically when you do an `npm install`) with: +We use Decorators to annotate components to indicate that they are Stratos extensions. -``` -npm run customize -``` +An example illustrating the various front-end extension points of Stratos is included in the folder `src/frontend/packages/example-extensions`. -You can now run Stratos locally to see the customizations - see the [Developer's Guide](../developer/frontend) for details. +To run Stratos with these customizations see [here](/docs/extensions/introduction#acme). For a walk-through of extending Stratos, see [Example: Adding a Custom Tab](#example-adding-a-custom-tab). +## Including modules and routes +To include code and angular routing in your component there needs to be two access points +- A core module that declares your extension components. +- A core routing module that calls `RouterModule.forRoot`. This is the root for all routes in your package. + +These modules should be made available externally to Stratos by the following steps + +1. Exported in the package's `public-api.ts`, for example `src/frontend/packages/example-extensions/src/public-api.ts`. The public api should be added to the applications `tsconfig.json` for example `src/tsconfig.json` +1. Reference as, or imported by, the two modules defined in the `stratos` section in the package's `package.json`, for example `src/frontend/packages/example-extensions/package.json` + ``` + "stratos": { + ... + "module": "ExampleModule", + "routingModule": "ExampleRoutingModule" + ... + } + ``` + +At build time these are then added to a dynamically created module `src/frontend/packages/core/src/_custom-import.module.ts` and included in the output. + ## Extension Points ### Side Navigation @@ -25,9 +47,9 @@ New items can be added to the Side Navigation menu with extensions. To do so, annotate the routes for your extension with custom metadata, which Stratos will then pick up and add to the side menu. -A full example is in the folder `examples/custom-src/frontend/app/custom/nav-extension`. +A full example is in `src/frontend/packages/example-extensions/src/example-routing.module.ts` and `src/frontend/packages/example-extensions/src/nav-extension`. -Your route should have the following metadata in the `data` field: +Your route should have the following metadata in the `data` field of the route: ``` stratosNavigation: { @@ -38,17 +60,17 @@ Your route should have the following metadata in the `data` field: Where `` is the text label to show in the side navigation and `<ICON NAME>` is the icon to use. -You should place your route declaration in a module named `CustomRoutingModule` in the file `custom-src/frontend/app/custom/custom-routing.module.ts`. +> The routing module must be, or referenced by, the core routing module as described [above](/docs/extensions/frontend#including-modules-and-routes) An example routing module would be: ``` import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; +import { RouterModule, Routes } from '@angular/router'; const customRoutes: Routes = [{ path: 'example', - loadChildren: 'app/custom/nav-extension/nav-extension.module#NavExtensionModule', + loadChildren: () => import('./nav-extension/nav-extension.module').then(m => m.NavExtensionModule), data: { stratosNavigation: { text: 'Example', @@ -63,10 +85,12 @@ const customRoutes: Routes = [{ ], declarations: [] }) -export class CustomRoutingModule { } +export class ExampleRoutingModule { } + ``` -This approach ensures that the Angular compiler creates a separate chunk for the extension at compile time. +This approach ensures that the Angular compiler creates a separate chunk for the extension at compile time which can be lazy loaded at run +time. ### Custom Tabs @@ -77,6 +101,8 @@ Tabs can be added to the following views in Stratos: - The Cloud Foundry Org view that shows detail for a Cloud Foundry organization - The Cloud Foundry Space view that shows detail for a Cloud Foundry space +A step by step guide on how to create a custom tab can be found [below](/docs/extensions/frontend#example-adding-a-custom-tab). + For example: ![Example Application tab extension](../../images/extensions/app-tab-example.png) @@ -84,28 +110,34 @@ For example: The approach for all of these is the same: 1. Create a new component that will provide the tab contents -2. Ensure that your component is included in the `EntryComponent` section of your custom module -2. Decorate the component with the `StratosTab` decorator, for example: - -``` -@StratosTab({ - type: StratosTabType.Application, - label: '<LABEL>', - link: '<LINK>' -}) -``` - -Where: - -- < TYPE > indicates where the tab should appear and can be: - - StratosTabType.Application - Application View - - StratosTabType.CloudFoundry - Cloud Foundry view - - StratosTabType.CloudFoundryOrg - Cloud Foundry Org view - - StratosTabType.CloudFoundrySpace - Cloud Foundry Space view -- < LABEL > is the text label to use for the tab -- < LINK > is the name to use for the route (this must only contain characters permitted in URLs) - -An example is included in the file `examples/custom-src/frontend/app/custom/app-tab-extension`. +1. Ensure that your component is included in the `EntryComponent` section of your custom module +1. Decorate the component with the `StratosTab` decorator, for example: + ``` + @StratosTab({ + icon: 'extension', + type: StratosTabType.Application, + label: 'Example App Tab', + link: 'example' + }) + ``` + Where: + - < ICON > is the material design icon name for the icon + - < TYPE > indicates where the tab should appear and can be: + - StratosTabType.Application - Application View + - StratosTabType.CloudFoundry - Cloud Foundry view + - StratosTabType.CloudFoundryOrg - Cloud Foundry Org view + - StratosTabType.CloudFoundrySpace - Cloud Foundry Space view + - < LABEL > is the text label to use for the tab + - < LINK > is the name to use for the route (this must only contain characters permitted in URLs) + An example is included in the file `src/frontend/packages/example-extensions/src/app-tab-extension/app-tab-extension.component.ts`. +1. Declare the component to avoid Angular tree shaking + - In the same module that the component is 'declared' in add the following to `imports` + ``` + ExtensionService.declare([ + <component name>, + ]) + ``` +> The module referencing the component, or another referencing it, must be imported by the core module as described [above](/docs/extensions/frontend#including-modules-and-routes). ### Custom Actions @@ -125,92 +157,239 @@ An action is a icon button that appears at the top-right of a View. For example: The approach for all of these is the same: 1. Create a new component that will provide the contents to show when the action is clicked -2. Ensure that your component is included in the `EntryComponent` section of your custom module -2. Decorate the component with the `StratosAction` decorator, for example: +1. Ensure that your component is included in the `EntryComponent` section of your custom module +1. Decorate the component with the `StratosAction` decorator, for example: + ``` + @StratosAction({ + type: StratosActionType.Applications, + label: '<LABEL>', + link: '<LINK>', + icon: '<ICON> + }) + ``` + Where: + - < TYPE > indicates where the action should appear and can be: + - StratosActionType.Applications - Application Wall View + - StratosActionType.Application - Application View + - StratosActionType.CloudFoundry - Cloud Foundry view + - StratosActionType.CloudFoundryOrg - Cloud Foundry Org view + - StratosActionType.CloudFoundrySpace - Cloud Foundry Space view + - StratosActionType.Endpoints - Endpoints view + - < ICON > is the icon to show + - < LABEL > is the text label to use for the tooltip of the icon (optional) + - < LINK > is the name to use for the route (this must only contain characters permitted in URLs) + An example is included in the file `src/frontend/packages/example-extensions/src/app-action-extension/app-action-extension.component.ts`. +1. Declare the component to avoid Angular tree shaking + - In the same module that the component is 'declared' in add the following to `imports`. + ``` + ExtensionService.declare([ + <component name>, + ]) + ``` + +> The module referencing the component, or another referencing it, must be imported by the core module as described in [above](/docs/extensions/frontend#including-modules-and-routes) + +### Loading Indicator + +On slower connections, it can take a few seconds to load the main Javascript resources for Stratos. + +In order to give the user some initial feedback that Stratos is loading, a loading indicator is included in the `index.html` file. This gets shown as early as possible, as soon as this main html file has loaded. Once the main code has been fetched, the view refreshes to show the application. + +A default loading indicator is provided that can be changed. To do so, create the following two in your extension or theme package: + +- `loading.css` - CSS styles to be included in a style block in the head of the index page +- `loading.html` - HTML markup to be included the the index page to render the loading indicator + +Then reference them to your package's `package.json` ``` -@StratosAction({ - type: StratosActionType.Applications, - label: '<LABEL>', - link: '<LINK>', - icon: '<ICON> -}) + "stratos": { + ... + "theme": { + "loadingCss": "loader/loading.css", + "loadingHtml": "loader/loading.html" + } + ... + }, ``` -Where: - -- < TYPE > indicates where the action should appear and can be: - - StratosActionType.Applications - Application Wall View - - StratosActionType.Application - Application View - - StratosActionType.CloudFoundry - Cloud Foundry view - - StratosActionType.CloudFoundryOrg - Cloud Foundry Org view - - StratosActionType.CloudFoundrySpace - Cloud Foundry Space view - - StratosActionType.Endpoints - Endpoints view -- < ICON > is the icon to show -- < LABEL > is the text label to use for the tooltip of the icon (optional) -- < LINK > is the name to use for the route (this must only contain characters permitted in URLs) - -An example is included in the file `examples/custom-src/frontend/app/custom/app-action-extension`. - -## Example: Adding a Custom Tab - -In this example, we will walk through extending the Stratos front-end. - -This walk-through assumes that you have installed the Angular CLI globally - this can be done with `npm install -g @angular/cli`. - -### Create a new module - -First, create the custom-src folder structure - from the top-level of the Stratos repository run: +The files for the default indicator can be found in the `src/frontend/packages/theme/loader` folder. + +An example of a different loading indicator is included with the ACME sample in `src/frontend/packages/example-theme/loader`. + +The customization task will insert the appropriate CSS and HTML files into the main index.html file when it runs. + +Take a look at the template for the `index.html` file in `src/frontend/packages/core/misc/custom/index.html`. The CSS file is inserted where the marker `/** @@LOADING_CSS@@ **/` is and the HTML file where `<!-- @@LOADING_HTML@@ -->` is. + +### Login Page + +The log in page can be replaced by another Angular component. This can extend the original log in component and provide the same functionality, +see `src/frontend/packages/example-extensions/src/acme-login`. + +1. Create a new log in component that will contain the same form and fields. The component should have the decorator `@StratosLoginComponent()` + ``` + @StratosLoginComponent() + @Component({ + selector: 'app-acme-login', + templateUrl: './acme-login.component.html', + styleUrls: ['./acme-login.component.scss'], + encapsulation: ViewEncapsulation.None + }) + export class AcmeLoginComponent extends LoginPageComponent { + ... + ``` +1. The new component should be declared and set as an entry point, as well as imported via the extension service, in a module + ``` + imports: [ + ... + ExtensionService.declare([ + AcmeLoginComponent, + ]) + ... + ], + // FIXME: Ensure that anything lazy loaded/in kube endpoint pages is not included here - #3675 + declarations: [ + ... + AcmeLoginComponent, + ... + ], + entryComponents: [ + ... + AcmeLoginComponent, + ... + ] + }) + ``` + +### Other Points + +#### Customization Service +A customization service provides a number of smaller extension points. + +|Property | Description| +|--|--| +|hasEula| True if there's a EULA to show. When set to true the asset `/core/eula.html` must exist. For information about custom package assets see the images section [here](/docs/extensions/theming#new-images). | +|copyright| Text shown at the bottom of the side nav| +|logoText| Text shown with the side nav logo| +|aboutInfoComponent| Replace the component used in the Stratos `About` page| +|supportInfoComponent| Replace the component used to provide support information int he Stratos `About` page| +|noEndpointsComponent| Replace the component used in the Endpoints page when there are no registered endpoints| +|alwaysShowNavForEndpointTypes| True to always show the side nav menu items even if an Endpoint for that type is not connected. For example set to `false` to hide CF based menu items such as `Application` if no CF is connected| + +To utilize these define them in a `CustomizationsMetadata` object and apply them using the Angular service `CustomizationService` ``` -mkdir -p custom-src/frontend/app/custom -mkdir -p custom-src/frontend/assets/custom + constructor(cs: CustomizationService) { + const customizations: CustomizationsMetadata = { + copyright: '© 2020 Me', + hasEula: true, + aboutInfoComponent: MyAboutInfoComponent, + noEndpointsComponent: MyWelcomeComponent, + alwaysShowNavForEndpointTypes: (typ) => false, + } + cs.set(customizations); + } + ``` -Next, run the customize task: +#### stratos.yaml +A few 'higher up' extension points can be found in `./stratos.yaml`. For example the [SUSE stratos.yaml](https://github.com/SUSE/stratos/blob/master/stratos.yaml) is below. ``` -npm run customize +title: SUSE Stratos Console +productVersion: 2.0.0 ``` -This will symlink our custom folder into the Stratos application source folder. +|Property|Description| +|--|--| +|title| Official product title, shown in `About` page and other custom places| +|productVersion| Use when building `helm` charts| -Next, use the Angular CLI to create the root module for our custom code with: -``` -ng generate module custom -``` +## Example: Adding a Custom Tab -This create a new Angular module `CustomModule`. +In this example, we will walk through extending the Stratos front-end. A new tab will be added to the Cloud Foundry Application page. -Run the customize script again, now that that we have created the custom module with: +This walk-through assumes that you have installed the Angular CLI globally - this can be done with `npm install -g @angular/cli`. -``` -npm run customize -``` +### Create a new extensions package + +> Extension packages can contain many components and even a theme. The example here assumes a fresh start so a new package must be created + +1. Create the directory + ``` + mdkir src/frontend/packages/my-custom-module + ``` +1. Create an angular module in `my-custom-module` called `my-example.module.ts` + ``` + import { CommonModule } from '@angular/common'; + import { NgModule } from '@angular/core'; + + @NgModule({ + imports: [ + CommonModule + ], + declarations: [ + ] + }) + export class MyExampleModule { } + ``` +1. Create a `public-api.ts` in `my-custom-module` and reference it in your applications `tsconfig.json`. + + `public-api.ts` + ``` + export * from './my-example.module'; + ``` + `tsconfig.json` + ``` + "paths": { + ... + "@myexamples/extensions": ["frontend/packages/my-custom-module/public-api.ts"] + .... + } + ``` + +1. Create a `package.json` in `my-custom-module` + ``` + { + "name": "@myexamples/extensions", + "version": "0.0.1", + "peerDependencies": { + "@angular/common": "^6.0.0-rc.0 || ^6.0.0", + "@angular/core": "^6.0.0-rc.0 || ^6.0.0" + }, + "stratos": { + "module": "MyExampleModule" + } + } + ``` ### Create a new Component for our Tab Create a new Angular component with the CLI: ``` -ng generate component custom/example-tab-extension +cd src/frontend/packages/my-custom-module +ng generate component example-tab-extension ``` +This will automatically declare the component in `MyExampleModule` + ### Add Decorator to make this Component an Extension In a text editor, open the file: ``` -src/frontend/app/custom/example-tab-extension/example-tab-extension.component.ts +src/frontend/packages/my-custom-module/example-tab-extension/example-tab-extension.component.ts ``` Add the following decorator to the component at the top of the file: ``` -import { StratosTab, StratosTabType } from '../../core/extension/extension-service'; +import { StratosTab, StratosTabType } from '@stratosui/core'; @StratosTab({ + icon: 'done', type: StratosTabType.Application, label: 'Example App Tab', link: 'example' @@ -221,9 +400,10 @@ The file should now look like this: ``` import { Component, OnInit } from '@angular/core'; -import { StratosTab, StratosTabType } from '../../core/extension/extension-service'; +import { StratosTab, StratosTabType } from '@stratosui/core'; @StratosTab({ + icon: 'done', type: StratosTabType.Application, label: 'Example App Tab', link: 'example' @@ -237,7 +417,7 @@ export class ExampleTabExtensionComponent implements OnInit { constructor() { } - ngOnInit() { + ngOnInit(): void { } } @@ -245,27 +425,35 @@ export class ExampleTabExtensionComponent implements OnInit { Save the file. +### Update the module -### Mark the component as an entry component - -The last thing we need to do is to mark our Extension component as an entry component. +The component must now be marked as an entry component and imported in such a way angular tree shaking is avoided. -To do this, in a text editor, open the file `src/frontend/app/custom/custom.module.ts` and add the entry components section so it looks like this: +To do this, in a text editor, open the file `src/frontend/packages/my-custom-module/my-example.module.ts` update +- the file imports section +- the module import array +- the entry component array ``` +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { ExtensionService } from '@stratosui/core'; + +import { ExampleTabExtensionComponent } from './example-tab-extension/example-tab-extension.component'; + @NgModule({ imports: [ - CommonModule + CommonModule, + ExtensionService.declare([ + ExampleTabExtensionComponent, + ]) ], declarations: [ExampleTabExtensionComponent], entryComponents: [ExampleTabExtensionComponent] }) -export class CustomModule { } +export class MyExampleModule { } ``` ### Run it -You should now be able to run Stratos locally and see this new tab on the application page for an application - as illustrated below: - -![Example tab extension](../../images/extensions/tab-example.png) - +You should now be able to run Stratos [locally](/docs/developer/introduction) and see this new tab on the application page for an application.