diff --git a/.codeclimate.yml b/.codeclimate.yml index fd65fd830a..801ada6c4e 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -14,7 +14,7 @@ plugins: markdownlint: enabled: true scss-lint: - enabled: true + enabled: false exclude_patterns: - "config/" - "db/" diff --git a/.gitignore b/.gitignore index fc81bdc82b..7b4a05898b 100644 --- a/.gitignore +++ b/.gitignore @@ -52,7 +52,6 @@ environment.dev.ts #v1 *.iml docs/src -lib tools/test-backend/config/mock.config.json tools/.coverage-karma/ dev-certs/* @@ -95,8 +94,9 @@ src/jetstream/console-database.db src/jetstream/config.properties src/jetstream/db/dbconf.yml -# Customisations - +# Customisations - these can be removed in the future +# Left in for now to prevent these files being checked-in, if they are still present +# from a previous checkout src/frontend/packages/core/favicon.ico src/frontend/packages/core/sass/custom.scss src/frontend/packages/core/assets/eula.html @@ -109,6 +109,9 @@ src/frontend/packages/core/assets/custom src/frontend/packages/core/sass/custom src/frontend/packages/core/src/index.html +# Customisation - generated import module +src/frontend/packages/core/src/_custom-import.module.ts + # Prebuild package stratos-frontend-prebuild.zip diff --git a/angular.json b/angular.json index 75d6a32748..61b8218e2d 100644 --- a/angular.json +++ b/angular.json @@ -4,14 +4,17 @@ "newProjectRoot": "src/frontend/packages", "projects": { "stratos": { - "root": "", + "root": "src/frontend/packages", "sourceRoot": "src/frontend/packages", "projectType": "application", "architect": { "build": { - "builder": "@angular-devkit/build-angular:browser", + "builder": "@angular-builders/custom-webpack:browser", "options": { - "aot": true, + "customWebpackConfig": { + "path": "./dist/tools/build/main.js" + }, + "indexTransform": "./dist/tools/build/index.transform.js", "preserveSymlinks": true, "outputPath": "dist", "index": "src/frontend/packages/core/src/index.html", @@ -36,10 +39,6 @@ }, "configurations": { "production": { - "budgets": [{ - "type": "anyComponentStyle", - "maximumWarning": "6kb" - }], "optimization": true, "outputHashing": "all", "sourceMap": false, @@ -57,7 +56,7 @@ } }, "serve": { - "builder": "@angular-devkit/build-angular:dev-server", + "builder": "@angular-builders/custom-webpack:dev-server", "options": { "aot": true, "sslCert": "dev-ssl/server.crt", @@ -96,34 +95,22 @@ }, "core": { "root": "src/frontend/packages/core/", - "sourceRoot": "src/frontend/packages/core/src", - "projectType": "application", + "sourceRoot": "src/frontend/packages/core", + "projectType": "library", "prefix": "app", "schematics": {}, "architect": { "build": { - "builder": "@angular-devkit/build-angular:browser", + "builder": "@angular-devkit/build-ng-packagr:build", "options": { - "aot": true, "preserveSymlinks": true, "outputPath": "dist/core", "index": "src/frontend/packages/core/src/index.html", "main": "src/frontend/packages/core/src/main.ts", "polyfills": "src/frontend/packages/core/src/polyfills.ts", "tsConfig": "src/frontend/packages/core/tsconfig.app.json", - "assets": [ - "src/frontend/packages/core/favicon.ico", - "src/frontend/packages/core/assets", - { - "glob": "**/*", - "input": "custom-src/frontend/assets/custom", - "output": "/core/assets/custom" - } - ], - "styles": [ - "src/frontend/packages/core/src/styles.css", - "src/frontend/packages/cf-autoscaler/src/styles.css" - ], + "assets": [], + "styles": [], "scripts": [] }, "configurations": { @@ -148,23 +135,6 @@ } } }, - "serve": { - "builder": "@angular-devkit/build-angular:dev-server", - "options": { - "browserTarget": "core:build" - }, - "configurations": { - "production": { - "browserTarget": "core:build:production" - } - } - }, - "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n", - "options": { - "browserTarget": "core:build" - } - }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { @@ -253,6 +223,37 @@ } } }, + "shared": { + "root": "src/frontend/packages/shared", + "sourceRoot": "src/frontend/packages/shared/src", + "projectType": "library", + "prefix": "lib", + "architect": { + "build": { + "builder": "@angular-devkit/build-ng-packagr:build", + "options": { + "tsConfig": "src/frontend/packages/shared/tsconfig.lib.json", + "project": "src/frontend/packages/shared/ng-package.json" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/frontend/packages/shared/src/test.ts", + "tsConfig": "src/frontend/packages/shared/tsconfig.spec.json", + "karmaConfig": "src/frontend/packages/shared/karma.conf.js" + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": ["src/tsconfig.json"], + "tslintConfig": "src/frontend/packages/shared/tslint.json", + "files": ["src/frontend/packages/shared/src/**/*.ts"] + } + } + } + }, "cloud-foundry": { "root": "src/frontend/packages/cloud-foundry", "sourceRoot": "src/frontend/packages/cloud-foundry/src", @@ -349,8 +350,5 @@ "@schematics/angular:directive": { "prefix": "app" } - }, - "cli": { - "_defaultCollection": "@nrwl/angular" } } diff --git a/build/customize-build.js b/build/customize-build.js deleted file mode 100644 index fb98297c18..0000000000 --- a/build/customize-build.js +++ /dev/null @@ -1,316 +0,0 @@ -/** - * Gulp build file for applying cutomizations - */ - -/* eslint-disable angular/log,no-console,no-process-env,angular/json-functions,no-sync */ -(function () { - 'use strict'; - - var gulp = require('gulp'); - var path = require('path'); - var fs = require('fs-extra'); - var yaml = require('js-yaml'); - var replace = require('replace-in-file'); - var execSync = require('child_process').execSync; - - const CUSTOM_YAML_MANIFEST = path.resolve(__dirname, '../src/frontend/packages/core/misc/custom/custom.yaml'); - const INDEX_TEMPLATE = path.resolve(__dirname, '../src/frontend/packages/core/misc/custom/index.html'); - const INDEX_HTML = path.resolve(__dirname, '../src/frontend/packages/core/src/index.html'); - const CUSTOM_METADATA = path.resolve(__dirname, '../custom-src/stratos.yaml'); - const GIT_FOLDER = path.resolve(__dirname, '../.git'); - const GIT_METADATA = path.resolve(__dirname, '../.stratos-git-metadata.json'); - const INDEX_LOADING_HTML_CUSTOM = path.resolve(__dirname, '../custom-src/frontend/loading.html'); - const INDEX_LOADING_HTML_DEFAULT = path.resolve(__dirname, '../src/frontend/packages/core/misc/custom/loading.html'); - const INDEX_LOADING_CSS_CUSTOM = path.resolve(__dirname, '../custom-src/frontend/loading.css'); - const INDEX_LOADING_CSS_DEFAULT = path.resolve(__dirname, '../src/frontend/packages/core/misc/custom/loading.css'); - - // Apply any customizations - // Symlink customizations of the default resources for Stratos - gulp.task('customize', function (cb) { - doShowVersions() - doCustomize(false); - doGenerateIndexHtml(true); - console.log('Finished applying customizations') - cb(); - }); - - // Apply defaults instead of any customizations that are available in custom-src - gulp.task('customize-default', function (cb) { - doCustomize(true); - doGenerateIndexHtml(false); - console.log('Finished applying default customizations') - cb(); - }); - - // Remove all customizations (removes all symlinks as if customize had not been run) - gulp.task('customize-reset', function (cb) { - doCustomize(true, true); - doGenerateIndexHtml(false); - console.log('Finished resetting customizations') - cb(); - }); - - // Store git metadata so we have it when we are running the the non-git world (Docker) - gulp.task('store-git-metadata', function (cb) { - storeGitRepositoryMetadata(); - cb(); - }); - - function doShowVersions() { - console.log('Node Version: ' + process.versions.node || 'N/A'); - try { - var response = execSync('npm --v'); - var npmVersion = response.toString().trim(); - console.log('NPM Version : ' + npmVersion || 'N/A'); - } catch (e) { - console.log('NPM Version : N/A'); - } - } - - function doCustomize(forceDefaults, reset) { - var msg = !forceDefaults ? 'Checking for and applying customizations' : 'Removing customizations and applying defaults'; - var msg = !reset ? msg : 'Removing all customizations'; - console.log(msg); - var customConfig; - - try { - customConfig = yaml.safeLoad(fs.readFileSync(CUSTOM_YAML_MANIFEST, 'utf8')); - } catch (e) { - console.log('Could not read custom.yaml file'); - console.log(e); - process.exit(1); - } - - const baseFolder = path.resolve(__dirname, '../src/frontend/packages/core'); - const customBaseFolder = path.resolve(__dirname, '../custom-src/frontend'); - doCustomizeFiles(forceDefaults, reset, customConfig, baseFolder, customBaseFolder); - doCustomizeFolders(forceDefaults, reset, customConfig, baseFolder, customBaseFolder); - doCustomizeCreateModule(forceDefaults, reset, customConfig, baseFolder, customBaseFolder); - - const backendBaseFolder = path.resolve(__dirname, '../src/jetstream/plugins'); - const backendCustomBaseFolder = path.resolve(__dirname, '../custom-src/jetstream'); - - // There are no defaults for the backend - its the same as removing all of the custom plugins that are there - doCustomizeBackend(forceDefaults || reset, backendBaseFolder, backendCustomBaseFolder); - }; - - function doCustomizeFiles(forceDefaults, reset, customConfig, baseFolder, customBaseFolder) { - // This is where we find the default files, if there are no customizations - const defaultSrcFolder = path.resolve(__dirname, '../src/frontend/packages/core/misc/custom'); - // Symlink custom files - Object.keys(customConfig.files).forEach(file => { - const dest = customConfig.files[file]; - - var srcFile = path.join(defaultSrcFolder, file); - const destFile = path.join(baseFolder, dest); - const customSrcFile = path.join(customBaseFolder, dest); - - // Use the custom file if there is one - if (!forceDefaults && fs.existsSync(customSrcFile)) { - srcFile = customSrcFile; - } - - // Doing an exists check on a symlink will tell if the link dest exists, not the link itself - // So try and delete anyway and catch any exception - try { - const existingLink = fs.readlinkSync(destFile); - fs.unlinkSync(destFile); - } catch (e) { } - - if (!reset) { - fs.symlinkSync(srcFile, destFile); - console.log(' + Linking file : ' + srcFile + ' ==> ' + destFile); - } - }) - - } - - function doCustomizeFolders(forceDefaults, reset, customConfig, baseFolder, customBaseFolder) { - // Symlink custom app folders if they are present - customConfig.folders.forEach(folder => { - var parts = folder.split(':') - var src = parts[0]; - var dest = src; - if (parts.length > 1) { - dest = parts[1]; - } - var destFolder = path.join(baseFolder, dest); - var srcFolder = path.join(customBaseFolder, src); - if (fs.existsSync(destFolder)) { - fs.unlinkSync(destFolder); - } - if (!reset && fs.existsSync(srcFolder)) { - fs.symlinkSync(srcFolder, destFolder); - console.log(' + Linking folder : ' + srcFolder + ' ==> ' + destFolder); - } - }); - } - - // Copy the correct custom module to either import the supplied custom module or provide an empty module - function doCustomizeCreateModule(forceDefaults, reset, customConfig, baseFolder, customBaseFolder) { - const defaultSrcFolder = path.resolve(__dirname, '../src/frontend/packages/core/misc/custom'); - const destFile = path.join(baseFolder, 'src/custom-import.module.ts'); - const customModuleFile = path.join(baseFolder, 'src/custom/custom.module.ts'); - const customRoutingModuleFile = path.join(baseFolder, 'src/custom/custom-routing.module.ts'); - - // Delete the existing file if it exists - if (fs.existsSync(destFile)) { - fs.unlinkSync(destFile) - } - - if (!reset) { - let srcFile = 'custom.module.ts_'; - if (fs.existsSync(customModuleFile)) { - srcFile = 'custom-src.module.ts_'; - if (fs.existsSync(customRoutingModuleFile)) { - srcFile = 'custom-src-routing.module.ts_'; - console.log(' + Found custom module with routing'); - } else { - console.log(' + Found custom module without routing'); - } - } else { - console.log(' + No custom module found - linking empty custom module'); - } - fs.copySync(path.join(defaultSrcFolder, srcFile), destFile); - console.log(' + Copying file : ' + path.join(defaultSrcFolder, srcFile) + ' ==> ' + destFile); - } - } - - function doCustomizeBackend(reset, baseFolder, customBaseFolder) { - // Symlink custom backend plugin folders if they are present - // Get all of the sub-folders in the custom-src/backend folder and symlink - - // Update the git metadata if we can - storeGitRepositoryMetadata(); - - // Remove all existing symlinks first - var existing = fs.readdirSync(baseFolder); - existing.forEach(file => { - var pluginPath = path.join(baseFolder, file); - var stats = fs.lstatSync(pluginPath); - if (stats.isSymbolicLink()) { - fs.unlinkSync(pluginPath); - } - }) - - if (reset) { - // If we are reseting then we are done, just return now - return; - } - - // Check if we have a customization folder - if (!fs.existsSync(customBaseFolder)) { - return; - } - - // Symlink any custom plugins - var plugins = fs.readdirSync(customBaseFolder); - plugins.forEach(file => { - var srcFolder = path.join(customBaseFolder, file); - var stats = fs.statSync(srcFolder); - var destFolder = path.join(baseFolder, file); - if (stats.isDirectory()) { - if (fs.existsSync(destFolder)) { - fs.unlinkSync(destFolder); - } - fs.symlinkSync(srcFolder, destFolder); - } - }) - } - - // Generate index.html from template - function doGenerateIndexHtml(customize) { - - console.log(' + Generating index.html'); - // Copy the default - fs.copySync(INDEX_TEMPLATE, INDEX_HTML); - - // Read custom metadata if we are customizing and the file is present - var metadata = {}; - if (customize && fs.existsSync(CUSTOM_METADATA)) { - try { - metadata = yaml.safeLoad(fs.readFileSync(CUSTOM_METADATA, 'utf8')); - } catch (e) { - console.log('Could not read stratos.yaml file'); - console.log(e); - process.exit(1); - } - } - - if (metadata.title) { - console.log(' + Overridding title to: "' + metadata.title + '"'); - } - - // Patch different page title if there is one - var title = metadata.title || 'Stratos'; - replace.sync({ files: INDEX_HTML, from: /@@TITLE@@/g, to: title }); - - // Read in the stored Git metadata if it is there, default to empty metadata - var gitMetadata = { - project: process.env.project || process.env.STRATOS_PROJECT || '', - branch: process.env.branch || process.env.STRATOS_BRANCH || '', - commit: process.env.commit || process.env.STRATOS_COMMIT || '' - }; - - if (fs.existsSync(GIT_METADATA)) { - gitMetadata = JSON.parse(fs.readFileSync(GIT_METADATA)); - console.log(' + Project Metadata file read OK'); - } else { - console.log(' + Project Metadata file does not exist'); - } - - console.log(" + Project Metadata: " + JSON.stringify(gitMetadata)); - - // Git Information - replace.sync({ files: INDEX_HTML, from: '@@stratos_git_project@@', to: gitMetadata.project }); - replace.sync({ files: INDEX_HTML, from: '@@stratos_git_branch@@', to: gitMetadata.branch }); - replace.sync({ files: INDEX_HTML, from: '@@stratos_git_commit@@', to: gitMetadata.commit }); - - // Date and Time that the build was made (approximately => it is when this script is run) - replace.sync({ files: INDEX_HTML, from: '@@stratos_build_date@@', to: new Date() }); - - // Replace loading indicator - HTML - let loadingHtmlFile = INDEX_LOADING_HTML_DEFAULT; - if (fs.existsSync(INDEX_LOADING_HTML_CUSTOM)) { - loadingHtmlFile = INDEX_LOADING_HTML_CUSTOM - } - const loadingHtml = fs.readFileSync(loadingHtmlFile, 'utf8'); - replace.sync({ files: INDEX_HTML, from: '', to: loadingHtml }); - - // Replace loading indicator - CSS - let loadingCssFile = INDEX_LOADING_CSS_DEFAULT; - if (fs.existsSync(INDEX_LOADING_CSS_CUSTOM)) { - loadingCssFile = INDEX_LOADING_CSS_CUSTOM - } - const loadingCss = fs.readFileSync(loadingCssFile, 'utf8'); - replace.sync({ files: INDEX_HTML, from: '/** @@LOADING_CSS@@ **/', to: loadingCss }); - } - - // We can only do this if we have a git repository checkout - // We'll store this in a file which we will then use - when in environments like Docker, we will run this - // in the host environment so that we can pick it up when we're running in the Docker world - function storeGitRepositoryMetadata() { - // Do we have a git folder? - if (!fs.existsSync(GIT_FOLDER)) { - console.log(' + Unable to store git repository metadata - .git folder not found'); - return; - } - var gitMetadata = { - project: execGit('git config --get remote.origin.url'), - branch: execGit('git rev-parse --abbrev-ref HEAD'), - commit: execGit('git rev-parse HEAD') - }; - - fs.writeFileSync(GIT_METADATA, JSON.stringify(gitMetadata, null, 2)); - } - - function execGit(cmd) { - try { - var response = execSync(cmd + ' 2> /dev/null'); - return response.toString().trim(); - } catch (e) { - return ''; - } - } - -})(); \ No newline at end of file diff --git a/build/fe-build.js b/build/fe-build.js index 0542f8942c..75946dd93c 100644 --- a/build/fe-build.js +++ b/build/fe-build.js @@ -17,9 +17,6 @@ var config = require('./gulp.config'); var paths = config.paths; - // Import customization tasks - require('./customize-build'); - // Clean dist dir gulp.task('clean', function (next) { del(paths.dist + '**/*', { diff --git a/build/tools/v4-migration/migrate.sh b/build/tools/v4-migration/migrate.sh new file mode 100755 index 0000000000..397162298f --- /dev/null +++ b/build/tools/v4-migration/migrate.sh @@ -0,0 +1,156 @@ +#!/usr/bin/env bash + +# Migrate custom theme and extensions into the new package structure + +set -e +set -o pipefail + +# Script folder +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" +STRATOS="`cd "${DIR}/../../..";pwd`" +CUSTOM="${STRATOS}/examples/custom-src" +TEMPLATES=${DIR}/templates + +STRATOS_YML=${STRATOS}/stratos.yaml +PKGS=${STRATOS}/src/frontend/packages + +echo $CUSTOM + +function migrateTitle() { + if [ -f "${CUSTOM}/stratos.yaml" ]; then + DATA=$(cat "${CUSTOM}/stratos.yaml") + + # Make sure we have a Stratos.yaml file + touch ${STRATOS_YML} + + TITLE=$(grep -o 'title: .*' ${CUSTOM}/stratos.yaml) + sed -i.bak -e '/^title:/d' ${STRATOS_YML} + echo -e "${TITLE}" >> ${STRATOS_YML} + fi +} + +function migrateTheme() { + echo "Looking for custom theme" + + # Custom theme if we have custom-src/frontend/sass/custom.scss + CUSTOM_THEME=${CUSTOM}/frontend/sass/custom.scss + if [ ! -f ${CUSTOM_THEME} ]; then + echo "No custom theme found" + return + fi + + echo "Custom theme found ... migrating" + + # Create a new package for the theme + THEME_DIR=${PKGS}/custom_theme + + rm -rf ${THEME_DIR} + mkdir ${THEME_DIR} + mkdir ${THEME_DIR}/sass + mkdir -p ${THEME_DIR}/assets/core + mkdir -p ${THEME_DIR}/assets/custom + mkdir -p ${THEME_DIR}/loader + + cp -R ${CUSTOM}/frontend/sass/* ${THEME_DIR}/sass + + cp ${TEMPLATES}/theme.package.json ${THEME_DIR}/package.json + cp ${TEMPLATES}/_index.scss ${THEME_DIR} + + cp ${CUSTOM}/frontend/loading.* ${THEME_DIR}/loader/ + + # Update the theme in the top-level stratos.yml + sed -i.bak -e 's/theme: .*/theme: \"@custom\/theme\"/g' ${STRATOS_YML} + + # Copy assets + cp -R ${CUSTOM}/frontend/assets/* ${THEME_DIR}/assets/core + # Favicon + cp -R ${CUSTOM}/frontend/favicon.ico ${THEME_DIR}/assets + + # Remove lines from package.josn that are not required + if [ ! -f "${THEME_DIR}/assets/favicon.ico" ]; then + sed -i.bak '/"favicon.ico"$/d' ${THEME_DIR}/package.json + fi + + # Loading screen + if [ ! -f "${THEME_DIR}/loader/loading.css" ]; then + sed -i.bak '/loading.css",$/d' ${THEME_DIR}/package.json + fi + + if [ ! -f "${THEME_DIR}/loader/loading.html" ]; then + sed -i.bak '/loading.html"$/d' ${THEME_DIR}/package.json + fi + + rm -rf ${THEME_DIR}/package.json.bak +} + +function migrateExtensions() { + echo "Looking for custom extensions" + + # Custom theme if we have custom-src/frontend/sass/custom.scss + CUSTOM_MODULE=${CUSTOM}/frontend/app/custom/custom.module.ts + if [ ! -f ${CUSTOM_MODULE} ]; then + echo "No custom extensions found" + return + fi + + echo "Custom extensions found ... migrating" + + # Create a new package for the extension(s) + EXT_DIR=${PKGS}/custom_extensions + + rm -rf ${EXT_DIR} + mkdir -p ${EXT_DIR}/src + cp ${TEMPLATES}/ext.package.json ${EXT_DIR}/package.json + + # Copy the source code into the src folder + cp -R ${CUSTOM}/frontend/app/custom/ ${EXT_DIR}/src + cp ${TEMPLATES}/public-api.ts_ ${EXT_DIR}/src/public-api.ts + + #IMPORT_LINE=$(awk '/imports:/{ print NR; exit }' ${CUSTOM_MODULE} + + sed -i '' "s/imports: \[/imports: \[ StratosComponentsModule,/" ${EXT_DIR}/src/custom.module.ts + + echo "import { StratosComponentsModule } from '@stratosui/shared';" | cat - ${EXT_DIR}/src/custom.module.ts > ${EXT_DIR}/temp.ts + mv -f ${EXT_DIR}/temp.ts ${EXT_DIR}/src/custom.module.ts + + if [ -f ${EXT_DIR}/src/custom-routing.module.ts ]; then + echo -e "\nexport * from './custom-routing.module';\n" >> ${EXT_DIR}/src/public-api.ts + + sed -i '' "s/_routingModule/routingModule/g" ${EXT_DIR}/package.json + fi + + # Need to update the import references as things will have moved + pushd ${EXT_DIR}/src + + # Not exhaustive, so extensions developers may need to manually fix imports + find . -name "*.ts" | xargs sed -i '' "s@'../../core@'../../../core/src/core@g" + find . -name "*.ts" | xargs sed -i '' "s@'../core/core.module@'../../core/src/core/core.module@g" + find . -name "*.ts" | xargs sed -i '' "s@'../core/customizations.types@'../../core/src/core/customizations.types@g" + find . -name "*.ts" | xargs sed -i '' 's@../core/md.module@../../core/src/core/md.module@g' + find . -name "*.ts" | xargs sed -i '' "s@'../shared/shared.module@'../../core/src/shared/shared.module@g" + find . -name "*.ts" | xargs sed -i '' "s@'../../../../store/src/app-state@'../../../store/src/app-state@g" + find . -name "*.ts" | xargs sed -i '' "s@'../../features/login/login-page/login-page.component@'../../../core/src/features/login/login-page/login-page.component@g" + + popd +} + +pushd "${STRATOS}" > /dev/null + +# Look for custom-src folder + + +if [ -d "${CUSTOM}" ]; then + echo "Found customizations to migrate" +else + echo "No custom src folder exists - nothing to migrate" + popd > /dev/null + exit 1 +fi + +migrateTitle +migrateTheme +#migrateExtensions + +popd > /dev/null + +cat $STRATOS_YML \ No newline at end of file diff --git a/build/tools/v4-migration/templates/_index.scss b/build/tools/v4-migration/templates/_index.scss new file mode 100644 index 0000000000..a8d3f300e1 --- /dev/null +++ b/build/tools/v4-migration/templates/_index.scss @@ -0,0 +1,9 @@ +@import '~@stratosui/theme/helper'; + +// Custom Theme +@import './sass/custom'; + +@function stratos-theme() { + $theme: stratos-theme-helper($stratos-theme); + @return $theme +} \ No newline at end of file diff --git a/build/tools/v4-migration/templates/ext.package.json b/build/tools/v4-migration/templates/ext.package.json new file mode 100644 index 0000000000..e22a84b356 --- /dev/null +++ b/build/tools/v4-migration/templates/ext.package.json @@ -0,0 +1,12 @@ +{ + "name": "@custom/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": "CustomModule", + "_routingModule": "CustomRoutingModule" + } +} \ No newline at end of file diff --git a/build/tools/v4-migration/templates/public-api.ts_ b/build/tools/v4-migration/templates/public-api.ts_ new file mode 100644 index 0000000000..b78971cc53 --- /dev/null +++ b/build/tools/v4-migration/templates/public-api.ts_ @@ -0,0 +1,3 @@ +// Custom Extensions + +export * from './custom.module'; \ No newline at end of file diff --git a/build/tools/v4-migration/templates/theme.package.json b/build/tools/v4-migration/templates/theme.package.json new file mode 100644 index 0000000000..a588ac2e99 --- /dev/null +++ b/build/tools/v4-migration/templates/theme.package.json @@ -0,0 +1,19 @@ +{ + "name": "@custom/theme", + "version": "0.0.1", + "stratos": { + "assets": { + "assets/core": "core/assets", + "assets/favicon.ico": "favicon.ico" + }, + "theme":{ + "loadingCss": "loader/loading.css", + "loadingHtml": "loader/loading.html" + } + }, + "peerDependencies": { + }, + "scripts": { + "build": "rm -rf ../../../../dist/theme && mkdir -p ../../../../dist/theme && cp -R * ../../../../dist/theme" + } +} diff --git a/deploy/cloud-foundry/build.sh b/deploy/cloud-foundry/build.sh index 0d3f2eb8d3..3d89979b33 100755 --- a/deploy/cloud-foundry/build.sh +++ b/deploy/cloud-foundry/build.sh @@ -39,7 +39,6 @@ else # Build front-end log "Fetching front-end dependencies" $CYAN npm install - npm run customize log "Building front-end" $CYAN npm run build-cf diff --git a/deploy/stratos-ui-release/packages/backend/pre_packaging b/deploy/stratos-ui-release/packages/backend/pre_packaging index 99faea2123..ba252553a7 100644 --- a/deploy/stratos-ui-release/packages/backend/pre_packaging +++ b/deploy/stratos-ui-release/packages/backend/pre_packaging @@ -10,7 +10,6 @@ curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh # Build backend npm install -npm run customize export PATH=$PATH:$PWD/node_modules/.bin npm run bosh-build-backend diff --git a/deploy/stratos-ui-release/packages/frontend/pre_packaging b/deploy/stratos-ui-release/packages/frontend/pre_packaging index c2c28d2215..440e323fa2 100644 --- a/deploy/stratos-ui-release/packages/frontend/pre_packaging +++ b/deploy/stratos-ui-release/packages/frontend/pre_packaging @@ -4,7 +4,6 @@ set -e -x cd ${BUILD_DIR}/stratos npm install -npm run customize export PATH=$PATH:$PWD/node_modules/.bin npm run build diff --git a/examples/custom-src/frontend/app/custom/custom.module.ts b/examples/custom-src/frontend/app/custom/custom.module.ts index 279ef8a0b3..c367087ce8 100644 --- a/examples/custom-src/frontend/app/custom/custom.module.ts +++ b/examples/custom-src/frontend/app/custom/custom.module.ts @@ -31,13 +31,6 @@ const AcmeCustomizations: CustomizationsMetadata = { AppTabExtensionComponent, AppActionExtensionComponent, AcmeSupportInfoComponent - ], - entryComponents: [ - AcmeLoginComponent, - // You must specify the tab and action as an entry components - AppTabExtensionComponent, - AppActionExtensionComponent, - AcmeSupportInfoComponent ] }) export class CustomModule { diff --git a/examples/custom-src/frontend/app/custom/nav-extension/nav-extension.module.ts b/examples/custom-src/frontend/app/custom/nav-extension/nav-extension.module.ts index 167fb93d96..e8c004a5bc 100644 --- a/examples/custom-src/frontend/app/custom/nav-extension/nav-extension.module.ts +++ b/examples/custom-src/frontend/app/custom/nav-extension/nav-extension.module.ts @@ -1,8 +1,9 @@ import { NgModule } from '@angular/core'; -import { NavExtensionRoutingModule } from './nav-extension.routing'; -import { ExampleComponent } from './example-component/example.component'; + import { CoreModule } from '../../core/core.module'; import { SharedModule } from '../../shared/shared.module'; +import { ExampleComponent } from './example-component/example.component'; +import { NavExtensionRoutingModule } from './nav-extension.routing'; @NgModule({ imports: [ @@ -12,9 +13,6 @@ import { SharedModule } from '../../shared/shared.module'; ], declarations: [ ExampleComponent - ], - entryComponents: [ - ExampleComponent ] }) export class NavExtensionModule {} diff --git a/package-lock.json b/package-lock.json index 200d6f47de..3c29d75c9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,20 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@angular-builders/custom-webpack": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@angular-builders/custom-webpack/-/custom-webpack-9.1.0.tgz", + "integrity": "sha512-Dek6KxNUFBELKqNRO4Im5JIP0/rZF4HmvgA8X+RyqOd9cyDxk16A441WlqTqy3UKX8lcbf6C9RcR5D2dI1ZATQ==", + "dev": true, + "requires": { + "@angular-devkit/architect": ">=0.900.0 < 0.1000.0", + "@angular-devkit/build-angular": ">=0.900.0 < 0.1000.0", + "@angular-devkit/core": "^9.0.0", + "lodash": "^4.17.10", + "ts-node": "^8.5.2", + "webpack-merge": "^4.2.1" + } + }, "@angular-devkit/architect": { "version": "0.901.7", "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.7.tgz", diff --git a/package.json b/package.json index 9e9e517679..030da548c9 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,12 @@ "build": "node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng build --prod", "build-cf": "node --max_old_space_size=1500 --gc_interval=100 node_modules/@angular/cli/bin/ng build --prod", "build-dev": "ng build --dev", - "prebuild-ui": "npm run customize && npm run build && gulp package-prebuild", + "prebuild-ui": "npm run build && gulp package-prebuild", "ng": "ng", - "start": "npm run customize && ng serve", - "start-high-mem": "npm run customize && node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng serve", - "start-dev-high-mem": "npm run customize && node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng serve --aot=false", - "start-prod-high-mem": "npm run customize && node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng serve --prod", + "start": "ng serve", + "start-high-mem": "node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng serve", + "start-dev-high-mem": "node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng serve --aot=false", + "start-prod-high-mem": "node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng serve --prod", "start-dev": "ng serve --aot=false", "test-clean": "./build/clean-test-reports.sh", "test-reports": "./build/show-test-reports.sh", @@ -37,11 +37,9 @@ "headless-e2e": "xvfb-run --server-args='-screen 0 1920x1080x24' protractor ./protractor.conf.js", "climate": "codeclimate analyze $(git diff --name-only master)", "gate-check": "npm run lint && npm run test-headless", - "customize": "gulp customize", - "customize-default": "gulp customize-default", - "customize-reset": "gulp customize-reset", "store-git-metadata": "gulp store-git-metadata", - "postinstall": "npm run customize && gulp dev-setup" + "postinstall": "gulp dev-setup && npm run build-tools", + "build-tools": "cd src/frontend/packages/tools && npm run build" }, "author": "", "license": "Apache-2.0", @@ -94,6 +92,7 @@ "node": "12.13.0" }, "devDependencies": { + "@angular-builders/custom-webpack": "^9.1.0", "@angular-devkit/build-angular": "~0.901.5", "@angular-devkit/build-ng-packagr": "~0.901.5", "@angular-devkit/schematics": "^9.1.5", @@ -109,6 +108,7 @@ "browserstack-local": "^1.4.5", "codecov": "^3.6.5", "codelyzer": "^5.1.2", + "copy-webpack-plugin": "5.1.1", "delete": "^1.1.0", "fs-extra": "^9.0.0", "globby": "^11.0.0", diff --git a/src/frontend/packages/cf-autoscaler/src/cf-autoscaler.module.ts b/src/frontend/packages/cf-autoscaler/src/cf-autoscaler.module.ts index e7463eee23..e470be161e 100644 --- a/src/frontend/packages/cf-autoscaler/src/cf-autoscaler.module.ts +++ b/src/frontend/packages/cf-autoscaler/src/cf-autoscaler.module.ts @@ -52,7 +52,6 @@ const customRoutes: Routes = [ ], declarations: [ AutoscalerTabExtensionComponent - ], - entryComponents: [AutoscalerTabExtensionComponent] + ] }) export class CfAutoscalerModule { } diff --git a/src/frontend/packages/cf-autoscaler/src/core/autoscaler.module.ts b/src/frontend/packages/cf-autoscaler/src/core/autoscaler.module.ts index 2faabe86af..cb76b829f2 100644 --- a/src/frontend/packages/cf-autoscaler/src/core/autoscaler.module.ts +++ b/src/frontend/packages/cf-autoscaler/src/core/autoscaler.module.ts @@ -83,13 +83,6 @@ import { AutoscalerRoutingModule } from './autoscaler.routing'; ], providers: [ ApplicationService - ], - entryComponents: [ - AppAutoscalerMetricChartCardComponent, - AppAutoscalerComboChartComponent, - AppAutoscalerComboSeriesVerticalComponent, - TableCellAutoscalerEventChangeComponent, - TableCellAutoscalerEventStatusComponent ] }) export class AutoscalerModule { } diff --git a/src/frontend/packages/cloud-foundry/package.json b/src/frontend/packages/cloud-foundry/package.json index 989436cb0d..844bc32e3a 100644 --- a/src/frontend/packages/cloud-foundry/package.json +++ b/src/frontend/packages/cloud-foundry/package.json @@ -4,5 +4,9 @@ "peerDependencies": { "@angular/common": "^6.0.0-rc.0 || ^6.0.0", "@angular/core": "^6.0.0-rc.0 || ^6.0.0" + }, + "stratos": { + "theming": "sass/_all-theme#apply-theme-stratos-cloud-foundry" } + } \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/sass/_all-theme.scss b/src/frontend/packages/cloud-foundry/sass/_all-theme.scss new file mode 100644 index 0000000000..fd92ae1354 --- /dev/null +++ b/src/frontend/packages/cloud-foundry/sass/_all-theme.scss @@ -0,0 +1,12 @@ +// Theming for the copmponents in the Cloud Foundry package + +@import '../src/features/applications/application-wall/application-wall.component.theme'; +@import '../src/shared/components/list/list-types/cf-security-groups/cf-security-groups-card/cf-security-groups-card.component.theme'; + +@mixin apply-theme-stratos-cloud-foundry($stratos-theme) { + + $theme: map-get($stratos-theme, theme); + $app-theme: map-get($stratos-theme, app-theme); + + @include cf-security-group-theme($theme); +} diff --git a/src/frontend/packages/cloud-foundry/src/public_api.ts b/src/frontend/packages/cloud-foundry/src/public_api.ts index eef53f2d79..dbe7a16cbd 100644 --- a/src/frontend/packages/cloud-foundry/src/public_api.ts +++ b/src/frontend/packages/cloud-foundry/src/public_api.ts @@ -5,3 +5,5 @@ // export * from './lib/cloud-foundry.service'; export * from './lib/cloud-foundry.component'; export * from './lib/cloud-foundry.module'; + +export * from './cf-api-svc.types'; \ No newline at end of file diff --git a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts index 7da0831fa8..aeef92fd78 100644 --- a/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/cf-shared.module.ts @@ -5,9 +5,6 @@ import { MaterialDesignFrameworkModule } from '@cfstratos/ajsf-material'; import { CoreModule } from '../../../core/src/core/core.module'; import { CardCell, TableCellCustom } from '../../../core/src/shared/components/list/list.types'; import { SharedModule } from '../../../core/src/shared/shared.module'; -import { - ApplicationInstanceChartComponent, -} from '../features/applications/application/application-instance-chart/application-instance-chart.component'; import { AddServiceInstanceBaseStepComponent, } from './components/add-service-instance/add-service-instance-base-step/add-service-instance-base-step.component'; @@ -23,6 +20,9 @@ import { import { SpecifyUserProvidedDetailsComponent, } from './components/add-service-instance/specify-user-provided-details/specify-user-provided-details.component'; +import { + ApplicationInstanceChartComponent, +} from './components/application-instance-chart/application-instance-chart.component'; import { CardAppInstancesComponent } from './components/cards/card-app-instances/card-app-instances.component'; import { CardAppStatusComponent } from './components/cards/card-app-status/card-app-status.component'; import { CardAppUptimeComponent } from './components/cards/card-app-uptime/card-app-uptime.component'; diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.html b/src/frontend/packages/cloud-foundry/src/shared/components/application-instance-chart/application-instance-chart.component.html similarity index 100% rename from src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.html rename to src/frontend/packages/cloud-foundry/src/shared/components/application-instance-chart/application-instance-chart.component.html diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.scss b/src/frontend/packages/cloud-foundry/src/shared/components/application-instance-chart/application-instance-chart.component.scss similarity index 100% rename from src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.scss rename to src/frontend/packages/cloud-foundry/src/shared/components/application-instance-chart/application-instance-chart.component.scss diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.spec.ts b/src/frontend/packages/cloud-foundry/src/shared/components/application-instance-chart/application-instance-chart.component.spec.ts similarity index 74% rename from src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.spec.ts rename to src/frontend/packages/cloud-foundry/src/shared/components/application-instance-chart/application-instance-chart.component.spec.ts index 07fb0f11ed..fc47c9f6b3 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.spec.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/application-instance-chart/application-instance-chart.component.spec.ts @@ -2,10 +2,10 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; -import { CoreModule } from '../../../../../../core/src/core/core.module'; -import { SharedModule } from '../../../../../../core/src/shared/shared.module'; -import { generateCfStoreModules } from '../../../../../test-framework/cloud-foundry-endpoint-service.helper'; -import { CloudFoundrySharedModule } from './../../../../shared/cf-shared.module'; +import { CoreModule } from '../../../../../core/src/core/core.module'; +import { SharedModule } from '../../../../../core/src/shared/shared.module'; +import { generateCfStoreModules } from '../../../../test-framework/cloud-foundry-endpoint-service.helper'; +import { CloudFoundrySharedModule } from '../../cf-shared.module'; import { ApplicationInstanceChartComponent } from './application-instance-chart.component'; describe('ApplicationInstanceChartComponent', () => { diff --git a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.ts b/src/frontend/packages/cloud-foundry/src/shared/components/application-instance-chart/application-instance-chart.component.ts similarity index 71% rename from src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.ts rename to src/frontend/packages/cloud-foundry/src/shared/components/application-instance-chart/application-instance-chart.component.ts index ae6d1e1eeb..3a54bec82d 100644 --- a/src/frontend/packages/cloud-foundry/src/features/applications/application/application-instance-chart/application-instance-chart.component.ts +++ b/src/frontend/packages/cloud-foundry/src/shared/components/application-instance-chart/application-instance-chart.component.ts @@ -1,12 +1,12 @@ import { Component, Input, OnInit } from '@angular/core'; -import { MetricsConfig } from '../../../../../../core/src/shared/components/metrics-chart/metrics-chart.component'; -import { MetricsLineChartConfig } from '../../../../../../core/src/shared/components/metrics-chart/metrics-chart.types'; -import { MetricsChartHelpers } from '../../../../../../core/src/shared/components/metrics-chart/metrics.component.helpers'; -import { MetricQueryConfig } from '../../../../../../store/src/actions/metrics.actions'; -import { IMetricMatrixResult } from '../../../../../../store/src/types/base-metric.types'; -import { IMetricApplication, MetricQueryType } from '../../../../../../store/src/types/metric.types'; -import { FetchApplicationMetricsAction } from '../../../../actions/cf-metrics.actions'; +import { MetricsConfig } from '../../../../../core/src/shared/components/metrics-chart/metrics-chart.component'; +import { MetricsLineChartConfig } from '../../../../../core/src/shared/components/metrics-chart/metrics-chart.types'; +import { MetricsChartHelpers } from '../../../../../core/src/shared/components/metrics-chart/metrics.component.helpers'; +import { MetricQueryConfig } from '../../../../../store/src/actions/metrics.actions'; +import { IMetricMatrixResult } from '../../../../../store/src/types/base-metric.types'; +import { IMetricApplication, MetricQueryType } from '../../../../../store/src/types/metric.types'; +import { FetchApplicationMetricsAction } from '../../../actions/cf-metrics.actions'; @Component({ selector: 'app-application-instance-chart', diff --git a/src/frontend/packages/core/misc/custom/custom-src-routing.module.ts_ b/src/frontend/packages/core/misc/custom/custom-src-routing.module.ts_ deleted file mode 100644 index a1f9fa4457..0000000000 --- a/src/frontend/packages/core/misc/custom/custom-src-routing.module.ts_ +++ /dev/null @@ -1,21 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CustomModule } from './custom/custom.module'; -import { CustomRoutingModule } from './custom/custom-routing.module'; - -// Default import customization module - DO NOT EDIT - -// This file is in the .gitignore - changes will not be flagged - -@NgModule({ - imports: [ - CustomModule, - ] -}) -export class CustomImportModule { } - -@NgModule({ - imports: [ - CustomRoutingModule, - ] -}) -export class CustomRoutingImportModule { } diff --git a/src/frontend/packages/core/misc/custom/custom-src.module.ts_ b/src/frontend/packages/core/misc/custom/custom-src.module.ts_ deleted file mode 100644 index 3e536cc582..0000000000 --- a/src/frontend/packages/core/misc/custom/custom-src.module.ts_ +++ /dev/null @@ -1,16 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CustomModule } from './custom/custom.module'; - -// Default import customization module - DO NOT EDIT - -// This file is in the .gitignore - changes will not be flagged - -@NgModule({ - imports: [ - CustomModule, - ] -}) -export class CustomImportModule { } - -@NgModule() -export class CustomRoutingImportModule { } diff --git a/src/frontend/packages/core/misc/custom/custom.scss b/src/frontend/packages/core/misc/custom/custom.scss deleted file mode 100644 index f6d83b743c..0000000000 --- a/src/frontend/packages/core/misc/custom/custom.scss +++ /dev/null @@ -1,5 +0,0 @@ -// Empty customization file - DO NOT EDIT - -// This file is in the .gitignore - changes will not be flagged - -// The customization build step will replace this file with the custom one if provided diff --git a/src/frontend/packages/core/misc/custom/custom.yaml b/src/frontend/packages/core/misc/custom/custom.yaml deleted file mode 100644 index db58c36ad7..0000000000 --- a/src/frontend/packages/core/misc/custom/custom.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# Customization manifest - -files: - custom.scss: "sass/custom.scss" - favicon.ico: "favicon.ico" - login-bg.jpg: "assets/login-bg.jpg" - logo.png: "assets/logo.png" - nav-logo.png: "assets/nav-logo.png" - eula.html: "assets/eula.html" - -folders: - - "app/custom:src/custom" - - "assets/custom" - - "sass/custom" diff --git a/src/frontend/packages/core/misc/custom/eula.html b/src/frontend/packages/core/misc/custom/eula.html deleted file mode 100644 index dfd92e3d98..0000000000 --- a/src/frontend/packages/core/misc/custom/eula.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/src/frontend/packages/core/ng-package.json b/src/frontend/packages/core/ng-package.json new file mode 100644 index 0000000000..9a348247b8 --- /dev/null +++ b/src/frontend/packages/core/ng-package.json @@ -0,0 +1,7 @@ +{ + "$schema": "../../../../node_modules/ng-packagr/ng-package.schema.json", + "dest": "../../../../dist/core", + "lib": { + "entryFile": "src/public-api.ts" + } +} \ No newline at end of file diff --git a/src/frontend/packages/core/package.json b/src/frontend/packages/core/package.json new file mode 100644 index 0000000000..63f4668511 --- /dev/null +++ b/src/frontend/packages/core/package.json @@ -0,0 +1,9 @@ +{ + "name": "@stratosui/core", + "version": "0.0.1", + "stratos": { + "assets": { + "assets": "core/assets" + } + } +} diff --git a/src/frontend/packages/core/sass/_all-theme.scss b/src/frontend/packages/core/sass/_all-theme.scss index 4f657dbc93..67ae92ae8b 100644 --- a/src/frontend/packages/core/sass/_all-theme.scss +++ b/src/frontend/packages/core/sass/_all-theme.scss @@ -48,7 +48,6 @@ @import '../src/shared/components/user-avatar/user-avatar.component.theme'; @import './components/text-status.theme'; @import './components/hyperlinks.theme'; -@import './mat-themes'; @import './mat-desktop'; @import './fonts'; @import './ansi-colors'; @@ -57,53 +56,28 @@ @import '../../cloud-foundry/src/shared/components/schema-form/schema-form.component.theme'; @import '../../cloud-foundry/src/features/services/services-wall/services-wall.component.theme'; -@import '../../cloud-foundry/src/shared/components/list/list-types/cf-security-groups/cf-security-groups-card/cf-security-groups-card.component.theme'; @import '../../cloud-foundry/src/features/cloud-foundry/tabs/cf-admin-add-user-warning/cf-admin-add-user-warning.component.theme'; @import '../../cloud-foundry/src/features/applications/application/application-base.component.theme'; @import '../../cloud-foundry/src/features/applications/deploy-application/deploy-application.component.theme'; @import '../../cloud-foundry/src/features/applications/deploy-application/deploy-application-step2/deploy-application-fs/deploy-application-fs.component.theme'; @import '../../cloud-foundry/src/features/cloud-foundry/tabs/cloud-foundry-firehose/cloud-foundry-firehose.component.theme'; @import '../../cloud-foundry/src/features/service-catalog/service-catalog-page/service-catalog-page.component.theme'; -@import '../../cloud-foundry/src/features/applications/application-wall/application-wall.component.theme'; @import '../../core/src/features/error-page/error-page/error-page.component.theme'; @import '../../core/src/features/endpoints/backup-restore/restore-endpoints/restore-endpoints.component.theme'; @import '../../core/src/features/metrics/metrics/metrics.component.theme'; - -// Defaults -$side-nav-light-text: #fff; -$side-nav-light-bg: #333; -$side-nav-light-hover: #555; -$side-nav-light-active: #484848; - // Creates the app theme and applies it to the application // $theme = Angular Material Theme // $nav-theme - Colors for the Side Nav (optional) // $status-theme - Colors for status (optional) -@mixin app-theme($theme, $nav-theme: null, $status-theme: null) { - $background-colors: map-get($theme, background); - $foreground-colors: map-get($theme, foreground); - $is-dark: map-get($theme, is-dark); - $app-background-color: white; - $app-background-text-color: rgba(mat-color($foreground-colors, base), .65); - $primary: map-get($theme, primary); - $accent: map-get($theme, accent); - $warn: map-get($theme, warn); - $subdued: mat-contrast($primary, 50); - - @if $is-dark == true { - $app-background-color: lighten(mat-color($background-colors, background), 10%); - $subdued: lighten($subdued, 90); - } @else { - $app-background-color: darken(mat-color($background-colors, background), 2%); - $subdued: lighten($subdued, 50); - } +@mixin app-theme($stratos-theme, $nav-theme: null, $status-theme: null) { + $theme: map-get($stratos-theme, theme); + $app-theme: map-get($stratos-theme, app-theme); + $app-background-color: map-get($app-theme, app-background-color); html { background-color: $app-background-color; } - // App Theme defines a set of colors used by stratos components - $app-theme: (app-background-color: $app-background-color, app-background-text-color: rgba(mat-color($foreground-colors, base), .65), side-nav: app-generate-nav-theme($theme, $nav-theme), status: app-generate-status-theme($theme, $status-theme), subdued-color: $subdued, ansi-colors: $ansi-color-palette); // Pass the Material theme and the App Theme to components that need to be themed @include dialog-error-theme($theme, $app-theme); @include login-page-theme($theme, $app-theme); @include side-nav-theme($theme, $app-theme); @@ -122,7 +96,6 @@ $side-nav-light-active: #484848; @include app-hyperlinks($theme, $app-theme); @include app-no-content-message-theme($theme, $app-theme); @include app-boolean-indicator-theme($theme, $app-theme); - @include cf-security-group-theme($theme); @include loading-page-theme($theme, $app-theme); @include app-log-viewer-theme($theme, $app-theme); @include app-deploy-app-theme($theme, $app-theme); @@ -164,23 +137,3 @@ $side-nav-light-active: #484848; @include restore-endpoints-theme($theme, $app-theme); @include metrics-component-theme($theme, $app-theme); } - -@function app-generate-nav-theme($theme, $nav-theme: null) { - @if ($nav-theme) { - @return $nav-theme; - } @else { - // Use default palette for side navigation - @return (background: $side-nav-light-bg, background-top: $side-nav-light-bg, text: darken($side-nav-light-text, 10%), active: $side-nav-light-active, active-text: $side-nav-light-text, hover: $side-nav-light-hover, hover-text: $side-nav-light-text); - } -} - -@function app-generate-status-theme($theme, $status-theme: null) { - @if ($status-theme) { - @return $status-theme; - } @else { - $warn: map-get($theme, warn); - $primary: map-get($theme, primary); - $white: #fff; // Use default palette for status - @return (success: map-get($mat-green, 500), warning: map-get($mat-orange, 500), danger: mat-color($warn), tentative: map-get($mat-grey, 500), busy: mat-color($primary), text: $white, ); - } -} diff --git a/src/frontend/packages/core/sass/colors.scss b/src/frontend/packages/core/sass/colors.scss deleted file mode 100644 index 75071fe6ba..0000000000 --- a/src/frontend/packages/core/sass/colors.scss +++ /dev/null @@ -1,7 +0,0 @@ -// @import './suse-theme'; -$dark-grey: rgb(95, 95, 95); -$middle-grey: rgb(167, 169, 172); -$light-grey: rgb(220, 221, 222); -// $blue: map-get($suse-blue, 500); - -// See here for palette info: https://github.com/angular/material2/blob/master/src/lib/core/theming/_palette.scss diff --git a/src/frontend/packages/core/sass/theme.scss b/src/frontend/packages/core/sass/theme.scss index 365cd4750e..11ba592a9f 100644 --- a/src/frontend/packages/core/sass/theme.scss +++ b/src/frontend/packages/core/sass/theme.scss @@ -1,45 +1,46 @@ @import '~@angular/material/theming'; -@import './mat-themes'; @import './all-theme'; -@import './mat-colors'; -// Custom theme support -@import './custom'; +// Import the theme +@import '~@stratosui/theme'; -body.stratos { - .dark-theme { - // Dark Theme defaults - $dark-primary: mat-palette($mat-blue); - $dark-accent: mat-palette($mat-amber, A400, A100, A700); - $dark-warn: mat-palette($mat-red); - $dark-theme: mat-dark-theme($dark-primary, $dark-accent, $dark-warn); +$stratos-dark-theme-supported: false !default; - $stratos-dark-theme: $dark-theme !default; - $stratos-dark-nav-theme: null !default; - $stratos-dark-status-theme: null !default; +// Themes - stratos-theme() function must be supplied by the theme +$stratos-themes: stratos-theme(); - @include angular-material-theme($stratos-dark-theme); - @include app-theme($stratos-dark-theme, $stratos-dark-nav-theme, $stratos-dark-status-theme); +// stratos-theme() can return a single theme rather than a map of default and dark themes +@if not map-has-key($stratos-themes, 'default') { + $tmp: $stratos-themes; + $stratos-themes: ( + default: $tmp + ) +} + +// Import any custom scss that the theme defines +@import '~@stratosui/theme/extensions'; + +// Default theme ( = light theme) +$stratos-theme: map-get($stratos-themes, default); +$theme: map-get($stratos-theme, theme); + +@if map-has-key($stratos-themes, 'dark') { + $stratos-dark-theme-supported: true; + $dark-stratos-theme: map-get($stratos-themes, dark); + $dark-theme: map-get($dark-stratos-theme, theme); + + body.stratos { + .dark-theme { + @include angular-material-theme($dark-theme); + @include app-theme($dark-stratos-theme); + } } } .default { - // Themes palettes and colors - $oss-theme-primary: mat-palette($mat-blue); - $oss-theme-accent: mat-palette($mat-blue); - $oss-theme-warn: mat-palette($mat-red); - $oss-theme: mat-light-theme($oss-theme-primary, $oss-theme-accent, $oss-theme-warn); - - // Default to using the open source theme - $stratos-theme: $oss-theme !default; - $stratos-nav-theme: null !default; - $stratos-status-theme: null !default; - - @include angular-material-theme($stratos-theme); - @include app-theme($stratos-theme, $stratos-nav-theme, $stratos-status-theme); + @include angular-material-theme($theme); + @include app-theme($stratos-theme); } -$stratos-dark-theme-supported: true !default; - -// Create the theme +// Import mat-core @include mat-core; diff --git a/src/frontend/packages/core/src/core/endpoints.service.spec.ts b/src/frontend/packages/core/src/core/endpoints.service.spec.ts index 006d10ccb7..3ac576abcd 100644 --- a/src/frontend/packages/core/src/core/endpoints.service.spec.ts +++ b/src/frontend/packages/core/src/core/endpoints.service.spec.ts @@ -1,8 +1,8 @@ import { inject, TestBed } from '@angular/core/testing'; - -import { CoreTestingModule } from '../../test-framework/core-test.modules'; import { createBasicStoreModule } from '@stratosui/store/testing'; + import { PaginationMonitorFactory } from '../../../store/src/monitors/pagination-monitor.factory'; +import { CoreTestingModule } from '../../test-framework/core-test.modules'; import { CoreModule } from './core.module'; import { EndpointsService } from './endpoints.service'; import { UtilsService } from './utils.service'; diff --git a/src/frontend/packages/core/src/core/logger.service.spec.ts b/src/frontend/packages/core/src/core/logger.service.spec.ts index e2f904e060..1720fe0b84 100644 --- a/src/frontend/packages/core/src/core/logger.service.spec.ts +++ b/src/frontend/packages/core/src/core/logger.service.spec.ts @@ -1,7 +1,7 @@ import { inject, TestBed } from '@angular/core/testing'; +import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../test-framework/core-test.modules'; -import { createBasicStoreModule } from '@stratosui/store/testing'; import { LoggerService } from './logger.service'; describe('LoggerService', () => { diff --git a/src/frontend/packages/core/src/core/user.service.spec.ts b/src/frontend/packages/core/src/core/user.service.spec.ts index 6fdaab8b3a..f831c61b18 100644 --- a/src/frontend/packages/core/src/core/user.service.spec.ts +++ b/src/frontend/packages/core/src/core/user.service.spec.ts @@ -1,7 +1,7 @@ import { inject, TestBed } from '@angular/core/testing'; +import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../test-framework/core-test.modules'; -import { createBasicStoreModule } from '@stratosui/store/testing'; import { SharedModule } from '../shared/shared.module'; import { CoreModule } from './core.module'; import { UserService } from './user.service'; diff --git a/src/frontend/packages/core/misc/custom/custom.module.ts_ b/src/frontend/packages/core/src/custom-import.module.ts similarity index 57% rename from src/frontend/packages/core/misc/custom/custom.module.ts_ rename to src/frontend/packages/core/src/custom-import.module.ts index b4118c293d..3d84d8fdec 100644 --- a/src/frontend/packages/core/misc/custom/custom.module.ts_ +++ b/src/frontend/packages/core/src/custom-import.module.ts @@ -2,7 +2,8 @@ import { NgModule } from '@angular/core'; // Default empty customization module - DO NOT EDIT -// This file is in the .gitignore - changes will not be flagged +// These modules will be intercepted by the custom webpack configuration +// They are only here so that on a fresh checkout, both modules are defined @NgModule() export class CustomImportModule { } diff --git a/src/frontend/packages/core/src/features/about/about.module.ts b/src/frontend/packages/core/src/features/about/about.module.ts index c71cd11f55..9fe18f06af 100644 --- a/src/frontend/packages/core/src/features/about/about.module.ts +++ b/src/frontend/packages/core/src/features/about/about.module.ts @@ -5,8 +5,7 @@ import { SharedModule } from '../../shared/shared.module'; import { AboutPageComponent } from './about-page/about-page.component'; import { AboutRoutingModule } from './about.routing'; import { DiagnosticsPageComponent } from './diagnostics-page/diagnostics-page.component'; -import { EulaPageComponent, EulaPageContentComponent } from './eula-page/eula-page.component'; - +import { EulaPageComponent } from './eula-page/eula-page.component'; @NgModule({ @@ -17,7 +16,6 @@ import { EulaPageComponent, EulaPageContentComponent } from './eula-page/eula-pa ], declarations: [ AboutPageComponent, - EulaPageContentComponent, EulaPageComponent, DiagnosticsPageComponent ] diff --git a/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.html b/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.html index 27791db6f3..3a40946d0b 100644 --- a/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.html +++ b/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.html @@ -8,4 +8,4 @@

