fix(web-ui): improve form field descriptions and align certificate settings with tile components

This commit is contained in:
2026-04-12 19:42:07 +00:00
parent b582d44502
commit 2861511d20
15 changed files with 144 additions and 143 deletions

View File

@@ -1,5 +1,13 @@
# Changelog # Changelog
## 2026-04-12 - 13.9.2 - fix(web-ui)
improve form field descriptions and align certificate settings with tile components
- Refines labels and adds descriptive helper text across API token, DNS, domain, route, edge, target profile, and VPN forms for clearer operator input
- Updates the DNS provider form to surface provider and credential guidance through built-in input metadata instead of custom help blocks
- Restyles the certificates ACME settings section to use tile-based layout and improves related form wording and file upload metadata
- Refreshes the Cloudflare DNS provider description and bumps UI-related dependencies
## 2026-04-08 - 13.9.1 - fix(network-ui) ## 2026-04-08 - 13.9.1 - fix(network-ui)
enable flashing table updates for network activity, remote ingress, and VPN views enable flashing table updates for network activity, remote ingress, and VPN views

View File

@@ -27,7 +27,7 @@
"@git.zone/tsrun": "^2.0.2", "@git.zone/tsrun": "^2.0.2",
"@git.zone/tstest": "^3.6.3", "@git.zone/tstest": "^3.6.3",
"@git.zone/tswatch": "^3.3.2", "@git.zone/tswatch": "^3.3.2",
"@types/node": "^25.5.2" "@types/node": "^25.6.0"
}, },
"dependencies": { "dependencies": {
"@api.global/typedrequest": "^3.3.0", "@api.global/typedrequest": "^3.3.0",
@@ -35,7 +35,7 @@
"@api.global/typedserver": "^8.4.6", "@api.global/typedserver": "^8.4.6",
"@api.global/typedsocket": "^4.1.2", "@api.global/typedsocket": "^4.1.2",
"@apiclient.xyz/cloudflare": "^7.1.0", "@apiclient.xyz/cloudflare": "^7.1.0",
"@design.estate/dees-catalog": "^3.70.0", "@design.estate/dees-catalog": "^3.76.1",
"@design.estate/dees-element": "^2.2.4", "@design.estate/dees-element": "^2.2.4",
"@push.rocks/lik": "^6.4.0", "@push.rocks/lik": "^6.4.0",
"@push.rocks/projectinfo": "^5.1.0", "@push.rocks/projectinfo": "^5.1.0",
@@ -67,7 +67,7 @@
"@serve.zone/remoteingress": "^4.15.3", "@serve.zone/remoteingress": "^4.15.3",
"@tsclass/tsclass": "^9.5.0", "@tsclass/tsclass": "^9.5.0",
"@types/qrcode": "^1.5.6", "@types/qrcode": "^1.5.6",
"lru-cache": "^11.3.2", "lru-cache": "^11.3.3",
"qrcode": "^1.5.4", "qrcode": "^1.5.4",
"uuid": "^13.0.0" "uuid": "^13.0.0"
}, },

103
pnpm-lock.yaml generated
View File

