Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/PULL_REQUEST_TEMPATE.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
## Description

<!-- Talk about the great work you've done! -->

### What's included?

<!-- List features included in this PR -->

- One
- Two
- Three

#### Test Steps

<!-- Add instructions on how to test your changes -->

- [ ] `npm ci`
- [ ] In `proxy.conf.js` file, change serverUrl to `https://appcenter.ux.ac.uda.io`
- [ ] `npm run serve`
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"stylelint": "./node_modules/.bin/stylelint 'src/**/*.scss' '!**/assets/**' --config stylelint.config.js --syntax scss",
"webdriver-update": "bash ./node_modules/.bin/webdriver-manager update",
"test": "ng test ui-platform --code-coverage --source-map=false --watch=false",
"test:schematics": "tsc -p src/lib/schematics/tsconfig.spec.json && jasmine src/lib/schematics/**/*.spec.js",
"coveralls": "cat ./coverage/lcov.info | node ./node_modules/coveralls/bin/coveralls.js",
"build:lib": "bash scripts/build-release && gulp version-placeholder",
"release:start": "bash scripts/start-release",
Expand Down
24 changes: 24 additions & 0 deletions scripts/test-schematics.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Run test and linter
npm run test:schematics
npm run tslint

# Link project
cd ../src/lib
npm link

# Create Angular base project
cd /tmp
rm -rf testxyz
ng new testxyz
cd testxyz
ng add @angular/material
ng add @covalent/core

# Run covalent schematics
cd testxyz
npm link @td-vantage/ui-platform
ng g @td-vantage/ui-platform:ng-add

# Check generated files
git status
npm i
5 changes: 5 additions & 0 deletions src/lib/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
},
"license": "MIT",
"author": "Teradata UI Team",
"schematics": "./schematics/collection.json",
"peerDependencies": {
"@angular/common": "^0.0.0-NG",
"@angular/core": "^0.0.0-NG",
Expand Down
4 changes: 4 additions & 0 deletions src/lib/schematics/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Outputs
**/*.js
**/*.js.map
**/*.d.ts
11 changes: 11 additions & 0 deletions src/lib/schematics/collection.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json",
"schematics": {
"ng-add": {
"description": "Adds vantage ui platform to the application without affecting any templates",
"factory": "./ng-add/index#addDependenciesAndFiles",
"schema": "./ng-add/schema.json",
"aliases": ["vantage-shell", "install"]
}
}
}
27 changes: 27 additions & 0 deletions src/lib/schematics/ng-add/files/proxy.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const vantageLoginProxyConfig = require('./src/lib/auth/config/vantageLoginProxyConfig');

/* * * * * * * * * * * */
/* Edit these variables to point to your */
/* Vantage and local development environments */
/* * * * * * * * * * * */

const serverUrl = 'https://vantage.url.io'; // REPLACE WITH VANTAGE BASE URL

const localUrl = 'localhost:4200';
const localProto = 'http'; // http or https

/* * * * * * * * * * * */
/* This section contains the routes proxied through */
/* your local development environment and the Vantage deployment */
/* * * * * * * * * * * */

const PROXY_CONFIG = {
...vantageLoginProxyConfig({ serverUrl, localUrl, localProto }),
'/api': {
target: serverUrl,
secure: false,
changeOrigin: true,
},
};

module.exports = PROXY_CONFIG;
16 changes: 16 additions & 0 deletions src/lib/schematics/ng-add/files/src/app/app.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Routes, RouterModule } from '@angular/router';

import { VantageAuthenticationGuard } from '@td-vantage/ui-platform/auth';

const routes: Routes = [
{
path: '',
canActivate: [VantageAuthenticationGuard],
children: [],
},
{ path: '**', redirectTo: '/' },
];

export const appRoutingProviders: any[] = [VantageAuthenticationGuard];

export const appRoutes: any = RouterModule.forRoot(routes);
84 changes: 84 additions & 0 deletions src/lib/schematics/ng-add/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { getFileContent } from '@schematics/angular/utility/test';
import { Tree } from '@angular-devkit/schematics';
import { uiPlatformVersion } from '../version-names';
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema';
import { Schema as ApplicationOptions } from '@schematics/angular/application/schema';

const collectionPath: string = require.resolve('../collection.json');

