This is an automated email from the ASF dual-hosted git repository.
hanicz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git
The following commit(s) were added to refs/heads/master by this push:
new d9978443c KNOX-3357: Upgrade Webshell UI frameworks/libraries (#1276)
d9978443c is described below
commit d9978443c041add98d386655d5069f6e99bbf4b5
Author: hanicz <[email protected]>
AuthorDate: Tue Jun 23 14:13:52 2026 +0200
KNOX-3357: Upgrade Webshell UI frameworks/libraries (#1276)
---
knox-webshell-ui/angular.json | 44 ++++++-------
knox-webshell-ui/eslint.config.js | 77 ++++++++++++++++++++++
knox-webshell-ui/package.json | 42 +++++++-----
knox-webshell-ui/pom.xml | 17 ++++-
knox-webshell-ui/tsconfig.app.json | 11 ----
knox-webshell-ui/tsconfig.json | 18 -----
knox-webshell-ui/webshell-ui/app/app.component.ts | 37 +++++------
knox-webshell-ui/webshell-ui/app/app.module.ts | 32 ---------
.../webshell-ui/environments/environment.ts | 13 ----
knox-webshell-ui/webshell-ui/main.ts | 22 +++++--
knox-webshell-ui/webshell-ui/polyfills.ts | 67 +------------------
knox-webshell-ui/webshell-ui/styles.css | 6 ++
knox-webshell-ui/webshell-ui/tsconfig.json | 16 +++++
13 files changed, 192 insertions(+), 210 deletions(-)
diff --git a/knox-webshell-ui/angular.json b/knox-webshell-ui/angular.json
index 6fc8b11a7..baaf6af92 100644
--- a/knox-webshell-ui/angular.json
+++ b/knox-webshell-ui/angular.json
@@ -36,26 +36,30 @@
"prefix": "app",
"architect": {
"build": {
- "builder": "@angular-devkit/build-angular:browser",
+ "builder": "@angular/build:application",
"options": {
- "outputPath": "target/classes/webshell-ui/app",
+ "outputPath": {
+ "base": "target/classes/webshell-ui/app",
+ "browser": ""
+ },
"index": "webshell-ui/index.html",
- "main": "webshell-ui/main.ts",
- "polyfills": "webshell-ui/polyfills.ts",
- "tsConfig": "tsconfig.app.json",
+ "polyfills": ["webshell-ui/polyfills.ts"],
+ "tsConfig": "webshell-ui/tsconfig.json",
"assets": [
- "webshell-ui/favicon.ico",
- "webshell-ui/assets"
+ "webshell-ui/favicon.ico"
],
"styles": [
"webshell-ui/styles.css"
],
- "scripts": []
+ "scripts": [],
+ "browser": "webshell-ui/main.ts",
+ "allowedCommonJsDependencies": [
+ "@xterm/xterm",
+ "@xterm/addon-fit"
+ ]
},
"configurations": {
"production": {
- "buildOptimizer": false,
- "aot": false,
"fileReplacements": [
{
"replace": "webshell-ui/environments/environment.ts",
@@ -65,9 +69,8 @@
"outputHashing": "all"
},
"development": {
- "buildOptimizer": false,
+ "aot": false,
"optimization": false,
- "vendorChunk": true,
"extractLicenses": false,
"sourceMap": true,
"namedChunks": true
@@ -76,21 +79,21 @@
"defaultConfiguration": "production"
},
"serve": {
- "builder": "@angular-devkit/build-angular:dev-server",
+ "builder": "@angular/build:dev-server",
"configurations": {
"production": {
- "browserTarget": "webshell-ui:build:production"
+ "buildTarget": "webshell-ui:build:production"
},
"development": {
- "browserTarget": "webshell-ui:build:development"
+ "buildTarget": "webshell-ui:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
- "builder": "@angular-devkit/build-angular:extract-i18n",
+ "builder": "@angular/build:extract-i18n",
"options": {
- "browserTarget": "webshell-ui:build"
+ "buildTarget": "webshell-ui:build"
}
},
"lint": {
@@ -104,12 +107,5 @@
}
}
}
- },
- "defaultProject": "webshell-ui",
- "cli": {
- "schematicCollections": [
- "@angular-eslint/schematics",
- "@angular-eslint/schematics"
- ]
}
}
diff --git a/knox-webshell-ui/eslint.config.js
b/knox-webshell-ui/eslint.config.js
new file mode 100644
index 000000000..b2372b914
--- /dev/null
+++ b/knox-webshell-ui/eslint.config.js
@@ -0,0 +1,77 @@
+import js from "@eslint/js";
+import tseslint from "typescript-eslint";
+import angular from "@angular-eslint/eslint-plugin";
+import angularTemplate from "@angular-eslint/eslint-plugin-template";
+import tsParser from "@typescript-eslint/parser";
+
+export default [
+ {
+ ignores: ["**/dist/**", "**/node_modules/**"],
+ },
+
+ js.configs.recommended,
+
+ {
+ files: ["**/*.ts"],
+ languageOptions: {
+ parser: tsParser,
+ parserOptions: {
+ project: ["./webshell-ui/tsconfig.json"],
+ tsconfigRootDir: import.meta.dirname,
+ },
+ globals: {
+ console: "readonly",
+ window: "readonly",
+ document: "readonly",
+ setTimeout: "readonly",
+ atob: "readonly",
+ location: "readonly",
+ WebSocket: "readonly",
+ },
+ },
+ plugins: {
+ "@typescript-eslint": tseslint.plugin,
+ "@angular-eslint": angular,
+ },
+ rules: {
+ "@typescript-eslint/naming-convention": [
+ "error",
+ {selector: "class", format: ["PascalCase"]},
+ ],
+
+ curly: "error",
+ eqeqeq: ["error", "always", {null: "ignore"}],
+ "guard-for-in": "error",
+ "max-len": ["error", {code: 140}],
+ "no-bitwise": "error",
+ "no-caller": "error",
+ "no-console": "off",
+ "no-debugger": "error",
+ "no-empty": "error",
+ "no-eval": "error",
+ "no-fallthrough": "error",
+ "no-trailing-spaces": "error",
+ "no-unused-expressions": "error",
+ "no-unused-labels": "error",
+ "no-var": "error",
+ quotes: ["error", "single"],
+ radix: "error",
+ semi: ["error", "always"],
+ "spaced-comment": "error",
+ "brace-style": ["error", "1tbs", {allowSingleLine: true}],
+
+ "@angular-eslint/directive-selector": [
+ "error",
+ {type: "attribute", prefix: "app", style: "camelCase"},
+ ],
+ "@angular-eslint/component-selector": [
+ "error",
+ {type: "element", prefix: "app", style: "kebab-case"},
+ ],
+ "@angular-eslint/no-output-rename": "error",
+ "@angular-eslint/use-pipe-transform-interface": "error",
+ "@angular-eslint/component-class-suffix": "error",
+ "@angular-eslint/directive-class-suffix": "error",
+ },
+ },
+];
diff --git a/knox-webshell-ui/package.json b/knox-webshell-ui/package.json
index a33ed3b75..fd7483f66 100644
--- a/knox-webshell-ui/package.json
+++ b/knox-webshell-ui/package.json
@@ -2,6 +2,7 @@
"name": "ng-knox-webshell-ui",
"version": "1.0.0",
"license": "Apache-2.0",
+ "type": "module",
"scripts": {
"start": "ng serve --verbose=true",
"build": "ng build",
@@ -10,25 +11,30 @@
},
"private": true,
"dependencies": {
- "@angular-eslint/schematics": "^15.1.0",
- "@angular/common": "~13.0.1",
- "@angular/compiler": "~13.0.1",
- "@angular/core": "~13.0.1",
- "@angular/platform-browser": "~13.0.1",
- "@angular/platform-browser-dynamic": "~13.0.1",
- "@angular/router": "~13.0.1",
- "ajv": "^6.12.6",
- "ng-terminal": "^3.1.1",
- "zone.js": "~0.11.4"
+ "@angular/common": "^21.0.5",
+ "@angular/compiler": "^21.0.5",
+ "@angular/core": "^21.0.5",
+ "@angular/platform-browser": "^21.0.5",
+ "@angular/platform-browser-dynamic": "^21.0.5",
+ "@angular/router": "^21.0.5",
+ "ng-terminal": "^6.6.0",
+ "zone.js": "~0.15.1"
},
"devDependencies": {
- "@angular-devkit/build-angular": "^13.3.11",
- "@angular-eslint/builder": "^12.6.1 ",
- "@angular/cli": "~14.2.9",
- "@angular/compiler-cli": "~13.0.1",
- "@types/jasmine": "~3.6.0",
- "@types/node": "16.18.11",
- "typescript": "~4.4.4",
- "codelyzer": "^4.1.0"
+ "@angular-eslint/builder": "21.1.0",
+ "@angular-eslint/eslint-plugin": "21.1.0",
+ "@angular-eslint/eslint-plugin-template": "21.1.0",
+ "@angular-eslint/schematics": "21.1.0",
+ "@angular-eslint/template-parser": "21.1.0",
+ "@angular/build": "^21.0.3",
+ "@angular/cli": "^21.0.3",
+ "@angular/compiler-cli": "^21.0.5",
+ "@angular/language-service": "^21.0.5",
+ "@eslint/js": "^9.39.0",
+ "@types/node": "^24.5.2",
+ "eslint": "^9.39.0",
+ "ts-node": "~10.9.0",
+ "typescript": "~5.9.3",
+ "typescript-eslint": "^8.46.2"
}
}
diff --git a/knox-webshell-ui/pom.xml b/knox-webshell-ui/pom.xml
index e4ab76927..02e722e49 100644
--- a/knox-webshell-ui/pom.xml
+++ b/knox-webshell-ui/pom.xml
@@ -37,7 +37,11 @@
<configuration>
<filesets>
<fileset>
- <directory>node_modules</directory>
+ <directory>${project.basedir}</directory>
+ <includes>
+ <include>package-lock.json</include>
+ <include>node_modules/**</include>
+ </includes>
</fileset>
</filesets>
</configuration>
@@ -65,7 +69,16 @@
<goal>npm</goal>
</goals>
<configuration>
- <arguments>install --legacy-peer-deps</arguments>
+ <arguments>install</arguments>
+ </configuration>
+ </execution>
+ <execution>
+ <id>knox-webshell-npm-run-lint</id>
+ <goals>
+ <goal>npm</goal>
+ </goals>
+ <configuration>
+ <arguments>run lint</arguments>
</configuration>
</execution>
<execution>
diff --git a/knox-webshell-ui/tsconfig.app.json
b/knox-webshell-ui/tsconfig.app.json
deleted file mode 100644
index 5d90aaafb..000000000
--- a/knox-webshell-ui/tsconfig.app.json
+++ /dev/null
@@ -1,11 +0,0 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
-{
- "extends": "./tsconfig.json",
- "files": [
- "webshell-ui/main.ts",
- "webshell-ui/polyfills.ts"
- ],
- "include": [
- "webshell-ui/**/*.d.ts"
- ]
-}
diff --git a/knox-webshell-ui/tsconfig.json b/knox-webshell-ui/tsconfig.json
deleted file mode 100644
index e73a7e37b..000000000
--- a/knox-webshell-ui/tsconfig.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "compilerOptions": {
- "baseUrl": "./",
- "declaration": false,
- "emitDecoratorMetadata": true,
- "experimentalDecorators": true,
- "lib": [
- "es2017",
- "dom"
- ],
- "mapRoot": "./",
- "module": "es6",
- "moduleResolution": "node",
- "outDir": "./dist/out-tsc",
- "sourceMap": true,
- "target": "es5"
- }
-}
diff --git a/knox-webshell-ui/webshell-ui/app/app.component.ts
b/knox-webshell-ui/webshell-ui/app/app.component.ts
index 85dc07ef2..81187a903 100644
--- a/knox-webshell-ui/webshell-ui/app/app.component.ts
+++ b/knox-webshell-ui/webshell-ui/app/app.component.ts
@@ -14,48 +14,43 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import {Component, OnInit, ViewChild, AfterViewInit, HostListener} from
'@angular/core';
-import { NgTerminal } from 'ng-terminal';
+import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
+import { NgTerminal, NgTerminalModule } from 'ng-terminal';
@Component({
selector: 'app-root',
+ standalone: true,
+ imports: [NgTerminalModule],
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, AfterViewInit {
- @ViewChild('term', {static: false}) child: NgTerminal;
- private websocket: WebSocket;
+ @ViewChild('term', {static: false}) child!: NgTerminal;
+ private websocket!: WebSocket;
constructor() { }
ngOnInit() {}
ngAfterViewInit() {
- const terminal = this.child.underlying;
- // todo: can add other options to customize xterm
+ const terminal = this.child.underlying!;
terminal.options.convertEol = true;
terminal.options.letterSpacing = 0;
terminal.options.fontFamily = 'Courier New';
- /* check font
- const fontFamily = terminal.getOption("fontFamily");
- console.log(fontFamily);
- */
-
- let endpoint = 'wss://'+ location.hostname + ':' + location.port + '/'+
+ const endpoint = 'wss://' + location.hostname + ':' + location.port + '/' +
location.pathname.split('/')[1] + '/webshell';
console.log(endpoint);
this.websocket = new WebSocket(endpoint);
- this.websocket.onmessage = function(event){
+ this.websocket.onmessage = (event) => {
terminal.write(event.data);
- }
- this.websocket.onclose = function(event){
- terminal.write("\r\nConnection closed");
- }
+ };
+ this.websocket.onclose = () => {
+ terminal.write('\r\nConnection closed');
+ };
- terminal.onData((userInput) => {
- // send userInput to backend server
- this.websocket.send(JSON.stringify({userInput:userInput}));
- })
+ terminal.onData((userInput: string) => {
+ this.websocket.send(JSON.stringify({userInput: userInput}));
+ });
}
}
diff --git a/knox-webshell-ui/webshell-ui/app/app.module.ts
b/knox-webshell-ui/webshell-ui/app/app.module.ts
deleted file mode 100644
index 110931de9..000000000
--- a/knox-webshell-ui/webshell-ui/app/app.module.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import { BrowserModule } from '@angular/platform-browser';
-import { NgModule } from '@angular/core';
-import { NgTerminalModule } from 'ng-terminal';
-import { AppComponent } from './app.component';
-@NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- NgTerminalModule
- ],
- providers: [],
- bootstrap: [AppComponent]
-})
-export class AppModule { }
diff --git a/knox-webshell-ui/webshell-ui/environments/environment.ts
b/knox-webshell-ui/webshell-ui/environments/environment.ts
index 283f02808..74510be22 100644
--- a/knox-webshell-ui/webshell-ui/environments/environment.ts
+++ b/knox-webshell-ui/webshell-ui/environments/environment.ts
@@ -14,19 +14,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-// This file can be replaced during build by using the `fileReplacements`
array.
-// `ng build` replaces `environment.ts` with `environment.prod.ts`.
-// The list of file replacements can be found in `angular.json`.
-
export const environment = {
production: false
};
-
-/*
- * For easier debugging in development mode, you can import the following file
- * to ignore zone related error stack frames such as `zone.run`,
`zoneDelegate.invokeTask`.
- *
- * This import should be commented out in production mode because it will have
a negative impact
- * on performance if an error is thrown.
- */
-// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
diff --git a/knox-webshell-ui/webshell-ui/main.ts
b/knox-webshell-ui/webshell-ui/main.ts
index 022708550..735d492fb 100644
--- a/knox-webshell-ui/webshell-ui/main.ts
+++ b/knox-webshell-ui/webshell-ui/main.ts
@@ -14,15 +14,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { enableProdMode } from '@angular/core';
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+import './polyfills.ts';
+
+import { enableProdMode, provideZoneChangeDetection } from '@angular/core';
+import { bootstrapApplication } from '@angular/platform-browser';
+import { provideRouter } from '@angular/router';
+import { APP_BASE_HREF } from '@angular/common';
-import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
+import { AppComponent } from './app/app.component';
if (environment.production) {
enableProdMode();
}
-platformBrowserDynamic().bootstrapModule(AppModule)
- .catch(err => console.error(err));
+bootstrapApplication(AppComponent, {
+ providers: [
+ provideZoneChangeDetection(),
+ provideRouter([]),
+ {
+ provide: APP_BASE_HREF,
+ useValue: (window as unknown as {'base-href'?: string})['base-href'] ||
'/'
+ }
+ ]
+}).catch(err => console.error(err));
diff --git a/knox-webshell-ui/webshell-ui/polyfills.ts
b/knox-webshell-ui/webshell-ui/polyfills.ts
index 5881c3011..aebd58c4e 100644
--- a/knox-webshell-ui/webshell-ui/polyfills.ts
+++ b/knox-webshell-ui/webshell-ui/polyfills.ts
@@ -14,69 +14,4 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/**
- * This file includes polyfills needed by Angular and is loaded before the app.
- * You can add your own extra polyfills to this file.
- *
- * This file is divided into 2 sections:
- * 1. Browser polyfills. These are applied before loading ZoneJS and are
sorted by browsers.
- * 2. Application imports. Files imported after ZoneJS that should be loaded
before your main
- * file.
- *
- * The current setup is for so-called "evergreen" browsers; the last versions
of browsers that
- * automatically update themselves. This includes Safari >= 10, Chrome >= 55
(including Opera),
- * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
- *
- * Learn more in https://angular.io/guide/browser-support
- */
-
-/***************************************************************************************************
- * BROWSER POLYFILLS
- */
-
-/**
- * IE11 requires the following for NgClass support on SVG elements
- */
-// import 'classlist.js'; // Run `npm install --save classlist.js`.
-
-/**
- * Web Animations `@angular/platform-browser/animations`
- * Only required if AnimationBuilder is used within the application and using
IE/Edge or Safari.
- * Standard animation support in Angular DOES NOT require any polyfills (as of
Angular 6.0).
- */
-// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
-
-/**
- * By default, zone.js will patch all possible macroTask and DomEvents
- * user can disable parts of macroTask/DomEvents patch by setting following
flags
- * because those flags need to be set before `zone.js` being loaded, and
webpack
- * will put import in the top of bundle, so user need to create a separate file
- * in this directory (for example: zone-flags.ts), and put the following flags
- * into that file, and then add the following code before importing zone.js.
- * import './zone-flags';
-
- *
- * The flags allowed in zone-flags.ts are listed here.
- *
- * The following flags will work for all browsers.
- *
- * (window as any).__Zone_disable_requestAnimationFrame = true; // disable
patch requestAnimationFrame
- * (window as any).__Zone_disable_on_property = true; // disable patch
onProperty such as onclick
- * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove'];
// disable patch specified eventNames
- *
- * in IE/Edge developer tools, the addEventListener will also be wrapped by
zone.js
- * with the following flag, it will bypass `zone.js` patch for IE/Edge
- *
- * (window as any).__Zone_enable_cross_context_check = true;
- *
- */
-
-/***************************************************************************************************
- * Zone JS is required by default for Angular itself.
- */
-import 'zone.js'; // Included with Angular CLI.
-
-
-/***************************************************************************************************
- * APPLICATION IMPORTS
- */
+import 'zone.js';
diff --git a/knox-webshell-ui/webshell-ui/styles.css
b/knox-webshell-ui/webshell-ui/styles.css
index 606962ea3..d5e1589d3 100644
--- a/knox-webshell-ui/webshell-ui/styles.css
+++ b/knox-webshell-ui/webshell-ui/styles.css
@@ -17,3 +17,9 @@
*/
/* You can add global styles to this file, and also import other style files */
+html, body {
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ overflow: hidden;
+}
diff --git a/knox-webshell-ui/webshell-ui/tsconfig.json
b/knox-webshell-ui/webshell-ui/tsconfig.json
new file mode 100644
index 000000000..38d744c40
--- /dev/null
+++ b/knox-webshell-ui/webshell-ui/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "baseUrl": "webshell-ui",
+ "declaration": false,
+ "emitDecoratorMetadata": true,
+ "experimentalDecorators": true,
+ "module": "ES2022",
+ "moduleResolution": "bundler",
+ "outDir": "../dist/out-tsc",
+ "sourceMap": true,
+ "target": "ES2022",
+ "typeRoots": [
+ "../node_modules/@types"
+ ]
+ }
+}