@@ -24,8 +24,8 @@ importers:
specifier: ^7.1.0 specifier: ^7.1.0
version: 7.1.0 version: 7.1.0
'@design.estate/dees-catalog': '@design.estate/dees-catalog':
specifier: ^3.70.0 specifier: ^3.76.1
version: 3.70.0(@tiptap/pm@2.27.2) version: 3.76.1(@tiptap/pm@2.27.2)
'@design.estate/dees-element': '@design.estate/dees-element':
specifier: ^2.2.4 specifier: ^2.2.4
version: 2.2.4 version: 2.2.4
@@ -120,8 +120,8 @@ importers:
specifier: ^1.5.6 specifier: ^1.5.6
version: 1.5.6 version: 1.5.6
lru-cache: lru-cache:
specifier: ^11.3.2 specifier: ^11.3.3
version: 11.3.2 version: 11.3.3
qrcode: qrcode:
specifier: ^1.5.4 specifier: ^1.5.4
version: 1.5.4 version: 1.5.4
@@ -145,8 +145,8 @@ importers:
specifier: ^3.3.2 specifier: ^3.3.2
version: 3.3.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@tiptap/pm@2.27.2) version: 3.3.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@tiptap/pm@2.27.2)
'@types/node': '@types/node':
specifier: ^25.5.2 specifier: ^25.6.0
version: 25.5.2 version: 25.6.0
packages: packages:
@@ -353,8 +353,8 @@ packages:
'@configvault.io/interfaces@1.0.17': '@configvault.io/interfaces@1.0.17':
resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==} resolution: {integrity: sha512-bEcCUR2VBDJsTin8HQh8Uw/mlYl2v8A3jMIaQ+MTB9Hrqd6CZL2dL7iJdWyFl/3EIX+LDxWFR+Oq7liIq7w+1Q==}
'@design.estate/dees-catalog@3.70.0': '@design.estate/dees-catalog@3.76.1':
resolution: {integrity: sha512-bNqOxxl83FNCCV+7QoUj6oeRC0VTExWOClrLrHNMoLIU0TCtzhcmQqiuJhdWrcCwZ5RBhXHGMSFsR62d2RcWpw==} resolution: {integrity: sha512-DSnu1NHz0C9CI13e6HMUV6lFiAKzOoPccZUZu6wDrpTcGha1trvFftcRzsieJ0NrvNJ6qZrh1vGL6ZYhu5RO0A==}
'@design.estate/dees-comms@1.0.30': '@design.estate/dees-comms@1.0.30':
resolution: {integrity: sha512-KchMlklJfKAjQiJiR0xmofXtQ27VgZtBIxcMwPE9d+h3jJRv+lPZxzBQVOM0eyM0uS44S5vJMZ11IeV4uDXSHg==} resolution: {integrity: sha512-KchMlklJfKAjQiJiR0xmofXtQ27VgZtBIxcMwPE9d+h3jJRv+lPZxzBQVOM0eyM0uS44S5vJMZ11IeV4uDXSHg==}
@@ -368,6 +368,9 @@ packages:
'@design.estate/dees-wcctools@3.8.0': '@design.estate/dees-wcctools@3.8.0':
resolution: {integrity: sha512-CC14iVKUrguzD9jIrdPBd9fZ4egVJEZMxl5y8iy0l7WLumeoYvGsoXj5INVkRPLRVLqziIdi4Je1hXqHt2NU+g==} resolution: {integrity: sha512-CC14iVKUrguzD9jIrdPBd9fZ4egVJEZMxl5y8iy0l7WLumeoYvGsoXj5INVkRPLRVLqziIdi4Je1hXqHt2NU+g==}
'@design.estate/dees-wcctools@3.8.4':
resolution: {integrity: sha512-KpFK/azK+a/Xpq33pXKcho+tdFKVHhKZM5ArvHqo9QMwTczgp5DZZgowTDUuqAofjZwnuVfCPHK/Pw9e64N46A==}
'@emnapi/core@1.9.2': '@emnapi/core@1.9.2':
resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==}
@@ -2054,8 +2057,8 @@ packages:
'@types/node@22.19.17': '@types/node@22.19.17':
resolution: {integrity: sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==} resolution: {integrity: sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==}
'@types/node@25.5.2': '@types/node@25.6.0':
resolution: {integrity: sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg==} resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==}
'@types/qrcode@1.5.6': '@types/qrcode@1.5.6':
resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==} resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}
@@ -2858,8 +2861,8 @@ packages:
humanize-ms@1.2.1: humanize-ms@1.2.1:
resolution: {integrity: sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=} resolution: {integrity: sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=}
ibantools@4.5.2: ibantools@4.5.4:
resolution: {integrity: sha512-is+8TgZcKS/AMv/z9nW1zz0bhjhoyjpA1p0nc3A6GkW/InOdcQiUZpkufADzh/aO/LY/TOD/P3oPWncNRn5QMA==} resolution: {integrity: sha512-6jX1gh4aH6XH+o0ey+wtkMTzkcvsEta7DakIOZSng9voZYpMw3U+gK1+tZChk3aRcPcloEt0NOzksjaRZiqXbw==}
iconv-lite@0.4.24: iconv-lite@0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
@@ -3076,16 +3079,16 @@ packages:
resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
lru-cache@11.3.2: lru-cache@11.3.3:
resolution: {integrity: sha512-wgWa6FWQ3QRRJbIjbsldRJZxdxYngT/dO0I5Ynmlnin8qy7tC6xYzbcJjtN4wHLXtkbVwHzk0C+OejVw1XM+DQ==} resolution: {integrity: sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==}
engines: {node: 20 || >=22} engines: {node: 20 || >=22}
lru-cache@7.18.3: lru-cache@7.18.3:
resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
engines: {node: '>=12'} engines: {node: '>=12'}
lucide@0.577.0: lucide@1.8.0:
resolution: {integrity: sha512-PpC/m5eOItp/WU/GlQPFBXDOhq6HibL73KzYP37OX3LM7VmzWQF8voEj8QRWUFvy9FIKfeDQkWYoyS1D/MdWFA==} resolution: {integrity: sha512-JjV/QnadgFLj1Pyu9IKl0lknrolFEzo04B64QcYLLeRzZl/iEHpdbSrRRKbyXcv45SZNv+WGjIUCT33e7xHO6Q==}
mailparser@3.9.6: mailparser@3.9.6:
resolution: {integrity: sha512-EJYTDWMrOS1kddK1mTsRkrx2Ngh2nYsg54SRMWVVWGVEGbHH4tod8tqqU9hIRPgGQVboSjFubDn9cboSitbM3Q==} resolution: {integrity: sha512-EJYTDWMrOS1kddK1mTsRkrx2Ngh2nYsg54SRMWVVWGVEGbHH4tod8tqqU9hIRPgGQVboSjFubDn9cboSitbM3Q==}
@@ -4098,8 +4101,8 @@ packages:
undici-types@6.21.0: undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
undici-types@7.18.2: undici-types@7.19.2:
resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==}
unified@11.0.5: unified@11.0.5:
resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
@@ -4315,7 +4318,7 @@ snapshots:
'@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedrequest-interfaces': 3.0.19
'@api.global/typedsocket': 4.1.2(@push.rocks/smartserve@2.0.3) '@api.global/typedsocket': 4.1.2(@push.rocks/smartserve@2.0.3)
'@cloudflare/workers-types': 4.20260405.1 '@cloudflare/workers-types': 4.20260405.1
'@design.estate/dees-catalog': 3.70.0(@tiptap/pm@2.27.2) '@design.estate/dees-catalog': 3.76.1(@tiptap/pm@2.27.2)
'@design.estate/dees-comms': 1.0.30 '@design.estate/dees-comms': 1.0.30
'@push.rocks/lik': 6.4.0 '@push.rocks/lik': 6.4.0
'@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartdelay': 3.0.5
@@ -4844,11 +4847,11 @@ snapshots:
dependencies: dependencies:
'@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedrequest-interfaces': 3.0.19
'@design.estate/dees-catalog@3.70.0(@tiptap/pm@2.27.2)': '@design.estate/dees-catalog@3.76.1(@tiptap/pm@2.27.2)':
dependencies: dependencies:
'@design.estate/dees-domtools': 2.5.4 '@design.estate/dees-domtools': 2.5.4
'@design.estate/dees-element': 2.2.4 '@design.estate/dees-element': 2.2.4
'@design.estate/dees-wcctools': 3.8.0 '@design.estate/dees-wcctools': 3.8.4
'@fortawesome/fontawesome-svg-core': 7.2.0 '@fortawesome/fontawesome-svg-core': 7.2.0
'@fortawesome/free-brands-svg-icons': 7.2.0 '@fortawesome/free-brands-svg-icons': 7.2.0
'@fortawesome/free-regular-svg-icons': 7.2.0 '@fortawesome/free-regular-svg-icons': 7.2.0
@@ -4866,9 +4869,9 @@ snapshots:
'@tsclass/tsclass': 9.5.0 '@tsclass/tsclass': 9.5.0
echarts: 5.6.0 echarts: 5.6.0
highlight.js: 11.11.1 highlight.js: 11.11.1
ibantools: 4.5.2 ibantools: 4.5.4
lightweight-charts: 5.1.0 lightweight-charts: 5.1.0
lucide: 0.577.0 lucide: 1.8.0
monaco-editor: 0.55.1 monaco-editor: 0.55.1
pdfjs-dist: 4.10.38 pdfjs-dist: 4.10.38
xterm: 5.3.0 xterm: 5.3.0
@@ -4937,6 +4940,18 @@ snapshots:
- supports-color - supports-color
- vue - vue
'@design.estate/dees-wcctools@3.8.4':
dependencies:
'@design.estate/dees-domtools': 2.5.4
'@design.estate/dees-element': 2.2.4
'@push.rocks/smartdelay': 3.0.5
lit: 3.3.2
transitivePeerDependencies:
- '@nuxt/kit'
- react
- supports-color
- vue
'@emnapi/core@1.9.2': '@emnapi/core@1.9.2':
dependencies: dependencies:
'@emnapi/wasi-threads': 1.2.1 '@emnapi/wasi-threads': 1.2.1
@@ -6404,7 +6419,7 @@ snapshots:
'@push.rocks/smartpath': 6.0.0 '@push.rocks/smartpath': 6.0.0
'@push.rocks/smartrust': 1.3.2 '@push.rocks/smartrust': 1.3.2
'@tsclass/tsclass': 9.5.0 '@tsclass/tsclass': 9.5.0
lru-cache: 11.3.2 lru-cache: 11.3.3
mailparser: 3.9.6 mailparser: 3.9.6
uuid: 13.0.0 uuid: 13.0.0
transitivePeerDependencies: transitivePeerDependencies:
@@ -6900,7 +6915,7 @@ snapshots:
'@serve.zone/catalog@2.12.3(@tiptap/pm@2.27.2)': '@serve.zone/catalog@2.12.3(@tiptap/pm@2.27.2)':
dependencies: dependencies:
'@design.estate/dees-catalog': 3.70.0(@tiptap/pm@2.27.2) '@design.estate/dees-catalog': 3.76.1(@tiptap/pm@2.27.2)
'@design.estate/dees-domtools': 2.5.4 '@design.estate/dees-domtools': 2.5.4
'@design.estate/dees-element': 2.2.4 '@design.estate/dees-element': 2.2.4
'@design.estate/dees-wcctools': 3.8.0 '@design.estate/dees-wcctools': 3.8.0
@@ -7442,7 +7457,7 @@ snapshots:
'@types/clean-css@4.2.11': '@types/clean-css@4.2.11':
dependencies: dependencies:
'@types/node': 25.5.2 '@types/node': 25.6.0
source-map: 0.6.1 source-map: 0.6.1
'@types/debug@4.1.13': '@types/debug@4.1.13':
@@ -7452,7 +7467,7 @@ snapshots:
'@types/fs-extra@11.0.4': '@types/fs-extra@11.0.4':
dependencies: dependencies:
'@types/jsonfile': 6.1.4 '@types/jsonfile': 6.1.4
'@types/node': 25.5.2 '@types/node': 25.6.0
'@types/hast@3.0.4': '@types/hast@3.0.4':
dependencies: dependencies:
@@ -7472,12 +7487,12 @@ snapshots:
'@types/jsonfile@6.1.4': '@types/jsonfile@6.1.4':
dependencies: dependencies:
'@types/node': 25.5.2 '@types/node': 25.6.0
'@types/jsonwebtoken@9.0.10': '@types/jsonwebtoken@9.0.10':
dependencies: dependencies:
'@types/ms': 2.1.0 '@types/ms': 2.1.0
'@types/node': 25.5.2 '@types/node': 25.6.0
'@types/linkify-it@5.0.0': {} '@types/linkify-it@5.0.0': {}
@@ -7498,16 +7513,16 @@ snapshots:
'@types/mute-stream@0.0.4': '@types/mute-stream@0.0.4':
dependencies: dependencies:
'@types/node': 25.5.2 '@types/node': 25.6.0
'@types/node-fetch@2.6.13': '@types/node-fetch@2.6.13':
dependencies: dependencies:
'@types/node': 25.5.2 '@types/node': 25.6.0
form-data: 4.0.5 form-data: 4.0.5
'@types/node-forge@1.3.14': '@types/node-forge@1.3.14':
dependencies: dependencies:
'@types/node': 25.5.2 '@types/node': 25.6.0
'@types/node@16.9.1': {} '@types/node@16.9.1': {}
@@ -7519,13 +7534,13 @@ snapshots:
dependencies: dependencies:
undici-types: 6.21.0 undici-types: 6.21.0
'@types/node@25.5.2': '@types/node@25.6.0':
dependencies: dependencies:
undici-types: 7.18.2 undici-types: 7.19.2
'@types/qrcode@1.5.6': '@types/qrcode@1.5.6':
dependencies: dependencies:
'@types/node': 25.5.2 '@types/node': 25.6.0
'@types/randomatic@3.1.5': {} '@types/randomatic@3.1.5': {}
@@ -7535,11 +7550,11 @@ snapshots:
'@types/tar-stream@3.1.4': '@types/tar-stream@3.1.4':
dependencies: dependencies:
'@types/node': 25.5.2 '@types/node': 25.6.0
'@types/through2@2.0.41': '@types/through2@2.0.41':
dependencies: dependencies:
'@types/node': 25.5.2 '@types/node': 25.6.0
'@types/trusted-types@2.0.7': {} '@types/trusted-types@2.0.7': {}
@@ -7569,11 +7584,11 @@ snapshots:
'@types/ws@8.18.1': '@types/ws@8.18.1':
dependencies: dependencies:
'@types/node': 25.5.2 '@types/node': 25.6.0
'@types/yauzl@2.10.3': '@types/yauzl@2.10.3':
dependencies: dependencies:
'@types/node': 25.5.2 '@types/node': 25.6.0
optional: true optional: true
'@ungap/structured-clone@1.3.0': {} '@ungap/structured-clone@1.3.0': {}
@@ -8390,7 +8405,7 @@ snapshots:
dependencies: dependencies:
ms: 2.1.3 ms: 2.1.3
ibantools@4.5.2: {} ibantools@4.5.4: {}
iconv-lite@0.4.24: iconv-lite@0.4.24:
dependencies: dependencies:
@@ -8628,11 +8643,11 @@ snapshots:
lowercase-keys@3.0.0: {} lowercase-keys@3.0.0: {}
lru-cache@11.3.2: {} lru-cache@11.3.3: {}
lru-cache@7.18.3: {} lru-cache@7.18.3: {}
lucide@0.577.0: {} lucide@1.8.0: {}
mailparser@3.9.6: mailparser@3.9.6:
dependencies: dependencies:
@@ -9268,7 +9283,7 @@ snapshots:
path-scurry@2.0.2: path-scurry@2.0.2:
dependencies: dependencies:
lru-cache: 11.3.2 lru-cache: 11.3.3
minipass: 7.1.3 minipass: 7.1.3
path-to-regexp@8.4.2: {} path-to-regexp@8.4.2: {}
@@ -9942,7 +9957,7 @@ snapshots:
undici-types@6.21.0: {} undici-types@6.21.0: {}
undici-types@7.18.2: {} undici-types@7.19.2: {}
unified@11.0.5: unified@11.0.5:
dependencies: dependencies:

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@serve.zone/dcrouter', name: '@serve.zone/dcrouter',
version: '13.9.1', version: '13.9.2',
description: 'A multifaceted routing service handling mail and SMS delivery functions.' description: 'A multifaceted routing service handling mail and SMS delivery functions.'
} }