describe('ng-add schematic', () => {
const testRunner: SchematicTestRunner = new SchematicTestRunner('rocket', collectionPath);

const workspaceOptions: WorkspaceOptions = {
name: 'workspace',
newProjectRoot: 'projects',
version: '1.0.0',
};

const appOptions: ApplicationOptions = {
name: 'ui-platform-workspace',
};

let appTree: UnitTestTree;

beforeEach(async () => {
const workspaceTree: UnitTestTree = await testRunner
.runExternalSchematicAsync('@schematics/angular', 'workspace', workspaceOptions)
.toPromise();
appTree = await testRunner
.runExternalSchematicAsync('@schematics/angular', 'application', appOptions, workspaceTree)
.toPromise();
});

it('should update package.json', async () => {
const tree: Tree = await testRunner.runSchematicAsync('ng-add', undefined, appTree).toPromise();
const packageJson: any = JSON.parse(getFileContent(tree, '/package.json'));
const dependencies: any = packageJson.dependencies;

const expectedUIPlatformVersion: string = `${uiPlatformVersion}`;

expectVersionToBe(dependencies, '@td-vantage/ui-platform', expectedUIPlatformVersion);
});

it('should create proxy.conf.js when sso option is selected by user', async () => {
const dependencyOptions: any = { ssoServerURL: 'https://vantage.url.io' };
const tree: Tree = await testRunner.runSchematicAsync('ng-add', dependencyOptions, appTree).toPromise();
expect(tree.exists('proxy.conf.js')).toBe(true);
const fileContent: string = getFileContent(tree, 'proxy.conf.js');
expect(fileContent).toContain('https://vantage.url.io');
});

it('should import Vantage Auth modules to app.module.ts when sso option is selected by user', async () => {
const dependencyOptions: any = { ssoServerURL: 'https://vantage.url.io' };
const tree: Tree = await testRunner.runSchematicAsync('ng-add', dependencyOptions, appTree).toPromise();
const fileContent: string = getFileContent(tree, 'projects/ui-platform-workspace/src/app/app.module.ts');
expect(fileContent).toContain('VantageAuthenticationModule');
expect(fileContent).toContain('VantageAuthenticationInterceptor');
expect(fileContent).toContain('VantageUserModule');
expect(fileContent).toContain('CovalentHttpModule');
});

it('should create app.routes.ts when sso option is selected by user', async () => {
const dependencyOptions: any = { ssoServerURL: 'https://vantage.url.io' };
const tree: Tree = await testRunner.runSchematicAsync('ng-add', dependencyOptions, appTree).toPromise();
expect(tree.exists('src/app/app.routes.ts')).toBe(true);
const fileContent: string = getFileContent(tree, 'src/app/app.routes.ts');
expect(fileContent).toContain('VantageAuthenticationGuard');
});

it('should import route provider to app.module.ts when sso option is selected by user', async () => {
const dependencyOptions: any = { ssoServerURL: 'https://vantage.url.io' };
const tree: Tree = await testRunner.runSchematicAsync('ng-add', dependencyOptions, appTree).toPromise();
const fileContent: string = getFileContent(tree, 'projects/ui-platform-workspace/src/app/app.module.ts');
expect(fileContent).toContain('appRoutes');
expect(fileContent).toContain('appRoutingProviders');
});

function expectVersionToBe(dependencies: any, name: string, expectedVersion: string): void {
expect(dependencies[name]).toBe(
expectedVersion,
'Expected ' + name + ' package to have ' + `${expectedVersion}` + ' version.',
);
}
});
122 changes: 122 additions & 0 deletions src/lib/schematics/ng-add/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@

import {
Rule,
chain,
Tree,
mergeWith,
url,
apply,
branchAndMerge,
template,
UpdateRecorder,
FileEntry,
SchematicContext,
} from '@angular-devkit/schematics';
import { addPackageToPackageJson } from '@angular/material/schematics/ng-add/package-config';
import { uiPlatformVersion } from '../version-names';
import { ISchema } from './schema';
import { strings } from '@angular-devkit/core';

import { getProjectFromWorkspace, addModuleImportToRootModule } from '@angular/cdk/schematics';
import { addProviderToModule } from '@schematics/angular/utility/ast-utils';
import { InsertChange } from '@schematics/angular/utility/change';
import { getAppModulePath } from '@schematics/angular/utility/ng-ast-utils';
import { getWorkspace } from '@schematics/angular/utility/config';
import { experimental } from '@angular-devkit/core';

import { getSourceFile, getProjectMainFile, getProjectStyleFile } from '@angular/cdk/schematics/utils';

import { SourceFile } from 'typescript';
import { Change } from '@schematics/angular/utility/change';

export function addDependenciesAndFiles(options: ISchema): Rule {
const addVantagePacakgeRule: Rule = (host: Tree) => {
addPackageToPackageJson(host, '@td-vantage/ui-platform', `${uiPlatformVersion}`);
};

const ruleSet: Rule[] = [addVantagePacakgeRule];

if (options.ssoServerURL && options.ssoServerURL.trim().length) {
// enable SSO
ruleSet.push(mergeFiles(options));
ruleSet.push(addSSOImports);
ruleSet.push(updateStyles);
}
return chain(ruleSet);
}

function mergeFiles(options: ISchema): Rule {
const templateSource: any = apply(url('./files'), [
template({
...strings,
...options,
}),
]);
return branchAndMerge(mergeWith(templateSource));
}

