mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
feat: add service uptime and start style changes (#2831)
This commit is contained in:
@@ -45,7 +45,6 @@
|
||||
],
|
||||
"styles": [
|
||||
"node_modules/@taiga-ui/core/styles/taiga-ui-theme.less",
|
||||
"node_modules/@taiga-ui/styles/taiga-ui-global.less",
|
||||
"projects/shared/styles/taiga.scss",
|
||||
"projects/shared/styles/shared.scss",
|
||||
"projects/ui/src/styles.scss"
|
||||
|
||||
152
web/package-lock.json
generated
152
web/package-lock.json
generated
@@ -25,19 +25,18 @@
|
||||
"@noble/hashes": "^1.4.0",
|
||||
"@start9labs/argon2": "^0.2.2",
|
||||
"@start9labs/start-sdk": "file:../sdk/baseDist",
|
||||
"@taiga-ui/addon-charts": "4.21.0",
|
||||
"@taiga-ui/addon-commerce": "4.21.0",
|
||||
"@taiga-ui/addon-mobile": "4.21.0",
|
||||
"@taiga-ui/addon-table": "4.21.0",
|
||||
"@taiga-ui/cdk": "4.21.0",
|
||||
"@taiga-ui/core": "4.21.0",
|
||||
"@taiga-ui/event-plugins": "4.3.1",
|
||||
"@taiga-ui/icons": "4.21.0",
|
||||
"@taiga-ui/kit": "4.21.0",
|
||||
"@taiga-ui/layout": "4.21.0",
|
||||
"@taiga-ui/legacy": "4.21.0",
|
||||
"@taiga-ui/addon-charts": "4.24.0",
|
||||
"@taiga-ui/addon-commerce": "4.24.0",
|
||||
"@taiga-ui/addon-mobile": "4.24.0",
|
||||
"@taiga-ui/addon-table": "4.24.0",
|
||||
"@taiga-ui/cdk": "4.24.0",
|
||||
"@taiga-ui/core": "4.24.0",
|
||||
"@taiga-ui/event-plugins": "4.4.0",
|
||||
"@taiga-ui/icons": "4.24.0",
|
||||
"@taiga-ui/kit": "4.24.0",
|
||||
"@taiga-ui/layout": "4.24.0",
|
||||
"@taiga-ui/legacy": "4.24.0",
|
||||
"@taiga-ui/polymorpheus": "4.8.0",
|
||||
"@taiga-ui/styles": "4.21.0",
|
||||
"@tinkoff/ng-dompurify": "4.0.0",
|
||||
"ansi-to-html": "^0.7.2",
|
||||
"base64-js": "^1.5.1",
|
||||
@@ -4416,9 +4415,9 @@
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@taiga-ui/addon-charts": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-4.21.0.tgz",
|
||||
"integrity": "sha512-ai213WTf+VG3hYLrusWJiSj7fY+Z5HjeZLmEJIMvFswzV8+Ekiiqb95+BnBUQaie6bwu3yAhcadwgun7u2Rq3w==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-charts/-/addon-charts-4.24.0.tgz",
|
||||
"integrity": "sha512-x75l4Dj1l7ForatbIdk4O8NzM6fQlKRp9UsXzMrKSoKj9O3jGHsFyMV67FhBS9oVitU4+3MIgPLuj09qpG1gBg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": ">=2.8.1"
|
||||
@@ -4427,15 +4426,15 @@
|
||||
"@angular/common": ">=16.0.0",
|
||||
"@angular/core": ">=16.0.0",
|
||||
"@ng-web-apis/common": "^4.11.1",
|
||||
"@taiga-ui/cdk": "^4.21.0",
|
||||
"@taiga-ui/core": "^4.21.0",
|
||||
"@taiga-ui/cdk": "^4.24.0",
|
||||
"@taiga-ui/core": "^4.24.0",
|
||||
"@taiga-ui/polymorpheus": "^4.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/addon-commerce": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-4.21.0.tgz",
|
||||
"integrity": "sha512-CmibFfEsSW2h9k6/NcAiverxiMZDk1e15j10Uupfodn7vpZk3u4j4/c8aS4klV4Hk3lC5UCCvpYVLpx/c9u+/A==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-commerce/-/addon-commerce-4.24.0.tgz",
|
||||
"integrity": "sha512-YAbhTZHXnN5TT9oO+KJX/NAehuHgMZ/QoVIuzQR16HiIoKTQQWznSipThnX2hinXrLNBas0O2Teo4Ij5kGIEOQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": ">=2.8.1"
|
||||
@@ -4448,18 +4447,18 @@
|
||||
"@maskito/core": "^3.2.1",
|
||||
"@maskito/kit": "^3.2.1",
|
||||
"@ng-web-apis/common": "^4.11.1",
|
||||
"@taiga-ui/cdk": "^4.21.0",
|
||||
"@taiga-ui/core": "^4.21.0",
|
||||
"@taiga-ui/i18n": "^4.21.0",
|
||||
"@taiga-ui/kit": "^4.21.0",
|
||||
"@taiga-ui/cdk": "^4.24.0",
|
||||
"@taiga-ui/core": "^4.24.0",
|
||||
"@taiga-ui/i18n": "^4.24.0",
|
||||
"@taiga-ui/kit": "^4.24.0",
|
||||
"@taiga-ui/polymorpheus": "^4.8.0",
|
||||
"rxjs": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/addon-mobile": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-mobile/-/addon-mobile-4.21.0.tgz",
|
||||
"integrity": "sha512-AIklfOfgiTuCFHvGb9Ok1nNtkelrEZmoeOQsLEH0wIA0+Ou/6XeAG03BkwrIJq4yQ1AI+ZCFeVNtl17bg+EzkA==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-mobile/-/addon-mobile-4.24.0.tgz",
|
||||
"integrity": "sha512-YdkhhgWsmtgi85sPbjibqa/BxdqKkETav/6O0KgFmBGvS4MF/Hr2sOXWMDUfskSALee9BJBNPdf8NrV/zNpcXw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": ">=2.8.1"
|
||||
@@ -4469,17 +4468,18 @@
|
||||
"@angular/common": ">=16.0.0",
|
||||
"@angular/core": ">=16.0.0",
|
||||
"@ng-web-apis/common": "^4.11.1",
|
||||
"@taiga-ui/cdk": "^4.21.0",
|
||||
"@taiga-ui/core": "^4.21.0",
|
||||
"@taiga-ui/kit": "^4.21.0",
|
||||
"@taiga-ui/cdk": "^4.24.0",
|
||||
"@taiga-ui/core": "^4.24.0",
|
||||
"@taiga-ui/kit": "^4.24.0",
|
||||
"@taiga-ui/layout": "^4.24.0",
|
||||
"@taiga-ui/polymorpheus": "^4.8.0",
|
||||
"rxjs": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/addon-table": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-table/-/addon-table-4.21.0.tgz",
|
||||
"integrity": "sha512-A3j4mfsM/S+IRQOEfZwVTFhy0zTSeeM7/ZHgQwuau7Xn8UN6S8X0HvZ2LCg6ZMJaXU1W79XMm2j1uLa/BDFcog==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/addon-table/-/addon-table-4.24.0.tgz",
|
||||
"integrity": "sha512-da/5FUmyrG6+pS9XgBY7B78EU6O1M9GPh9fxTtYTDjRgEpFdb/4TX0J79v5InSTGQV77ITVkpqbTB1moRgUVfA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": ">=2.8.1"
|
||||
@@ -4488,18 +4488,18 @@
|
||||
"@angular/common": ">=16.0.0",
|
||||
"@angular/core": ">=16.0.0",
|
||||
"@ng-web-apis/intersection-observer": "^4.11.1",
|
||||
"@taiga-ui/cdk": "^4.21.0",
|
||||
"@taiga-ui/core": "^4.21.0",
|
||||
"@taiga-ui/i18n": "^4.21.0",
|
||||
"@taiga-ui/kit": "^4.21.0",
|
||||
"@taiga-ui/cdk": "^4.24.0",
|
||||
"@taiga-ui/core": "^4.24.0",
|
||||
"@taiga-ui/i18n": "^4.24.0",
|
||||
"@taiga-ui/kit": "^4.24.0",
|
||||
"@taiga-ui/polymorpheus": "^4.8.0",
|
||||
"rxjs": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/cdk": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-4.21.0.tgz",
|
||||
"integrity": "sha512-PfHMELF2OHO7GNjdyfz1LpyjrsQMEa7oqZoyqz5s4W7W/KWpds3Cm6RP2inFQsZofXrJQNDGtThb1UgNYH5AsQ==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/cdk/-/cdk-4.24.0.tgz",
|
||||
"integrity": "sha512-vsI+Jyzj4yfMolCg42OOyDvT30g1WFoupfOGlUk8A9R2HTVhMTeFeoA186A7c5KLI3e9fxj/60Rc9LbIbacnDA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "2.8.1"
|
||||
@@ -4522,15 +4522,15 @@
|
||||
"@ng-web-apis/platform": "^4.11.1",
|
||||
"@ng-web-apis/resize-observer": "^4.11.1",
|
||||
"@ng-web-apis/screen-orientation": "^4.11.1",
|
||||
"@taiga-ui/event-plugins": "^4.3.1",
|
||||
"@taiga-ui/event-plugins": "^4.4.0",
|
||||
"@taiga-ui/polymorpheus": "^4.8.0",
|
||||
"rxjs": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/core": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-4.21.0.tgz",
|
||||
"integrity": "sha512-O91kueQldSGCxR+IshcgwAOJukwkV2gEu/MBhw7t5fDEvW6aNbKjFl/RZcDSMguVIzOdRAyTrWm+UyVLYeOphA==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/core/-/core-4.24.0.tgz",
|
||||
"integrity": "sha512-tHHxdwXtvMI8W2Ct1YgLZGg5UEDRPq3j3fYwLV0P/G+17TU1rVeF9/JxVe8ZdZ1Mo55LNLDflTnenC13GK0R/w==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": ">=2.8.1"
|
||||
@@ -4544,17 +4544,17 @@
|
||||
"@angular/router": ">=16.0.0",
|
||||
"@ng-web-apis/common": "^4.11.1",
|
||||
"@ng-web-apis/mutation-observer": "^4.11.1",
|
||||
"@taiga-ui/cdk": "^4.21.0",
|
||||
"@taiga-ui/event-plugins": "^4.3.1",
|
||||
"@taiga-ui/i18n": "^4.21.0",
|
||||
"@taiga-ui/cdk": "^4.24.0",
|
||||
"@taiga-ui/event-plugins": "^4.4.0",
|
||||
"@taiga-ui/i18n": "^4.24.0",
|
||||
"@taiga-ui/polymorpheus": "^4.8.0",
|
||||
"rxjs": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/event-plugins": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/event-plugins/-/event-plugins-4.3.1.tgz",
|
||||
"integrity": "sha512-DhD1hdOYNidngdkxQQDGKawfn6fuhPcVVsbafZIJNAgw5P1+nN9b+J/3DB+GJJ1X3ODyMDl73Qubz0lPlMdRGw==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/event-plugins/-/event-plugins-4.4.0.tgz",
|
||||
"integrity": "sha512-Tv8C0p5EZXl7s1Vc+MrLbAblbYvyswomY/xvyFcI9NgMj6JyfsStu6jpCiRMfzojz3G70PRFsk0+WwI19lRJCQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
@@ -4566,9 +4566,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/i18n": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-4.23.0.tgz",
|
||||
"integrity": "sha512-+7AxbAKeQYmS0uK0LqhDqCDwJhuZlNhO4vZ8FTjmgPDWKF/VeRua+v7ei1pp3b6u+n8ADn9wq7Y2oitLjrH2gg==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/i18n/-/i18n-4.24.0.tgz",
|
||||
"integrity": "sha512-F3s+SGJ6QkGIWDpTcJvqiE++WHHF95o11tokQvzFq9pCLfMrxehNx38Dv/JnZK3FA2vYlVqdaQc0OsRMfMDRMw==",
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
@@ -4581,18 +4581,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/icons": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-4.21.0.tgz",
|
||||
"integrity": "sha512-lzUYj/LOIFVJqdhzl0mgFUMASicQb2b+0MG5YELZik69hU+QAAKjCBzqDAaOqIMA/MVnERXiOxl62yWLjBR9+Q==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/icons/-/icons-4.24.0.tgz",
|
||||
"integrity": "sha512-VGWKMuVayab+/MJ60JuxRM2zTJG2WelDmUuTMdYqnh+zAWTn7FoPjDgAREiT7m84XryZdKtkUqGK6aLI+J62Sg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/kit": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-4.21.0.tgz",
|
||||
"integrity": "sha512-7/V6laRXsu+CQA+LnVVQJhb0m6hH1/FbElqictaiIyIKguIELpq64XMcspEPpnkVkEMatn47YA4xPH6PCF5Mng==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/kit/-/kit-4.24.0.tgz",
|
||||
"integrity": "sha512-qz+OpsAyHWUT6fcfBPd+RJTv98J5USezh028B7TpSLSSyRE6mbklKIj2gteJQVnwVS0AXwm69WgQDXMVolbJnw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": ">=2.8.1"
|
||||
@@ -4610,17 +4610,17 @@
|
||||
"@ng-web-apis/intersection-observer": "^4.11.1",
|
||||
"@ng-web-apis/mutation-observer": "^4.11.1",
|
||||
"@ng-web-apis/resize-observer": "^4.11.1",
|
||||
"@taiga-ui/cdk": "^4.21.0",
|
||||
"@taiga-ui/core": "^4.21.0",
|
||||
"@taiga-ui/i18n": "^4.21.0",
|
||||
"@taiga-ui/cdk": "^4.24.0",
|
||||
"@taiga-ui/core": "^4.24.0",
|
||||
"@taiga-ui/i18n": "^4.24.0",
|
||||
"@taiga-ui/polymorpheus": "^4.8.0",
|
||||
"rxjs": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/layout": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/layout/-/layout-4.21.0.tgz",
|
||||
"integrity": "sha512-st8CEVPZSNCC9a/6pEbzMYO0vdHSWvua/nHoNbE4100AkW593DBQD2442LMF7ENRjFrPS+Ffuv8s5GFGasE/nw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/layout/-/layout-4.24.0.tgz",
|
||||
"integrity": "sha512-xwWB2iXeQWipzw0jTvqFL6V/20bhyM5lNT2AyAo6EcI8fX1N8x/RThaz9crf1jexajynHm4qirGT1M8tblg+Pw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": ">=2.8.1"
|
||||
@@ -4628,17 +4628,17 @@
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=16.0.0",
|
||||
"@angular/core": ">=16.0.0",
|
||||
"@taiga-ui/cdk": "^4.21.0",
|
||||
"@taiga-ui/core": "^4.21.0",
|
||||
"@taiga-ui/kit": "^4.21.0",
|
||||
"@taiga-ui/cdk": "^4.24.0",
|
||||
"@taiga-ui/core": "^4.24.0",
|
||||
"@taiga-ui/kit": "^4.24.0",
|
||||
"@taiga-ui/polymorpheus": "^4.8.0",
|
||||
"rxjs": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/legacy": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/legacy/-/legacy-4.21.0.tgz",
|
||||
"integrity": "sha512-B6QeYOyJ5F8WtrL/H3Wa1tiWogH8ruS1aGysASrDSo7wZfS66AzjAdNUuHX3L3HJcqp0xAAVDKL/LNW2S/fckg==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/legacy/-/legacy-4.24.0.tgz",
|
||||
"integrity": "sha512-J3CJwDuaVV1zMUunZWru6Syg1cFPL0uF8qWyAis+tgllfYxFpUstvJfKhqezSauXifFsDqcLJYKGu3/fMLIsmA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": ">=2.8.1"
|
||||
@@ -4660,16 +4660,6 @@
|
||||
"@angular/platform-browser": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@taiga-ui/styles": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/@taiga-ui/styles/-/styles-4.21.0.tgz",
|
||||
"integrity": "sha512-ZFbE1nIz0V3R/4ufXGJxxA+cX17dM7efFT38QKmZpsfSyGJBeASg1FQ5ENqIE3lR8kq+GmNNtro4oo+uCjH/7w==",
|
||||
"peerDependencies": {
|
||||
"@taiga-ui/cdk": "^4.21.0",
|
||||
"@taiga-ui/core": "^4.21.0",
|
||||
"tslib": ">=2.8.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tinkoff/ng-dompurify": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tinkoff/ng-dompurify/-/ng-dompurify-4.0.0.tgz",
|
||||
|
||||
@@ -47,19 +47,18 @@
|
||||
"@noble/hashes": "^1.4.0",
|
||||
"@start9labs/argon2": "^0.2.2",
|
||||
"@start9labs/start-sdk": "file:../sdk/baseDist",
|
||||
"@taiga-ui/addon-charts": "4.21.0",
|
||||
"@taiga-ui/addon-commerce": "4.21.0",
|
||||
"@taiga-ui/addon-mobile": "4.21.0",
|
||||
"@taiga-ui/addon-table": "4.21.0",
|
||||
"@taiga-ui/cdk": "4.21.0",
|
||||
"@taiga-ui/core": "4.21.0",
|
||||
"@taiga-ui/event-plugins": "4.3.1",
|
||||
"@taiga-ui/icons": "4.21.0",
|
||||
"@taiga-ui/kit": "4.21.0",
|
||||
"@taiga-ui/layout": "4.21.0",
|
||||
"@taiga-ui/legacy": "4.21.0",
|
||||
"@taiga-ui/addon-charts": "4.24.0",
|
||||
"@taiga-ui/addon-commerce": "4.24.0",
|
||||
"@taiga-ui/addon-mobile": "4.24.0",
|
||||
"@taiga-ui/addon-table": "4.24.0",
|
||||
"@taiga-ui/cdk": "4.24.0",
|
||||
"@taiga-ui/core": "4.24.0",
|
||||
"@taiga-ui/event-plugins": "4.4.0",
|
||||
"@taiga-ui/icons": "4.24.0",
|
||||
"@taiga-ui/kit": "4.24.0",
|
||||
"@taiga-ui/layout": "4.24.0",
|
||||
"@taiga-ui/legacy": "4.24.0",
|
||||
"@taiga-ui/polymorpheus": "4.8.0",
|
||||
"@taiga-ui/styles": "4.21.0",
|
||||
"@tinkoff/ng-dompurify": "4.0.0",
|
||||
"ansi-to-html": "^0.7.2",
|
||||
"base64-js": "^1.5.1",
|
||||
|
||||
@@ -2,12 +2,9 @@ import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
EventEmitter,
|
||||
inject,
|
||||
Input,
|
||||
Output,
|
||||
} from '@angular/core'
|
||||
import { Router } from '@angular/router'
|
||||
import { THEME } from '@start9labs/shared'
|
||||
|
||||
@Component({
|
||||
selector: 'marketplace-search',
|
||||
@@ -21,8 +18,6 @@ export class SearchComponent {
|
||||
|
||||
@Output()
|
||||
readonly queryChange = new EventEmitter<string>()
|
||||
private readonly router = inject(Router)
|
||||
readonly theme$ = inject(THEME)
|
||||
|
||||
onModelChange(query: string) {
|
||||
this.query = query
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
tuiButton
|
||||
iconEnd="@tui.external-link"
|
||||
size="s"
|
||||
appearance="glass"
|
||||
appearance="secondary-grayscale"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
[href]="url"
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.6 MiB After Width: | Height: | Size: 8.1 MiB |
@@ -46,7 +46,6 @@ export * from './types/url'
|
||||
export * from './types/workspace-config'
|
||||
|
||||
export * from './tokens/relative-url'
|
||||
export * from './tokens/theme'
|
||||
|
||||
export * from './util/base-64'
|
||||
export * from './util/convert-ansi'
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
import { InjectionToken } from '@angular/core'
|
||||
import { EMPTY, Observable } from 'rxjs'
|
||||
|
||||
export const THEME = new InjectionToken<Observable<string>>('App theme', {
|
||||
factory: () => EMPTY,
|
||||
})
|
||||
@@ -1,184 +1,102 @@
|
||||
@import '@taiga-ui/core/styles/taiga-ui-local';
|
||||
|
||||
:root {
|
||||
--tui-background-accent-1: #3880ff;
|
||||
--tui-background-accent-1-hover: #4c8dff;
|
||||
--tui-background-accent-1-pressed: #3171e0;
|
||||
[tuiTheme='dark'] {
|
||||
--tui-background-base: rgba(23, 23, 23, 1);
|
||||
--tui-background-base-alt: rgba(23, 24, 29, 1);
|
||||
--tui-background-neutral-1: rgba(255, 255, 255, 0.06);
|
||||
--tui-background-neutral-1-hover: rgba(255, 255, 255, 0.12);
|
||||
--tui-background-neutral-1-pressed: rgba(255, 255, 255, 0.18);
|
||||
--tui-background-neutral-2: rgba(255, 255, 255, 0.16);
|
||||
--tui-background-neutral-2-hover: rgba(255, 255, 255, 0.2);
|
||||
--tui-background-neutral-2-pressed: rgba(255, 255, 255, 0.24);
|
||||
|
||||
--tui-background-accent-1: rgba(53, 96, 240, 1);
|
||||
--tui-background-accent-1-hover: rgba(50, 92, 227, 1);
|
||||
--tui-background-accent-1-pressed: rgba(50, 92, 227, 1); /* update */
|
||||
--tui-background-accent-2: rgba(180, 59, 201, 1);
|
||||
--tui-background-accent-2-hover: rgba(166, 0, 191, 1);
|
||||
--tui-background-accent-2-pressed: rgba(166, 0, 191, 1); /* update */
|
||||
|
||||
--tui-background-elevation-1: rgba(23, 24, 29, 1);
|
||||
--tui-background-elevation-2: rgba(33, 33, 33, 1);
|
||||
--tui-background-elevation-3: rgba(34, 34, 34, 1);
|
||||
|
||||
--tui-border-normal: rgba(255, 255, 255, 0.14);
|
||||
--tui-border-hover: rgba(255, 255, 255, 0.4);
|
||||
|
||||
--tui-status-negative: rgba(236, 46, 52, 1);
|
||||
--tui-status-negative-pale: color-mix(in hsl, var(--tui-status-negative) 12%, transparent);
|
||||
--tui-status-negative-pale-hover: color-mix(in hsl, var(--tui-status-negative) 24%, transparent);
|
||||
--tui-status-positive: rgba(0, 151, 0, 1); /* update */
|
||||
--tui-status-positive-pale: color-mix(in hsl, var(--tui-status-positive) 12%, transparent);
|
||||
--tui-status-positive-pale-hover: color-mix(in hsl, var(--tui-status-positive) 24%, transparent);
|
||||
--tui-status-warning: rgba(255, 179, 0, 1);
|
||||
--tui-status-warning-pale: color-mix(in hsl, var(--tui-status-warning) 12%, transparent);
|
||||
--tui-status-warning-pale-hover: color-mix(in hsl, var(--tui-status-warning) 24%, transparent);
|
||||
--tui-status-info: rgba(128, 89, 229, 1);
|
||||
--tui-status-info-pale: color-mix(in hsl, var(--tui-status-info) 12%, transparent);
|
||||
--tui-status-info-pale-hover: color-mix(in hsl, var(--tui-status-info) 24%, transparent);
|
||||
--tui-status-neutral: rgba(137, 137, 137, 1);
|
||||
|
||||
--tui-text-primary: rgba(255, 255, 255, 1);
|
||||
--tui-text-secondary: rgba(255, 255, 255, 0.7);
|
||||
--tui-text-tertiary: rgba(255, 255, 255, 0.5);
|
||||
|
||||
--tui-text-action: rgba(53, 96, 240, 1);
|
||||
--tui-text-action-hover: rgba(50, 92, 227, 1);
|
||||
--tui-text-positive: rgba(0, 151, 0, 1); /* update */
|
||||
--tui-text-positive-hover: rgba(0, 151, 0, 1); /* update */
|
||||
--tui-text-negative: rgba(236, 46, 52, 1);
|
||||
--tui-text-negative-hover: rgba(236, 46, 52, 1);
|
||||
|
||||
--start9-base-1: rgba(34, 36, 40, 1);
|
||||
--start9-base-2: rgba(46, 47, 52, 1);
|
||||
--start9-base-3: rgba(50, 51, 53, 1);
|
||||
--start9-base-4: rgba(52, 54, 58, 1);
|
||||
--start9-base-5: rgba(60, 62, 64, 1);
|
||||
}
|
||||
|
||||
/* stylelint-disable order/order */
|
||||
[tuiAppearance][data-appearance='secondary-warning'] {
|
||||
background: var(--tui-status-warning-pale);
|
||||
color: var(--tui-text-primary);
|
||||
|
||||
@include appearance-hover {
|
||||
background: var(--tui-status-warning-pale-hover);
|
||||
}
|
||||
|
||||
@include appearance-active {
|
||||
background: var(--tui-status-warning-pale-hover);
|
||||
}
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='icon-success'] {
|
||||
color: var(--tui-status-positive);
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='icon-warning'] {
|
||||
color: var(--tui-status-warning);
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='icon-error'] {
|
||||
color: var(--tui-status-negative);
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='primary'] {
|
||||
[tuiAppearance][data-appearance^='primary'] {
|
||||
@include appearance-disabled {
|
||||
background: #eaecee;
|
||||
background: var(--tui-status-neutral);
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='secondary-solid'] {
|
||||
background: #3dc2ff;
|
||||
color: #fff;
|
||||
|
||||
@include appearance-hover {
|
||||
background: #50c8ff;
|
||||
}
|
||||
|
||||
@include appearance-active {
|
||||
background: #36abe0;
|
||||
}
|
||||
|
||||
@include appearance-disabled {
|
||||
background: #eaecee;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='tertiary-solid'] {
|
||||
background: #5260ff;
|
||||
color: #fff;
|
||||
|
||||
@include appearance-hover {
|
||||
background: #6370ff;
|
||||
}
|
||||
|
||||
@include appearance-active {
|
||||
background: #4854e0;
|
||||
}
|
||||
|
||||
@include appearance-disabled {
|
||||
background: #eaecee;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='success-solid'] {
|
||||
background: #2dd36f;
|
||||
color: #fff;
|
||||
|
||||
@include appearance-hover {
|
||||
background: #42d77d;
|
||||
}
|
||||
|
||||
@include appearance-active {
|
||||
background: #28ba62;
|
||||
}
|
||||
|
||||
@include appearance-disabled {
|
||||
background: #eaecee;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='warning-solid'] {
|
||||
background: #ffc409;
|
||||
color: #fff;
|
||||
|
||||
@include appearance-hover {
|
||||
background: #ffca22;
|
||||
}
|
||||
|
||||
@include appearance-active {
|
||||
background: #e0ac08;
|
||||
}
|
||||
|
||||
@include appearance-disabled {
|
||||
background: #eaecee;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='danger-solid'] {
|
||||
background: #eb445a;
|
||||
color: #fff;
|
||||
|
||||
@include appearance-hover {
|
||||
background: #ed576b;
|
||||
}
|
||||
|
||||
@include appearance-active {
|
||||
background: #cf3c4f;
|
||||
}
|
||||
|
||||
@include appearance-disabled {
|
||||
background: #eaecee;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='input-file'] {
|
||||
&:hover,
|
||||
&:active {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
tui-root._mobile &::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
tui-dialog {
|
||||
transform: translate3d(0, 0, 0);
|
||||
}
|
||||
|
||||
tui-opt-group[data-label^='⚠️']::before {
|
||||
color: var(--tui-status-warning);
|
||||
}
|
||||
|
||||
tui-hint[data-appearance='onDark'] {
|
||||
background: white !important;
|
||||
color: #222 !important;
|
||||
}
|
||||
|
||||
[tuiLink] {
|
||||
color: var(--tui-text-action) !important;
|
||||
|
||||
&:hover {
|
||||
color: var(--tui-text-action-hover) !important;
|
||||
}
|
||||
}
|
||||
|
||||
[tuiAppearance][data-appearance='drawer'] {
|
||||
// TODO: Theme
|
||||
background: rgb(81 80 83 / 86%);
|
||||
border-radius: 10rem;
|
||||
|
||||
&._focused::after {
|
||||
color: var(--tui-background-accent-1);
|
||||
}
|
||||
}
|
||||
|
||||
tui-dropdown[data-appearance='start-os'][data-appearance='start-os'] {
|
||||
border: 0;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(0.25rem);
|
||||
box-shadow: 0 0.25rem 0.25rem rgb(0 0 0 / 25%);
|
||||
border-radius: 0.325rem;
|
||||
// TODO: Replace --tui-background-elevation-2 when Taiga UI is updated
|
||||
background: rgb(63 63 63 / 80%);
|
||||
background-color: color-mix(
|
||||
in hsl,
|
||||
var(--tui-background-elevation-3) 75%,
|
||||
transparent
|
||||
);
|
||||
background-image: linear-gradient(
|
||||
to bottom,
|
||||
rgba(255, 255, 255, 0.15),
|
||||
transparent
|
||||
),
|
||||
linear-gradient(to bottom, rgba(255, 255, 255, 0.15), transparent);
|
||||
background-size: 1px 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-position:
|
||||
top left,
|
||||
top right;
|
||||
box-shadow:
|
||||
0 0.25rem 0.125rem rgba(0, 0, 0, 0.25),
|
||||
0 -0.125rem 0.25rem rgba(55, 155, 255, 0.08),
|
||||
0 0 0.5rem rgba(0, 0, 0, 0.3),
|
||||
inset 0 -0.125rem rgba(255, 255, 255, 0.03),
|
||||
inset 0 1px rgba(255, 255, 255, 0.15),
|
||||
inset 0 0 1rem rgba(0, 0, 0, 0.25),
|
||||
var(--tui-shadow-medium);
|
||||
|
||||
tui-opt-group {
|
||||
&::before {
|
||||
@@ -215,3 +133,7 @@ a[tuiIconButton]:not([href]) {
|
||||
pointer-events: none;
|
||||
opacity: var(--tui-disabled-opacity);
|
||||
}
|
||||
|
||||
tui-badge-notification {
|
||||
background: var(--tui-status-negative);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
<svg-definitions />
|
||||
<tui-root tuiTheme="dark" [class.offline]="offline$ | async">
|
||||
<router-outlet />
|
||||
<toast-container />
|
||||
|
||||
|
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 164 B |
@@ -1,10 +1,8 @@
|
||||
import { Component, inject, OnInit } from '@angular/core'
|
||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'
|
||||
import { Title } from '@angular/platform-browser'
|
||||
import { THEME } from '@start9labs/shared'
|
||||
import { PatchDB } from 'patch-db-client'
|
||||
import { combineLatest, map, merge, startWith } from 'rxjs'
|
||||
import { AuthService } from './services/auth.service'
|
||||
import { ConnectionService } from './services/connection.service'
|
||||
import { PatchDataService } from './services/patch-data.service'
|
||||
import { DataModel } from './services/patch-db/data-model'
|
||||
@@ -19,8 +17,6 @@ export class AppComponent implements OnInit {
|
||||
private readonly title = inject(Title)
|
||||
private readonly patch = inject<PatchDB<DataModel>>(PatchDB)
|
||||
|
||||
readonly auth = inject(AuthService)
|
||||
readonly theme$ = inject(THEME)
|
||||
readonly subscription = merge(
|
||||
inject(PatchDataService),
|
||||
inject(PatchMonitorService),
|
||||
@@ -30,14 +26,13 @@ export class AppComponent implements OnInit {
|
||||
|
||||
readonly offline$ = combineLatest([
|
||||
inject(ConnectionService),
|
||||
this.auth.isVerified$,
|
||||
this.patch
|
||||
.watch$('serverInfo', 'statusInfo')
|
||||
.pipe(startWith({ restarting: false, shuttingDown: false })),
|
||||
]).pipe(
|
||||
map(
|
||||
([connected, verified, status]) =>
|
||||
connected && (!verified || status.restarting || status.shuttingDown),
|
||||
([connected, { restarting, shuttingDown }]) =>
|
||||
connected && (restarting || shuttingDown),
|
||||
),
|
||||
startWith(true),
|
||||
)
|
||||
|
||||
@@ -4,7 +4,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
|
||||
import { ServiceWorkerModule } from '@angular/service-worker'
|
||||
import { TuiRoot } from '@taiga-ui/core'
|
||||
import { SidebarHostComponent } from 'src/app/components/sidebar-host.component'
|
||||
import { SvgDefinitionsComponent } from 'src/app/components/svg-definitions.component'
|
||||
import { ToastContainerComponent } from 'src/app/components/toast-container.component'
|
||||
import { environment } from '../environments/environment'
|
||||
import { AppComponent } from './app.component'
|
||||
@@ -26,7 +25,6 @@ import { RoutingModule } from './routing.module'
|
||||
registrationStrategy: 'registerWhenStable:30000',
|
||||
}),
|
||||
SidebarHostComponent,
|
||||
SvgDefinitionsComponent,
|
||||
],
|
||||
providers: APP_PROVIDERS,
|
||||
bootstrap: [AppComponent],
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
AbstractCategoryService,
|
||||
FilterPackagesPipe,
|
||||
} from '@start9labs/marketplace'
|
||||
import { RELATIVE_URL, THEME, WorkspaceConfig } from '@start9labs/shared'
|
||||
import { RELATIVE_URL, WorkspaceConfig } from '@start9labs/shared'
|
||||
import {
|
||||
TUI_DATE_FORMAT,
|
||||
TUI_DIALOGS_CLOSE,
|
||||
@@ -35,7 +35,6 @@ import { ClientStorageService } from './services/client-storage.service'
|
||||
import { DateTransformerService } from './services/date-transformer.service'
|
||||
import { DatetimeTransformerService } from './services/datetime-transformer.service'
|
||||
import { StorageService } from './services/storage.service'
|
||||
import { ThemeSwitcherService } from './services/theme-switcher.service'
|
||||
|
||||
const {
|
||||
useMocks,
|
||||
@@ -84,10 +83,6 @@ export const APP_PROVIDERS: Provider[] = [
|
||||
provide: RELATIVE_URL,
|
||||
useValue: `/${api.url}/${api.version}`,
|
||||
},
|
||||
{
|
||||
provide: THEME,
|
||||
useExisting: ThemeSwitcherService,
|
||||
},
|
||||
{
|
||||
provide: AbstractCategoryService,
|
||||
useClass: CategoryService,
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core'
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'svg-definitions',
|
||||
template: `
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<filter id="bevel-light">
|
||||
<feFlood flood-color="white" flood-opacity="0.1" />
|
||||
<feComposite in2="SourceAlpha" operator="out" />
|
||||
<feGaussianBlur stdDeviation="0.5" result="blur" />
|
||||
<feOffset dx="-1" dy="1" />
|
||||
<feComposite operator="atop" in2="SourceGraphic" />
|
||||
</filter>
|
||||
<filter id="bevel-dark">
|
||||
<feFlood flood-color="black" flood-opacity="0.3" />
|
||||
<feComposite in2="SourceAlpha" operator="out" />
|
||||
<feGaussianBlur stdDeviation="0.5" result="blur" />
|
||||
<feOffset dx="1" dy="-1" />
|
||||
<feComposite operator="atop" in2="SourceGraphic" />
|
||||
</filter>
|
||||
<filter id="round-corners">
|
||||
<feGaussianBlur in="SourceGraphic" stdDeviation="3" result="blur" />
|
||||
<feColorMatrix
|
||||
in="blur"
|
||||
type="matrix"
|
||||
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9"
|
||||
result="flt_tag"
|
||||
/>
|
||||
<feComposite in="SourceGraphic" in2="flt_tag" operator="atop" />
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
||||
`,
|
||||
styles: `
|
||||
:host {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class SvgDefinitionsComponent {}
|
||||
@@ -28,7 +28,6 @@
|
||||
<a
|
||||
tuiButton
|
||||
size="s"
|
||||
appearance="tertiary-solid"
|
||||
iconEnd="@tui.download"
|
||||
href="/static/local-root-ca.crt"
|
||||
>
|
||||
@@ -61,7 +60,7 @@
|
||||
tuiButton
|
||||
size="s"
|
||||
class="refresh"
|
||||
appearance="success-solid"
|
||||
appearance="positive"
|
||||
iconEnd="@tui.refresh-cw"
|
||||
(click)="refresh()"
|
||||
>
|
||||
@@ -84,22 +83,13 @@
|
||||
|
||||
<ng-template #trusted>
|
||||
<div tuiCardLarge tuiSurface="floating" class="card">
|
||||
<tui-icon
|
||||
icon="@tui.shield"
|
||||
tuiAppearance="icon-success"
|
||||
[style.font-size.rem]="4"
|
||||
/>
|
||||
<tui-icon icon="@tui.shield" class="g-success" [style.font-size.rem]="4" />
|
||||
<h1>Root CA Trusted!</h1>
|
||||
<p>
|
||||
You have successfully trusted your server's Root CA and may now log in
|
||||
securely.
|
||||
</p>
|
||||
<button
|
||||
tuiButton
|
||||
appearance="tertiary-solid"
|
||||
iconEnd="@tui.external-link"
|
||||
(click)="launchHttps()"
|
||||
>
|
||||
<button tuiButton iconEnd="@tui.external-link" (click)="launchHttps()">
|
||||
Go to login
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { CommonModule, DOCUMENT } from '@angular/common'
|
||||
import { Component, inject } from '@angular/core'
|
||||
import { RELATIVE_URL } from '@start9labs/shared'
|
||||
import { TuiAppearance, TuiButton, TuiIcon, TuiSurface } from '@taiga-ui/core'
|
||||
import { TuiButton, TuiIcon, TuiSurface } from '@taiga-ui/core'
|
||||
import { TuiCardLarge } from '@taiga-ui/layout'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { ConfigService } from 'src/app/services/config.service'
|
||||
@@ -11,14 +11,7 @@ import { ConfigService } from 'src/app/services/config.service'
|
||||
selector: 'ca-wizard',
|
||||
templateUrl: './ca-wizard.component.html',
|
||||
styleUrls: ['./ca-wizard.component.scss'],
|
||||
imports: [
|
||||
CommonModule,
|
||||
TuiIcon,
|
||||
TuiButton,
|
||||
TuiAppearance,
|
||||
TuiCardLarge,
|
||||
TuiSurface,
|
||||
],
|
||||
imports: [CommonModule, TuiIcon, TuiButton, TuiCardLarge, TuiSurface],
|
||||
})
|
||||
export class CAWizardComponent {
|
||||
private readonly api = inject(ApiService)
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
Password
|
||||
</tui-input-password>
|
||||
<tui-error class="error" [error]="error || null" />
|
||||
<button tuiButton class="button" appearance="tertiary-solid">
|
||||
Login
|
||||
</button>
|
||||
<button tuiButton class="button">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
width: max(33%, 20rem);
|
||||
background: var(--tui-background-base-alt);
|
||||
background: var(--start9-base-1);
|
||||
box-shadow: var(--tui-shadow-small);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
class="button"
|
||||
[class.button_open]="open"
|
||||
[style.border-radius.%]="100"
|
||||
[appearance]="invalid ? 'danger-solid' : 'secondary'"
|
||||
[appearance]="invalid ? 'primary-destructive' : 'secondary'"
|
||||
></button>
|
||||
<ng-content />
|
||||
{{ spec.name }}
|
||||
|
||||
@@ -54,7 +54,11 @@ import { HeaderStatusComponent } from './status.component'
|
||||
border-radius: inherit;
|
||||
backdrop-filter: blur(1rem);
|
||||
transform: skewX(30deg);
|
||||
background: rgb(75 75 75 / 65%);
|
||||
background: color-mix(
|
||||
in hsl,
|
||||
var(--start9-base-2) 75%,
|
||||
transparent
|
||||
);
|
||||
box-shadow: inset 0 1px rgb(255 255 255 / 25%);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ import { ABOUT } from './about.component'
|
||||
<a
|
||||
tuiOption
|
||||
iconStart="@tui.wrench"
|
||||
routerLink="/portal/system/settings"
|
||||
routerLink="/portal/settings"
|
||||
(click)="open = false"
|
||||
>
|
||||
System Settings
|
||||
|
||||
@@ -94,7 +94,7 @@ import { getMenu } from 'src/app/utils/system-utilities'
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
transform: skewX(30deg);
|
||||
background: rgb(75 75 75 / 65%);
|
||||
background: color-mix(in hsl, var(--start9-base-2) 75%, transparent);
|
||||
box-shadow: inset 0 1px rgb(255 255 255 / 25%);
|
||||
z-index: -1;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ import { getMenu } from 'src/app/utils/system-utilities'
|
||||
|
||||
&::before {
|
||||
border-radius: var(--bumper);
|
||||
filter: brightness(0.65);
|
||||
filter: brightness(0.5);
|
||||
}
|
||||
|
||||
span {
|
||||
|
||||
@@ -42,7 +42,7 @@ export class ClearnetAddressesDirective implements AddressesService {
|
||||
buttons: [
|
||||
{
|
||||
text: 'Manage domains',
|
||||
link: 'portal/system/settings/domains',
|
||||
link: 'portal/settings/domains',
|
||||
},
|
||||
{
|
||||
text: 'Save',
|
||||
|
||||
@@ -15,11 +15,7 @@ import { BadgeService } from 'src/app/services/badge.service'
|
||||
import { RESOURCES } from 'src/app/utils/resources'
|
||||
import { getMenu } from 'src/app/utils/system-utilities'
|
||||
|
||||
const FILTER = [
|
||||
'/portal/services',
|
||||
'/portal/system/settings',
|
||||
'/portal/system/marketplace',
|
||||
]
|
||||
const FILTER = ['/portal/services', '/portal/settings', '/portal/marketplace']
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
@@ -38,7 +34,7 @@ const FILTER = [
|
||||
<a
|
||||
tuiTabBarItem
|
||||
icon="@tui.shopping-cart"
|
||||
routerLink="/portal/system/marketplace"
|
||||
routerLink="/portal/marketplace"
|
||||
routerLinkActive
|
||||
(isActiveChange)="update()"
|
||||
>
|
||||
@@ -47,7 +43,7 @@ const FILTER = [
|
||||
<a
|
||||
tuiTabBarItem
|
||||
icon="@tui.settings"
|
||||
routerLink="/portal/system/settings"
|
||||
routerLink="/portal/settings"
|
||||
routerLinkActive
|
||||
[badge]="badge()"
|
||||
(isActiveChange)="update()"
|
||||
@@ -145,10 +141,9 @@ export class TabsComponent {
|
||||
|
||||
readonly resources = RESOURCES
|
||||
readonly menu = getMenu().filter(item => !FILTER.includes(item.routerLink))
|
||||
readonly badge = toSignal(
|
||||
inject(BadgeService).getCount('/portal/system/settings'),
|
||||
{ initialValue: 0 },
|
||||
)
|
||||
readonly badge = toSignal(inject(BadgeService).getCount('/portal/settings'), {
|
||||
initialValue: 0,
|
||||
})
|
||||
|
||||
readonly all = computed(() =>
|
||||
this.menu.reduce((acc, item) => acc + item.badge(), 0),
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { Routes } from '@angular/router'
|
||||
import { ActivatedRouteSnapshot, Routes } from '@angular/router'
|
||||
import { PackageDataEntry } from '../../services/patch-db/data-model'
|
||||
import { getManifest } from '../../utils/get-package-data'
|
||||
import { SYSTEM_UTILITIES } from '../../utils/system-utilities'
|
||||
import { toRouterLink } from '../../utils/to-router-link'
|
||||
import { PortalComponent } from './portal.component'
|
||||
|
||||
const ROUTES: Routes = [
|
||||
@@ -14,15 +18,85 @@ const ROUTES: Routes = [
|
||||
{
|
||||
path: 'services',
|
||||
loadChildren: () =>
|
||||
import('./routes/service/service.module').then(m => m.ServiceModule),
|
||||
import('./routes/services/services.module').then(
|
||||
m => m.ServicesModule,
|
||||
),
|
||||
},
|
||||
{
|
||||
path: 'system',
|
||||
loadChildren: () =>
|
||||
import('./routes/system/system.module').then(m => m.SystemModule),
|
||||
title: systemTabResolver,
|
||||
path: 'backups',
|
||||
loadComponent: () => import('./routes/backups/backups.component'),
|
||||
data: toNavigationItem('/portal/backups'),
|
||||
},
|
||||
{
|
||||
title: systemTabResolver,
|
||||
path: 'logs',
|
||||
loadComponent: () => import('./routes/logs/logs.component'),
|
||||
data: toNavigationItem('/portal/logs'),
|
||||
},
|
||||
{
|
||||
title: systemTabResolver,
|
||||
path: 'marketplace',
|
||||
loadChildren: () => import('./routes/marketplace/marketplace.routes'),
|
||||
data: toNavigationItem('/portal/marketplace'),
|
||||
},
|
||||
{
|
||||
title: systemTabResolver,
|
||||
path: 'settings',
|
||||
loadChildren: () => import('./routes/settings/settings.routes'),
|
||||
data: toNavigationItem('/portal/settings'),
|
||||
},
|
||||
{
|
||||
title: systemTabResolver,
|
||||
path: 'notifications',
|
||||
loadComponent: () =>
|
||||
import('./routes/notifications/notifications.component'),
|
||||
data: toNavigationItem('/portal/notifications'),
|
||||
},
|
||||
{
|
||||
title: systemTabResolver,
|
||||
path: 'sideload',
|
||||
loadComponent: () => import('./routes/sideload/sideload.component'),
|
||||
data: toNavigationItem('/portal/sideload'),
|
||||
},
|
||||
// {
|
||||
// title: systemTabResolver,
|
||||
// path: 'updates',
|
||||
// loadComponent: () => import('./routes/updates/updates.component'),
|
||||
// data: toNavigationItem('/portal/updates'),
|
||||
// },
|
||||
{
|
||||
title: systemTabResolver,
|
||||
path: 'metrics',
|
||||
loadComponent: () => import('./routes/metrics/metrics.component'),
|
||||
data: toNavigationItem('/portal/metrics'),
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
export default ROUTES
|
||||
|
||||
function systemTabResolver({ data }: ActivatedRouteSnapshot): string {
|
||||
return data['title']
|
||||
}
|
||||
|
||||
function toNavigationItem(
|
||||
id: string,
|
||||
packages: Record<string, PackageDataEntry> = {},
|
||||
) {
|
||||
const item = SYSTEM_UTILITIES[id]
|
||||
const routerLink = toRouterLink(id)
|
||||
|
||||
return SYSTEM_UTILITIES[id]
|
||||
? {
|
||||
icon: item.icon,
|
||||
title: item.title,
|
||||
routerLink,
|
||||
}
|
||||
: {
|
||||
icon: packages[id]?.icon,
|
||||
title: getManifest(packages[id]).title,
|
||||
routerLink,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import { HasErrorPipe } from '../pipes/has-error.pipe'
|
||||
Past Events
|
||||
<button
|
||||
tuiButton
|
||||
appearance="danger-solid"
|
||||
appearance="primary-destructive"
|
||||
[disabled]="disabled"
|
||||
(click)="delete()"
|
||||
>
|
||||
@@ -6,6 +6,6 @@ import { Pipe, PipeTransform } from '@angular/core'
|
||||
})
|
||||
export class DurationPipe implements PipeTransform {
|
||||
transform(start: string, finish: string): number {
|
||||
return (new Date(finish).valueOf() - new Date(start).valueOf()) / 100
|
||||
return (new Date(finish).valueOf() - new Date(start).valueOf()) / 1000 / 60
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import { TuiTextfieldControllerModule, TuiSelectModule } from '@taiga-ui/legacy'
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { TuiSelectModule, TuiTextfieldControllerModule } from '@taiga-ui/legacy'
|
||||
import { LogsComponent } from 'src/app/routes/portal/components/logs/logs.component'
|
||||
import { RR } from 'src/app/services/api/api.types'
|
||||
import { LogsComponent } from '../../../components/logs/logs.component'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
@@ -42,7 +42,7 @@ import { ToManifestPipe } from 'src/app/routes/portal/pipes/to-manifest'
|
||||
<button
|
||||
tuiButton
|
||||
type="button"
|
||||
appearance="warning-solid"
|
||||
appearance="secondary-destructive"
|
||||
(click)="tryInstall()"
|
||||
>
|
||||
Downgrade
|
||||
@@ -62,7 +62,7 @@ import { ToManifestPipe } from 'src/app/routes/portal/pipes/to-manifest'
|
||||
<button
|
||||
tuiButton
|
||||
type="button"
|
||||
appearance="tertiary-solid"
|
||||
appearance="secondary-grayscale"
|
||||
(click)="tryInstall()"
|
||||
>
|
||||
Reinstall
|
||||
@@ -50,6 +50,7 @@ import { MarketplaceControlsComponent } from './controls.component'
|
||||
type="button"
|
||||
appearance="icon"
|
||||
iconStart="@tui.x"
|
||||
[tuiAppearanceFocus]="false"
|
||||
(click)="toggle(false)"
|
||||
></button>
|
||||
<marketplace-controls
|
||||
@@ -2,10 +2,10 @@ import { AsyncPipe } from '@angular/common'
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core'
|
||||
import { toSignal } from '@angular/core/rxjs-interop'
|
||||
import { TuiProgress } from '@taiga-ui/kit'
|
||||
import { CpuComponent } from 'src/app/routes/portal/routes/system/metrics/cpu.component'
|
||||
import { TemperatureComponent } from 'src/app/routes/portal/routes/system/metrics/temperature.component'
|
||||
import { MetricComponent } from 'src/app/routes/portal/routes/system/metrics/metric.component'
|
||||
import { MetricsService } from 'src/app/routes/portal/routes/system/metrics/metrics.service'
|
||||
import { CpuComponent } from 'src/app/routes/portal/routes/metrics/cpu.component'
|
||||
import { TemperatureComponent } from 'src/app/routes/portal/routes/metrics/temperature.component'
|
||||
import { MetricComponent } from 'src/app/routes/portal/routes/metrics/metric.component'
|
||||
import { MetricsService } from 'src/app/routes/portal/routes/metrics/metrics.service'
|
||||
import { TimeService } from 'src/app/services/time.service'
|
||||
|
||||
@Component({
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { tuiPure } from '@taiga-ui/cdk'
|
||||
import { tuiButtonOptionsProvider } from '@taiga-ui/core'
|
||||
import { DependencyInfo } from 'src/app/routes/portal/routes/service/types/dependency-info'
|
||||
import { DependencyInfo } from 'src/app/routes/portal/routes/services/types/dependency-info'
|
||||
import { ControlsService } from '../../../../../services/controls.service'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { PackageStatus } from 'src/app/services/pkg-status-rendering.service'
|
||||
@@ -22,7 +22,7 @@ const STOPPABLE = ['running', 'starting', 'restarting']
|
||||
@if (canStop) {
|
||||
<button
|
||||
tuiButton
|
||||
appearance="danger-solid"
|
||||
appearance="primary-destructive"
|
||||
iconStart="@tui.square"
|
||||
(click)="actions.stop(manifest)"
|
||||
>
|
||||
@@ -24,9 +24,9 @@ import { T } from '@start9labs/start-sdk'
|
||||
<a
|
||||
tuiButton
|
||||
iconStart="@tui.square-plus"
|
||||
routerLink="/portal/system/backups"
|
||||
routerLink="/portal/backups"
|
||||
size="s"
|
||||
appearance="secondary-warning"
|
||||
appearance="warning"
|
||||
>
|
||||
Manage
|
||||
</a>
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
Input,
|
||||
} from '@angular/core'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { ServiceHealthCheckComponent } from 'src/app/routes/portal/routes/service/components/health-check.component'
|
||||
import { ServiceHealthCheckComponent } from 'src/app/routes/portal/routes/services/components/health-check.component'
|
||||
import { ConnectionService } from 'src/app/services/connection.service'
|
||||
|
||||
@Component({
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ChangeDetectionStrategy, Component, Input } from '@angular/core'
|
||||
import { T } from '@start9labs/start-sdk'
|
||||
import { TuiProgress } from '@taiga-ui/kit'
|
||||
import { InstallingProgressPipe } from 'src/app/routes/portal/routes/service/pipes/install-progress.pipe'
|
||||
import { InstallingProgressPipe } from 'src/app/routes/portal/routes/services/pipes/install-progress.pipe'
|
||||
|
||||
@Component({
|
||||
selector: '[progress]',
|
||||
@@ -18,6 +18,7 @@ import { ServicesService } from './services.service'
|
||||
<th [style.width.rem]="3"></th>
|
||||
<th tuiTh [requiredSort]="true" [sorter]="name">Name</th>
|
||||
<th tuiTh>Version</th>
|
||||
<th tuiTh [requiredSort]="true" [sorter]="uptime">Uptime</th>
|
||||
<th
|
||||
tuiTh
|
||||
[requiredSort]="true"
|
||||
@@ -38,7 +39,7 @@ import { ServicesService } from './services.service'
|
||||
></tr>
|
||||
} @empty {
|
||||
<tr>
|
||||
<td colspan="5">
|
||||
<td colspan="6">
|
||||
{{ services() ? 'No services installed' : 'Loading...' }}
|
||||
</td>
|
||||
</tr>
|
||||
@@ -98,5 +99,8 @@ export class DashboardComponent {
|
||||
readonly status: TuiComparator<PackageDataEntry> = (a, b) =>
|
||||
getInstalledPrimaryStatus(b) > getInstalledPrimaryStatus(a) ? -1 : 1
|
||||
|
||||
readonly uptime: TuiComparator<any> = (a, b) =>
|
||||
a.startedAt || '' > b.startedAt || '' ? -1 : 1
|
||||
|
||||
sorter = this.name
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import { ConnectionService } from 'src/app/services/connection.service'
|
||||
import { PkgDependencyErrors } from 'src/app/services/dep-error.service'
|
||||
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
|
||||
import { getManifest } from 'src/app/utils/get-package-data'
|
||||
import { UptimeComponent } from './uptime.component'
|
||||
import { ControlsComponent } from './controls.component'
|
||||
import { StatusComponent } from './status.component'
|
||||
|
||||
@@ -26,6 +27,7 @@ import { StatusComponent } from './status.component'
|
||||
<a [routerLink]="routerLink">{{ manifest.title }}</a>
|
||||
</td>
|
||||
<td [style.grid-area]="'2 / 2'">{{ manifest.version }}</td>
|
||||
<td [appUptime]="$any(pkg).startedAt"></td>
|
||||
<td
|
||||
[style.grid-area]="'3 / 2'"
|
||||
appStatus
|
||||
@@ -97,7 +99,13 @@ import { StatusComponent } from './status.component'
|
||||
`,
|
||||
hostDirectives: [RouterLink],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [RouterLink, AsyncPipe, StatusComponent, ControlsComponent],
|
||||
imports: [
|
||||
RouterLink,
|
||||
AsyncPipe,
|
||||
StatusComponent,
|
||||
ControlsComponent,
|
||||
UptimeComponent,
|
||||
],
|
||||
})
|
||||
export class ServiceComponent implements OnChanges {
|
||||
private readonly link = inject(RouterLink)
|
||||
@@ -0,0 +1,49 @@
|
||||
import { Component, Input, OnChanges, OnDestroy } from '@angular/core'
|
||||
import { tuiInjectElement } from '@taiga-ui/cdk'
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: '[appUptime]',
|
||||
template: '',
|
||||
styles: `
|
||||
:host-context(tui-root._mobile) {
|
||||
display: none;
|
||||
}
|
||||
`,
|
||||
})
|
||||
export class UptimeComponent implements OnChanges, OnDestroy {
|
||||
private readonly el = tuiInjectElement()
|
||||
private interval: any = NaN
|
||||
|
||||
@Input()
|
||||
appUptime = ''
|
||||
|
||||
ngOnChanges() {
|
||||
if (!this.appUptime) {
|
||||
this.el.textContent = '-'
|
||||
} else {
|
||||
clearInterval(this.interval)
|
||||
this.el.textContent = uptime(new Date(this.appUptime))
|
||||
this.interval = setInterval(() => {
|
||||
this.el.textContent = uptime(new Date(this.appUptime))
|
||||
}, 60 * 1000)
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
clearInterval(this.interval)
|
||||
}
|
||||
}
|
||||
|
||||
function uptime(date: Date): string {
|
||||
const delta = Date.now() - date.getTime()
|
||||
const days = Math.floor(delta / (1000 * 60 * 60 * 24))
|
||||
const hours = Math.floor((delta / (1000 * 60 * 60)) % 24)
|
||||
const minutes = Math.floor((delta / (1000 * 60)) % 60)
|
||||
|
||||
if (days > 0) return `${days}d ${hours}h ${minutes}m`
|
||||
|
||||
if (hours > 0) return `${hours}h ${minutes}m`
|
||||
|
||||
return `${minutes}m`
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user