From e939777ddb5a90c51508d90c069099ab64f2ca6a Mon Sep 17 00:00:00 2001 From: nfebe Date: Thu, 27 Nov 2025 00:03:35 +0100 Subject: [PATCH] feat: Add database management, system views, and CI improvements - Add database connection manager with Docker container support - Add system ports and Docker ports views - Add services view for running containers - Convert database management from modal to full page - Fix deployment modal close button on landing page - Add ESLint, Prettier config, and GitHub Actions CI - Add TypeScript Vite environment types --- .eslintrc.cjs | 11 + .github/workflows/ci.yml | 73 ++ .prettierrc | 8 + package.json | 4 +- src/App.vue | 4 +- src/assets/design-system.css | 4 +- src/components/ConfirmModal.vue | 14 +- src/components/DataTable.vue | 159 +-- src/components/FileBrowser.vue | 338 ++++--- src/components/LogViewer.vue | 16 +- src/components/LogsModal.vue | 2 +- src/components/NewDeploymentModal.vue | 416 +++----- src/components/OperationModal.vue | 23 +- src/components/ToastNotifications.vue | 10 +- src/components/base/BaseModal.vue | 32 +- src/components/plugins/PluginWidget.vue | 25 +- src/layouts/DashboardLayout.vue | 286 ++---- src/router/index.ts | 30 +- src/services/api.ts | 129 ++- src/views/CertificatesView.vue | 102 +- src/views/ContainersView.vue | 68 +- src/views/DatabaseManagerView.vue | 937 ++++++++++++++++++ src/views/DatabasesView.vue | 839 ++++++++++++++++ src/views/DeploymentDetailView.vue | 362 ++----- src/views/DeploymentsView.vue | 197 ++-- src/views/DockerPortsView.vue | 384 +++++++ src/views/HomeView.vue | 73 +- src/views/ImagesView.vue | 97 +- src/views/LoginView.vue | 29 +- src/views/MarketplaceView.vue | 40 +- src/views/NetworksView.vue | 203 +--- src/views/PluginsView.vue | 108 +- src/views/ServicesView.vue | 389 ++++++++ src/views/SettingsView.vue | 105 +- .../{PortsView.vue => SystemPortsView.vue} | 58 +- src/views/VolumesView.vue | 141 +-- src/vite-env.d.ts | 10 + tsconfig.json | 5 +- 38 files changed, 3679 insertions(+), 2052 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .prettierrc create mode 100644 src/views/DatabaseManagerView.vue create mode 100644 src/views/DatabasesView.vue create mode 100644 src/views/DockerPortsView.vue create mode 100644 src/views/ServicesView.vue rename src/views/{PortsView.vue => SystemPortsView.vue} (89%) create mode 100644 src/vite-env.d.ts diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 48a64f1..b4bee41 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -20,5 +20,16 @@ module.exports = { rules: { 'vue/multi-word-component-names': 'off', '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + 'vue/max-attributes-per-line': 'off', + 'vue/singleline-html-element-content-newline': 'off', + 'vue/html-self-closing': ['warn', { + html: { void: 'any', normal: 'always', component: 'always' }, + svg: 'always', + math: 'always', + }], + 'vue/attributes-order': 'off', + 'vue/require-default-prop': 'off', + 'vue/use-v-on-exact': 'off', }, }; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..6c4e1d9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,73 @@ +name: CI + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Run ESLint + run: npm run lint + + - name: Check formatting + run: npm run format:check + + type-check: + name: Type Check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Run type check + run: npm run type-check + + build: + name: Build + runs-on: ubuntu-latest + needs: [lint, type-check] + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + retention-days: 7 diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..444c6ff --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "semi": true, + "singleQuote": false, + "tabWidth": 2, + "trailingComma": "all", + "printWidth": 100, + "vueIndentScriptAndStyle": false +} diff --git a/package.json b/package.json index 4317ad6..38b10df 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,11 @@ "dev": "vite", "build": "vue-tsc && vite build", "preview": "vite preview", + "type-check": "vue-tsc --noEmit", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --ignore-path .gitignore", "lint:fix": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", - "format": "prettier --write src/" + "format": "prettier --write src/", + "format:check": "prettier --check src/" }, "dependencies": { "@codemirror/lang-yaml": "^6.1.2", diff --git a/src/App.vue b/src/App.vue index 16065fb..9df6252 100644 --- a/src/App.vue +++ b/src/App.vue @@ -17,9 +17,7 @@ import ToastNotifications from "@/components/ToastNotifications.vue"; } body { - font-family: - -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, - sans-serif; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, sans-serif; background-color: #f8fafc; color: #1e293b; } diff --git a/src/assets/design-system.css b/src/assets/design-system.css index a97ea7f..f167d6e 100644 --- a/src/assets/design-system.css +++ b/src/assets/design-system.css @@ -72,9 +72,7 @@ --space-12: 3rem; /* Typography */ - --font-sans: - -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, - sans-serif; + --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, sans-serif; --font-mono: "JetBrains Mono", "SF Mono", "Consolas", monospace; --text-xs: 0.6875rem; diff --git a/src/components/ConfirmModal.vue b/src/components/ConfirmModal.vue index 7df3d07..14ce6e5 100644 --- a/src/components/ConfirmModal.vue +++ b/src/components/ConfirmModal.vue @@ -1,11 +1,7 @@ @@ -353,9 +261,7 @@ const filteredItems = computed(() => { return result; }); -const totalPages = computed(() => - Math.ceil(filteredItems.value.length / pageSize.value), -); +const totalPages = computed(() => Math.ceil(filteredItems.value.length / pageSize.value)); const startIndex = computed(() => (currentPage.value - 1) * pageSize.value); const endIndex = computed(() => Math.min(startIndex.value + pageSize.value, filteredItems.value.length), @@ -488,8 +394,7 @@ watch(selectedItems, () => { .search-input:focus { outline: none; border-color: var(--color-primary-500, #3b82f6); - box-shadow: 0 0 0 var(--ring-width, 2px) - var(--ring-color, rgba(59, 130, 246, 0.1)); + box-shadow: 0 0 0 var(--ring-width, 2px) var(--ring-color, rgba(59, 130, 246, 0.1)); } .view-toggle { diff --git a/src/components/FileBrowser.vue b/src/components/FileBrowser.vue index 2010769..34769f3 100644 --- a/src/components/FileBrowser.vue +++ b/src/components/FileBrowser.vue @@ -3,21 +3,12 @@
-
+
Name Size @@ -137,23 +106,17 @@ {{ file.name }} - + {{ file.child_count }} items - {{ file.is_dir ? '-' : formatSize(file.size) }} + {{ file.is_dir ? "-" : formatSize(file.size) }} {{ formatDate(file.mod_time) }} - +
+ +
+
+
+ +
+
{{ file.name }}
+
+ {{ + file.is_dir + ? file.child_count !== undefined + ? `${file.child_count} items` + : "Folder" + : formatSize(file.size) + }} +
+
+ + +
+
+
-