function updateStyles(): Rule {
return (host: Tree, context: SchematicContext) => {
const workspace: experimental.workspace.WorkspaceSchema = getWorkspace(host);
const project: experimental.workspace.WorkspaceProject = getProjectFromWorkspace(workspace);
const styleFilePath: string = getProjectStyleFile(project);
const file: Buffer = host.read(styleFilePath);
const themeFile: FileEntry = host.get('theme.scss');
const fileContent: string = file.toString();
const content: string = themeFile && themeFile.content.toString();

if (content) {
host.overwrite(styleFilePath, fileContent + '\n' + content);
host.delete('theme.scss');
}

return host;
};
}

function addSSOImports(): Rule {
return (host: Tree) => {
const workspace: experimental.workspace.WorkspaceSchema = getWorkspace(host);
const project: experimental.workspace.WorkspaceProject = getProjectFromWorkspace(workspace);
const replacementString: string = `CovalentHttpModule.forRoot({
interceptors: [{
interceptor: VantageAuthenticationInterceptor, paths: ['**'],
}],
})`;

addModuleImportToRootModule(host, 'VantageAuthenticationModule', '@td-vantage/ui-platform/auth', project);
addModuleImportToRootModule(host, 'VantageUserModule', '@td-vantage/ui-platform/user', project);
addModuleImportToRootModule(host, `CovalentHttpModule.forRoot()`, '@covalent/http', project);
replaceContentInAppModule(host, `CovalentHttpModule.forRoot()`, replacementString);
addModuleImportToRootModule(host, 'appRoutes', './app.routes', project);
addProvider(host, `VantageAuthenticationInterceptor`, '@td-vantage/ui-platform/auth');
addProvider(host, `appRoutingProviders`, './app.routes');
};
}

function addProvider(host: Tree, classifiedName: string, importPath: string): void {
const workspace: experimental.workspace.WorkspaceSchema = getWorkspace(host);
const project: experimental.workspace.WorkspaceProject = getProjectFromWorkspace(workspace);
const modulePath: string = getAppModulePath(host, getProjectMainFile(project));
const moduleSource: SourceFile = getSourceFile(host, modulePath);
const changes: Change[] = addProviderToModule(moduleSource, modulePath, classifiedName, importPath);
applyChanges(host, modulePath, changes);
}

function applyChanges(tree: Tree, path: string, changes: Change[]): void {
const recorder: UpdateRecorder = tree.beginUpdate(path);
for (const change of changes) {
if (change instanceof InsertChange) {
recorder.insertLeft(change.pos, change.toAdd);
}
}
tree.commitUpdate(recorder);
}

function replaceContentInAppModule(host: Tree, match: string, replacement: string): void {
const workspace: experimental.workspace.WorkspaceSchema = getWorkspace(host);
const project: experimental.workspace.WorkspaceProject = getProjectFromWorkspace(workspace);
const modulePath: string = getAppModulePath(host, getProjectMainFile(project));
const content: string = host.get(modulePath).content.toString();
host.overwrite(modulePath, content.replace(match, replacement));
}
14 changes: 14 additions & 0 deletions src/lib/schematics/ng-add/schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "http://json-schema.org/schema",
"id": "vantage-ui-platform-ng-add",
"title": "Vantage UI Platform ng-add schematic",
"type": "object",
"properties": {
"ssoServerURL": {
"type": "string",
"description": "Add SSO if user provides SSO server URL",
"x-prompt": "Add SSO server url to setup SSO or press enter to skip"
}
},
"required": []
}
4 changes: 4 additions & 0 deletions src/lib/schematics/ng-add/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ISchema {
/** Whether SSO should be set up. */
ssoServerURL: string;
}
23 changes: 23 additions & 0 deletions src/lib/schematics/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"compileOnSave": false,
"compilerOptions": {
"rootDir": "./",
"baseUrl": "./",
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"outDir": "../../../../deploy/ui-platform/schematics",
"lib": ["es2017", "dom"],
"moduleResolution": "node",
"sourceMap": true,
"target": "es5",
"typeRoots": ["./../../../../node_modules/@types"],
"noUnusedParameters": false,
"noUnusedLocals": false,
"allowUnreachableCode": false,
"pretty": true,
"importHelpers": true
},
"include": ["**/*"],
"exclude": ["**/*.spec.ts", "**/files/**/*"]
}
12 changes: 12 additions & 0 deletions src/lib/schematics/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"baseUrl": ".",
"outDir": "./",
"lib": ["es6", "dom"],
"module": "commonjs",
"types": ["jasmine", "hammerjs", "node"]
},
"include": ["**/*", "**/*.spec.ts"],
"exclude": ["*/files/**/*", "*/files/**/**/*"]
}
1 change: 1 addition & 0 deletions src/lib/schematics/version-names.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const uiPlatformVersion: string = '1.0.0-beta.0';
Loading