diff --git a/frontend/src/views/components/ConfigSettings/ConfigEditor/ConfigEditor.css b/frontend/src/views/components/ConfigSettings/ConfigEditor/ConfigEditor.css index 60c0364..8550401 100644 --- a/frontend/src/views/components/ConfigSettings/ConfigEditor/ConfigEditor.css +++ b/frontend/src/views/components/ConfigSettings/ConfigEditor/ConfigEditor.css @@ -1,6 +1,6 @@ .config-overview { min-width: 0; - padding-bottom: 18px; + padding-bottom: 10px; border-bottom: 1px solid var(--pm-border-color); } @@ -8,7 +8,7 @@ display: flex; align-items: flex-start; justify-content: space-between; - gap: 16px; + gap: 12px; } .overview-copy { @@ -31,7 +31,7 @@ } .overview-copy .settings-desc { - margin: 6px 0 0; + margin: 4px 0 0; } .overview-actions { @@ -47,7 +47,7 @@ display: flex; flex-wrap: wrap; gap: 10px 0; - margin: 16px 0 0; + margin: 8px 0 0; } .overview-meta-item { @@ -56,7 +56,7 @@ flex-wrap: wrap; gap: 4px 8px; min-width: 0; - padding: 0 16px; + padding: 0 12px; border-left: 1px solid var(--pm-border-color); font-size: 12px; line-height: 1.7; diff --git a/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.css b/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.css index f151ca4..844e537 100644 --- a/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.css +++ b/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.css @@ -2,7 +2,7 @@ display: flex; flex-direction: column; align-items: stretch; - gap: 8px; + gap: 4px; min-width: 0; } @@ -31,6 +31,40 @@ font-weight: 400; } +.field-help { + display: inline-grid; + place-items: center; + flex: none; + width: 16px; + height: 16px; + padding: 0; + border: 1px solid var(--pm-border-color); + border-radius: 50%; + background: var(--pm-bg-primary); + color: var(--pm-text-secondary); + font: inherit; + font-size: 11px; + cursor: pointer; +} + +.field-help:hover, +.field-help:focus-visible { + color: var(--pm-primary-color); + border-color: currentColor; + outline: 2px solid color-mix(in srgb, var(--pm-primary-color) 15%, transparent); +} + +/* 说明由可聚焦的帮助按钮展开,同时保留表单控件的无障碍描述。 */ +.field-description { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; +} + .config-field > .el-input-number, .config-field > .el-select { width: 100%; @@ -115,7 +149,7 @@ color: var(--pm-text-secondary); } -@container config-main (max-width: 620px) { +@container config-main (max-width: 440px) { .network-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); padding: 10px; diff --git a/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.js b/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.js index 636f347..330e7ed 100644 --- a/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.js +++ b/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.js @@ -1,5 +1,6 @@ -import { computed } from 'vue' +import { computed, nextTick } from 'vue' import { fieldKey } from '../ConfigForm/ConfigForm.js' +import { usePagination } from '../ConfigPagination/ConfigPagination.js' export { fieldKey } @@ -10,6 +11,7 @@ export function useField(props, emit) { props.error && `${id.value}-error` ].filter(Boolean).join(' ') || undefined) const entries = computed(() => Array.isArray(props.value) ? props.value : []) + const pagination = usePagination(entries, 2) const selectOptions = computed(() => { const values = props.field.options || [] const current = props.value ?? props.field.fallback ?? '' @@ -23,6 +25,11 @@ export function useField(props, emit) { const updateEntry = (index, value) => update(entries.value.map((entry, current) => current === index ? value : entry)) const updateTarget = (index, key, value) => updateEntry(index, { ...entries.value[index], [key]: value ?? null }) const removeEntry = index => update(entries.value.filter((_, current) => current !== index)) + const addEntry = async () => { + update([...entries.value, props.field.type === 'network' ? { scheme: 'https', host: '', port: 443 } : '']) + await nextTick() + pagination.currentPage.value = pagination.pageCount.value + } - return { id, descriptionId, entries, selectOptions, update, updateEntry, updateTarget, removeEntry } + return { id, descriptionId, entries, selectOptions, update, updateEntry, updateTarget, removeEntry, addEntry, ...pagination } } diff --git a/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.vue b/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.vue index 62d9b1e..c2e29ef 100644 --- a/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.vue +++ b/frontend/src/views/components/ConfigSettings/ConfigField/ConfigField.vue @@ -4,6 +4,11 @@ {{ field.label }} 系统维护 + + +
-
+
移除
- 添加一项 + 添加一项
-
+
移除
- 添加网络目标 + 添加网络目标
+
{{ value === field.recommendedPort ? '已使用推荐端口' : '推荐端口' }}:{{ field.recommendedPort }} @@ -130,13 +142,14 @@ 使用推荐端口
-

{{ field.hint }}

+

{{ field.hint }}

diff --git a/frontend/src/views/components/ConfigSettings/ConfigForm/ConfigForm.css b/frontend/src/views/components/ConfigSettings/ConfigForm/ConfigForm.css index 36cfdb5..8c40c22 100644 --- a/frontend/src/views/components/ConfigSettings/ConfigForm/ConfigForm.css +++ b/frontend/src/views/components/ConfigSettings/ConfigForm/ConfigForm.css @@ -1,11 +1,11 @@ .config-form { display: grid; - gap: 20px; + gap: 12px; min-width: 0; } .config-form:not(:first-child) { - margin-top: 16px; + margin-top: 10px; } .form-group { @@ -13,14 +13,14 @@ } .form-group + .form-group { - padding-top: 20px; + padding-top: 12px; border-top: 1px solid var(--pm-border-color); } .credential-status, .form-group-note, .form-empty { - margin: 0 0 12px; + margin: 0 0 8px; color: var(--pm-text-secondary); font-size: 12px; line-height: 1.7; @@ -31,12 +31,37 @@ display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; - gap: 20px; + gap: 12px 16px; } -@container config-main (max-width: 620px) { +@container config-main (min-width: 640px) { .form-grid { - grid-template-columns: minmax(0, 1fr); - gap: 18px; + grid-template-columns: repeat(3, minmax(0, 1fr)); + } + + .config-form[data-form-section="base"] { + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 12px; + } + + .config-form[data-form-section="base"] .form-group { + align-self: start; + padding: 12px; + border: 1px solid var(--pm-border-color); + border-radius: 10px; + background: var(--pm-bg-primary); + } + + .config-form[data-form-section="base"] .form-grid, + .config-form[data-form-section="email"] .form-grid, + .form-group[data-group="verification"] .form-grid { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } +} + +@container config-main (max-width: 440px) { + .form-grid { + grid-template-columns: minmax(0, 1fr); + gap: 12px; } } diff --git a/frontend/src/views/components/ConfigSettings/ConfigForm/ConfigForm.vue b/frontend/src/views/components/ConfigSettings/ConfigForm/ConfigForm.vue index 96d67fd..a942094 100644 --- a/frontend/src/views/components/ConfigSettings/ConfigForm/ConfigForm.vue +++ b/frontend/src/views/components/ConfigSettings/ConfigForm/ConfigForm.vue @@ -1,7 +1,7 @@