From 81856fa5dd980b1e41a786aac55771770bbf6f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez=20Garc=C3=ADa?= Date: Thu, 20 Jun 2024 04:24:03 +0200 Subject: [PATCH] upgraded user interface (Angular 18) --- angular.json | 14 +++---- package.json | 50 ++++++++++++------------ src/app/app.module.ts | 18 +++------ src/app/gui/navbar/navbar.component.scss | 2 +- src/globals.scss | 14 +++---- src/styles.scss | 2 +- toUDS.py | 50 +++++++++++++----------- tsconfig.json | 2 +- 8 files changed, 74 insertions(+), 78 deletions(-) diff --git a/angular.json b/angular.json index edf274b..c4d8904 100644 --- a/angular.json +++ b/angular.json @@ -12,11 +12,12 @@ "projectType": "application", "architect": { "build": { - "builder": "@angular-devkit/build-angular:browser", + "builder": "@angular-devkit/build-angular:application", "options": { - "outputPath": "dist", + "outputPath": { + "base": "dist" + }, "index": "src/index.html", - "main": "src/main.ts", "tsConfig": "src/tsconfig.app.json", "polyfills": ["zone.js"], "assets": [ @@ -30,12 +31,11 @@ "scripts": [ "node_modules/cookieconsent/build/cookieconsent.min.js" ], - "vendorChunk": true, "extractLicenses": false, - "buildOptimizer": false, "sourceMap": true, "optimization": false, - "namedChunks": true + "namedChunks": true, + "browser": "src/main.ts" }, "configurations": { "production": { @@ -50,8 +50,6 @@ "sourceMap": false, "namedChunks": false, "extractLicenses": true, - "vendorChunk": false, - "buildOptimizer": true, "fileReplacements": [ { "replace": "src/environments/environment.ts", diff --git a/package.json b/package.json index a821175..273ae6b 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "ng": "ng", "start": "ng serve --host 0.0.0.0 --port 9000 --proxy-config proxy.conf.json", - "build": "ng build --configuration production --output-hashing=none --aot --delete-output-path --build-optimizer --deploy-url /uds/res/modern/ --base-href /uds/page", + "build": "ng build --configuration production --output-hashing=none --aot --delete-output-path --deploy-url /uds/res/modern/ --base-href /uds/page", "postbuild": "python3 toUDS.py", "test": "ng test", "lint": "ng lint", @@ -17,16 +17,16 @@ }, "private": true, "dependencies": { - "@angular/animations": "^17.2.2", - "@angular/cdk": "^17.2.1", - "@angular/common": "^17.2.2", - "@angular/compiler": "^17.2.2", - "@angular/core": "^17.2.2", - "@angular/forms": "^17.2.2", - "@angular/material": "^17.2.1", - "@angular/platform-browser": "^17.2.2", - "@angular/platform-browser-dynamic": "^17.2.2", - "@angular/router": "^17.2.2", + "@angular/animations": "^18.0.3", + "@angular/cdk": "^18.0.3", + "@angular/common": "^18.0.3", + "@angular/compiler": "^18.0.3", + "@angular/core": "^18.0.3", + "@angular/forms": "^18.0.3", + "@angular/material": "^18.0.3", + "@angular/platform-browser": "^18.0.3", + "@angular/platform-browser-dynamic": "^18.0.3", + "@angular/router": "^18.0.3", "cookieconsent": "^3.1.1", "core-js": "^3.21.1", "rxjs": "^7.5.4", @@ -34,26 +34,26 @@ "zone.js": "^0.14.3" }, "devDependencies": { - "@angular-devkit/build-angular": "^17.2.1", + "@angular-devkit/build-angular": "^18.0.4", "@angular-devkit/core": "^18.0.4", "@angular-devkit/schematics": "^18.0.4", - "@angular-eslint/builder": "^17.2.1", - "@angular-eslint/eslint-plugin": "^17.2.1", - "@angular-eslint/eslint-plugin-template": "^17.2.1", - "@angular-eslint/schematics": "17.2.1", - "@angular-eslint/template-parser": "^17.2.1", - "@angular/cli": "^17.2.1", - "@angular/compiler-cli": "^17.2.2", - "@angular/language-service": "^17.2.2", + "@angular-eslint/builder": "^18.0.1", + "@angular-eslint/eslint-plugin": "^18.0.1", + "@angular-eslint/eslint-plugin-template": "^18.0.1", + "@angular-eslint/schematics": "18.0.1", + "@angular-eslint/template-parser": "^18.0.1", + "@angular/cli": "^18.0.4", + "@angular/compiler-cli": "^18.0.3", + "@angular/language-service": "^18.0.3", "@types/jasmine": "~3.6.0", "@types/jasminewd2": "~2.0.6", "@types/node": "^12.11.1", - "@typescript-eslint/eslint-plugin": "^7.13.1", - "@typescript-eslint/parser": "^6.10.0", - "@typescript-eslint/utils": "^7.13.1", + "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/parser": "^7.2.0", + "@typescript-eslint/utils": "^7.2.0", "browser-sync": "^3.0.2", "codelyzer": "^6.0.2", - "eslint": "^9.5.0", + "eslint": "^8.57.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-import": "^2.25.4", "eslint-plugin-prefer-arrow": "^1.2.3", @@ -69,6 +69,6 @@ "prettier-eslint": "^13.0.0", "protractor": "^7.0.0", "ts-node": "~8.4.1", - "typescript": "~5.2.2" + "typescript": "~5.4.5" } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 24aa4a9..d708d35 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -2,7 +2,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { LayoutModule } from '@angular/cdk/layout'; import { NgModule } from '@angular/core'; -import { HttpClientModule } from '@angular/common/http'; +import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { AppRoutingModule } from './modules/app-routing.module'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -42,8 +42,7 @@ import { FilterComponent } from './gui/components/filter/filter.component'; import { CredentialsModalComponent } from './gui/credentials-modal/credentials-modal.component'; -@NgModule({ - declarations: [ +@NgModule({ declarations: [ AppComponent, NavbarComponent, TranslateDirective, @@ -64,18 +63,13 @@ import { CredentialsModalComponent } from './gui/credentials-modal/credentials-m FilterComponent, MfaComponent, ], - imports: [ - BrowserModule, + bootstrap: [AppComponent], imports: [BrowserModule, LayoutModule, - HttpClientModule, AppRoutingModule, BrowserAnimationsModule, - AppMaterialModule, - ], - providers: [ + AppMaterialModule], providers: [ UDSApiService, UDSGuiService, - ], - bootstrap: [AppComponent] -}) + provideHttpClient(withInterceptorsFromDi()), + ] }) export class AppModule { } diff --git a/src/app/gui/navbar/navbar.component.scss b/src/app/gui/navbar/navbar.component.scss index 6dc2794..33e5520 100644 --- a/src/app/gui/navbar/navbar.component.scss +++ b/src/app/gui/navbar/navbar.component.scss @@ -1,4 +1,4 @@ -@import "globals.scss"; +@import "../../../globals.scss"; .uds-nav { position: fixed; diff --git a/src/globals.scss b/src/globals.scss index dff9351..b1eb346 100644 --- a/src/globals.scss +++ b/src/globals.scss @@ -1,32 +1,32 @@ @use '@angular/material' as mat; @include mat.core(); -$angular-primary: mat.define-palette(mat.$indigo-palette, 500, 100, 900); -$angular-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); +$angular-primary: mat.m2-define-palette(mat.$m2-indigo-palette, 500, 100, 900); +$angular-accent: mat.m2-define-palette(mat.$m2-pink-palette, A200, A100, A400); // The "warn" palette is optional and defaults to red if not specified. -$angular-warn: mat.define-palette(mat.$red-palette); +$angular-warn: mat.m2-define-palette(mat.$m2-red-palette); -$angular-default-theme: mat.define-light-theme( +$angular-default-theme: mat.m2-define-light-theme( ( color: ( primary: $angular-primary, accent: $angular-accent, warn: $angular-warn, ), - typography: mat.define-typography-config(), + typography: mat.m2-define-typography-config(), density: 0, ) ); -$angular-dark-theme: mat.define-dark-theme( +$angular-dark-theme: mat.m2-define-dark-theme( ( color: ( primary: $angular-primary, accent: $angular-accent, warn: $angular-warn, ), - typography: mat.define-typography-config(), + typography: mat.m2-define-typography-config(), density: 0, ) ); diff --git a/src/styles.scss b/src/styles.scss index 660aca1..64d0d9a 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -6,7 +6,7 @@ @include mat.all-component-themes($angular-default-theme); /* Cookie consent */ -@import '~cookieconsent/build/cookieconsent.min.css'; +@import 'cookieconsent/build/cookieconsent.min.css'; // variables $font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif; diff --git a/toUDS.py b/toUDS.py index 78e4276..a9735d8 100755 --- a/toUDS.py +++ b/toUDS.py @@ -33,14 +33,15 @@ import glob import re import typing -DIST = 'dist' +DIST = 'dist/browser' +THIRD_PARTY_LICENSES = 'dist/3rdpartylicenses.txt' SRC = 'src' UDS = os.path.join(DIST, 'uds') STATIC = 'static/modern' TEMPLATE = 'templates/uds/modern' -def mkPath(path) -> None: +def make_path(path) -> None: folder = '' for p in path.split(os.path.sep): folder = os.path.join(folder, p) @@ -50,29 +51,29 @@ def mkPath(path) -> None: pass # Already exits, ignore -def locateFiles(files: typing.List[str], folder: str, extension: str) -> None: +def locate_files(files: typing.List[str], folder: str, extension: str) -> None: for f in glob.glob(folder+"/*"): if os.path.isdir(f): # Recurse - locateFiles(files, os.path.join(f), extension) + locate_files(files, os.path.join(f), extension) else: if os.path.splitext(f)[1][1:].lower() == extension: files.append(f) -def locateHtmlFiles() -> typing.List[str]: +def locate_html_files() -> typing.List[str]: files: typing.List[str] = [] - locateFiles(files, SRC, 'html') + locate_files(files, SRC, 'html') return files -def locateTypeScriptFiles() -> typing.List[str]: +def locate_typescript_files() -> typing.List[str]: files: typing.List[str] = [] - locateFiles(files, SRC, 'ts') + locate_files(files, SRC, 'ts') return files -def fixIndex() -> None: +def fix_index_html() -> None: print('Fixing index.html...') translations = '' jsdata = '' @@ -98,7 +99,7 @@ def fixIndex() -> None: f.write(translatePattern.sub(translations + jsdata, html)) -def extractTranslations(): +def extract_translations(): print('Extracting translations from HTML') # Generate "fake" translations file (just to use django translator) @@ -121,21 +122,24 @@ def extractTranslations(): # First, extract translations from typescript typeScriptTranslationPattern = re.compile(r'django\.gettext\(\s*([\'"])(?P.*?)\1\)') print('// Typescript', file=output) - getTranslations(locateTypeScriptFiles, typeScriptTranslationPattern, output, strip=False) + getTranslations(locate_typescript_files, typeScriptTranslationPattern, output, strip=False) # Now extract translations from html htmlTranslationPattern = re.compile(r']*>(?P.*?)', re.MULTILINE | re.IGNORECASE | re.DOTALL) print('// HTML', file=output) - getTranslations(locateHtmlFiles, htmlTranslationPattern, output) + getTranslations(locate_html_files, htmlTranslationPattern, output) -def copyImages(): +def copy_images(): print('Copying images') outputPath = os.path.join(UDS, STATIC, 'img') - mkPath(outputPath) + make_path(outputPath) for f in glob.glob(DIST + '/static/modern/img/*'): shutil.copy(f, outputPath) +def copy_third_party_licenses() -> None: + print('Copying third party licenses') + shutil.copy(THIRD_PARTY_LICENSES, os.path.join(UDS, STATIC)) def organize(): print('Organizing content') @@ -147,13 +151,13 @@ def organize(): shutil.copy(f, os.path.join(UDS, STATIC)) -def cleanUp(): +def clean_up(): print('Cleaning unneeded content') folder = os.path.join(UDS, STATIC) os.unlink(os.path.join(folder, 'favicon.ico')) -def createDirs(): +def create_output_folders(): try: print('Creating output uds dir...') os.mkdir(UDS) @@ -163,8 +167,8 @@ def createDirs(): os.mkdir(UDS) # Static folders - mkPath(os.path.join(UDS, STATIC)) - mkPath(os.path.join(UDS, TEMPLATE)) + make_path(os.path.join(UDS, STATIC)) + make_path(os.path.join(UDS, TEMPLATE)) # # def buildSource(): @@ -174,12 +178,12 @@ def createDirs(): def main(): print('Use "yarn build" to correctly build for UDS') # buildSource() - createDirs() - extractTranslations() - fixIndex() - copyImages() + create_output_folders() + extract_translations() + fix_index_html() + copy_images() organize() - cleanUp() + clean_up() # Updades index.html diff --git a/tsconfig.json b/tsconfig.json index ed966d4..4ec7ddc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "baseUrl": "./", "outDir": "./dist/out-tsc", "forceConsistentCasingInFileNames": true, + "esModuleInterop": true, "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, @@ -12,7 +13,6 @@ "noFallthroughCasesInSwitch": true, "sourceMap": true, "declaration": false, - "downlevelIteration": true, "experimentalDecorators": true, "moduleResolution": "node", "importHelpers": true,