appclean 2.0.0 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +104 -0
- package/DEVELOPMENT.md +84 -0
- package/RELEASE_GUIDE.md +257 -0
- package/RELEASE_QUICK_START.md +176 -0
- package/assets/logo.svg +48 -32
- package/dist/index.js +1 -1
- package/dist/ui/client/api/client.d.ts.map +1 -1
- package/dist/ui/client/api/client.js +5 -1
- package/dist/ui/client/api/client.js.map +1 -1
- package/dist/ui/client/app.d.ts +1 -1
- package/dist/ui/client/app.d.ts.map +1 -1
- package/dist/ui/client/app.js +10 -6
- package/dist/ui/client/app.js.map +1 -1
- package/dist/ui/client/index.html +103 -46
- package/dist/ui/client/pages/appSearch.js +12 -1
- package/dist/ui/client/pages/appSearch.js.map +1 -1
- package/dist/ui/client/pages/dashboard.d.ts.map +1 -1
- package/dist/ui/client/pages/dashboard.js +26 -5
- package/dist/ui/client/pages/dashboard.js.map +1 -1
- package/dist/ui/client/state/appStore.d.ts.map +1 -1
- package/dist/ui/client/state/appStore.js +21 -12
- package/dist/ui/client/state/appStore.js.map +1 -1
- package/dist/ui/client/state/dashboardStore.d.ts.map +1 -1
- package/dist/ui/client/state/dashboardStore.js +9 -3
- package/dist/ui/client/state/dashboardStore.js.map +1 -1
- package/dist/ui/client/styles/animations.css +384 -2
- package/dist/ui/client/styles/base.css +347 -73
- package/dist/ui/client/styles/components.css +566 -189
- package/dist/ui/client/styles/layout.css +618 -1
- package/dist/ui/client/styles/responsive.css +388 -0
- package/dist/ui/client/styles/variables.css +163 -69
- package/dist/ui/guiServer.d.ts +3 -0
- package/dist/ui/guiServer.d.ts.map +1 -1
- package/dist/ui/guiServer.js +48 -1
- package/dist/ui/guiServer.js.map +1 -1
- package/dist/utils/upgrade.d.ts +2 -1
- package/dist/utils/upgrade.d.ts.map +1 -1
- package/dist/utils/upgrade.js +14 -1
- package/dist/utils/upgrade.js.map +1 -1
- package/package.json +1 -1
- package/scripts/publish-npm.sh +64 -0
- package/src/index.ts +1 -1
- package/src/ui/client/api/client.ts +6 -1
- package/src/ui/client/app.ts +15 -11
- package/src/ui/client/index.html +103 -46
- package/src/ui/client/pages/appSearch.ts +14 -1
- package/src/ui/client/pages/dashboard.ts +27 -5
- package/src/ui/client/state/appStore.ts +24 -12
- package/src/ui/client/state/dashboardStore.ts +13 -3
- package/src/ui/client/styles/animations.css +384 -2
- package/src/ui/client/styles/base.css +347 -73
- package/src/ui/client/styles/components.css +566 -189
- package/src/ui/client/styles/layout.css +618 -1
- package/src/ui/client/styles/responsive.css +388 -0
- package/src/ui/client/styles/variables.css +163 -69
- package/src/ui/guiServer.ts +67 -1
- package/src/utils/upgrade.ts +18 -1
package/dist/ui/guiServer.js
CHANGED
|
@@ -3,6 +3,7 @@ import { readFileSync, existsSync } from 'fs';
|
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import { dirname } from 'path';
|
|
6
|
+
import { execFile } from 'child_process';
|
|
6
7
|
import { Logger } from '../utils/logger.js';
|
|
7
8
|
import { sendError } from './server/middleware/errorHandler.js';
|
|
8
9
|
import { handleAppRoutes } from './server/routes/apps.js';
|
|
@@ -14,6 +15,7 @@ export class GUIServer {
|
|
|
14
15
|
constructor(port = 3000) {
|
|
15
16
|
this.port = 3000;
|
|
16
17
|
this.spaHtml = null;
|
|
18
|
+
this.browserProcess = null;
|
|
17
19
|
this.port = port;
|
|
18
20
|
}
|
|
19
21
|
async start() {
|
|
@@ -23,19 +25,64 @@ export class GUIServer {
|
|
|
23
25
|
this.handleRequest(req, res);
|
|
24
26
|
});
|
|
25
27
|
return new Promise((resolve) => {
|
|
26
|
-
this.server.listen(this.port, () => {
|
|
28
|
+
this.server.listen(this.port, async () => {
|
|
27
29
|
Logger.success(`✨ AppClean GUI running at http://localhost:${this.port}`);
|
|
28
30
|
Logger.info('Press Ctrl+C to stop the server');
|
|
31
|
+
await this.openBrowser();
|
|
29
32
|
resolve();
|
|
30
33
|
});
|
|
31
34
|
});
|
|
32
35
|
}
|
|
33
36
|
async stop() {
|
|
37
|
+
await this.closeBrowser();
|
|
34
38
|
if (this.server) {
|
|
35
39
|
this.server.close();
|
|
36
40
|
Logger.info('GUI server stopped');
|
|
37
41
|
}
|
|
38
42
|
}
|
|
43
|
+
async openBrowser() {
|
|
44
|
+
const url = `http://localhost:${this.port}`;
|
|
45
|
+
try {
|
|
46
|
+
const platform = process.platform;
|
|
47
|
+
if (platform === 'darwin') {
|
|
48
|
+
this.browserProcess = execFile('open', [url]);
|
|
49
|
+
}
|
|
50
|
+
else if (platform === 'win32') {
|
|
51
|
+
this.browserProcess = execFile('cmd', ['/c', 'start', url]);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
this.browserProcess = execFile('xdg-open', [url]);
|
|
55
|
+
}
|
|
56
|
+
this.browserProcess.on('error', (error) => {
|
|
57
|
+
Logger.warn(`Could not open browser: ${error.message}`);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
Logger.warn(`Failed to open browser: ${error.message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async closeBrowser() {
|
|
65
|
+
if (!this.browserProcess) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const platform = process.platform;
|
|
70
|
+
if (platform === 'win32') {
|
|
71
|
+
if (this.browserProcess.pid) {
|
|
72
|
+
process.kill(this.browserProcess.pid, 'SIGTERM');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
if (this.browserProcess.pid) {
|
|
77
|
+
process.kill(this.browserProcess.pid);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
this.browserProcess = null;
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
Logger.debug(`Note: Could not close browser process: ${error.message}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
39
86
|
async handleRequest(req, res) {
|
|
40
87
|
const url = req.url || '/';
|
|
41
88
|
const method = req.method || 'GET';
|
package/dist/ui/guiServer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guiServer.js","sourceRoot":"","sources":["../../src/ui/guiServer.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAmC,MAAM,MAAM,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAY,SAAS,EAAoB,MAAM,qCAAqC,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,OAAO,SAAS;
|
|
1
|
+
{"version":3,"file":"guiServer.js","sourceRoot":"","sources":["../../src/ui/guiServer.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAmC,MAAM,MAAM,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAA4B,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAY,SAAS,EAAoB,MAAM,qCAAqC,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAGnE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,MAAM,OAAO,SAAS;IAMpB,YAAY,OAAe,IAAI;QALvB,SAAI,GAAW,IAAI,CAAC;QAEpB,YAAO,GAAkB,IAAI,CAAC;QAC9B,mBAAc,GAAwB,IAAI,CAAC;QAGjD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAKD,KAAK,CAAC,KAAK;QACT,MAAM,CAAC,IAAI,CAAC,wCAAwC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC;QAGpE,IAAI,CAAC,WAAW,EAAE,CAAC;QAEnB,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACtC,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE;gBACvC,MAAM,CAAC,OAAO,CAAC,8CAA8C,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC1E,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;gBAG/C,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;gBAEzB,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAKD,KAAK,CAAC,IAAI;QAER,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAE1B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAKO,KAAK,CAAC,WAAW;QACvB,MAAM,GAAG,GAAG,oBAAoB,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;YAElC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAE1B,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YAChD,CAAC;iBAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAEhC,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YAC9D,CAAC;iBAAM,CAAC;gBAEN,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACpD,CAAC;YAED,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACxC,MAAM,CAAC,IAAI,CAAC,2BAA2B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,2BAA4B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IAKO,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;YAElC,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;gBAEzB,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC;oBAC5B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;iBAAM,CAAC;gBAEN,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC;oBAC5B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,0CAA2C,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;IAKO,KAAK,CAAC,aAAa,CAAC,GAAoB,EAAE,GAAmB;QACnE,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;QAC3B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC;QACnC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAGnC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAGzB,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YAEH,IAAI,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjC,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YAC3D,CAAC;YAGD,IAAI,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACpC,OAAO,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;YAC9C,CAAC;YAGD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,kBAAmB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3D,SAAS,CAAC,GAAG,EAAE,uBAAuB,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAKO,gBAAgB,CACtB,MAAc,EACd,QAAgB,EAChB,GAAoB,EACpB,GAAmB;QAGnB,IAAI,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YAChD,OAAO;QACT,CAAC;QAGD,IAAI,qBAAqB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YACtD,OAAO;QACT,CAAC;QAGD,IAAI,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YACrD,OAAO;QACT,CAAC;QAGD,SAAS,CAAC,GAAG,EAAE,wBAAwB,EAAE,GAAG,CAAC,CAAC;IAChD,CAAC;IAKO,gBAAgB,CAAC,QAAgB,EAAE,GAAmB;QAE5D,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAGvC,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,SAAS,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QAGD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QAGzD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,SAAS,CAAC,GAAG,EAAE,iBAAiB,EAAE,GAAG,CAAC,CAAC;YACvC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YACvC,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;YAElD,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;gBACjB,cAAc,EAAE,WAAW;gBAC3B,eAAe,EAAE,sBAAsB;aACxC,CAAC,CAAC;YACH,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,yBAAyB,QAAQ,KAAM,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9E,SAAS,CAAC,GAAG,EAAE,sBAAsB,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAKO,QAAQ,CAAC,GAAmB;QAClC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAElB,MAAM,YAAY,GAAG;;;;;;;;;;;;;;QAcnB,CAAC;YAEH,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACtB,OAAO;QACT,CAAC;QAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,WAAW;YAC3B,eAAe,EAAE,UAAU;SAC5B,CAAC,CAAC;QACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAKO,WAAW;QACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QAEzD,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAC/C,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,6BAA6B,QAAQ,EAAE,CAAC,CAAC;gBACrD,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,4BAA6B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAKO,cAAc,CAAC,QAAgB;QACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAEpD,MAAM,OAAO,GAA2B;YACtC,IAAI,EAAE,uCAAuC;YAC7C,KAAK,EAAE,yBAAyB;YAChC,MAAM,EAAE,0BAA0B;YAClC,MAAM,EAAE,iCAAiC;YACzC,KAAK,EAAE,eAAe;YACtB,KAAK,EAAE,WAAW;YAClB,KAAK,EAAE,YAAY;YACnB,MAAM,EAAE,YAAY;YACpB,KAAK,EAAE,WAAW;YAClB,KAAK,EAAE,cAAc;YACrB,MAAM,EAAE,YAAY;YACpB,MAAM,EAAE,WAAW;YACnB,OAAO,EAAE,YAAY;YACrB,KAAK,EAAE,UAAU;YACjB,KAAK,EAAE,+BAA+B;SACvC,CAAC;QAEF,OAAO,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,IAAI,0BAA0B,CAAC;IAC1D,CAAC;IAKO,cAAc,CAAC,GAAmB;QACxC,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QAClD,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,iCAAiC,CAAC,CAAC;QACjF,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,6BAA6B,CAAC,CAAC;QAC7E,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;CACF;AAGD,eAAe,SAAS,CAAC"}
|
package/dist/utils/upgrade.d.ts
CHANGED
|
@@ -5,7 +5,8 @@ export interface VersionInfo {
|
|
|
5
5
|
}
|
|
6
6
|
export declare class UpgradeManager {
|
|
7
7
|
private readonly packageName;
|
|
8
|
-
private
|
|
8
|
+
private currentVersion;
|
|
9
|
+
constructor();
|
|
9
10
|
getVersionInfo(): Promise<VersionInfo>;
|
|
10
11
|
private compareVersions;
|
|
11
12
|
upgrade(): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/utils/upgrade.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/utils/upgrade.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,cAAc,CAAS;;IAmBzB,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAmC5C,OAAO,CAAC,eAAe;IAkBjB,OAAO,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAsC/D,iBAAiB,IAAI,MAAM;IAOrB,eAAe,IAAI,OAAO,CAAC,WAAW,CAAC;IAOvC,SAAS,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAqBlE"}
|
package/dist/utils/upgrade.js
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
2
|
import { Logger } from './logger.js';
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { dirname, join } from 'path';
|
|
3
6
|
export class UpgradeManager {
|
|
4
7
|
constructor() {
|
|
5
8
|
this.packageName = 'appclean';
|
|
6
|
-
|
|
9
|
+
try {
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
const packagePath = join(__dirname, '../../package.json');
|
|
13
|
+
const packageData = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
14
|
+
this.currentVersion = packageData.version || '2.0.0';
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
Logger.debug('Failed to read version from package.json, using fallback');
|
|
18
|
+
this.currentVersion = '2.0.0';
|
|
19
|
+
}
|
|
7
20
|
}
|
|
8
21
|
async getVersionInfo() {
|
|
9
22
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/utils/upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAQrC,MAAM,OAAO,cAAc;
|
|
1
|
+
{"version":3,"file":"upgrade.js","sourceRoot":"","sources":["../../src/utils/upgrade.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# AppClean NPM Publishing Script
|
|
4
|
+
# Usage: ./scripts/publish-npm.sh [version]
|
|
5
|
+
# Example: ./scripts/publish-npm.sh 2.0.1
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
VERSION=${1:-}
|
|
10
|
+
|
|
11
|
+
if [ -z "$VERSION" ]; then
|
|
12
|
+
echo "Usage: ./scripts/publish-npm.sh <version>"
|
|
13
|
+
echo "Example: ./scripts/publish-npm.sh 2.0.1"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Check if npm is logged in
|
|
18
|
+
if ! npm whoami &>/dev/null; then
|
|
19
|
+
echo "❌ Not logged into npm"
|
|
20
|
+
echo "Please run: npm login"
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
echo "📦 Publishing AppClean v$VERSION to npm..."
|
|
25
|
+
|
|
26
|
+
# Ensure clean working directory
|
|
27
|
+
if [ -n "$(git status --porcelain)" ]; then
|
|
28
|
+
echo "❌ Working directory not clean. Please commit all changes."
|
|
29
|
+
git status
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Update version in package.json and src/index.ts
|
|
34
|
+
echo "📝 Updating version to $VERSION..."
|
|
35
|
+
sed -i.bak "s/\"version\": \"[^\"]*\"/\"version\": \"$VERSION\"/" package.json
|
|
36
|
+
sed -i.bak "s/const VERSION = '[^']*'/const VERSION = '$VERSION'/" src/index.ts
|
|
37
|
+
rm -f package.json.bak src/index.ts.bak
|
|
38
|
+
|
|
39
|
+
# Build the project
|
|
40
|
+
echo "🔨 Building project..."
|
|
41
|
+
npm run build
|
|
42
|
+
|
|
43
|
+
# Commit version changes
|
|
44
|
+
echo "📌 Committing version changes..."
|
|
45
|
+
git add package.json src/index.ts
|
|
46
|
+
git commit -m "chore: Bump version to $VERSION"
|
|
47
|
+
|
|
48
|
+
# Create git tag
|
|
49
|
+
echo "🏷️ Creating git tag v$VERSION..."
|
|
50
|
+
git tag -a "v$VERSION" -m "AppClean v$VERSION - Published to npm" || true
|
|
51
|
+
|
|
52
|
+
# Publish to npm
|
|
53
|
+
echo "🚀 Publishing to npm..."
|
|
54
|
+
npm publish
|
|
55
|
+
|
|
56
|
+
# Push changes and tags to origin
|
|
57
|
+
echo "📤 Pushing changes to origin..."
|
|
58
|
+
git push origin main
|
|
59
|
+
git push origin "v$VERSION" || true
|
|
60
|
+
|
|
61
|
+
echo ""
|
|
62
|
+
echo "✅ Successfully published AppClean v$VERSION"
|
|
63
|
+
echo "📍 View on npm: https://www.npmjs.com/package/appclean"
|
|
64
|
+
echo "🏷️ View on GitHub: https://github.com/praveenkay/AppClean/releases/tag/v$VERSION"
|
package/src/index.ts
CHANGED
|
@@ -26,7 +26,7 @@ import { Logger, formatBytes } from './utils/logger.js';
|
|
|
26
26
|
import { UpgradeManager } from './utils/upgrade.js';
|
|
27
27
|
import { InstalledApp } from './types';
|
|
28
28
|
|
|
29
|
-
const VERSION = '2.0.
|
|
29
|
+
const VERSION = '2.0.3';
|
|
30
30
|
|
|
31
31
|
async function interactiveMode(): Promise<void> {
|
|
32
32
|
showHeader();
|
|
@@ -119,7 +119,12 @@ export class ApiClient {
|
|
|
119
119
|
const contentType = response.headers.get('content-type');
|
|
120
120
|
|
|
121
121
|
if (contentType?.includes('application/json')) {
|
|
122
|
-
|
|
122
|
+
const json = await response.json();
|
|
123
|
+
// Extract data from wrapped response format: { success: true, data: T }
|
|
124
|
+
if (json && typeof json === 'object' && 'data' in json && 'success' in json) {
|
|
125
|
+
return json.data as T;
|
|
126
|
+
}
|
|
127
|
+
return json as T;
|
|
123
128
|
}
|
|
124
129
|
|
|
125
130
|
if (contentType?.includes('text/')) {
|
package/src/ui/client/app.ts
CHANGED
|
@@ -17,18 +17,18 @@ import { renderSettings } from './pages/settings.js';
|
|
|
17
17
|
/**
|
|
18
18
|
* Initialize the SPA
|
|
19
19
|
*/
|
|
20
|
-
export function initApp(): void {
|
|
20
|
+
export async function initApp(): Promise<void> {
|
|
21
21
|
console.log('🧹 AppClean GUI v1.0.0 initializing...');
|
|
22
22
|
|
|
23
|
-
// Register routes
|
|
23
|
+
// Register routes first
|
|
24
24
|
registerRoutes();
|
|
25
25
|
|
|
26
|
-
// Initialize stores
|
|
27
|
-
initializeStores();
|
|
28
|
-
|
|
29
26
|
// Setup UI listeners
|
|
30
27
|
setupUIListeners();
|
|
31
28
|
|
|
29
|
+
// Initialize stores with data
|
|
30
|
+
await initializeStores();
|
|
31
|
+
|
|
32
32
|
// Navigate to initial route
|
|
33
33
|
router.navigate('');
|
|
34
34
|
|
|
@@ -65,11 +65,13 @@ function registerRoutes(): void {
|
|
|
65
65
|
*/
|
|
66
66
|
async function initializeStores(): Promise<void> {
|
|
67
67
|
try {
|
|
68
|
-
// Load dashboard stats
|
|
68
|
+
// Load dashboard stats (required for initial render)
|
|
69
69
|
await dashboardStore.loadStats();
|
|
70
70
|
|
|
71
|
-
// Load
|
|
72
|
-
|
|
71
|
+
// Load app list in background (don't block on this)
|
|
72
|
+
appStore.loadApps().catch((error) => {
|
|
73
|
+
console.error('Failed to load apps:', error);
|
|
74
|
+
});
|
|
73
75
|
} catch (error) {
|
|
74
76
|
console.error('Failed to initialize stores:', error);
|
|
75
77
|
uiStore.showError('Failed to load application data');
|
|
@@ -87,7 +89,9 @@ function setupUIListeners(): void {
|
|
|
87
89
|
|
|
88
90
|
// Subscribe to app store changes
|
|
89
91
|
appStore.subscribe((state) => {
|
|
90
|
-
|
|
92
|
+
if (state && state.apps) {
|
|
93
|
+
console.log(`Apps loaded: ${state.apps.length}`);
|
|
94
|
+
}
|
|
91
95
|
});
|
|
92
96
|
|
|
93
97
|
// Subscribe to dashboard store changes
|
|
@@ -115,7 +119,7 @@ export { appStore, dashboardStore, uiStore, router };
|
|
|
115
119
|
|
|
116
120
|
// Initialize on DOM ready
|
|
117
121
|
if (document.readyState === 'loading') {
|
|
118
|
-
document.addEventListener('DOMContentLoaded', initApp);
|
|
122
|
+
document.addEventListener('DOMContentLoaded', () => initApp().catch(e => console.error('Init error:', e)));
|
|
119
123
|
} else {
|
|
120
|
-
initApp();
|
|
124
|
+
initApp().catch(e => console.error('Init error:', e));
|
|
121
125
|
}
|
package/src/ui/client/index.html
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
|
6
6
|
<meta name="description" content="AppClean - Intelligently remove applications and all their hidden files">
|
|
7
7
|
<meta name="theme-color" content="#3b82f6">
|
|
8
|
+
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
9
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
8
10
|
<title>AppClean - Application Remover</title>
|
|
9
11
|
|
|
10
12
|
<!-- Styles -->
|
|
@@ -13,78 +15,130 @@
|
|
|
13
15
|
<link rel="stylesheet" href="/static/styles/layout.css">
|
|
14
16
|
<link rel="stylesheet" href="/static/styles/components.css">
|
|
15
17
|
<link rel="stylesheet" href="/static/styles/animations.css">
|
|
18
|
+
<link rel="stylesheet" href="/static/styles/responsive.css">
|
|
16
19
|
</head>
|
|
17
20
|
<body>
|
|
18
21
|
<!-- Root container for SPA -->
|
|
19
22
|
<div id="app" class="app-root">
|
|
20
|
-
<!--
|
|
21
|
-
<
|
|
22
|
-
<div class="container
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
<!-- Modern Navigation Header -->
|
|
24
|
+
<header class="app-header" id="app-header">
|
|
25
|
+
<div class="header-container">
|
|
26
|
+
<!-- Logo and Brand -->
|
|
27
|
+
<div class="header-brand">
|
|
28
|
+
<button class="sidebar-toggle" id="sidebar-toggle" aria-label="Toggle sidebar" aria-expanded="false">
|
|
29
|
+
<svg class="menu-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
30
|
+
<line x1="3" y1="6" x2="21" y2="6"></line>
|
|
31
|
+
<line x1="3" y1="12" x2="21" y2="12"></line>
|
|
32
|
+
<line x1="3" y1="18" x2="21" y2="18"></line>
|
|
33
|
+
</svg>
|
|
34
|
+
</button>
|
|
35
|
+
<a href="#/" class="logo-link" aria-label="AppClean Home">
|
|
36
|
+
<img src="/static/assets/logo.svg" alt="AppClean Logo" class="logo-image">
|
|
37
|
+
<span class="logo-text">AppClean</span>
|
|
38
|
+
</a>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<!-- Header Actions -->
|
|
42
|
+
<div class="header-actions">
|
|
43
|
+
<button class="btn-icon theme-toggle" id="theme-toggle" aria-label="Toggle dark mode">
|
|
44
|
+
<svg class="icon-sun" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
45
|
+
<circle cx="12" cy="12" r="5"></circle>
|
|
46
|
+
<line x1="12" y1="1" x2="12" y2="3"></line>
|
|
47
|
+
<line x1="12" y1="21" x2="12" y2="23"></line>
|
|
48
|
+
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
|
49
|
+
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
|
50
|
+
<line x1="1" y1="12" x2="3" y2="12"></line>
|
|
51
|
+
<line x1="21" y1="12" x2="23" y2="12"></line>
|
|
52
|
+
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
|
53
|
+
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
|
54
|
+
</svg>
|
|
55
|
+
<svg class="icon-moon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
56
|
+
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
|
|
57
|
+
</svg>
|
|
58
|
+
</button>
|
|
59
|
+
<div class="version-badge" id="version-badge">v2.0.2</div>
|
|
35
60
|
</div>
|
|
36
61
|
</div>
|
|
37
|
-
</
|
|
62
|
+
</header>
|
|
38
63
|
|
|
39
|
-
<!-- Main
|
|
40
|
-
<div class="app-layout
|
|
41
|
-
<!-- Sidebar -->
|
|
42
|
-
<aside class="sidebar" id="sidebar">
|
|
43
|
-
<
|
|
44
|
-
<
|
|
45
|
-
<a href="#/" class="nav-
|
|
46
|
-
<span class="nav-icon"
|
|
64
|
+
<!-- Main Layout Container -->
|
|
65
|
+
<div class="app-layout">
|
|
66
|
+
<!-- Sidebar Navigation -->
|
|
67
|
+
<aside class="sidebar" id="sidebar" aria-label="Navigation">
|
|
68
|
+
<nav class="sidebar-nav">
|
|
69
|
+
<div class="nav-items">
|
|
70
|
+
<a href="#/" class="nav-item active" data-view="dashboard" aria-current="page">
|
|
71
|
+
<span class="nav-icon">
|
|
72
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
73
|
+
<line x1="12" y1="2" x2="12" y2="22"></line>
|
|
74
|
+
<path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path>
|
|
75
|
+
</svg>
|
|
76
|
+
</span>
|
|
47
77
|
<span class="nav-label">Dashboard</span>
|
|
48
78
|
</a>
|
|
49
|
-
<a href="#/apps" class="nav-
|
|
50
|
-
<span class="nav-icon"
|
|
79
|
+
<a href="#/apps" class="nav-item" data-view="apps">
|
|
80
|
+
<span class="nav-icon">
|
|
81
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
82
|
+
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
83
|
+
<line x1="9" y1="9" x2="9" y2="9.01"></line>
|
|
84
|
+
<line x1="15" y1="9" x2="15" y2="9.01"></line>
|
|
85
|
+
<line x1="9" y1="15" x2="9" y2="15.01"></line>
|
|
86
|
+
<line x1="15" y1="15" x2="15" y2="15.01"></line>
|
|
87
|
+
</svg>
|
|
88
|
+
</span>
|
|
51
89
|
<span class="nav-label">Apps</span>
|
|
52
90
|
</a>
|
|
53
|
-
<a href="#/settings" class="nav-
|
|
54
|
-
<span class="nav-icon"
|
|
91
|
+
<a href="#/settings" class="nav-item" data-view="settings">
|
|
92
|
+
<span class="nav-icon">
|
|
93
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
94
|
+
<circle cx="12" cy="12" r="3"></circle>
|
|
95
|
+
<path d="M12 1v6m0 6v6M4.22 4.22l4.24 4.24m3.08 3.08l4.24 4.24M1 12h6m6 0h6M4.22 19.78l4.24-4.24m3.08-3.08l4.24-4.24M19.78 19.78l-4.24-4.24m-3.08-3.08l-4.24-4.24"></path>
|
|
96
|
+
</svg>
|
|
97
|
+
</span>
|
|
55
98
|
<span class="nav-label">Settings</span>
|
|
56
99
|
</a>
|
|
57
|
-
</
|
|
58
|
-
</
|
|
100
|
+
</div>
|
|
101
|
+
</nav>
|
|
102
|
+
|
|
103
|
+
<!-- Sidebar Footer -->
|
|
59
104
|
<div class="sidebar-footer">
|
|
60
|
-
<a href="https://github.com/praveenkay/AppClean" target="_blank" rel="noopener" class="sidebar-link">
|
|
61
|
-
<span class="nav-icon"
|
|
105
|
+
<a href="https://github.com/praveenkay/AppClean" target="_blank" rel="noopener noreferrer" class="nav-item sidebar-link" title="View on GitHub">
|
|
106
|
+
<span class="nav-icon">
|
|
107
|
+
<svg viewBox="0 0 24 24" fill="currentColor">
|
|
108
|
+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v 3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
|
109
|
+
</svg>
|
|
110
|
+
</span>
|
|
62
111
|
<span class="nav-label">GitHub</span>
|
|
63
112
|
</a>
|
|
64
113
|
</div>
|
|
65
114
|
</aside>
|
|
66
115
|
|
|
67
|
-
<!-- Main
|
|
68
|
-
<main class="main-content" id="main-content">
|
|
69
|
-
<div class="
|
|
70
|
-
<!--
|
|
116
|
+
<!-- Main Content Area -->
|
|
117
|
+
<main class="main-content" id="main-content" role="main">
|
|
118
|
+
<div class="content-wrapper">
|
|
119
|
+
<!-- Page Container -->
|
|
71
120
|
<div id="page-container" class="page-container">
|
|
72
|
-
<!-- Loading
|
|
121
|
+
<!-- Loading State -->
|
|
73
122
|
<div class="loading-state" id="loading-state">
|
|
74
|
-
<div class="spinner
|
|
75
|
-
<p class="
|
|
123
|
+
<div class="spinner"></div>
|
|
124
|
+
<p class="loading-text">Loading AppClean...</p>
|
|
76
125
|
</div>
|
|
77
126
|
</div>
|
|
78
127
|
</div>
|
|
79
128
|
</main>
|
|
80
129
|
</div>
|
|
81
130
|
|
|
82
|
-
<!--
|
|
83
|
-
<div class="modal-
|
|
84
|
-
<div class="modal" id="modal" role="dialog" aria-labelledby="modal-title">
|
|
131
|
+
<!-- Modal Dialog -->
|
|
132
|
+
<div class="modal-overlay" id="modal-overlay" role="presentation">
|
|
133
|
+
<div class="modal-dialog" id="modal" role="dialog" aria-modal="true" aria-labelledby="modal-title">
|
|
85
134
|
<div class="modal-header">
|
|
86
135
|
<h2 class="modal-title" id="modal-title">Dialog</h2>
|
|
87
|
-
<button class="modal-close" id="modal-close" aria-label="Close dialog"
|
|
136
|
+
<button class="modal-close" id="modal-close" aria-label="Close dialog">
|
|
137
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
138
|
+
<line x1="18" y1="6" x2="6" y2="18"></line>
|
|
139
|
+
<line x1="6" y1="6" x2="18" y2="18"></line>
|
|
140
|
+
</svg>
|
|
141
|
+
</button>
|
|
88
142
|
</div>
|
|
89
143
|
<div class="modal-body" id="modal-body">
|
|
90
144
|
<!-- Content will be rendered here -->
|
|
@@ -95,10 +149,13 @@
|
|
|
95
149
|
</div>
|
|
96
150
|
</div>
|
|
97
151
|
|
|
98
|
-
<!-- Notifications -->
|
|
99
|
-
<div class="notifications-container" id="notifications-container" role="region" aria-label="Notifications" aria-live="polite">
|
|
152
|
+
<!-- Toast Notifications -->
|
|
153
|
+
<div class="notifications-container" id="notifications-container" role="region" aria-label="Notifications" aria-live="polite" aria-atomic="true">
|
|
100
154
|
<!-- Notifications will be rendered here -->
|
|
101
155
|
</div>
|
|
156
|
+
|
|
157
|
+
<!-- Sidebar Overlay (Mobile) -->
|
|
158
|
+
<div class="sidebar-overlay" id="sidebar-overlay" aria-hidden="true"></div>
|
|
102
159
|
</div>
|
|
103
160
|
|
|
104
161
|
<!-- Scripts -->
|
|
@@ -40,6 +40,19 @@ export function renderAppSearch(): void {
|
|
|
40
40
|
function renderAppSearchContent(container: HTMLElement): void {
|
|
41
41
|
const state = appStore.getState();
|
|
42
42
|
|
|
43
|
+
// Ensure state has apps array
|
|
44
|
+
if (!state || !state.apps) {
|
|
45
|
+
console.error('AppStore state is invalid:', state);
|
|
46
|
+
container.innerHTML = `
|
|
47
|
+
<div class="alert alert-danger">
|
|
48
|
+
<h3>Error Loading Apps</h3>
|
|
49
|
+
<p>Failed to load application state. Please refresh the page.</p>
|
|
50
|
+
<button class="btn btn-primary btn-sm mt-4" onclick="window.location.reload()">Reload</button>
|
|
51
|
+
</div>
|
|
52
|
+
`;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
43
56
|
container.innerHTML = `
|
|
44
57
|
<div class="app-search-page">
|
|
45
58
|
<!-- Header -->
|
|
@@ -82,7 +95,7 @@ function renderAppSearchContent(container: HTMLElement): void {
|
|
|
82
95
|
<!-- Apps Grid -->
|
|
83
96
|
<div class="apps-grid">
|
|
84
97
|
${
|
|
85
|
-
state.apps.length > 0
|
|
98
|
+
(state.apps && state.apps.length > 0)
|
|
86
99
|
? `
|
|
87
100
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
88
101
|
${state.apps.map((app) => renderAppCard(app)).join('')}
|
|
@@ -25,11 +25,24 @@ export function renderDashboard(): void {
|
|
|
25
25
|
dashboardStore.refreshStats(true).then(() => {
|
|
26
26
|
const state = dashboardStore.getState();
|
|
27
27
|
const stats = state.stats;
|
|
28
|
+
const error = state.error;
|
|
29
|
+
|
|
30
|
+
if (error) {
|
|
31
|
+
container.innerHTML = `
|
|
32
|
+
<div class="alert alert-danger" style="margin: 20px;">
|
|
33
|
+
<h3 style="margin-top: 0;">⚠️ Error Loading Dashboard</h3>
|
|
34
|
+
<p>${escapeHtml(error)}</p>
|
|
35
|
+
<button class="btn btn-primary btn-sm" onclick="window.location.reload()">Retry</button>
|
|
36
|
+
</div>
|
|
37
|
+
`;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
28
40
|
|
|
29
41
|
if (!stats) {
|
|
30
42
|
container.innerHTML = `
|
|
31
|
-
<div class="alert alert-
|
|
32
|
-
<
|
|
43
|
+
<div class="alert alert-warning" style="margin: 20px;">
|
|
44
|
+
<h3 style="margin-top: 0;">⏳ Initializing</h3>
|
|
45
|
+
<p>Dashboard is loading. Please wait...</p>
|
|
33
46
|
</div>
|
|
34
47
|
`;
|
|
35
48
|
return;
|
|
@@ -43,6 +56,15 @@ export function renderDashboard(): void {
|
|
|
43
56
|
renderDashboardContent(container, newState.stats);
|
|
44
57
|
}
|
|
45
58
|
});
|
|
59
|
+
}).catch((error) => {
|
|
60
|
+
console.error('Dashboard error:', error);
|
|
61
|
+
container.innerHTML = `
|
|
62
|
+
<div class="alert alert-danger" style="margin: 20px;">
|
|
63
|
+
<h3 style="margin-top: 0;">❌ Failed to Load Dashboard</h3>
|
|
64
|
+
<p>An unexpected error occurred. Please check the console for details.</p>
|
|
65
|
+
<button class="btn btn-primary btn-sm" onclick="window.location.reload()">Reload Page</button>
|
|
66
|
+
</div>
|
|
67
|
+
`;
|
|
46
68
|
});
|
|
47
69
|
}
|
|
48
70
|
|
|
@@ -51,7 +73,7 @@ export function renderDashboard(): void {
|
|
|
51
73
|
*/
|
|
52
74
|
function renderDashboardContent(container: HTMLElement, stats: DashboardStats): void {
|
|
53
75
|
container.innerHTML = `
|
|
54
|
-
<div class="dashboard-page">
|
|
76
|
+
<div class="dashboard-page fade-in">
|
|
55
77
|
<!-- Header -->
|
|
56
78
|
<div class="page-header mb-8">
|
|
57
79
|
<h1 class="text-3xl font-bold">📊 Dashboard</h1>
|
|
@@ -88,10 +110,10 @@ function renderDashboardContent(container: HTMLElement, stats: DashboardStats):
|
|
|
88
110
|
</div>
|
|
89
111
|
<p class="text-sm text-muted">
|
|
90
112
|
${stats.diskUsagePercent < 80
|
|
91
|
-
? '
|
|
113
|
+
? '✅ Disk usage is healthy'
|
|
92
114
|
: stats.diskUsagePercent < 90
|
|
93
115
|
? '⚠️ Disk usage is getting high'
|
|
94
|
-
: '
|
|
116
|
+
: '🔴 Disk usage is critical'}
|
|
95
117
|
</p>
|
|
96
118
|
</div>
|
|
97
119
|
</div>
|