appmanager-ui: network selector
diff --git a/core/appmanager/sveltekit/appmanager/package-lock.json b/core/appmanager/sveltekit/appmanager/package-lock.json
index 3997d88..f2daa8d 100644
--- a/core/appmanager/sveltekit/appmanager/package-lock.json
+++ b/core/appmanager/sveltekit/appmanager/package-lock.json
@@ -8,11 +8,19 @@
"name": "appmanager",
"version": "0.0.1",
"dependencies": {
+ "@melt-ui/svelte": "^0.15.0",
+ "@picocss/pico": "^1.5.10",
"@restspace/svelte-schema-form": "^0.1.5",
+ "@svelteuidev/composables": "^0.13.0",
+ "@svelteuidev/core": "^0.13.0",
+ "@svelteuidev/motion": "^0.13.0",
+ "flexboxgrid": "^6.3.1",
"sass": "^1.62.1",
+ "svelte-french-toast": "^1.1.0",
"svelte-split-pane": "^0.1.2"
},
"devDependencies": {
+ "@iconify/svelte": "^3.1.4",
"@skeletonlabs/skeleton": "^1.6.2",
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.5.0",
@@ -22,14 +30,14 @@
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte": "^2.26.0",
- "postcss": "^8.4.23",
+ "postcss": "^8.4.24",
"postcss-load-config": "^4.0.1",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.8.1",
"svelte": "^3.54.0",
"svelte-check": "^3.0.1",
"svelte-preprocess": "^5.0.3",
- "tailwindcss": "^3.3.1",
+ "tailwindcss": "^3.3.2",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.3.0"
@@ -460,6 +468,19 @@
"resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.0.1.tgz",
"integrity": "sha512-PQdbF8dGd4LnbwBlcc4ML8RKYdplm+e9sUeWBTr4zgF13/Shiuov9XznvM4T8cb1CfyKK21yTUkuAIIh/DAH/g=="
},
+ "node_modules/@floating-ui/core": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.3.1.tgz",
+ "integrity": "sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g=="
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.8.tgz",
+ "integrity": "sha512-XLwhYV90MxiHDq6S0rzFZj00fnDM+A1R9jhSioZoMsa7G0Q0i+Q4x40ajR8FHSdYDE1bgjG45mIWe6jtv9UPmg==",
+ "dependencies": {
+ "@floating-ui/core": "^1.2.6"
+ }
+ },
"node_modules/@humanwhocodes/config-array": {
"version": "0.11.8",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
@@ -493,6 +514,27 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
+ "node_modules/@iconify/svelte": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/@iconify/svelte/-/svelte-3.1.4.tgz",
+ "integrity": "sha512-YDwQlN46ka8KPRayDb7TivmkAPizfTXi6BSRNqa1IV0+byA907n8JcgQafA7FD//pW5XCuuAhVx6uRbKTo+CfA==",
+ "dev": true,
+ "dependencies": {
+ "@iconify/types": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/cyberalien"
+ },
+ "peerDependencies": {
+ "svelte": "*"
+ }
+ },
+ "node_modules/@iconify/types": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
+ "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
+ "dev": true
+ },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
@@ -547,6 +589,45 @@
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
"dev": true
},
+ "node_modules/@melt-ui/svelte": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/@melt-ui/svelte/-/svelte-0.15.0.tgz",
+ "integrity": "sha512-xcNAYu1v1xjikIreoF+Pbr3Eh6Ngo8yVeQBhCc9rczoOmrT+GNpYqEyTWzFu6Wdkn2i+a8jJZw3RPlnO4b8Y0Q==",
+ "dependencies": {
+ "@floating-ui/core": "^1.3.1",
+ "@floating-ui/dom": "^1.4.2",
+ "focus-trap": "^7.4.3",
+ "nanoid": "^4.0.2"
+ },
+ "peerDependencies": {
+ "svelte": ">=3 <5"
+ }
+ },
+ "node_modules/@melt-ui/svelte/node_modules/@floating-ui/dom": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.4.3.tgz",
+ "integrity": "sha512-nB/68NyaQlcdY22L+Fgd1HERQ7UGv7XFN+tPxwrEfQL4nKtAP/jIZnZtpUlXbtV+VEGHh6W/63Gy2C5biWI3sA==",
+ "dependencies": {
+ "@floating-ui/core": "^1.3.1"
+ }
+ },
+ "node_modules/@melt-ui/svelte/node_modules/nanoid": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz",
+ "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "bin": {
+ "nanoid": "bin/nanoid.js"
+ },
+ "engines": {
+ "node": "^14 || ^16 || >=18"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -582,6 +663,11 @@
"node": ">= 8"
}
},
+ "node_modules/@picocss/pico": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/@picocss/pico/-/pico-1.5.10.tgz",
+ "integrity": "sha512-+LafMsrwPxXQMk6sI///TmSInCwwZmq+K7SikyL3N/4GhhwzyPC+TQLUEqmrLyjluR+uIpFFcqjty30Rtr6GxQ=="
+ },
"node_modules/@polka/url": {
"version": "1.0.0-next.21",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
@@ -616,6 +702,11 @@
"node": ">= 8"
}
},
+ "node_modules/@stitches/core": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@stitches/core/-/core-1.2.8.tgz",
+ "integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg=="
+ },
"node_modules/@sveltejs/adapter-auto": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-2.1.0.tgz",
@@ -699,6 +790,35 @@
"vite": "^4.0.0"
}
},
+ "node_modules/@svelteuidev/composables": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@svelteuidev/composables/-/composables-0.13.0.tgz",
+ "integrity": "sha512-vnDcmSMwav11Xp4f9PUJW5wlHbj1rQTIU9v62C0eOjfq4r/CLyj8FTRslKX5nrBUQxxlYlamsdM5rqCUm4aEbw==",
+ "peerDependencies": {
+ "svelte": ">=3.55.0"
+ }
+ },
+ "node_modules/@svelteuidev/core": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@svelteuidev/core/-/core-0.13.0.tgz",
+ "integrity": "sha512-Jtl8J8leUkEHTpLQsJ5Rgeb0CqTAcn4ol656bqLjy/ZMLCpaRP867E5W31htLn7BxOVLpUe9QKpiuoTz7nHLcQ==",
+ "dependencies": {
+ "@floating-ui/dom": "1.2.8",
+ "@stitches/core": "1.2.8"
+ },
+ "peerDependencies": {
+ "@svelteuidev/composables": "0.13.0",
+ "svelte": ">=3.55.0"
+ }
+ },
+ "node_modules/@svelteuidev/motion": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@svelteuidev/motion/-/motion-0.13.0.tgz",
+ "integrity": "sha512-Bq96zJokjCgBMoNLzx5bvScIMxCi5sBJqaEmHSGXcSaVxmPOBXGHMSZ5myX/TWOhr/1oEsSzlVeJ08Z0Yjmj4A==",
+ "peerDependencies": {
+ "svelte": ">=3.55.0"
+ }
+ },
"node_modules/@types/cookie": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.1.tgz",
@@ -1824,6 +1944,19 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"dev": true
},
+ "node_modules/flexboxgrid": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/flexboxgrid/-/flexboxgrid-6.3.1.tgz",
+ "integrity": "sha512-OS//6OHK9i3Hy5mLwD49uRYvnZ9fdfSkq7omO5uJPA2CD7JeBuDY7xleqN1h3MGJZNvKUskyNTv0ot0JKvOAsg=="
+ },
+ "node_modules/focus-trap": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.4.3.tgz",
+ "integrity": "sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==",
+ "dependencies": {
+ "tabbable": "^6.1.2"
+ }
+ },
"node_modules/fraction.js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
@@ -2564,9 +2697,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.23",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
- "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==",
+ "version": "8.4.24",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz",
+ "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==",
"dev": true,
"funding": [
{
@@ -3138,7 +3271,6 @@
"version": "3.59.1",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.1.tgz",
"integrity": "sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==",
- "dev": true,
"engines": {
"node": ">= 8"
}
@@ -3215,6 +3347,17 @@
"node": ">=4.0"
}
},
+ "node_modules/svelte-french-toast": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/svelte-french-toast/-/svelte-french-toast-1.1.0.tgz",
+ "integrity": "sha512-OWlOJD0iqZpL4apMbtsbSZKYukBz9CuME2KoW/zzHfFWVImXVH5zAiCmUU4N0OSPo9fY34TZKIL/5+Sbt5KkPA==",
+ "dependencies": {
+ "svelte-writable-derived": "^3.1.0"
+ },
+ "peerDependencies": {
+ "svelte": "^3.57.0 || ^4.0.0"
+ }
+ },
"node_modules/svelte-hmr": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
@@ -3306,6 +3449,22 @@
"resolved": "https://registry.npmjs.org/svelte-split-pane/-/svelte-split-pane-0.1.2.tgz",
"integrity": "sha512-JluEydC9v2DetyhlwCF3CdqAkET8XPHP7WeWbl4lVLOg55avDOhoS5U6BRhvWd104HOqhUcCSz+7Nveyjmzjeg=="
},
+ "node_modules/svelte-writable-derived": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/svelte-writable-derived/-/svelte-writable-derived-3.1.0.tgz",
+ "integrity": "sha512-cTvaVFNIJ036vSDIyPxJYivKC7ZLtcFOPm1Iq6qWBDo1fOHzfk6ZSbwaKrxhjgy52Rbl5IHzRcWgos6Zqn9/rg==",
+ "funding": {
+ "url": "https://ko-fi.com/pixievoltno1"
+ },
+ "peerDependencies": {
+ "svelte": "^3.2.1 || ^4.0.0-next.1"
+ }
+ },
+ "node_modules/tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
+ },
"node_modules/tailwindcss": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz",
@@ -3852,6 +4011,19 @@
"resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.0.1.tgz",
"integrity": "sha512-PQdbF8dGd4LnbwBlcc4ML8RKYdplm+e9sUeWBTr4zgF13/Shiuov9XznvM4T8cb1CfyKK21yTUkuAIIh/DAH/g=="
},
+ "@floating-ui/core": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.3.1.tgz",
+ "integrity": "sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g=="
+ },
+ "@floating-ui/dom": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.8.tgz",
+ "integrity": "sha512-XLwhYV90MxiHDq6S0rzFZj00fnDM+A1R9jhSioZoMsa7G0Q0i+Q4x40ajR8FHSdYDE1bgjG45mIWe6jtv9UPmg==",
+ "requires": {
+ "@floating-ui/core": "^1.2.6"
+ }
+ },
"@humanwhocodes/config-array": {
"version": "0.11.8",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
@@ -3875,6 +4047,21 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
+ "@iconify/svelte": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/@iconify/svelte/-/svelte-3.1.4.tgz",
+ "integrity": "sha512-YDwQlN46ka8KPRayDb7TivmkAPizfTXi6BSRNqa1IV0+byA907n8JcgQafA7FD//pW5XCuuAhVx6uRbKTo+CfA==",
+ "dev": true,
+ "requires": {
+ "@iconify/types": "^2.0.0"
+ }
+ },
+ "@iconify/types": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
+ "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
+ "dev": true
+ },
"@jridgewell/gen-mapping": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
@@ -3922,6 +4109,32 @@
}
}
},
+ "@melt-ui/svelte": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/@melt-ui/svelte/-/svelte-0.15.0.tgz",
+ "integrity": "sha512-xcNAYu1v1xjikIreoF+Pbr3Eh6Ngo8yVeQBhCc9rczoOmrT+GNpYqEyTWzFu6Wdkn2i+a8jJZw3RPlnO4b8Y0Q==",
+ "requires": {
+ "@floating-ui/core": "^1.3.1",
+ "@floating-ui/dom": "^1.4.2",
+ "focus-trap": "^7.4.3",
+ "nanoid": "^4.0.2"
+ },
+ "dependencies": {
+ "@floating-ui/dom": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.4.3.tgz",
+ "integrity": "sha512-nB/68NyaQlcdY22L+Fgd1HERQ7UGv7XFN+tPxwrEfQL4nKtAP/jIZnZtpUlXbtV+VEGHh6W/63Gy2C5biWI3sA==",
+ "requires": {
+ "@floating-ui/core": "^1.3.1"
+ }
+ },
+ "nanoid": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-4.0.2.tgz",
+ "integrity": "sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw=="
+ }
+ }
+ },
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -3948,6 +4161,11 @@
"fastq": "^1.6.0"
}
},
+ "@picocss/pico": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/@picocss/pico/-/pico-1.5.10.tgz",
+ "integrity": "sha512-+LafMsrwPxXQMk6sI///TmSInCwwZmq+K7SikyL3N/4GhhwzyPC+TQLUEqmrLyjluR+uIpFFcqjty30Rtr6GxQ=="
+ },
"@polka/url": {
"version": "1.0.0-next.21",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
@@ -3981,6 +4199,11 @@
}
}
},
+ "@stitches/core": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@stitches/core/-/core-1.2.8.tgz",
+ "integrity": "sha512-Gfkvwk9o9kE9r9XNBmJRfV8zONvXThnm1tcuojL04Uy5uRyqg93DC83lDebl0rocZCfKSjUv+fWYtMQmEDJldg=="
+ },
"@sveltejs/adapter-auto": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-2.1.0.tgz",
@@ -4035,6 +4258,27 @@
"debug": "^4.3.4"
}
},
+ "@svelteuidev/composables": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@svelteuidev/composables/-/composables-0.13.0.tgz",
+ "integrity": "sha512-vnDcmSMwav11Xp4f9PUJW5wlHbj1rQTIU9v62C0eOjfq4r/CLyj8FTRslKX5nrBUQxxlYlamsdM5rqCUm4aEbw==",
+ "requires": {}
+ },
+ "@svelteuidev/core": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@svelteuidev/core/-/core-0.13.0.tgz",
+ "integrity": "sha512-Jtl8J8leUkEHTpLQsJ5Rgeb0CqTAcn4ol656bqLjy/ZMLCpaRP867E5W31htLn7BxOVLpUe9QKpiuoTz7nHLcQ==",
+ "requires": {
+ "@floating-ui/dom": "1.2.8",
+ "@stitches/core": "1.2.8"
+ }
+ },
+ "@svelteuidev/motion": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@svelteuidev/motion/-/motion-0.13.0.tgz",
+ "integrity": "sha512-Bq96zJokjCgBMoNLzx5bvScIMxCi5sBJqaEmHSGXcSaVxmPOBXGHMSZ5myX/TWOhr/1oEsSzlVeJ08Z0Yjmj4A==",
+ "requires": {}
+ },
"@types/cookie": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.5.1.tgz",
@@ -4801,6 +5045,19 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"dev": true
},
+ "flexboxgrid": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/flexboxgrid/-/flexboxgrid-6.3.1.tgz",
+ "integrity": "sha512-OS//6OHK9i3Hy5mLwD49uRYvnZ9fdfSkq7omO5uJPA2CD7JeBuDY7xleqN1h3MGJZNvKUskyNTv0ot0JKvOAsg=="
+ },
+ "focus-trap": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.4.3.tgz",
+ "integrity": "sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==",
+ "requires": {
+ "tabbable": "^6.1.2"
+ }
+ },
"fraction.js": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
@@ -5343,9 +5600,9 @@
"dev": true
},
"postcss": {
- "version": "8.4.23",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
- "integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==",
+ "version": "8.4.24",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz",
+ "integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==",
"dev": true,
"requires": {
"nanoid": "^3.3.6",
@@ -5698,8 +5955,7 @@
"svelte": {
"version": "3.59.1",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.59.1.tgz",
- "integrity": "sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ==",
- "dev": true
+ "integrity": "sha512-pKj8fEBmqf6mq3/NfrB9SLtcJcUvjYSWyePlfCqN9gujLB25RitWK8PvFzlwim6hD/We35KbPlRteuA6rnPGcQ=="
},
"svelte-check": {
"version": "3.3.2",
@@ -5746,6 +6002,14 @@
}
}
},
+ "svelte-french-toast": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/svelte-french-toast/-/svelte-french-toast-1.1.0.tgz",
+ "integrity": "sha512-OWlOJD0iqZpL4apMbtsbSZKYukBz9CuME2KoW/zzHfFWVImXVH5zAiCmUU4N0OSPo9fY34TZKIL/5+Sbt5KkPA==",
+ "requires": {
+ "svelte-writable-derived": "^3.1.0"
+ }
+ },
"svelte-hmr": {
"version": "0.15.1",
"resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.1.tgz",
@@ -5782,6 +6046,17 @@
"resolved": "https://registry.npmjs.org/svelte-split-pane/-/svelte-split-pane-0.1.2.tgz",
"integrity": "sha512-JluEydC9v2DetyhlwCF3CdqAkET8XPHP7WeWbl4lVLOg55avDOhoS5U6BRhvWd104HOqhUcCSz+7Nveyjmzjeg=="
},
+ "svelte-writable-derived": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/svelte-writable-derived/-/svelte-writable-derived-3.1.0.tgz",
+ "integrity": "sha512-cTvaVFNIJ036vSDIyPxJYivKC7ZLtcFOPm1Iq6qWBDo1fOHzfk6ZSbwaKrxhjgy52Rbl5IHzRcWgos6Zqn9/rg==",
+ "requires": {}
+ },
+ "tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
+ },
"tailwindcss": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.2.tgz",
diff --git a/core/appmanager/sveltekit/appmanager/package.json b/core/appmanager/sveltekit/appmanager/package.json
index c7cab68..b46b740 100644
--- a/core/appmanager/sveltekit/appmanager/package.json
+++ b/core/appmanager/sveltekit/appmanager/package.json
@@ -12,31 +12,30 @@
"format": "prettier --plugin-search-dir . --write ."
},
"devDependencies": {
- "@skeletonlabs/skeleton": "^1.6.2",
+ "@iconify/svelte": "^3.1.4",
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.5.0",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
- "autoprefixer": "^10.4.14",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte": "^2.26.0",
- "postcss": "^8.4.23",
+ "postcss": "^8.4.24",
"postcss-load-config": "^4.0.1",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.8.1",
"svelte": "^3.54.0",
"svelte-check": "^3.0.1",
"svelte-preprocess": "^5.0.3",
- "tailwindcss": "^3.3.1",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.3.0"
},
"type": "module",
"dependencies": {
- "@restspace/svelte-schema-form": "^0.1.5",
+ "@melt-ui/svelte": "^0.15.0",
+ "@picocss/pico": "^1.5.10",
"sass": "^1.62.1",
- "svelte-split-pane": "^0.1.2"
+ "svelte-french-toast": "^1.1.0"
}
}
diff --git a/core/appmanager/sveltekit/appmanager/postcss.config.cjs b/core/appmanager/sveltekit/appmanager/postcss.config.cjs
index fe10e55..9bd9f09 100644
--- a/core/appmanager/sveltekit/appmanager/postcss.config.cjs
+++ b/core/appmanager/sveltekit/appmanager/postcss.config.cjs
@@ -1,11 +1,7 @@
-const tailwindcss = require('tailwindcss');
const autoprefixer = require('autoprefixer');
const config = {
plugins: [
- //Some plugins, like tailwindcss/nesting, need to run before Tailwind,
- tailwindcss(),
- //But others, like autoprefixer, need to run after,
autoprefixer
]
};
diff --git a/core/appmanager/sveltekit/appmanager/src/app.html b/core/appmanager/sveltekit/appmanager/src/app.html
index e13964e..9950a7e 100644
--- a/core/appmanager/sveltekit/appmanager/src/app.html
+++ b/core/appmanager/sveltekit/appmanager/src/app.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html lang="en" class="dark">
+<html lang="en" data-theme="light">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
@@ -7,6 +7,6 @@
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
- <div style="display: contents" class="h-full overflow-hidden">%sveltekit.body%</div>
+ <div class="container">%sveltekit.body%</div>
</body>
</html>
diff --git a/core/appmanager/sveltekit/appmanager/src/app.postcss b/core/appmanager/sveltekit/appmanager/src/app.postcss
index 4bdf31e..7e8304a 100644
--- a/core/appmanager/sveltekit/appmanager/src/app.postcss
+++ b/core/appmanager/sveltekit/appmanager/src/app.postcss
@@ -2,3 +2,7 @@
html, body {
@apply h-full overflow-hidden;
}
+
+div.container {
+ margin-top: 10px;
+}
diff --git a/core/appmanager/sveltekit/appmanager/src/lib/ConfigurationForm.svelte b/core/appmanager/sveltekit/appmanager/src/lib/ConfigurationForm.svelte
new file mode 100644
index 0000000..4b1844c
--- /dev/null
+++ b/core/appmanager/sveltekit/appmanager/src/lib/ConfigurationForm.svelte
@@ -0,0 +1,59 @@
+<script lang="ts">
+import { createEventDispatcher } from 'svelte';
+
+ import { derived, writable, type Writable } from 'svelte/store'
+
+ import NetworkSelector from "./NetworkSelector.svelte";
+ import TextInput from "./TextInput.svelte";
+
+ export let availableNetworks = [
+ {
+ name: "Public",
+ domain: "qwe.lekva.me",
+ },
+ {
+ name: "Private",
+ domain: "p.qwe.lekva.me",
+ },
+ ];
+ export let schema = null;
+
+ const isNetwork = (schema): boolean => {
+ return "$ref" in schema &&
+ typeof schema["$ref"] === "string" &&
+ schema["$ref"] === "#/definitions/network";
+ };
+
+ type Data = Record<string, Writable<any>>;
+
+ const children = Object.fromEntries(Object.entries(schema.properties).map(([field, fieldSchema]) => {
+ switch (fieldSchema.type) {
+ case "object":
+ return [field, writable<Data | undefined>(undefined)];
+ default:
+ return [field, writable<string | undefined>(field)];
+ }
+ }));
+ const data = derived(Object.values(children), ($values) => {
+ return Object.fromEntries(Object.keys(children).map((field, index) => ([
+ field,
+ $values[index],
+ ])));
+ });
+
+ const dispatch = createEventDispatcher();
+ $: dispatch("change", $data);
+</script>
+
+{#each Object.entries(schema.properties) as [name, schema]}
+ {#if schema.type === "object"}
+ <svelte:self schema />
+ {:else if isNetwork(schema)}
+ <NetworkSelector {name} {availableNetworks} on:input={(v) => children[name].set(v.detail)} />
+ {:else if schema.type === "string"}
+ <TextInput {name} on:input={(v) => children[name].set(v.detail)} />
+ {/if}
+{/each}
+
+<style>
+</style>
diff --git a/core/appmanager/sveltekit/appmanager/src/lib/NetworkSelector.svelte b/core/appmanager/sveltekit/appmanager/src/lib/NetworkSelector.svelte
new file mode 100644
index 0000000..57df66b
--- /dev/null
+++ b/core/appmanager/sveltekit/appmanager/src/lib/NetworkSelector.svelte
@@ -0,0 +1,44 @@
+<script lang="ts">
+ import { createLabel, createSelect } from '@melt-ui/svelte';
+ import { createEventDispatcher } from 'svelte';
+ import { derived } from 'svelte/store';
+
+ export let name = "";
+ export let availableNetworks = [];
+ export let value: string | number | undefined | null = undefined;
+
+ const { root } = createLabel();
+ const { label, trigger, option, isSelected } = createSelect();
+
+ const triggerWithoutRole = derived(trigger, ($trigger) => {
+ const {role: _, ...rest} = $trigger;
+ return rest;
+ });
+
+ $: (() => value = $label)();
+
+ const dispatch = createEventDispatcher();
+ $: dispatch("input", value);
+</script>
+
+<label use:root.action>
+ <span>{name}</span>
+</label>
+<details role="list">
+ <summary aria-haspopup="listbox" {...$triggerWithoutRole} use:trigger.action>{$label || "Select network"}</summary>
+ <ul role="listbox">
+ {#each availableNetworks as n}
+ <li {...$option({ value: n.name, label: n.name })} use:option.action>
+ <a>
+ {n.name}: {n.domain}
+ {#if $isSelected(n.name)}
+ s
+ {/if}
+ </a>
+ </li>
+ {/each}
+ </ul>
+</details>
+
+<style lang="postcss">
+</style>
diff --git a/core/appmanager/sveltekit/appmanager/src/lib/TextInput.svelte b/core/appmanager/sveltekit/appmanager/src/lib/TextInput.svelte
new file mode 100644
index 0000000..b104a1c
--- /dev/null
+++ b/core/appmanager/sveltekit/appmanager/src/lib/TextInput.svelte
@@ -0,0 +1,20 @@
+<script lang="ts">
+ import { createEventDispatcher } from 'svelte';
+ import { createLabel } from '@melt-ui/svelte';
+
+ export let name: string = "";
+ export let prefix: string = "";
+ export let value: string | undefined = undefined;
+
+ const { root } = createLabel();
+
+ const dispatch = createEventDispatcher();
+
+ $: id = `${prefix}${name}`;
+ $: dispatch("input", value);
+</script>
+
+<label use:root.action for={name} class="font-medium">
+ <span>{name}</span>
+</label>
+<input type="text" {id} {name} bind:value />
diff --git a/core/appmanager/sveltekit/appmanager/src/lib/network.ts b/core/appmanager/sveltekit/appmanager/src/lib/network.ts
new file mode 100644
index 0000000..384198a
--- /dev/null
+++ b/core/appmanager/sveltekit/appmanager/src/lib/network.ts
@@ -0,0 +1,4 @@
+export type Network = {
+ name: string;
+ domain: string;
+};
diff --git a/core/appmanager/sveltekit/appmanager/src/routes/+layout.svelte b/core/appmanager/sveltekit/appmanager/src/routes/+layout.svelte
index f7560fd..3437503 100644
--- a/core/appmanager/sveltekit/appmanager/src/routes/+layout.svelte
+++ b/core/appmanager/sveltekit/appmanager/src/routes/+layout.svelte
@@ -1,18 +1,13 @@
<script lang="ts">
- import "@skeletonlabs/skeleton/themes/theme-skeleton.css";
- import "@skeletonlabs/skeleton/styles/skeleton.css";
+ import "@picocss/pico";
import "../app.postcss";
-import { onMount } from "svelte";
- onMount(() => {
- window.addEventListener('message', (e) => {
- console.log(e);
- if ("go_back" in e.data) {
- window.history.go(-1);
- }
- });
- });
+ import { Toaster } from "svelte-french-toast";
</script>
<slot />
+<Toaster />
+
+<style>
+</style>
diff --git a/core/appmanager/sveltekit/appmanager/src/routes/+page.svelte b/core/appmanager/sveltekit/appmanager/src/routes/+page.svelte
index c6ee5fe..c75ac34 100644
--- a/core/appmanager/sveltekit/appmanager/src/routes/+page.svelte
+++ b/core/appmanager/sveltekit/appmanager/src/routes/+page.svelte
@@ -1,9 +1,12 @@
<script lang="ts">
- import { onMount } from "svelte";
+ import { onMount } from "svelte";
+ import Icon from '@iconify/svelte';
type app = {
name: string;
- slug: string;
+ slug: string;
+ icon: string;
+ shortDescription: string;
};
let apps: app[] = [];
@@ -12,20 +15,78 @@
const resp = await fetch("/api/app-repo");
apps = await resp.json();
});
+
+ let cur = null;
+ const view = (e) => {
+ if (cur === e.target) {
+ cur = null;
+ return;
+ }
+ console.log(111)
+ console.log(cur?.parentElement);
+ cur?.parentElement.toggleAttribute("open");
+ cur = e.target;
+ };
+
+ const search = (e) => {
+ console.log(e.target.value);
+ };
</script>
+<div class="main">
+<form>
+ <input type="search" placeholder="Search" on:input={search} />
+</form>
+<aside>
+ <nav>
+ <ul>
+ {#each apps as app}
+ <li>
+ <article>
+ <div>
+ <a href="/app/{app.slug}" class="logo">
+ <Icon icon="{app.icon}" width="50" height="50" />
+ </a>
+ </div>
+ <div>
+ <a href="/app/{app.slug}">
+ {app.name}
+ </a>
+ {app.shortDescription}
+ </div>
+ </article>
+ </li>
+ {/each}
+ </ul>
+ </nav>
+</aside>
+</div>
-<nav class="list-nav">
- <!-- (optionally you can provide a label here) -->
- <ul>
- {#each apps as app}
- <li>
- <a href="/app/{app.slug}">
- <span class="badge bg-primary-500">💀</span>
- <span class="flex-auto">{app.name}</span>
- </a>
- </li>
- {/each}
- </ul>
-</nav>
+<style>
+ .main {
+ max-width: 70%;
+ margin: 0 auto;
+ }
+
+ article {
+ margin: 0.3em;
+ margin-bottom: 0.3em;
+
+ display: flex;
+ flex-direction: row;
+ }
+
+ .logo {
+ display: table-cell;
+ vertical-align: middle;
+ }
+ nav li {
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+
+ input[type="search"] {
+ margin-bottom: 0;
+ }
+</style>
diff --git "a/core/appmanager/sveltekit/appmanager/src/routes/app/\133slug\135/+page.svelte" "b/core/appmanager/sveltekit/appmanager/src/routes/app/\133slug\135/+page.svelte"
index d280fad..946f08f 100644
--- "a/core/appmanager/sveltekit/appmanager/src/routes/app/\133slug\135/+page.svelte"
+++ "b/core/appmanager/sveltekit/appmanager/src/routes/app/\133slug\135/+page.svelte"
@@ -1,82 +1,91 @@
<script lang="ts">
import { onMount } from "svelte";
- import { HSplitPane, VSplitPane } from "svelte-split-pane";
- import { TabGroup, Tab, Toast, toastStore } from "@skeletonlabs/skeleton";
import { SubmitForm } from "@restspace/svelte-schema-form";
import "@restspace/svelte-schema-form/css/layout.scss";
- import "@restspace/svelte-schema-form/css/basic-skin.scss";
+ // import "@restspace/svelte-schema-form/css/basic-skin.scss";
+ import Icon from '@iconify/svelte';
+ import toast from "svelte-french-toast";
- interface File {
- name string;
- contents string;
- }
+ import ConfigurationForm from "$lib/ConfigurationForm.svelte";
+import { writable } from "svelte/store";
export let data: AppData;
- let readme: string = "";
- let files: File[] = [];
+ let config: Record<string, any> = null;
+ let readme: string = null;
- let tabSet: number = 0;
-
- const submit = async (e) => {
- const resp = await fetch(`/api/app/${data.slug}/install`, {
- method: "POST",
- headers: {
- "Accept": "application/json",
- "Content-Type": "application/json"
- },
- body: JSON.stringify(e.detail.value),
- });
- toastStore.trigger({
- message: await resp.text(),
- timeout: 1000,
- });
- return false;
+ const submit = async (config) => {
+ const resp = await fetch(`/api/app/${data.slug}/install`, {
+ method: "POST",
+ headers: {
+ "Accept": "application/json",
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify(config),
+ });
+ if (resp.status === 200) {
+ toast.success("Installed");
+ } else {
+ toast.error("Installation failed");
+ }
+ return false;
};
const render = async (config) => {
- const resp = await fetch(`/api/app/${data.slug}/render`, {
- method: "POST",
- headers: {
- "Accept": "application/json",
- "Content-Type": "application/json"
- },
- body: JSON.stringify(config),
- });
- const app = await resp.json();
- readme = app.readme;
- files = app.files;
+ const resp = await fetch(`/api/app/${data.slug}/render`, {
+ method: "POST",
+ headers: {
+ "Accept": "application/json",
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify(config),
+ });
+ const app = await resp.json();
+ readme = app.readme;
};
- const change = (e) => render(e.detail.value);
+ const extractDefaultValues = (schema) => {
+ switch (schema.type) {
+ case "string": return schema.default ?? "";
+ case "object": {
+ const ret: Record<string, any> = {};
+ for (const [key, value] of Object.entries(schema.properties)) {
+ ret[key] = extractDefaultValues(value);
+ };
+ return ret;
+ }
+ }
+ };
onMount(() => {
+ data.config = null; // TODO(giolekva): remove
if (data.config != null) {
- render(data.config);
+ config = data.config;
+ } else {
+ config = extractDefaultValues(data.schema);
+ console.log(config);
}
+ render(config);
});
+
+ const formData = writable(null);
+ $: render($formData);
</script>
-{data.slug}
-<HSplitPane>
- <left slot="left">
- <SubmitForm schema={data.schema} value={data.config ?? {}} on:submit={submit} on:value={change} submitText="Install" />
- </left>
- <right slot="right">
- <TabGroup>
- <Tab bind:group={tabSet} name="Readme" value={0}>Readme</Tab>
- {#each files as file, i }
- <Tab bind:group={tabSet} name={file.name} value={i + 1}>{file.name}</Tab>
- {/each}
- <svelte:fragment slot="panel">
- {#if tabSet === 0}
- {readme}
- {:else}
- <pre>
-{files[tabSet - 1].contents}
- </pre>
- {/if}
- </svelte:fragment>
- </TabGroup>
- </right>
-</HSplitPane>
-<Toast />
\ No newline at end of file
+<h1><Icon icon="{data.icon}" width="50" height="50" />{data.name}</h1>
+<pre>{readme}</pre>
+
+<form on:submit={() => submit($formData)}>
+ <ConfigurationForm schema={data.schema} on:change={(e) => formData.set(e.detail)} />
+ <input type="submit" value="Install" />
+</form>
+
+<style>
+ pre {
+ white-space: pre-wrap; /* Since CSS 2.1 */
+ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
+ white-space: -pre-wrap; /* Opera 4-6 */
+ white-space: -o-pre-wrap; /* Opera 7 */
+ word-wrap: break-word; /* Internet Explorer 5.5+ */
+ background-color: transparent;
+ }
+</style>
diff --git "a/core/appmanager/sveltekit/appmanager/src/routes/app/\133slug\135/+page.ts" "b/core/appmanager/sveltekit/appmanager/src/routes/app/\133slug\135/+page.ts"
index c614133..0f355f9 100644
--- "a/core/appmanager/sveltekit/appmanager/src/routes/app/\133slug\135/+page.ts"
+++ "b/core/appmanager/sveltekit/appmanager/src/routes/app/\133slug\135/+page.ts"
@@ -1,6 +1,8 @@
export const ssr = false;
export type AppData = {
+ name: string;
+ icon: string;
slug: string;
schema: Record<string, unknown>;
config: Record<string, unknown>;
@@ -9,7 +11,10 @@
export async function load({ params, fetch }): Promise<AppData> {
const resp = await fetch(`/api/app/${params.slug}`);
const ret = await resp.json();
+ console.log(ret);
return {
+ name: ret.name,
+ icon: ret.icon,
slug: params.slug,
schema: JSON.parse(ret.schema),
config: ret.config,
diff --git a/core/appmanager/sveltekit/appmanager/tailwind.config.cjs b/core/appmanager/sveltekit/appmanager/tailwind.config.cjs
deleted file mode 100644
index ce8ca4e..0000000
--- a/core/appmanager/sveltekit/appmanager/tailwind.config.cjs
+++ /dev/null
@@ -1,20 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-module.exports = {
- // 1. Apply the dark mode class setting:
- darkMode: 'class',
- content: [
- './src/**/*.{html,js,svelte,ts}',
- // 2. Append the path for the Skeleton NPM package and files:
- require('path').join(require.resolve(
- '@skeletonlabs/skeleton'),
- '../**/*.{html,js,svelte,ts}'
- )
- ],
- theme: {
- extend: {},
- },
- plugins: [
- // 3. Append the Skeleton plugin to the end of this list
- ...require('@skeletonlabs/skeleton/tailwind/skeleton.cjs')()
- ]
-}