View File

@@ -150,7 +150,7 @@ export const dnsProviderTypeDescriptors: ReadonlyArray<IDnsProviderTypeDescripto
type: 'cloudflare', type: 'cloudflare',
displayName: 'Cloudflare', displayName: 'Cloudflare',
description: description:
'Manages records via the Cloudflare API. Provider stays authoritative; dcrouter pushes record changes.', 'External DNS provider. The provider stays authoritative; dcrouter pushes record changes via its API.',
credentialFields: [ credentialFields: [
{ {
key: 'apiToken', key: 'apiToken',

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@serve.zone/dcrouter', name: '@serve.zone/dcrouter',
version: '13.9.1', version: '13.9.2',
description: 'A multifaceted routing service handling mail and SMS delivery functions.' description: 'A multifaceted routing service handling mail and SMS delivery functions.'
} }

View File

@@ -222,7 +222,7 @@ export class OpsViewApiTokens extends DeesElement {
.suggestions=${allScopes} .suggestions=${allScopes}
.required=${true} .required=${true}
></dees-input-tags> ></dees-input-tags>
<dees-input-text .key=${'expiresInDays'} .label=${'Expires in (days, blank = never)'}></dees-input-text> <dees-input-text .key=${'expiresInDays'} .label=${'Expires in'} .description=${'Number of days; leave blank for no expiration'}></dees-input-text>
</dees-form> </dees-form>
`, `,
menuOptions: [ menuOptions: [

View File

@@ -80,22 +80,6 @@ export class DnsProviderForm extends DeesElement {
margin-bottom: 12px; margin-bottom: 12px;
} }
.helpText {
font-size: 12px;
opacity: 0.7;
margin-top: -6px;
margin-bottom: 8px;
}
.typeDescription {
font-size: 12px;
opacity: 0.8;
margin: 4px 0 16px;
padding: 8px 12px;
background: ${cssManager.bdTheme('#f3f4f6', '#1f2937')};
border-radius: 6px;
}
.credentialsHint { .credentialsHint {
font-size: 12px; font-size: 12px;
opacity: 0.7; opacity: 0.7;
@@ -130,6 +114,7 @@ export class DnsProviderForm extends DeesElement {
<dees-input-text <dees-input-text
.key=${'__type_display'} .key=${'__type_display'}
.label=${'Type'} .label=${'Type'}
.infoText=${descriptor?.description || ''}
.value=${descriptor?.displayName ?? this.selectedType} .value=${descriptor?.displayName ?? this.selectedType}
.disabled=${true} .disabled=${true}
></dees-input-text> ></dees-input-text>
@@ -140,6 +125,7 @@ export class DnsProviderForm extends DeesElement {
<dees-input-dropdown <dees-input-dropdown
.key=${'__type'} .key=${'__type'}
.label=${'Provider type'} .label=${'Provider type'}
.infoText=${descriptor?.description || ''}
.options=${descriptors.map((d) => ({ option: d.displayName, key: d.type }))} .options=${descriptors.map((d) => ({ option: d.displayName, key: d.type }))}
.selectedOption=${descriptor .selectedOption=${descriptor
? { option: descriptor.displayName, key: descriptor.type } ? { option: descriptor.displayName, key: descriptor.type }
@@ -158,7 +144,6 @@ export class DnsProviderForm extends DeesElement {
`} `}
${descriptor ${descriptor
? html` ? html`
<div class="typeDescription">${descriptor.description}</div>
${this.credentialsHint ${this.credentialsHint
? html`<div class="credentialsHint">${this.credentialsHint}</div>` ? html`<div class="credentialsHint">${this.credentialsHint}</div>`
: ''} : ''}
@@ -168,9 +153,9 @@ export class DnsProviderForm extends DeesElement {
<dees-input-text <dees-input-text
.key=${f.key} .key=${f.key}
.label=${f.label} .label=${f.label}
.description=${f.helpText || ''}
.required=${f.required && !this.lockType} .required=${f.required && !this.lockType}
></dees-input-text> ></dees-input-text>
${f.helpText ? html`<div class="helpText">${f.helpText}</div>` : ''}
</div> </div>
`, `,
)} )}

View File

@@ -54,35 +54,31 @@ export class OpsViewCertificates extends DeesElement {
gap: 24px; gap: 24px;
} }
.acmeCard { .acmeTileHeader {
padding: 16px 20px;
background: ${cssManager.bdTheme('#f9fafb', '#111827')};
border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
border-radius: 8px;
}
.acmeCard.acmeCardEmpty {
background: ${cssManager.bdTheme('#fffbeb', '#1c1917')};
border-color: ${cssManager.bdTheme('#fde68a', '#78350f')};
}
.acmeCardHeader {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 12px; width: 100%;
padding: 8px 12px;
} }
.acmeCardTitle { .acmeTileHeading {
font-size: 14px; font-size: 14px;
font-weight: 600; font-weight: 600;
color: ${cssManager.bdTheme('#111827', '#f3f4f6')}; }
.acmeEmptyContent {
padding: 16px;
font-size: 13px;
line-height: 1.5;
color: ${cssManager.bdTheme('#78350f', '#fde68a')};
} }
.acmeGrid { .acmeGrid {
display: grid; display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 12px 24px; gap: 12px 24px;
padding: 16px;
} }
.acmeField { .acmeField {
@@ -103,13 +99,6 @@ export class OpsViewCertificates extends DeesElement {
color: ${cssManager.bdTheme('#111827', '#f3f4f6')}; color: ${cssManager.bdTheme('#111827', '#f3f4f6')};
} }
.acmeEmptyHint {
margin: 0;
font-size: 13px;
line-height: 1.5;
color: ${cssManager.bdTheme('#78350f', '#fde68a')};
}
.statusBadge { .statusBadge {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
@@ -226,41 +215,40 @@ export class OpsViewCertificates extends DeesElement {
<dees-heading level="3">Certificates</dees-heading> <dees-heading level="3">Certificates</dees-heading>
<div class="certificatesContainer"> <div class="certificatesContainer">
${this.renderAcmeSettingsCard()}
${this.renderStatsTiles(summary)} ${this.renderStatsTiles(summary)}
${this.renderAcmeSettingsTile()}
${this.renderCertificateTable()} ${this.renderCertificateTable()}
</div> </div>
`; `;
} }
private renderAcmeSettingsCard(): TemplateResult { private renderAcmeSettingsTile(): TemplateResult {
const config = this.acmeState.config; const config = this.acmeState.config;
if (!config) { if (!config) {
return html` return html`
<div class="acmeCard acmeCardEmpty"> <dees-tile .heading=${'ACME Settings'}>
<div class="acmeCardHeader"> <div slot="header" class="acmeTileHeader">
<span class="acmeCardTitle">ACME Settings</span> <span class="acmeTileHeading">ACME Settings</span>
<dees-button <dees-button
eventName="edit-acme"
@click=${() => this.showEditAcmeDialog()} @click=${() => this.showEditAcmeDialog()}
.type=${'highlighted'} .type=${'highlighted'}
>Configure</dees-button> >Configure</dees-button>
</div> </div>
<p class="acmeEmptyHint"> <div class="acmeEmptyContent">
No ACME configuration yet. Click <strong>Configure</strong> to set up automated TLS No ACME configuration yet. Click <strong>Configure</strong> to set up automated TLS
certificate issuance via Let's Encrypt. You'll also need at least one DNS provider certificate issuance via Let's Encrypt. You'll also need at least one DNS provider
under <strong>Domains &gt; Providers</strong>. under <strong>Domains &gt; Providers</strong>.
</p> </div>
</div> </dees-tile>
`; `;
} }
return html` return html`
<div class="acmeCard"> <dees-tile>
<div class="acmeCardHeader"> <div slot="header" class="acmeTileHeader">
<span class="acmeCardTitle">ACME Settings</span> <span class="acmeTileHeading">ACME Settings</span>
<dees-button eventName="edit-acme" @click=${() => this.showEditAcmeDialog()}>Edit</dees-button> <dees-button @click=${() => this.showEditAcmeDialog()}>Edit</dees-button>
</div> </div>
<div class="acmeGrid"> <div class="acmeGrid">
<div class="acmeField"> <div class="acmeField">
@@ -292,7 +280,7 @@ export class OpsViewCertificates extends DeesElement {
<span class="acmeValue">${config.renewThresholdDays} days</span> <span class="acmeValue">${config.renewThresholdDays} days</span>
</div> </div>
</div> </div>
</div> </dees-tile>
`; `;
} }
@@ -317,7 +305,8 @@ export class OpsViewCertificates extends DeesElement {
></dees-input-checkbox> ></dees-input-checkbox>
<dees-input-checkbox <dees-input-checkbox
.key=${'useProduction'} .key=${'useProduction'}
.label=${"Use Let's Encrypt production (uncheck for staging)"} .label=${"Use Let's Encrypt production"}
.description=${'Uncheck to use the staging environment'}
.value=${current?.useProduction ?? true} .value=${current?.useProduction ?? true}
></dees-input-checkbox> ></dees-input-checkbox>
<dees-input-checkbox <dees-input-checkbox
@@ -327,7 +316,8 @@ export class OpsViewCertificates extends DeesElement {
></dees-input-checkbox> ></dees-input-checkbox>
<dees-input-text <dees-input-text
.key=${'renewThresholdDays'} .key=${'renewThresholdDays'}
.label=${'Renewal threshold (days)'} .label=${'Renewal threshold'}
.description=${'Number of days before expiry to trigger renewal'}
.value=${String(current?.renewThresholdDays ?? 30)} .value=${String(current?.renewThresholdDays ?? 30)}
></dees-input-text> ></dees-input-text>
</dees-form> </dees-form>
@@ -456,11 +446,12 @@ export class OpsViewCertificates extends DeesElement {
content: html` content: html`
<dees-form> <dees-form>
<dees-input-fileupload <dees-input-fileupload
key="certJsonFile" .key=${'certJsonFile'}
label="Certificate JSON (.tsclass.cert.json)" .label=${'Certificate JSON'}
accept=".json" .description=${'Upload a .tsclass.cert.json file'}
.accept=${'.json'}
.multiple=${false} .multiple=${false}
required .required=${true}
></dees-input-fileupload> ></dees-input-fileupload>
</dees-form> </dees-form>
`, `,

View File

@@ -101,8 +101,8 @@ export class OpsViewDns extends DeesElement {
<dees-heading level="3">DNS Records</dees-heading> <dees-heading level="3">DNS Records</dees-heading>
<div class="dnsContainer"> <div class="dnsContainer">
<div class="domainPicker"> <div class="domainPicker">
<span>Domain:</span>
<dees-input-dropdown <dees-input-dropdown
.label=${'Domain'}
.options=${domains.map((d) => ({ option: d.name, key: d.id }))} .options=${domains.map((d) => ({ option: d.name, key: d.id }))}
.selectedOption=${selectedId .selectedOption=${selectedId
? { option: domains.find((d) => d.id === selectedId)?.name || '', key: selectedId } ? { option: domains.find((d) => d.id === selectedId)?.name || '', key: selectedId }
@@ -196,7 +196,7 @@ export class OpsViewDns extends DeesElement {
heading: 'Add DNS Record', heading: 'Add DNS Record',
content: html` content: html`
<dees-form> <dees-form>
<dees-input-text .key=${'name'} .label=${'Name (FQDN)'} .required=${true}></dees-input-text> <dees-input-text .key=${'name'} .label=${'Name'} .description=${'Fully qualified domain name'} .required=${true}></dees-input-text>
<dees-input-dropdown <dees-input-dropdown
.key=${'type'} .key=${'type'}
.label=${'Type'} .label=${'Type'}
@@ -205,10 +205,11 @@ export class OpsViewDns extends DeesElement {
></dees-input-dropdown> ></dees-input-dropdown>
<dees-input-text <dees-input-text
.key=${'value'} .key=${'value'}
.label=${'Value (for MX use "10 mail.example.com")'} .label=${'Value'}
.description=${'For MX records use priority format, e.g. "10 mail.example.com"'}
.required=${true} .required=${true}
></dees-input-text> ></dees-input-text>
<dees-input-text .key=${'ttl'} .label=${'TTL (seconds)'} .value=${'300'}></dees-input-text> <dees-input-text .key=${'ttl'} .label=${'TTL'} .description=${'Time to live in seconds'} .value=${'300'}></dees-input-text>
</dees-form> </dees-form>
`, `,
menuOptions: [ menuOptions: [
@@ -242,9 +243,9 @@ export class OpsViewDns extends DeesElement {
heading: `Edit ${rec.type} ${rec.name}`, heading: `Edit ${rec.type} ${rec.name}`,
content: html` content: html`
<dees-form> <dees-form>
<dees-input-text .key=${'name'} .label=${'Name (FQDN)'} .value=${rec.name}></dees-input-text> <dees-input-text .key=${'name'} .label=${'Name'} .description=${'Fully qualified domain name'} .value=${rec.name}></dees-input-text>
<dees-input-text .key=${'value'} .label=${'Value'} .value=${rec.value}></dees-input-text> <dees-input-text .key=${'value'} .label=${'Value'} .value=${rec.value}></dees-input-text>
<dees-input-text .key=${'ttl'} .label=${'TTL (seconds)'} .value=${String(rec.ttl)}></dees-input-text> <dees-input-text .key=${'ttl'} .label=${'TTL'} .description=${'Time to live in seconds'} .value=${String(rec.ttl)}></dees-input-text>
</dees-form> </dees-form>
`, `,
menuOptions: [ menuOptions: [

View File

@@ -181,8 +181,8 @@ export class OpsViewDomains extends DeesElement {
heading: 'Add DcRouter Domain', heading: 'Add DcRouter Domain',
content: html` content: html`
<dees-form> <dees-form>
<dees-input-text .key=${'name'} .label=${'FQDN (e.g. example.com)'} .required=${true}></dees-input-text> <dees-input-text .key=${'name'} .label=${'FQDN'} .description=${'e.g. example.com'} .required=${true}></dees-input-text>
<dees-input-text .key=${'description'} .label=${'Description (optional)'}></dees-input-text> <dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
</dees-form> </dees-form>
<p style="margin-top: 12px; font-size: 12px; opacity: 0.7;"> <p style="margin-top: 12px; font-size: 12px; opacity: 0.7;">
dcrouter will become the authoritative DNS server for this domain. You'll need to dcrouter will become the authoritative DNS server for this domain. You'll need to
@@ -235,7 +235,8 @@ export class OpsViewDomains extends DeesElement {
></dees-input-dropdown> ></dees-input-dropdown>
<dees-input-text <dees-input-text
.key=${'domainNames'} .key=${'domainNames'}
.label=${'Comma-separated FQDNs to import (e.g. example.com, foo.com)'} .label=${'Domain Names'}
.description=${'Comma-separated FQDNs, e.g. example.com, foo.com'}
.required=${true} .required=${true}
></dees-input-text> ></dees-input-text>
</dees-form> </dees-form>

View File

@@ -243,9 +243,9 @@ export class OpsViewRemoteIngress extends DeesElement {
content: html` content: html`
<dees-form> <dees-form>
<dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text> <dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
<dees-input-text .key=${'listenPorts'} .label=${'Additional Manual Ports (comma-separated, optional)'}></dees-input-text> <dees-input-text .key=${'listenPorts'} .label=${'Manual Ports'} .description=${'Comma-separated port numbers, optional'}></dees-input-text>
<dees-input-checkbox .key=${'autoDerivePorts'} .label=${'Auto-derive ports from routes'} .value=${true}></dees-input-checkbox> <dees-input-checkbox .key=${'autoDerivePorts'} .label=${'Auto-derive ports from routes'} .value=${true}></dees-input-checkbox>
<dees-input-text .key=${'tags'} .label=${'Tags (comma-separated, optional)'}></dees-input-text> <dees-input-text .key=${'tags'} .label=${'Tags'} .description=${'Comma-separated, optional'}></dees-input-text>
</dees-form> </dees-form>
`, `,
menuOptions: [ menuOptions: [
@@ -320,9 +320,9 @@ export class OpsViewRemoteIngress extends DeesElement {
content: html` content: html`
<dees-form> <dees-form>
<dees-input-text .key=${'name'} .label=${'Name'} .value=${edge.name}></dees-input-text> <dees-input-text .key=${'name'} .label=${'Name'} .value=${edge.name}></dees-input-text>
<dees-input-text .key=${'listenPorts'} .label=${'Manual Ports (comma-separated)'} .value=${(edge.listenPorts || []).join(', ')}></dees-input-text> <dees-input-text .key=${'listenPorts'} .label=${'Manual Ports'} .description=${'Comma-separated port numbers'} .value=${(edge.listenPorts || []).join(', ')}></dees-input-text>
<dees-input-checkbox .key=${'autoDerivePorts'} .label=${'Auto-derive ports from routes'} .value=${edge.autoDerivePorts !== false}></dees-input-checkbox> <dees-input-checkbox .key=${'autoDerivePorts'} .label=${'Auto-derive ports from routes'} .value=${edge.autoDerivePorts !== false}></dees-input-checkbox>
<dees-input-text .key=${'tags'} .label=${'Tags (comma-separated)'} .value=${(edge.tags || []).join(', ')}></dees-input-text> <dees-input-text .key=${'tags'} .label=${'Tags'} .description=${'Comma-separated'} .value=${(edge.tags || []).join(', ')}></dees-input-text>
</dees-form> </dees-form>
`, `,
menuOptions: [ menuOptions: [

View File

@@ -473,19 +473,19 @@ export class OpsViewRoutes extends DeesElement {
content: html` content: html`
<dees-form> <dees-form>
<dees-input-text .key=${'name'} .label=${'Route Name'} .value=${route.name || ''} .required=${true}></dees-input-text> <dees-input-text .key=${'name'} .label=${'Route Name'} .value=${route.name || ''} .required=${true}></dees-input-text>
<dees-input-text .key=${'ports'} .label=${'Ports (comma-separated)'} .value=${currentPorts} .required=${true}></dees-input-text> <dees-input-text .key=${'ports'} .label=${'Ports'} .description=${'Comma-separated, e.g. 80, 443'} .value=${currentPorts} .required=${true}></dees-input-text>
<dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'Add domain...'} .value=${currentDomains}></dees-input-list> <dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'Add domain...'} .value=${currentDomains}></dees-input-list>
<dees-input-text .key=${'priority'} .label=${'Priority (higher = matched first)'} .value=${route.priority != null ? String(route.priority) : ''}></dees-input-text> <dees-input-text .key=${'priority'} .label=${'Priority'} .description=${'Higher values are matched first'} .value=${route.priority != null ? String(route.priority) : ''}></dees-input-text>
<dees-input-dropdown .key=${'sourceProfileRef'} .label=${'Source Profile'} .options=${profileOptions} .selectedOption=${profileOptions.find((o) => o.key === (merged.metadata?.sourceProfileRef || '')) || null}></dees-input-dropdown> <dees-input-dropdown .key=${'sourceProfileRef'} .label=${'Source Profile'} .options=${profileOptions} .selectedOption=${profileOptions.find((o) => o.key === (merged.metadata?.sourceProfileRef || '')) || null}></dees-input-dropdown>
<dees-input-dropdown .key=${'networkTargetRef'} .label=${'Network Target'} .options=${targetOptions} .selectedOption=${targetOptions.find((o) => o.key === (merged.metadata?.networkTargetRef || '')) || null}></dees-input-dropdown> <dees-input-dropdown .key=${'networkTargetRef'} .label=${'Network Target'} .options=${targetOptions} .selectedOption=${targetOptions.find((o) => o.key === (merged.metadata?.networkTargetRef || '')) || null}></dees-input-dropdown>
<dees-input-text .key=${'targetHost'} .label=${'Target Host (if no target selected)'} .value=${currentTargetHost}></dees-input-text> <dees-input-text .key=${'targetHost'} .label=${'Target Host'} .description=${'Used when no network target is selected'} .value=${currentTargetHost}></dees-input-text>
<dees-input-text .key=${'targetPort'} .label=${'Target Port (if no target selected)'} .value=${currentTargetPort}></dees-input-text> <dees-input-text .key=${'targetPort'} .label=${'Target Port'} .description=${'Used when no network target is selected'} .value=${currentTargetPort}></dees-input-text>
<dees-input-dropdown .key=${'tlsMode'} .label=${'TLS Mode'} .options=${tlsModeOptions} .selectedOption=${tlsModeOptions.find((o) => o.key === currentTlsMode) || tlsModeOptions[0]}></dees-input-dropdown> <dees-input-dropdown .key=${'tlsMode'} .label=${'TLS Mode'} .options=${tlsModeOptions} .selectedOption=${tlsModeOptions.find((o) => o.key === currentTlsMode) || tlsModeOptions[0]}></dees-input-dropdown>
<div class="tlsCertificateGroup" style="display: ${needsCert ? 'flex' : 'none'}; flex-direction: column; gap: 16px;"> <div class="tlsCertificateGroup" style="display: ${needsCert ? 'flex' : 'none'}; flex-direction: column; gap: 16px;">
<dees-input-dropdown .key=${'tlsCertificate'} .label=${'Certificate'} .options=${tlsCertOptions} .selectedOption=${tlsCertOptions.find((o) => o.key === currentTlsCert) || tlsCertOptions[0]}></dees-input-dropdown> <dees-input-dropdown .key=${'tlsCertificate'} .label=${'Certificate'} .options=${tlsCertOptions} .selectedOption=${tlsCertOptions.find((o) => o.key === currentTlsCert) || tlsCertOptions[0]}></dees-input-dropdown>
<div class="tlsCustomCertGroup" style="display: ${needsCert && isCustom ? 'flex' : 'none'}; flex-direction: column; gap: 16px;"> <div class="tlsCustomCertGroup" style="display: ${needsCert && isCustom ? 'flex' : 'none'}; flex-direction: column; gap: 16px;">
<dees-input-text .key=${'tlsCertKey'} .label=${'Private Key (PEM)'} .value=${currentCustomKey}></dees-input-text> <dees-input-text .key=${'tlsCertKey'} .label=${'Private Key'} .description=${'PEM-encoded private key'} .value=${currentCustomKey}></dees-input-text>
<dees-input-text .key=${'tlsCertCert'} .label=${'Certificate (PEM)'} .value=${currentCustomCert}></dees-input-text> <dees-input-text .key=${'tlsCertCert'} .label=${'Certificate'} .description=${'PEM-encoded certificate'} .value=${currentCustomCert}></dees-input-text>
</div> </div>
</div> </div>
</dees-form> </dees-form>
@@ -607,19 +607,19 @@ export class OpsViewRoutes extends DeesElement {
content: html` content: html`
<dees-form> <dees-form>
<dees-input-text .key=${'name'} .label=${'Route Name'} .required=${true}></dees-input-text> <dees-input-text .key=${'name'} .label=${'Route Name'} .required=${true}></dees-input-text>
<dees-input-text .key=${'ports'} .label=${'Ports (comma-separated)'} .required=${true}></dees-input-text> <dees-input-text .key=${'ports'} .label=${'Ports'} .description=${'Comma-separated, e.g. 80, 443'} .required=${true}></dees-input-text>
<dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'Add domain...'}></dees-input-list> <dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'Add domain...'}></dees-input-list>
<dees-input-text .key=${'priority'} .label=${'Priority (higher = matched first)'}></dees-input-text> <dees-input-text .key=${'priority'} .label=${'Priority'} .description=${'Higher values are matched first'}></dees-input-text>
<dees-input-dropdown .key=${'sourceProfileRef'} .label=${'Source Profile'} .options=${profileOptions}></dees-input-dropdown> <dees-input-dropdown .key=${'sourceProfileRef'} .label=${'Source Profile'} .options=${profileOptions}></dees-input-dropdown>
<dees-input-dropdown .key=${'networkTargetRef'} .label=${'Network Target'} .options=${targetOptions}></dees-input-dropdown> <dees-input-dropdown .key=${'networkTargetRef'} .label=${'Network Target'} .options=${targetOptions}></dees-input-dropdown>
<dees-input-text .key=${'targetHost'} .label=${'Target Host (if no target selected)'} .value=${'localhost'}></dees-input-text> <dees-input-text .key=${'targetHost'} .label=${'Target Host'} .description=${'Used when no network target is selected'} .value=${'localhost'}></dees-input-text>
<dees-input-text .key=${'targetPort'} .label=${'Target Port (if no target selected)'}></dees-input-text> <dees-input-text .key=${'targetPort'} .label=${'Target Port'} .description=${'Used when no network target is selected'}></dees-input-text>
<dees-input-dropdown .key=${'tlsMode'} .label=${'TLS Mode'} .options=${tlsModeOptions} .selectedOption=${tlsModeOptions[0]}></dees-input-dropdown> <dees-input-dropdown .key=${'tlsMode'} .label=${'TLS Mode'} .options=${tlsModeOptions} .selectedOption=${tlsModeOptions[0]}></dees-input-dropdown>
<div class="tlsCertificateGroup" style="display: none; flex-direction: column; gap: 16px;"> <div class="tlsCertificateGroup" style="display: none; flex-direction: column; gap: 16px;">
<dees-input-dropdown .key=${'tlsCertificate'} .label=${'Certificate'} .options=${tlsCertOptions} .selectedOption=${tlsCertOptions[0]}></dees-input-dropdown> <dees-input-dropdown .key=${'tlsCertificate'} .label=${'Certificate'} .options=${tlsCertOptions} .selectedOption=${tlsCertOptions[0]}></dees-input-dropdown>
<div class="tlsCustomCertGroup" style="display: none; flex-direction: column; gap: 16px;"> <div class="tlsCustomCertGroup" style="display: none; flex-direction: column; gap: 16px;">
<dees-input-text .key=${'tlsCertKey'} .label=${'Private Key (PEM)'}></dees-input-text> <dees-input-text .key=${'tlsCertKey'} .label=${'Private Key'} .description=${'PEM-encoded private key'}></dees-input-text>
<dees-input-text .key=${'tlsCertCert'} .label=${'Certificate (PEM)'}></dees-input-text> <dees-input-text .key=${'tlsCertCert'} .label=${'Certificate'} .description=${'PEM-encoded certificate'}></dees-input-text>
</div> </div>
</div> </div>
</dees-form> </dees-form>

View File

@@ -176,7 +176,7 @@ export class OpsViewTargetProfiles extends DeesElement {
<dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text> <dees-input-text .key=${'name'} .label=${'Name'} .required=${true}></dees-input-text>
<dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text> <dees-input-text .key=${'description'} .label=${'Description'}></dees-input-text>
<dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'e.g. *.example.com'} .allowFreeform=${true}></dees-input-list> <dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'e.g. *.example.com'} .allowFreeform=${true}></dees-input-list>
<dees-input-list .key=${'targets'} .label=${'Targets (ip:port)'} .placeholder=${'e.g. 10.0.0.1:443'} .allowFreeform=${true}></dees-input-list> <dees-input-list .key=${'targets'} .label=${'Targets'} .description=${'Format: ip:port, e.g. 10.0.0.1:443'} .placeholder=${'e.g. 10.0.0.1:443'} .allowFreeform=${true}></dees-input-list>
<dees-input-list .key=${'routeRefs'} .label=${'Route Refs'} .placeholder=${'Type to search routes...'} .candidates=${routeCandidates} .allowFreeform=${true}></dees-input-list> <dees-input-list .key=${'routeRefs'} .label=${'Route Refs'} .placeholder=${'Type to search routes...'} .candidates=${routeCandidates} .allowFreeform=${true}></dees-input-list>
</dees-form> </dees-form>
`, `,
@@ -235,7 +235,7 @@ export class OpsViewTargetProfiles extends DeesElement {
<dees-input-text .key=${'name'} .label=${'Name'} .value=${profile.name}></dees-input-text> <dees-input-text .key=${'name'} .label=${'Name'} .value=${profile.name}></dees-input-text>
<dees-input-text .key=${'description'} .label=${'Description'} .value=${profile.description || ''}></dees-input-text> <dees-input-text .key=${'description'} .label=${'Description'} .value=${profile.description || ''}></dees-input-text>
<dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'e.g. *.example.com'} .allowFreeform=${true} .value=${currentDomains}></dees-input-list> <dees-input-list .key=${'domains'} .label=${'Domains'} .placeholder=${'e.g. *.example.com'} .allowFreeform=${true} .value=${currentDomains}></dees-input-list>
<dees-input-list .key=${'targets'} .label=${'Targets (ip:port)'} .placeholder=${'e.g. 10.0.0.1:443'} .allowFreeform=${true} .value=${currentTargets}></dees-input-list> <dees-input-list .key=${'targets'} .label=${'Targets'} .description=${'Format: ip:port, e.g. 10.0.0.1:443'} .placeholder=${'e.g. 10.0.0.1:443'} .allowFreeform=${true} .value=${currentTargets}></dees-input-list>
<dees-input-list .key=${'routeRefs'} .label=${'Route Refs'} .placeholder=${'Type to search routes...'} .candidates=${routeCandidates} .allowFreeform=${true} .value=${currentRouteRefs}></dees-input-list> <dees-input-list .key=${'routeRefs'} .label=${'Route Refs'} .placeholder=${'Type to search routes...'} .candidates=${routeCandidates} .allowFreeform=${true} .value=${currentRouteRefs}></dees-input-list>
</dees-form> </dees-form>
`, `,

View File

@@ -371,8 +371,8 @@ export class OpsViewVpn extends DeesElement {
</div> </div>
<dees-input-checkbox .key=${'allowAdditionalAcls'} .label=${'Allow additional ACLs'} .value=${false}></dees-input-checkbox> <dees-input-checkbox .key=${'allowAdditionalAcls'} .label=${'Allow additional ACLs'} .value=${false}></dees-input-checkbox>
<div class="aclGroup" style="display: none; flex-direction: column; gap: 16px;"> <div class="aclGroup" style="display: none; flex-direction: column; gap: 16px;">
<dees-input-text .key=${'destinationAllowList'} .label=${'Destination Allow List (comma-separated IPs/CIDRs)'}></dees-input-text> <dees-input-text .key=${'destinationAllowList'} .label=${'Destination Allow List'} .description=${'Comma-separated IPs or CIDRs'}></dees-input-text>
<dees-input-text .key=${'destinationBlockList'} .label=${'Destination Block List (comma-separated IPs/CIDRs)'}></dees-input-text> <dees-input-text .key=${'destinationBlockList'} .label=${'Destination Block List'} .description=${'Comma-separated IPs or CIDRs'}></dees-input-text>
</div> </div>
</dees-form> </dees-form>
`, `,
@@ -681,8 +681,8 @@ export class OpsViewVpn extends DeesElement {
</div> </div>
<dees-input-checkbox .key=${'allowAdditionalAcls'} .label=${'Allow additional ACLs'} .value=${currentAllowAcls}></dees-input-checkbox> <dees-input-checkbox .key=${'allowAdditionalAcls'} .label=${'Allow additional ACLs'} .value=${currentAllowAcls}></dees-input-checkbox>
<div class="aclGroup" style="display: ${currentAllowAcls ? 'flex' : 'none'}; flex-direction: column; gap: 16px;"> <div class="aclGroup" style="display: ${currentAllowAcls ? 'flex' : 'none'}; flex-direction: column; gap: 16px;">
<dees-input-text .key=${'destinationAllowList'} .label=${'Destination Allow List (comma-separated IPs/CIDRs)'} .value=${currentAllowList}></dees-input-text> <dees-input-text .key=${'destinationAllowList'} .label=${'Destination Allow List'} .description=${'Comma-separated IPs or CIDRs'} .value=${currentAllowList}></dees-input-text>
<dees-input-text .key=${'destinationBlockList'} .label=${'Destination Block List (comma-separated IPs/CIDRs)'} .value=${currentBlockList}></dees-input-text> <dees-input-text .key=${'destinationBlockList'} .label=${'Destination Block List'} .description=${'Comma-separated IPs or CIDRs'} .value=${currentBlockList}></dees-input-text>
</div> </div>
</dees-form> </dees-form>
`, `,