From 3bd799817b2ffb72aeaa321cf374246ebe44cd11 Mon Sep 17 00:00:00 2001 From: Jan Lauber Date: Thu, 21 Mar 2024 00:13:59 +0100 Subject: [PATCH 1/9] feat: Add dependencies and components for map functionality Signed-off-by: Jan Lauber --- frontend/package-lock.json | 389 +++++++++++++++++- frontend/package.json | 1 + .../lib/components/projects/SideNav.svelte | 8 + .../routes/app/projects/[id]/map/+page.svelte | 49 +++ .../app/projects/[id]/map/TurboEdge.svelte | 32 ++ .../app/projects/[id]/map/TurboNode.svelte | 39 ++ .../app/projects/[id]/map/nodes-and-edges.ts | 37 ++ .../routes/app/projects/[id]/map/turbo.css | 164 ++++++++ pocketbase/go.mod | 1 + pocketbase/go.sum | 2 + pocketbase/main.go | 56 +++ pocketbase/pkg/k8s/watch.go | 58 +++ 12 files changed, 816 insertions(+), 20 deletions(-) create mode 100644 frontend/src/routes/app/projects/[id]/map/+page.svelte create mode 100644 frontend/src/routes/app/projects/[id]/map/TurboEdge.svelte create mode 100644 frontend/src/routes/app/projects/[id]/map/TurboNode.svelte create mode 100644 frontend/src/routes/app/projects/[id]/map/nodes-and-edges.ts create mode 100644 frontend/src/routes/app/projects/[id]/map/turbo.css create mode 100644 pocketbase/pkg/k8s/watch.go diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 2ce5034f..b575868e 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -15,6 +15,7 @@ "@sveltejs/adapter-node": "^5.0.1", "@sveltejs/adapter-static": "^3.0.0", "@webcontainer/api": "^1.1.4", + "@xyflow/svelte": "^0.0.39", "chart.js": "^4.3.0", "diff": "^5.2.0", "diff2html": "^3.4.47", @@ -1195,6 +1196,11 @@ "win32" ] }, + "node_modules/@svelte-put/shortcut": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@svelte-put/shortcut/-/shortcut-3.1.0.tgz", + "integrity": "sha512-EWMEDkZ0+O3yMhb9yrqe5UYisV9CNRKX6Pl/JW3x62t74CiN+3COu1L9NzZUG0omagc2Z3J14PZNYxs77IC9NA==" + }, "node_modules/@sveltejs/adapter-auto": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.1.1.tgz", @@ -1347,11 +1353,238 @@ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz", + "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz", + "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.9.tgz", + "integrity": "sha512-IKtvyFdb4Q0LWna6ymywQsEYjK/94SGhPrMfEr1TIc5OBeziTi+1jcCvttts8e0UWZIxpasjnQk9MNk/3iS+kA==" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz", + "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz", + "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz", + "integrity": "sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz", + "integrity": "sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz", + "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.8.tgz", + "integrity": "sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, + "node_modules/@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -1373,8 +1606,7 @@ "node_modules/@types/pug": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.7.tgz", - "integrity": "sha512-I469DU0UXNC1aHepwirWhu9YKg5fkxohZD95Ey/5A7lovC+Siu+MCLffva87lnfThaOrw9Vb1DUN5t55oULAAw==", - "dev": true + "integrity": "sha512-I469DU0UXNC1aHepwirWhu9YKg5fkxohZD95Ey/5A7lovC+Siu+MCLffva87lnfThaOrw9Vb1DUN5t55oULAAw==" }, "node_modules/@types/resolve": { "version": "1.20.2", @@ -1679,6 +1911,34 @@ "resolved": "https://registry.npmjs.org/@webcontainer/api/-/api-1.1.4.tgz", "integrity": "sha512-JjGQl25+QzuHOKLKr5QX0dAvqOFLw06YY47eWKMwkxz1otfYPtuhTRRjascqMLxGbLoRF6i1idV+vlInp5gwvA==" }, + "node_modules/@xyflow/svelte": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@xyflow/svelte/-/svelte-0.0.39.tgz", + "integrity": "sha512-Kam9VMXIrKjIpBvalJLNrxqbI/ASHaYHj6ZRkdGsnAx3aYgB+de0McAqiJToKdlOeZyHoQtxzSRX9D+ZTSEVZw==", + "dependencies": { + "@svelte-put/shortcut": "^3.1.0", + "@xyflow/system": "0.0.20", + "classcat": "^5.0.4", + "svelte-preprocess": "^5.1.3" + }, + "peerDependencies": { + "svelte": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/@xyflow/system": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.20.tgz", + "integrity": "sha512-OQ9irX0HtZqAzOKtnNi7WpDT6SEp7VpR16VRatd7oImw5vahyjmggUSY7as9XvJnAz0D9H0g1qjRX99moabvQA==", + "dependencies": { + "@types/d3": "^7.4.0", + "@types/d3-drag": "^3.0.1", + "@types/d3-selection": "^3.0.3", + "@types/d3-zoom": "^3.0.1", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0" + } + }, "node_modules/@yr/monotone-cubic-spline": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz", @@ -1979,7 +2239,6 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, "engines": { "node": "*" } @@ -2148,6 +2407,11 @@ "node": ">=10" } }, + "node_modules/classcat": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.4.tgz", + "integrity": "sha512-sbpkOw6z413p+HDGcBENe498WM9woqWHiJxCq7nvmxe9WmrUmqfAcxpIwAiMtM5Q3AhYkzXcNQHqsWq0mND51g==" + }, "node_modules/clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -2311,6 +2575,102 @@ "node": ">=4" } }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2375,7 +2735,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, "engines": { "node": ">=8" } @@ -2509,8 +2868,7 @@ "node_modules/es6-promise": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==" }, "node_modules/esbuild": { "version": "0.19.12", @@ -3150,8 +3508,7 @@ "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "devOptional": true + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, "node_modules/grapheme-splitter": { "version": "1.0.4", @@ -3544,7 +3901,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, + "devOptional": true, "engines": { "node": ">=10" } @@ -3722,7 +4079,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, "engines": { "node": ">=4" } @@ -3751,7 +4107,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3848,7 +4203,6 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, "dependencies": { "minimist": "^1.2.6" }, @@ -4365,7 +4719,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", - "dev": true, + "devOptional": true, "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" @@ -4776,7 +5130,6 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", - "dev": true, "dependencies": { "es6-promise": "^3.1.2", "graceful-fs": "^4.1.3", @@ -4788,7 +5141,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -4910,7 +5262,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz", "integrity": "sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==", - "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.14", "buffer-crc32": "^0.2.5", @@ -5009,7 +5360,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, "dependencies": { "min-indent": "^1.0.0" }, @@ -5287,7 +5637,6 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.3.tgz", "integrity": "sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==", - "dev": true, "hasInstallScript": true, "dependencies": { "@types/pug": "^2.0.6", @@ -6223,7 +6572,7 @@ "version": "5.4.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6435,7 +6784,7 @@ "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, + "devOptional": true, "engines": { "node": ">= 6" } diff --git a/frontend/package.json b/frontend/package.json index 24b0d73f..90a5aacb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -57,6 +57,7 @@ "@sveltejs/adapter-node": "^5.0.1", "@sveltejs/adapter-static": "^3.0.0", "@webcontainer/api": "^1.1.4", + "@xyflow/svelte": "^0.0.39", "chart.js": "^4.3.0", "diff": "^5.2.0", "diff2html": "^3.4.47", diff --git a/frontend/src/lib/components/projects/SideNav.svelte b/frontend/src/lib/components/projects/SideNav.svelte index ec1b5ef0..6af23ed5 100644 --- a/frontend/src/lib/components/projects/SideNav.svelte +++ b/frontend/src/lib/components/projects/SideNav.svelte @@ -10,7 +10,9 @@ HardDrive, History, LineChart, + Map, Network, + ShipWheel, Variable } from "lucide-svelte"; @@ -23,6 +25,12 @@ current: false, icon: LineChart }, + { + name: "Map", + href: `/app/projects/${projectId}/map`, + current: false, + icon: Map + }, { name: "Rollouts", href: `/app/projects/${projectId}/rollouts`, diff --git a/frontend/src/routes/app/projects/[id]/map/+page.svelte b/frontend/src/routes/app/projects/[id]/map/+page.svelte new file mode 100644 index 00000000..7bd56438 --- /dev/null +++ b/frontend/src/routes/app/projects/[id]/map/+page.svelte @@ -0,0 +1,49 @@ + + +
+
+ Map +