EULA

- \ No newline at end of file +
diff --git a/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.spec.ts b/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.spec.ts index 20023d114b..113aac37d3 100644 --- a/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.spec.ts +++ b/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.spec.ts @@ -1,3 +1,5 @@ +import { HttpClientModule } from '@angular/common/http'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { createBasicStoreModule } from '@stratosui/store/testing'; @@ -5,7 +7,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { TabNavService } from '../../../../tab-nav.service'; import { CoreModule } from '../../../core/core.module'; import { SharedModule } from '../../../shared/shared.module'; -import { EulaPageComponent, EulaPageContentComponent } from './eula-page.component'; +import { EulaPageComponent } from './eula-page.component'; describe('EulaPageComponent', () => { let component: EulaPageComponent; @@ -13,11 +15,13 @@ describe('EulaPageComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [EulaPageComponent, EulaPageContentComponent], + declarations: [EulaPageComponent], imports: [ CoreModule, RouterTestingModule, SharedModule, + HttpClientModule, + HttpClientTestingModule, createBasicStoreModule(), ], providers: [TabNavService] diff --git a/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.ts b/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.ts index 8271e24c66..a93e345bf3 100644 --- a/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.ts +++ b/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.ts @@ -1,17 +1,12 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-eula-content', - templateUrl: '../../../../assets/eula.html' -}) -export class EulaPageContentComponent { } +import { Component } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-eula-page', templateUrl: './eula-page.component.html', styleUrls: ['./eula-page.component.scss'] }) -export class EulaPageComponent implements OnInit { +export class EulaPageComponent { public breadcrumbs = [ { @@ -19,10 +14,14 @@ export class EulaPageComponent implements OnInit { } ]; - constructor() { } - - ngOnInit() { + public eulaHtml = ''; + // Load the EULA + constructor(http: HttpClient) { + http.get('/core/assets/eula.html', {responseType: 'text'}).subscribe( + html => this.eulaHtml = html, + () => this.eulaHtml = 'An error occurred retrieving the EULA' + ); } } diff --git a/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.scss b/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.scss index d212cac3c2..26a2d129ce 100644 --- a/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.scss +++ b/src/frontend/packages/core/src/features/dashboard/dashboard-base/dashboard-base.component.scss @@ -1,4 +1,3 @@ -@import '../../../../sass/colors'; @import '../../../../sass/mixins'; $app-sub-header-height: 48px; diff --git a/src/frontend/packages/core/misc/custom/index.html b/src/frontend/packages/core/src/index.html similarity index 95% rename from src/frontend/packages/core/misc/custom/index.html rename to src/frontend/packages/core/src/index.html index b6c415d27c..5756ba3e60 100644 --- a/src/frontend/packages/core/misc/custom/index.html +++ b/src/frontend/packages/core/src/index.html @@ -11,7 +11,7 @@ - +