@dlr-eoc/core-ui
Version:
This project includes schematics to add the base UKIS-Layout to an angular application. The Layout is based on Clarity so [add this first](https://clarity.design/get-started/developing/angular)!
421 lines • 18.9 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ngAdd = ngAdd;
const schematics_1 = require("@angular-devkit/schematics");
const core_1 = require("@angular-devkit/core");
const workspace_utils_1 = require("../workspace-utils");
const ast_utils_1 = require("../ast-utils");
const json_utils_1 = require("../json-utils");
const html_utils_1 = require("../html-utils");
const workspace_1 = require("@schematics/angular/utility/workspace");
/**
* You should add @dlr-eoc/core-ui only to an angular application not a library!
*/
function isProjectTypeApplication(projectName) {
return (tree) => __awaiter(this, void 0, void 0, function* () {
const workspace = yield (0, workspace_1.getWorkspace)(tree);
(0, workspace_utils_1.checkProjectIsApplication)(workspace, projectName);
});
}
// https://angular.io/guide/schematics-for-libraries
// https://dev.to/thisdotmedia/schematics-pt-3-add-tailwind-css-to-your-angular-project-40pp
function ngAdd(options) {
/* return async host => {
}; */
const addRoutingOptions = {
project: options.project,
addFiles: options.addFiles,
updateFiles: options.updateFiles
};
const rules = [
/**
* externalSchematic not working with @angular-devkit ^8.3.20 (from 9.0.0 ???)
* https://github.com/angular/angular-cli/issues/17085
* maybe add @angular/clr to dependencies not peer..
*
* https://github.com/angular/angular-cli/issues/15250
* https://medium.com/@coco.boudard/hello-1ab084f63a1
* https://github.com/BottleRocketStudios/ng-momentum/issues/10
*/
(options.addClr === false) ? (0, schematics_1.noop)() : (0, schematics_1.externalSchematic)('@clr/angular', 'ng-add', options),
isProjectTypeApplication(options === null || options === void 0 ? void 0 : options.project),
(options.addFiles === false) ? (0, schematics_1.noop)() : ruleAddFiles(options),
(options.updateFiles === false) ? (0, schematics_1.noop)() : ruleAddImportsInAppModule(options.project),
(options.updateFiles === false) ? (0, schematics_1.noop)() : ruleUpdateAngularJson(options),
(options.updateFiles === false) ? (0, schematics_1.noop)() : ruleUpdateTsConfigFile(),
(options.updateFiles === false) ? (0, schematics_1.noop)() : ruleUpdateIndexHtml(options),
(options.routing === false) ? (0, schematics_1.noop)() : (0, schematics_1.schematic)('add-routing', addRoutingOptions),
(options.routing === true) ? removeViewsAfterRouting(options.project) : (0, schematics_1.noop)()
];
return (0, schematics_1.chain)(rules);
}
/**
*
*/
function removeViewsFiles(optionsProject) {
return (tree, context) => __awaiter(this, void 0, void 0, function* () {
// check if /views/example-view is existing from ng-add
const workspace = yield (0, workspace_1.getWorkspace)(tree);
const projectName = (0, workspace_utils_1.getProjectName)(workspace, optionsProject);
if (projectName) {
const project = workspace.projects.get(projectName);
if (project && (0, workspace_utils_1.checkProjectSourceRoot)(project, context)) {
const sourcePath = (0, core_1.join)(tree.root.path, (0, core_1.normalize)(project.root), project.sourceRoot); // project.sourceRoot
const appPath = (0, core_1.join)(sourcePath, 'app');
const viewsPath = (0, core_1.join)(appPath, 'views/example-view/');
/**
* loop over the tree and then use tree.delete
* check that the path is correct src/.. or /src/...
*/
tree.visit(file => {
if (file.startsWith(viewsPath)) {
tree.delete(file);
}
});
}
}
});
}
/**
* remove import { ExampleViewComponent } from './views/example-view/example-view.component';
*/
function removeViewsImports(optionsProject) {
const rules = [];
const imports = [
{ classifiedName: 'ExampleViewComponent', path: './views/example-view/example-view.component', declare: true }
];
imports.map(item => {
rules.push((0, ast_utils_1.removeServiceComponentModule)(optionsProject, item));
});
// then chain the rules to one
return (0, schematics_1.chain)(rules);
}
/**
* remove import and files for views/example-view;
*
* TODO: warnings
* In your workspace is no style extension defined use default scss
*/
function removeViewsAfterRouting(optionsProject) {
return (0, schematics_1.chain)([
removeViewsFiles(optionsProject),
removeViewsImports(optionsProject)
]);
}
/**
* add files from template folder
* - src
* - assets
* - styles
* - app
*/
function ruleAddFiles(options) {
/**
* app.component.html
* add default template from files
* <clr-main-container>
* ...
* </clr-main-container>
*
* TODO: check for style files and replace them e.g. app.component.styl ...
*/
return (tree, context) => __awaiter(this, void 0, void 0, function* () {
const workspace = yield (0, workspace_1.getWorkspace)(tree);
const projectName = (0, workspace_utils_1.getProjectName)(workspace, options.project);
if (projectName) {
const project = workspace.projects.get(projectName);
if (project && (0, workspace_utils_1.checkProjectSourceRoot)(project, context)) {
const sourcePath = (0, core_1.join)((0, core_1.normalize)(project.root), project.sourceRoot); // project.sourceRoot
const assetsPath = (0, core_1.join)(sourcePath, 'assets');
const stylesPath = (0, core_1.join)(sourcePath, 'styles');
const appPath = (0, core_1.join)(sourcePath, 'app');
const styleExt = (0, workspace_utils_1.getStyleExt)(project, workspace, context);
const templateVariabels = Object.assign(options, {
appPrefix: project.prefix,
styleExt
});
const srcTemplateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files/src/'), [
(0, schematics_1.applyTemplates)(Object.assign({}, templateVariabels)),
(0, schematics_1.filter)((path) => {
const separator = /[\\|\/]/g;
const pathSeperators = path.match(separator);
if (pathSeperators && pathSeperators.length > 1) {
return false;
}
else {
const testFiles = ['favicon.ico', 'styles.css', 'styles.scss'];
/**
* check for existing files the are allowed to overwrite!
*/
const destPath = (0, core_1.join)(sourcePath, path);
if (tree.exists(destPath)) {
for (const f of testFiles) {
/** delete styles.css file it is replaced with scss */
if (f === 'styles.css') {
const styleExtTest = (0, core_1.join)(sourcePath, f);
if (tree.exists(styleExtTest)) {
tree.delete(styleExtTest);
}
}
if (destPath.includes(f)) {
tree.delete(destPath);
}
}
}
return true;
}
}),
// renameTemplateFiles(), // Remove every `.template` suffix from file names.
(0, schematics_1.move)((0, core_1.getSystemPath)(sourcePath)),
]);
const assetsTemplateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files/src/assets'), [
(0, schematics_1.applyTemplates)(Object.assign({}, templateVariabels)),
(0, schematics_1.move)((0, core_1.getSystemPath)(assetsPath)),
]);
const stylesTemplateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files/src/styles'), [
(0, schematics_1.applyTemplates)(Object.assign({}, templateVariabels)),
(0, schematics_1.move)((0, core_1.getSystemPath)(stylesPath)),
]);
const appTemplateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files/src/app'), [
(0, schematics_1.applyTemplates)(Object.assign({}, templateVariabels)),
(0, schematics_1.filter)((path) => {
const testFiles = ['app.component.html', 'app.component.ts', 'app.component.css', 'app.component.scss'];
/**
* check for existing files the are allowed to overwrite!
*/
const destPath = (0, core_1.join)(appPath, path);
if (tree.exists(destPath)) {
for (const f of testFiles) {
/** delete app.component.css file it is replaced with scss */
if (f === 'app.component.css') {
const styleExtTest = (0, core_1.join)(appPath, f);
if (tree.exists(styleExtTest)) {
tree.delete(styleExtTest);
}
}
if (destPath.includes(f)) {
tree.delete(destPath);
}
}
}
return true;
}),
(0, schematics_1.move)((0, core_1.getSystemPath)(appPath)),
]);
return (0, schematics_1.chain)([
(0, schematics_1.mergeWith)(srcTemplateSource),
(0, schematics_1.mergeWith)(appTemplateSource),
(0, schematics_1.mergeWith)(assetsTemplateSource),
(0, schematics_1.mergeWith)(stylesTemplateSource)
]);
}
}
});
}
/**
* app.module.ts add imports
* - core-ui components
* - HttpClientModule?
*/
function ruleAddImportsInAppModule(optionsProject) {
const rules = [];
const imports = [
// { classifiedName: 'HttpClientModule', path: '@angular/common/http', module: true },
{ classifiedName: 'HeaderComponent', path: './components/header/header.component', declare: true },
{ classifiedName: 'GlobalAlertComponent', path: './components/global-alert/global-alert.component', declare: true },
{ classifiedName: 'AlertService', path: './components/global-alert/alert.service', provide: true },
{ classifiedName: 'GlobalProgressComponent', path: './components/global-progress/global-progress.component', declare: true },
{ classifiedName: 'ProgressService', path: './components/global-progress/progress.service', provide: true },
{ classifiedName: 'ExampleViewComponent', path: './views/example-view/example-view.component', declare: true }
];
/**
* create a rule for each insertImport/addProviderToModule because addProviderToModule is not working multiple times in one Rule???
*/
imports.map(item => {
rules.push((0, ast_utils_1.addServiceComponentModule)(optionsProject, item));
});
// then chain the rules to one
return (0, schematics_1.chain)(rules);
}
/**
* angular.json
* add to
* - assets
* - styles
*/
function ruleUpdateAngularJson(options) {
return (0, schematics_1.chain)([
updateProjectStylesExtension(options),
updateWorkspaceAndProjectStyleExtension(options)
]);
}
function updateProjectStylesExtension(options) {
return (tree) => __awaiter(this, void 0, void 0, function* () {
const workspace = yield (0, workspace_1.getWorkspace)(tree);
const projectName = (0, workspace_utils_1.getProjectName)(workspace, options.project);
if (projectName) {
const project = workspace.projects.get(projectName);
if (project) {
project.targets.forEach((target, key) => {
var _a;
if (((_a = target === null || target === void 0 ? void 0 : target.options) === null || _a === void 0 ? void 0 : _a.styles) && Array.isArray(target.options.styles)) {
target.options.styles = replaceStyles(target.options.styles);
project.targets.set(key, target);
}
});
return (0, workspace_1.updateWorkspace)((workspace) => {
workspace.projects.set(projectName, project);
});
}
}
});
}
/**
* replace styles.css in array if it exists
*/
function replaceStyles(styles) {
return styles.map(i => {
if (i.includes('styles.css')) {
return i.replace('.css', '.scss');
}
else {
return i;
}
});
}
/**
* Update Workspace file extension for style files.
*/
function updateWorkspaceAndProjectStyleExtension(options) {
return (tree) => __awaiter(this, void 0, void 0, function* () {
const workspace = yield (0, workspace_1.getWorkspace)(tree);
const projectName = (0, workspace_utils_1.getProjectName)(workspace, options.project);
if (projectName) {
const project = workspace.projects.get(projectName);
if (project) {
if ((0, workspace_utils_1.hasSchematicsStyle)(project.extensions)) {
project.extensions.schematics['@schematics/angular:component'].style = 'scss';
}
else {
if (typeof project.extensions === 'object') {
project.extensions.schematics = {
'@schematics/angular:component': {
style: 'scss'
}
};
}
}
return (0, workspace_1.updateWorkspace)((workspace) => {
workspace.projects.set(projectName, project);
});
}
}
});
}
/**
* tsconfig.base.json add
*
* - compilerOptions.paths
*/
function ruleUpdateTsConfigFile() {
return (tree) => {
let path = 'tsconfig.json';
const pathBase = 'tsconfig.base.json';
if (tree.exists(pathBase)) {
path = pathBase;
}
else if (!tree.exists(pathBase) && !tree.exists(path)) {
throw new schematics_1.SchematicsException(`${path} or ${pathBase} is not in the workspace!`);
}
return (0, json_utils_1.updateJsonFile)(path, (json) => {
const tsconfigPaths = [
{ name: '@dlr-eoc/*', paths: ['./frontend-libraries/projects/*'] }
];
if (!json.compilerOptions) {
json.compilerOptions = {};
}
if (!json.compilerOptions.paths) {
json.compilerOptions.paths = {};
}
for (const p of tsconfigPaths) {
json.compilerOptions.paths[p.name] = p.paths;
}
// skipLibCheck for libraries like OpenLayers
if (!json.compilerOptions.skipLibCheck) {
json.compilerOptions.skipLibCheck = true;
}
return json;
});
};
}
/**
* index.html
* add to <head>
* meta:
* - title
* - short-title
* - description
* - version
* - theme-color
* - viewport?
* - http-equiv?
*
* link:
* - shortcut icon
* - manifest
*/
function ruleUpdateIndexHtml(options) {
return (tree, context) => __awaiter(this, void 0, void 0, function* () {
const workspace = yield (0, workspace_1.getWorkspace)(tree);
const projectName = (0, workspace_utils_1.getProjectName)(workspace, options.project);
if (projectName) {
const project = workspace.projects.get(projectName);
if (project && (0, workspace_utils_1.checkProjectSourceRoot)(project, context)) {
const sourcePath = (0, core_1.join)((0, core_1.normalize)(project.root), project.sourceRoot, 'index.html'); // project.sourceRoot
let projectTitle = 'Your App';
if (options.project) {
projectTitle = options.project;
}
const headerTags = [
` <meta name="title" content="${projectTitle}">\n`,
` <meta name="short-title" content="This should be a shorter title like - ${projectTitle}">\n`,
` <meta name="description" content="This should be the description for - ${projectTitle}">\n`,
` <meta name="version" content="This should be the version of - ${projectTitle}">\n`,
` <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">\n`,
` <link rel="icon" type="image/x-icon" href="favicon.ico">\n`
];
return (0, schematics_1.chain)([
(0, html_utils_1.updateHtmlFile)(sourcePath, 'head', 'head', headerTags)
]);
}
}
});
}
// TODO: maybe update this files instead of replacing them
/**
* app.component.ts
* add imports for
* - icons
* - services
* - Router
* - variables for UI
* - constructor imports
* - init()
* - getHtmlMeta()
*
* maybe use template file??
*/
/**
* styles.scss //style.css
* if style.css remove and add file styles.scss from templates
*/
//# sourceMappingURL=index.js.map