Map of your resources.

+
+
+ +
+ + + + + + + + + + + +
diff --git a/frontend/src/routes/app/projects/[id]/map/TurboEdge.svelte b/frontend/src/routes/app/projects/[id]/map/TurboEdge.svelte new file mode 100644 index 00000000..85e15d5b --- /dev/null +++ b/frontend/src/routes/app/projects/[id]/map/TurboEdge.svelte @@ -0,0 +1,32 @@ + + + diff --git a/frontend/src/routes/app/projects/[id]/map/TurboNode.svelte b/frontend/src/routes/app/projects/[id]/map/TurboNode.svelte new file mode 100644 index 00000000..be619063 --- /dev/null +++ b/frontend/src/routes/app/projects/[id]/map/TurboNode.svelte @@ -0,0 +1,39 @@ + + +
+
+ +
+
+
+
+
+ {#if data.icon} +
+ {#if data.icon === "ingress"} + + {:else if data.icon === "service"} + + {:else if data.icon === "pod"} + + {/if} +
+ {/if} +
+
{data.title}
+ {#if data.subline} +
{data.subline}
+ {/if} +
+
+ + +
+
diff --git a/frontend/src/routes/app/projects/[id]/map/nodes-and-edges.ts b/frontend/src/routes/app/projects/[id]/map/nodes-and-edges.ts new file mode 100644 index 00000000..5a836d09 --- /dev/null +++ b/frontend/src/routes/app/projects/[id]/map/nodes-and-edges.ts @@ -0,0 +1,37 @@ +import type { Node, Edge } from "@xyflow/svelte"; + +export const initialNodes: Node[] = [ + { + id: "1", + position: { x: 250, y: 125 }, + data: { icon: "ingress", title: "ingress" }, + type: "turbo" + }, + { + id: "2", + position: { x: 500, y: 125 }, + data: { icon: "service", title: "service" }, + type: "turbo" + }, + { + id: "3", + position: { x: 750, y: 125 }, + data: { icon: "pod", title: "pod" }, + type: "turbo" + } +]; + +export const initialEdges: Edge[] = [ + { + id: "e1-2", + source: "1", + target: "2", + animated: true + }, + { + id: "e3-4", + source: "2", + target: "3", + animated: true + } +]; diff --git a/frontend/src/routes/app/projects/[id]/map/turbo.css b/frontend/src/routes/app/projects/[id]/map/turbo.css new file mode 100644 index 00000000..77129fe3 --- /dev/null +++ b/frontend/src/routes/app/projects/[id]/map/turbo.css @@ -0,0 +1,164 @@ +.svelte-flow { + --bg-color: #F7F9FC; + --text-color: rgb(17, 17, 17); + --node-border-radius: 10px; + --node-box-shadow: 10px 0 15px rgba(42, 138, 246, 0.3), -10px 0 15px rgba(233, 42, 103, 0.3); + background-color: var(--bg-color) !important; + color: var(--text-color); + border: 2px solid var(--text-color); + border-radius: 10px; +} + +.svelte-flow__node-turbo { + border-radius: var(--node-border-radius); + display: flex; + height: 70px; + min-width: 150px; + font-family: "Fira Mono", Monospace; + font-weight: 500; + letter-spacing: -0.2px; + box-shadow: var(--node-box-shadow); +} + +.svelte-flow__node-turbo .wrapper { + overflow: hidden; + display: flex; + padding: 2px; + position: relative; + border-radius: var(--node-border-radius); + flex-grow: 1; +} + +.gradient:before { + content: ""; + position: absolute; + padding-bottom: calc(100% * 1.41421356237); + width: calc(100% * 1.41421356237); + background: conic-gradient( + from -160deg at 50% 50%, + #e92a67 0deg, + #a853ba 120deg, + #2a8af6 240deg, + #e92a67 360deg + ); + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + border-radius: 100%; +} + +@keyframes spinner { + 100% { + transform: translate(-50%, -50%) rotate(-360deg); + } +} + +.svelte-flow__node-turbo .inner { + background: var(--bg-color); + padding: 16px 20px; + border-radius: var(--node-border-radius); + display: flex; + flex-direction: column; + justify-content: center; + flex-grow: 1; + position: relative; +} + +.svelte-flow__node-turbo .icon { + margin-right: 8px; +} + +.svelte-flow__node-turbo .body { + display: flex; +} + +.svelte-flow__node-turbo .title { + font-size: 16px; + margin-bottom: 2px; + line-height: 1; +} + +.svelte-flow__node-turbo .subline { + font-size: 12px; + color: #777; +} + +.svelte-flow__node-turbo .cloud { + border-radius: 100%; + width: 30px; + height: 30px; + right: 0; + position: absolute; + top: 0; + transform: translate(50%, -50%); + display: flex; + transform-origin: center center; + padding: 2px; + overflow: hidden; + box-shadow: var(--node-box-shadow); + z-index: 1; +} + +.svelte-flow__node-turbo .cloud div { + background-color: var(--bg-color); + flex-grow: 1; + border-radius: 100%; + display: flex; + justify-content: center; + align-items: center; + position: relative; +} + +.svelte-flow__handle { + opacity: 0; +} + +.svelte-flow__handle.source { + right: -10px; +} + +.svelte-flow__handle.target { + left: -10px; +} + +.svelte-flow__node:focus { + outline: none; +} + +.svelte-flow__edge .svelte-flow__edge-path { + stroke: url(#edge-gradient); + stroke-width: 2; + stroke-opacity: 0.75; +} + +.svelte-flow__controls button { + background-color: var(--bg-color); + color: var(--text-color); + border: 1px solid #95679e; + border-bottom: none; +} + +.svelte-flow__controls button:hover { + background-color: rgb(37, 37, 37); +} + +.svelte-flow__controls button:first-child { + border-radius: 5px 5px 0 0; +} + +.svelte-flow__controls button:last-child { + border-bottom: 1px solid #95679e; + border-radius: 0 0 5px 5px; +} + +.svelte-flow__controls button path { + fill: var(--text-color); +} + +.svelte-flow__attribution { + background: rgba(200, 200, 200, 0.2); +} + +.svelte-flow__attribution a { + color: #95679e; +} diff --git a/pocketbase/go.mod b/pocketbase/go.mod index b0e9b9eb..ec650f76 100644 --- a/pocketbase/go.mod +++ b/pocketbase/go.mod @@ -6,6 +6,7 @@ toolchain go1.21.5 require ( github.com/caarlos0/env/v8 v8.0.0 + github.com/gorilla/websocket v1.5.1 github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61 github.com/pocketbase/dbx v1.10.1 github.com/pocketbase/pocketbase v0.22.4 diff --git a/pocketbase/go.sum b/pocketbase/go.sum index 3aa44f75..944a6e31 100644 --- a/pocketbase/go.sum +++ b/pocketbase/go.sum @@ -209,6 +209,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= +github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= +github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog= diff --git a/pocketbase/main.go b/pocketbase/main.go index 3feaa71a..c0310252 100644 --- a/pocketbase/main.go +++ b/pocketbase/main.go @@ -1,11 +1,14 @@ package main import ( + "encoding/json" "log" + "net/http" "os" "path/filepath" "strings" + "github.com/gorilla/websocket" "github.com/janlauber/one-click/hooks" "github.com/janlauber/one-click/pkg/controller" "github.com/janlauber/one-click/pkg/env" @@ -19,6 +22,57 @@ import ( "github.com/pocketbase/pocketbase/tools/cron" ) +var upgrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true // Consider your CORS policy here + }, +} + +type RolloutStatusRequest struct { + RolloutId string `json:"rolloutId"` +} + +func wsK8sRolloutsHandler(c echo.Context) error { + ws, err := upgrader.Upgrade(c.Response(), c.Request(), nil) + if err != nil { + log.Println("WebSocket upgrade error:", err) + return err + } + defer ws.Close() + + // Wait for a single message that contains the rolloutId + _, msg, err := ws.ReadMessage() + if err != nil { + log.Println("WebSocket read error:", err) + return err // or handle the error as appropriate + } + + // Unmarshal JSON to a struct and handle the message + var request RolloutStatusRequest + err = json.Unmarshal(msg, &request) + if err != nil { + log.Println("WebSocket unmarshal error:", err) + ws.WriteMessage(websocket.TextMessage, []byte("{\"error\":\"Invalid request format\"}")) + return err // or handle the error as appropriate + } + + log.Printf("Setting up watch for rolloutId: %s\n", request.RolloutId) + + // Assuming you've set up a function to watch Kubernetes Pods as described previously: + go k8s.WatchPodsAndSendUpdates(ws, request.RolloutId, request.RolloutId) // Assuming "default" namespace; adjust as needed + + // Keep the WebSocket connection open + for { + if _, _, err := ws.NextReader(); err != nil { + ws.Close() + break + } + // Optionally, you could handle additional messages from the client here + } + + return nil +} + func defaultPublicDir() string { if strings.HasPrefix(os.Args[0], os.TempDir()) { // most likely ran with go run @@ -145,6 +199,8 @@ func main() { return controller.HandleAutoUpdate(c, app, autoUpdateId) }) + e.Router.GET("/ws/k8s/rollouts", wsK8sRolloutsHandler) // WebSocket handler for Kubernetes rollouts + return nil }) diff --git a/pocketbase/pkg/k8s/watch.go b/pocketbase/pkg/k8s/watch.go new file mode 100644 index 00000000..34b85567 --- /dev/null +++ b/pocketbase/pkg/k8s/watch.go @@ -0,0 +1,58 @@ +package k8s + +import ( + "encoding/json" + "fmt" + "log" + + "github.com/gorilla/websocket" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/watch" +) + +func WatchPodsAndSendUpdates(ws *websocket.Conn, projectId string, rolloutId string) { + // Prepare the label selector string + labelSelector := fmt.Sprintf("rollout.one-click.dev/name=%s", rolloutId) + + // Start watching Pods with the specified label selector + watchInterface, err := Clientset.CoreV1().Pods(projectId).Watch(Ctx, metav1.ListOptions{ + LabelSelector: labelSelector, + }) + if err != nil { + log.Fatalf("Error setting up watch: %v", err) + } + + defer watchInterface.Stop() + + for event := range watchInterface.ResultChan() { + switch event.Type { + case watch.Added, watch.Modified, watch.Deleted, watch.Error: + pod, ok := event.Object.(*corev1.Pod) + if !ok { + log.Printf("Unexpected type") + continue + } + + // Prepare and marshal the pod information + podInfo := map[string]interface{}{ + "name": pod.Name, + "namespace": pod.Namespace, + "status": pod.Status.Phase, + "labels": pod.Labels, + } + msg, err := json.Marshal(podInfo) + if err != nil { + log.Printf("Error marshaling pod info: %v", err) + continue + } + + // Send the message over WebSocket + if err := ws.WriteMessage(websocket.TextMessage, msg); err != nil { + log.Printf("WebSocket write error: %v", err) + // Handle WebSocket disconnection or errors as needed + return + } + } + } +} From 8a222cc5eb81658daaa11e6cb152608658978f3a Mon Sep 17 00:00:00 2001 From: Jan Lauber Date: Thu, 21 Mar 2024 21:48:17 +0100 Subject: [PATCH 2/9] feat: Refactor code and comment out unused initialNodes and initialEdges Signed-off-by: Jan Lauber --- .../components/rollouts/RolloutsTable.svelte | 18 +- .../routes/app/projects/[id]/map/+page.svelte | 381 ++++++++++++++++-- .../app/projects/[id]/map/TurboNode.svelte | 24 +- .../app/projects/[id]/map/nodes-and-edges.ts | 30 -- pocketbase/main.go | 3 +- pocketbase/pkg/k8s/watch.go | 196 +++++++-- 6 files changed, 549 insertions(+), 103 deletions(-) diff --git a/frontend/src/lib/components/rollouts/RolloutsTable.svelte b/frontend/src/lib/components/rollouts/RolloutsTable.svelte index aa7293f5..ae1e1ac1 100644 --- a/frontend/src/lib/components/rollouts/RolloutsTable.svelte +++ b/frontend/src/lib/components/rollouts/RolloutsTable.svelte @@ -120,22 +120,22 @@ selectedRollout = rollout; $currentRollout = $rollouts.find((r) => !r.endDate); - if ($currentRollout == undefined) { - toast.error("There is no rollout to rollback to."); - return; - } + // if ($currentRollout == undefined) { + // toast.error("There is no rollout to rollback to."); + // return; + // } - if ($currentRollout.manifest == undefined) { - toast.error("The current rollout has no manifest."); - return; - } + // if ($currentRollout.manifest == undefined) { + // toast.error("The current rollout has no manifest."); + // return; + // } if (rollout.manifest == undefined) { toast.error("This rollout has no manifest."); return; } - modalTitle1 = $currentRollout.id; + modalTitle1 = $currentRollout?.id ?? "None"; modalTitle2 = rollout.id; defaultModal = true; diff --git a/frontend/src/routes/app/projects/[id]/map/+page.svelte b/frontend/src/routes/app/projects/[id]/map/+page.svelte index 7bd56438..740c13a8 100644 --- a/frontend/src/routes/app/projects/[id]/map/+page.svelte +++ b/frontend/src/routes/app/projects/[id]/map/+page.svelte @@ -1,30 +1,352 @@
@@ -34,16 +356,23 @@
-
- - - - - - - - - - - -
+ +{#if $pods.length > 0 && $services.length > 0 && $ingresses.length > 0 && $secrets.length > 0 } +
+ + + + + + + + + + + +
+{:else} +
+

No resources found.

+
+{/if} diff --git a/frontend/src/routes/app/projects/[id]/map/TurboNode.svelte b/frontend/src/routes/app/projects/[id]/map/TurboNode.svelte index be619063..82244805 100644 --- a/frontend/src/routes/app/projects/[id]/map/TurboNode.svelte +++ b/frontend/src/routes/app/projects/[id]/map/TurboNode.svelte @@ -1,7 +1,7 @@ -
+
{#if data.icon === "ingress"} @@ -23,11 +43,12 @@ {/if}
+
{ $drawerHidden = false; }} diff --git a/frontend/src/routes/app/projects/[id]/map/turbo.css b/frontend/src/routes/app/projects/[id]/map/turbo.css index 77129fe3..913a1e8e 100644 --- a/frontend/src/routes/app/projects/[id]/map/turbo.css +++ b/frontend/src/routes/app/projects/[id]/map/turbo.css @@ -2,11 +2,9 @@ --bg-color: #F7F9FC; --text-color: rgb(17, 17, 17); --node-border-radius: 10px; - --node-box-shadow: 10px 0 15px rgba(42, 138, 246, 0.3), -10px 0 15px rgba(233, 42, 103, 0.3); + --node-box-shadow: 10px 0 15px -3px rgba(0, 0, 0, 0.1), 4px 0 6px -2px rgba(0, 0, 0, 0.05); background-color: var(--bg-color) !important; color: var(--text-color); - border: 2px solid var(--text-color); - border-radius: 10px; } .svelte-flow__node-turbo { @@ -162,3 +160,39 @@ .svelte-flow__attribution a { color: #95679e; } + +.status-problematic:before { + content: ""; + position: absolute; + padding-bottom: calc(100% * 1.41421356237); + width: calc(100% * 1.41421356237); + background: linear-gradient(135deg, #ff7675 0%, #d63031 100%); + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + border-radius: 100%; +} + +.status-pending:before { + content: ""; + position: absolute; + padding-bottom: calc(100% * 1.41421356237); + width: calc(100% * 1.41421356237); + background: linear-gradient(135deg, #ffeaa7 0%, #fdcb6e 100%); + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + border-radius: 100%; +} + +.status-ok:before { + content: ""; + position: absolute; + padding-bottom: calc(100% * 1.41421356237); + width: calc(100% * 1.41421356237); + background: linear-gradient(135deg, #55efc4 0%, #00b894 100%); + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + border-radius: 100%; +} From db6ad795d549eedf3813b5853be2c91b90cb8923 Mon Sep 17 00:00:00 2001 From: Jan Lauber Date: Fri, 22 Mar 2024 11:07:05 +0100 Subject: [PATCH 5/9] feat: add border Signed-off-by: Jan Lauber --- frontend/src/routes/app/+layout.svelte | 2 +- frontend/src/routes/app/projects/[id]/map/+page.svelte | 2 +- frontend/src/routes/app/projects/[id]/map/turbo.css | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/src/routes/app/+layout.svelte b/frontend/src/routes/app/+layout.svelte index 72c7bd79..cec6395f 100644 --- a/frontend/src/routes/app/+layout.svelte +++ b/frontend/src/routes/app/+layout.svelte @@ -22,7 +22,7 @@ Welcome to OneClick prototypebeta {#if initialLoadComplete} -
+
diff --git a/frontend/src/routes/app/projects/[id]/map/turbo.css b/frontend/src/routes/app/projects/[id]/map/turbo.css index 913a1e8e..b78979bd 100644 --- a/frontend/src/routes/app/projects/[id]/map/turbo.css +++ b/frontend/src/routes/app/projects/[id]/map/turbo.css @@ -4,6 +4,8 @@ --node-border-radius: 10px; --node-box-shadow: 10px 0 15px -3px rgba(0, 0, 0, 0.1), 4px 0 6px -2px rgba(0, 0, 0, 0.05); background-color: var(--bg-color) !important; + border: 2px solid var(--text-color); + border-radius: 10px; color: var(--text-color); } From 25e988692d4ad92d35fc3b1ba3049fced8e842a6 Mon Sep 17 00:00:00 2001 From: Jan Lauber Date: Tue, 26 Mar 2024 13:50:03 +0100 Subject: [PATCH 6/9] feat: enhance ingress and storage class select Signed-off-by: Jan Lauber --- .../lib/components/volumes/NewVolume.svelte | 20 ++++-- frontend/src/lib/stores/data.ts | 12 ++++ frontend/src/lib/utils/cluster-info.ts | 46 +++++++++++++ .../routes/app/projects/[id]/map/+page.svelte | 10 ++- .../app/projects/[id]/network/+page.svelte | 65 ++++++++++++++++--- .../app/projects/[id]/volumes/+page.svelte | 5 ++ pocketbase/main.go | 5 ++ pocketbase/pkg/controller/clusterInfo.go | 18 +++++ pocketbase/pkg/k8s/info.go | 37 +++++++++++ 9 files changed, 201 insertions(+), 17 deletions(-) create mode 100644 frontend/src/lib/utils/cluster-info.ts create mode 100644 pocketbase/pkg/controller/clusterInfo.go create mode 100644 pocketbase/pkg/k8s/info.go diff --git a/frontend/src/lib/components/volumes/NewVolume.svelte b/frontend/src/lib/components/volumes/NewVolume.svelte index bcd8bdd5..0cdb8bbe 100644 --- a/frontend/src/lib/components/volumes/NewVolume.svelte +++ b/frontend/src/lib/components/volumes/NewVolume.svelte @@ -5,9 +5,10 @@ updateDataStores, type Rexpand, UpdateFilterEnum, - currentRollout + currentRollout, + clusterInfo } from "$lib/stores/data"; - import { Accordion, AccordionItem, Button, Input, Label, Toggle } from "flowbite-svelte"; + import { Accordion, AccordionItem, Button, Input, Label, Select, Toggle } from "flowbite-svelte"; import selectedProjectId from "$lib/stores/project"; import toast from "svelte-french-toast"; @@ -82,7 +83,7 @@ let new_manifest: any = { ...$currentRollout.manifest, spec: { - // @ts-ignore + // @ts-ignore ...$currentRollout.manifest.spec, volumes: [ // @ts-ignore @@ -95,8 +96,7 @@ } ] } - } - + }; const data: RolloutsRecord = { manifest: new_manifest, @@ -149,7 +149,15 @@ Storage Class * - +