From 8cfd99417048b0b5352428b9a206161788047796 Mon Sep 17 00:00:00 2001 From: Alex Inkin Date: Thu, 28 Mar 2024 00:27:51 +0800 Subject: [PATCH] fix: address todos (#2578) --- sdk/package-lock.json | 302 +++++++++++++----- sdk/package.json | 6 +- web/package.json | 32 +- web/projects/shared/styles/shared.scss | 5 +- .../routes/dashboard/controls.component.ts | 42 ++- .../routes/dashboard/services.component.ts | 2 +- .../routes/dashboard/status.component.ts | 12 +- .../portal/routes/dashboard/ui.component.ts | 20 +- .../system/settings/settings.service.ts | 46 ++- .../{pipes => }/filter-updates.pipe.ts | 0 .../{components => }/item.component.ts | 55 ++-- .../system/updates/updates.component.ts | 4 +- .../app/apps/portal/services/badge.service.ts | 8 +- .../src/app/services/patch-monitor.service.ts | 3 +- .../ui/src/app/util/get-package-data.ts | 6 +- web/projects/ui/src/styles.scss | 8 +- 16 files changed, 359 insertions(+), 192 deletions(-) rename web/projects/ui/src/app/apps/portal/routes/system/updates/{pipes => }/filter-updates.pipe.ts (100%) rename web/projects/ui/src/app/apps/portal/routes/system/updates/{components => }/item.component.ts (84%) diff --git a/sdk/package-lock.json b/sdk/package-lock.json index f0d61ea4d..1f0e5a5ac 100644 --- a/sdk/package-lock.json +++ b/sdk/package-lock.json @@ -15,6 +15,7 @@ "devDependencies": { "@iarna/toml": "^2.2.5", "@types/jest": "^29.4.0", + "copyfiles": "^2.4.1", "jest": "^29.4.3", "prettier": "^3.2.5", "ts-jest": "^29.0.5", @@ -1525,35 +1526,6 @@ "node": ">=12" } }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -1600,6 +1572,69 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/copyfiles": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-2.4.1.tgz", + "integrity": "sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==", + "dev": true, + "dependencies": { + "glob": "^7.0.5", + "minimatch": "^3.0.3", + "mkdirp": "^1.0.4", + "noms": "0.0.0", + "through2": "^2.0.1", + "untildify": "^4.0.0", + "yargs": "^16.1.0" + }, + "bin": { + "copyfiles": "copyfiles", + "copyup": "copyfiles" + } + }, + "node_modules/copyfiles/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/copyfiles/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/copyfiles/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -1697,6 +1732,12 @@ "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2035,6 +2076,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-generator-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", @@ -2065,6 +2115,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2926,6 +2982,18 @@ "node": "*" } }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2950,6 +3018,16 @@ "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true }, + "node_modules/noms": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "integrity": "sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "~1.0.31" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -3177,6 +3255,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -3212,6 +3296,18 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -3277,6 +3373,12 @@ "node": ">=10" } }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -3365,6 +3467,12 @@ "node": ">=10" } }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -3378,6 +3486,20 @@ "node": ">=10" } }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3458,6 +3580,46 @@ "node": ">=8" } }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -4057,6 +4219,15 @@ "node": ">=12.20" } }, + "node_modules/untildify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -4083,6 +4254,12 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -4169,35 +4346,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4217,6 +4365,15 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -4268,35 +4425,6 @@ "node": ">=12" } }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/sdk/package.json b/sdk/package.json index 6176f4d8e..b64f336d4 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -15,6 +15,7 @@ } }, "scripts": { + "build": "tsc && tsc --project tsconfig-cjs.json && copyfiles package.json dist", "test": "jest -c ./jest.config.js --coverage", "buildOutput": "ts-node --project ./tsconfig-cjs.json ./lib/test/makeOutput.ts && npx prettier --write '**/*.ts'", "check": "tsc --noEmit" @@ -41,13 +42,14 @@ }, "devDependencies": { "@iarna/toml": "^2.2.5", - "yaml": "^2.2.2", "@types/jest": "^29.4.0", + "copyfiles" : "^2.4.1", "jest": "^29.4.3", "prettier": "^3.2.5", "ts-jest": "^29.0.5", "ts-node": "^10.9.1", "tsx": "^4.7.1", - "typescript": "^5.0.4" + "typescript": "^5.0.4", + "yaml": "^2.2.2" } } diff --git a/web/package.json b/web/package.json index 20d18d919..012d56b94 100644 --- a/web/package.json +++ b/web/package.json @@ -11,7 +11,7 @@ "check:install": "tsc --project projects/install-wizard/tsconfig.json --noEmit --skipLibCheck", "check:setup": "tsc --project projects/setup-wizard/tsconfig.json --noEmit --skipLibCheck", "check:ui": "tsc --project projects/ui/tsconfig.json --noEmit --skipLibCheck", - "build:deps": "npx rimraf .angular/cache && (cd ../patch-db/client && npm ci && npm run build) && (cd ../sdk && make bundle)", + "build:deps": "npx rimraf .angular/cache && (cd ../sdk && npm ci && npm run build) && (cd ../patch-db/client && npm ci && npm run build)", "build:install": "ng run install-wizard:build", "build:setup": "ng run setup-wizard:build", "build:ui": "ng run ui:build", @@ -30,17 +30,17 @@ "build-config": "node build-config.js" }, "dependencies": { - "@angular/animations": "^17.0.6", - "@angular/cdk": "^17.0.3", - "@angular/common": "^17.0.6", - "@angular/compiler": "^17.0.6", - "@angular/core": "^17.0.6", - "@angular/forms": "^17.0.6", - "@angular/platform-browser": "^17.0.6", - "@angular/platform-browser-dynamic": "^17.0.6", - "@angular/pwa": "^17.0.6", - "@angular/router": "^17.0.6", - "@angular/service-worker": "^17.0.6", + "@angular/animations": "^17.3.1", + "@angular/cdk": "^17.3.1", + "@angular/common": "^17.3.1", + "@angular/compiler": "^17.3.1", + "@angular/core": "^17.3.1", + "@angular/forms": "^17.3.1", + "@angular/platform-browser": "^17.3.1", + "@angular/platform-browser-dynamic": "^17.3.1", + "@angular/pwa": "^17.3.1", + "@angular/router": "^17.3.1", + "@angular/service-worker": "^17.3.1", "@ionic/angular": "^6.1.15", "@materia-ui/ngx-monaco-editor": "^6.0.0", "@start9labs/argon2": "^0.1.0", @@ -84,10 +84,10 @@ "zone.js": "^0.14.2" }, "devDependencies": { - "@angular-devkit/build-angular": "^17.0.6", - "@angular/cli": "^17.0.6", - "@angular/compiler-cli": "^17.0.6", - "@angular/language-service": "^17.0.6", + "@angular-devkit/build-angular": "^17.3.1", + "@angular/cli": "^17.3.1", + "@angular/compiler-cli": "^17.3.1", + "@angular/language-service": "^17.3.1", "@ionic/cli": "^6.19.0", "@types/dompurify": "^2.3.3", "@types/estree": "^0.0.51", diff --git a/web/projects/shared/styles/shared.scss b/web/projects/shared/styles/shared.scss index 73d206721..1752c198f 100644 --- a/web/projects/shared/styles/shared.scss +++ b/web/projects/shared/styles/shared.scss @@ -225,7 +225,6 @@ h3, h4, h5, h6, -hr, -p { +hr { margin: 0; -} \ No newline at end of file +} diff --git a/web/projects/ui/src/app/apps/portal/routes/dashboard/controls.component.ts b/web/projects/ui/src/app/apps/portal/routes/dashboard/controls.component.ts index 9fc5faa22..4ca933b89 100644 --- a/web/projects/ui/src/app/apps/portal/routes/dashboard/controls.component.ts +++ b/web/projects/ui/src/app/apps/portal/routes/dashboard/controls.component.ts @@ -2,7 +2,9 @@ import { AsyncPipe } from '@angular/common' import { ChangeDetectionStrategy, Component, + computed, inject, + input, Input, } from '@angular/core' import { TuiLetModule, tuiPure } from '@taiga-ui/cdk' @@ -22,11 +24,11 @@ import { Manifest } from '@start9labs/marketplace' standalone: true, selector: 'fieldset[appControls]', template: ` - @if (pkg.status.main.status === 'running') { + @if (pkg().status.main.status === 'running') { @@ -34,7 +36,7 @@ import { Manifest } from '@start9labs/marketplace' @@ -43,8 +45,8 @@ import { Manifest } from '@start9labs/marketplace' *tuiLet="hasUnmet() | async as hasUnmet" tuiIconButton iconLeft="tuiIconPlay" - [disabled]="!pkg.status.configured" - (click)="actions.start(manifest, !!hasUnmet)" + [disabled]="!pkg().status.configured" + (click)="actions.start(manifest(), !!hasUnmet)" > Start @@ -52,39 +54,33 @@ import { Manifest } from '@start9labs/marketplace' } - + `, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TuiButtonModule, UILaunchComponent, TuiLetModule, AsyncPipe], providers: [tuiButtonOptionsProvider({ size: 's', appearance: 'none' })], + styles: ':host { padding: 0; border: none }', }) export class ControlsComponent { private readonly errors = inject(DepErrorService) - - @Input() - pkg!: PackageDataEntry - - get manifest(): Manifest { - return getManifest(this.pkg) - } - readonly actions = inject(ActionsService) - @tuiPure - hasUnmet(): Observable { - const id = this.manifest.id - return this.errors.getPkgDepErrors$(id).pipe( + pkg = input.required() + + readonly manifest = computed(() => getManifest(this.pkg())) + readonly hasUnmet = computed(() => + this.errors.getPkgDepErrors$(this.manifest().id).pipe( map(errors => - Object.keys(this.pkg.currentDependencies) - .map(id => !!(errors[id] as any)?.[id]) // @TODO-Alex fix + Object.keys(this.pkg().currentDependencies) + .map(id => !!(errors[id] as any)?.[id]) // @TODO fix type .some(Boolean), ), - ) - } + ), + ) } diff --git a/web/projects/ui/src/app/apps/portal/routes/dashboard/services.component.ts b/web/projects/ui/src/app/apps/portal/routes/dashboard/services.component.ts index c40212420..2d976c199 100644 --- a/web/projects/ui/src/app/apps/portal/routes/dashboard/services.component.ts +++ b/web/projects/ui/src/app/apps/portal/routes/dashboard/services.component.ts @@ -16,7 +16,7 @@ import { ToManifestPipe } from '../../pipes/to-manifest' Name Version - Status + Status Controls diff --git a/web/projects/ui/src/app/apps/portal/routes/dashboard/status.component.ts b/web/projects/ui/src/app/apps/portal/routes/dashboard/status.component.ts index af1003bb0..3343df80a 100644 --- a/web/projects/ui/src/app/apps/portal/routes/dashboard/status.component.ts +++ b/web/projects/ui/src/app/apps/portal/routes/dashboard/status.component.ts @@ -1,4 +1,9 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core' +import { + ChangeDetectionStrategy, + Component, + inject, + Input, +} from '@angular/core' import { tuiPure } from '@taiga-ui/cdk' import { TuiLoaderModule } from '@taiga-ui/core' import { TuiIconModule } from '@taiga-ui/experimental' @@ -35,8 +40,11 @@ import { InstallingProgressDisplayPipe } from '../service/pipes/install-progress `, changeDetection: ChangeDetectionStrategy.OnPush, imports: [TuiIconModule, TuiLoaderModule], + providers: [InstallingProgressDisplayPipe], }) export class StatusComponent { + private readonly pipe = inject(InstallingProgressDisplayPipe) + @Input() pkg!: PackageDataEntry @@ -64,7 +72,7 @@ export class StatusComponent { get status(): string { if (this.pkg.stateInfo.installingInfo) { - return `Installing...${new InstallingProgressDisplayPipe().transform(this.pkg.stateInfo.installingInfo.progress.overall)}` + return `Installing... ${this.pipe.transform(this.pkg.stateInfo.installingInfo.progress.overall)}` } switch (this.getStatus(this.pkg).primary) { diff --git a/web/projects/ui/src/app/apps/portal/routes/dashboard/ui.component.ts b/web/projects/ui/src/app/apps/portal/routes/dashboard/ui.component.ts index 5d917b949..8cb56f1cc 100644 --- a/web/projects/ui/src/app/apps/portal/routes/dashboard/ui.component.ts +++ b/web/projects/ui/src/app/apps/portal/routes/dashboard/ui.component.ts @@ -43,17 +43,15 @@ import { } @else { - @if (interfaces[0]; as info) { - - {{ info.name }} - - } + + {{ interfaces[0]?.name }} + } `, changeDetection: ChangeDetectionStrategy.OnPush, diff --git a/web/projects/ui/src/app/apps/portal/routes/system/settings/settings.service.ts b/web/projects/ui/src/app/apps/portal/routes/system/settings/settings.service.ts index 5f2425a8b..c55add8c1 100644 --- a/web/projects/ui/src/app/apps/portal/routes/system/settings/settings.service.ts +++ b/web/projects/ui/src/app/apps/portal/routes/system/settings/settings.service.ts @@ -1,8 +1,15 @@ -import { inject, Injectable } from '@angular/core' +import { + ChangeDetectionStrategy, + Component, + inject, + Injectable, +} from '@angular/core' +import { FormsModule } from '@angular/forms' import { TuiAlertService, TuiDialogService } from '@taiga-ui/core' import * as argon2 from '@start9labs/argon2' import { ErrorService, LoadingService } from '@start9labs/shared' -import { TUI_PROMPT } from '@taiga-ui/kit' +import { TUI_PROMPT, TuiCheckboxLabeledModule } from '@taiga-ui/kit' +import { PolymorpheusComponent } from '@tinkoff/ng-polymorpheus' import { PatchDB } from 'patch-db-client' import { filter, firstValueFrom, from, take } from 'rxjs' import { switchMap } from 'rxjs/operators' @@ -30,6 +37,8 @@ export class SettingsService { private readonly api = inject(ApiService) private readonly isTor = inject(ConfigService).isTor() + wipe = false + readonly settings: Record = { General: [ { @@ -122,19 +131,19 @@ export class SettingsService { await this.proxyService.presentModalSetOutboundProxy(proxy) } - // @TODO-Alex previous this was done in experimental settings using a template ref. private promptResetTor() { + this.wipe = false this.dialogs .open(TUI_PROMPT, { label: this.isTor ? 'Warning' : 'Confirm', data: { - content: '@TODO how to display a checkbox in here?', + content: new PolymorpheusComponent(WipeComponent), yes: 'Reset', no: 'Cancel', }, }) .pipe(filter(Boolean)) - .subscribe(() => this.resetTor(true)) + .subscribe(() => this.resetTor(this.wipe)) } private async resetTor(wipeState: boolean) { @@ -258,3 +267,30 @@ export class SettingsService { } } } + +@Component({ + standalone: true, + template: ` +

+ @if (isTor) { + You are currently connected over Tor. If you reset the Tor daemon, you + will lose connectivity until it comes back online. + } @else { + Reset Tor? + } +

+

+ Optionally wipe state to forcibly acquire new guard nodes. It is + recommended to try without wiping state first. +

+ + Wipe state + + `, + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [TuiCheckboxLabeledModule, FormsModule], +}) +class WipeComponent { + readonly isTor = inject(ConfigService).isTor() + readonly service = inject(SettingsService) +} diff --git a/web/projects/ui/src/app/apps/portal/routes/system/updates/pipes/filter-updates.pipe.ts b/web/projects/ui/src/app/apps/portal/routes/system/updates/filter-updates.pipe.ts similarity index 100% rename from web/projects/ui/src/app/apps/portal/routes/system/updates/pipes/filter-updates.pipe.ts rename to web/projects/ui/src/app/apps/portal/routes/system/updates/filter-updates.pipe.ts diff --git a/web/projects/ui/src/app/apps/portal/routes/system/updates/components/item.component.ts b/web/projects/ui/src/app/apps/portal/routes/system/updates/item.component.ts similarity index 84% rename from web/projects/ui/src/app/apps/portal/routes/system/updates/components/item.component.ts rename to web/projects/ui/src/app/apps/portal/routes/system/updates/item.component.ts index 40dda37d4..f08ca2d9a 100644 --- a/web/projects/ui/src/app/apps/portal/routes/system/updates/components/item.component.ts +++ b/web/projects/ui/src/app/apps/portal/routes/system/updates/item.component.ts @@ -1,4 +1,3 @@ -import { NgIf } from '@angular/common' import { Component, inject, Input } from '@angular/core' import { RouterLink } from '@angular/router' import { @@ -27,17 +26,17 @@ import { TuiProgressModule, } from '@taiga-ui/kit' import { NgDompurifyModule } from '@tinkoff/ng-dompurify' +import { PatchDB } from 'patch-db-client' +import { InstallingProgressPipe } from 'src/app/apps/portal/routes/service/pipes/install-progress.pipe' +import { MarketplaceService } from 'src/app/services/marketplace.service' import { DataModel, InstalledState, PackageDataEntry, UpdatingState, } from 'src/app/services/patch-db/data-model' -import { MarketplaceService } from 'src/app/services/marketplace.service' -import { hasCurrentDeps } from 'src/app/util/has-deps' -import { InstallingProgressPipe } from '../../../service/pipes/install-progress.pipe' -import { PatchDB } from 'patch-db-client' import { getAllPackages } from 'src/app/util/get-package-data' +import { hasCurrentDeps } from 'src/app/util/has-deps' @Component({ selector: 'updates-item', @@ -56,29 +55,30 @@ import { getAllPackages } from 'src/app/util/get-package-data'
{{ errors }}
- - - - - - - + [max]="1" + [value]=" + (localPkg.stateInfo.installingInfo.progress.overall + | installingProgress) || 0 + " + /> + } @else { + @if (ready) { + + } @else { + + } + } What's new @@ -114,7 +114,6 @@ import { getAllPackages } from 'src/app/util/get-package-data' ], standalone: true, imports: [ - NgIf, RouterLink, EmverPipesModule, MarkdownPipeModule, diff --git a/web/projects/ui/src/app/apps/portal/routes/system/updates/updates.component.ts b/web/projects/ui/src/app/apps/portal/routes/system/updates/updates.component.ts index 717621b57..b309357a6 100644 --- a/web/projects/ui/src/app/apps/portal/routes/system/updates/updates.component.ts +++ b/web/projects/ui/src/app/apps/portal/routes/system/updates/updates.component.ts @@ -15,8 +15,8 @@ import { UpdatingState, } from 'src/app/services/patch-db/data-model' import { ConfigService } from 'src/app/services/config.service' -import { FilterUpdatesPipe } from './pipes/filter-updates.pipe' -import { UpdatesItemComponent } from './components/item.component' +import { FilterUpdatesPipe } from 'src/app/apps/portal/routes/system/updates/filter-updates.pipe' +import { UpdatesItemComponent } from 'src/app/apps/portal/routes/system/updates/item.component' import { isInstalled, isUpdating } from 'src/app/util/get-package-data' @Component({ diff --git a/web/projects/ui/src/app/apps/portal/services/badge.service.ts b/web/projects/ui/src/app/apps/portal/services/badge.service.ts index 52b797f2e..3cc13d98e 100644 --- a/web/projects/ui/src/app/apps/portal/services/badge.service.ts +++ b/web/projects/ui/src/app/apps/portal/services/badge.service.ts @@ -42,9 +42,12 @@ export class BadgeService { pairwise(), filter(([prev, curr]) => Object.values(prev).some(p => { - const id = getManifest(p).id - !curr[id] || + const { id } = getManifest(p) + + return ( + !curr[id] || (p.stateInfo.installingInfo && !curr[id].stateInfo.installingInfo) + ) }), ), map(([_, curr]) => curr), @@ -73,7 +76,6 @@ export class BadgeService { new Set(), ).size, ), - // @TODO-Alex shareReplay is preventing the badge from decrementing shareReplay(1), ) diff --git a/web/projects/ui/src/app/services/patch-monitor.service.ts b/web/projects/ui/src/app/services/patch-monitor.service.ts index 7a01e4d20..87cc996d1 100644 --- a/web/projects/ui/src/app/services/patch-monitor.service.ts +++ b/web/projects/ui/src/app/services/patch-monitor.service.ts @@ -9,8 +9,7 @@ import { LocalStorageBootstrap } from './patch-db/local-storage-bootstrap' @Injectable({ providedIn: 'root', }) -export class PatchMonitorService extends Observable { - // @TODO-Alex not happy with Observable +export class PatchMonitorService extends Observable { private readonly stream$ = this.authService.isVerified$.pipe( tap(verified => verified ? this.patch.start(this.bootstrapper) : this.patch.stop(), diff --git a/web/projects/ui/src/app/util/get-package-data.ts b/web/projects/ui/src/app/util/get-package-data.ts index 244324501..e986bbf43 100644 --- a/web/projects/ui/src/app/util/get-package-data.ts +++ b/web/projects/ui/src/app/util/get-package-data.ts @@ -24,9 +24,9 @@ export async function getAllPackages( } export function getManifest(pkg: PackageDataEntry): Manifest { - if (isInstalled(pkg) || isRemoving(pkg)) return pkg.stateInfo.manifest - - return (pkg.stateInfo as InstallingState).installingInfo.newManifest + return isInstalling(pkg) + ? pkg.stateInfo.installingInfo.newManifest + : pkg.stateInfo.manifest! } export function isInstalled( diff --git a/web/projects/ui/src/styles.scss b/web/projects/ui/src/styles.scss index 6bb7775c2..3b6684e27 100644 --- a/web/projects/ui/src/styles.scss +++ b/web/projects/ui/src/styles.scss @@ -523,19 +523,19 @@ button.g-action { overflow: auto !important; } -.g-success { +.g-success.g-success { color: var(--tui-success-fill); } -.g-warning { +.g-warning.g-warning { color: var(--tui-warning-fill); } -.g-error { +.g-error.g-error { color: var(--tui-error-fill); } -.g-info { +.g-info.g-info { color: var(--tui-info-fill); }