补齐用户信息标题并将数据库选择归入存储分组
This commit is contained in:
parent
c220b7d06d
commit
6c129bb81e
@ -4,7 +4,7 @@
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "node --test src/App.test.js src/views/SetupWizard/SetupWizard.test.js src/views/SetupWizard/SetupWizardBootstrap.test.js src/views/SetupWizard/DatabaseSetup.test.js src/views/SetupWizard/BootstrapPayload.test.js src/views/Dashboard/Dashboard.test.js src/views/UserManagement/UserManagement.test.js src/views/components/HelpTip/HelpTip.test.js",
|
||||
"test": "node --test src/App.test.js src/views/SetupWizard/SetupWizard.test.js src/views/SetupWizard/SetupWizardBootstrap.test.js src/views/SetupWizard/DatabaseSetup.test.js src/views/SetupWizard/SetupWizardLayout.test.js src/views/SetupWizard/BootstrapPayload.test.js src/views/Dashboard/Dashboard.test.js src/views/UserManagement/UserManagement.test.js src/views/components/HelpTip/HelpTip.test.js",
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
|
||||
@ -11,6 +11,14 @@ const emit = defineEmits(["test"]);
|
||||
|
||||
<template>
|
||||
<section class="database-setup" aria-label="数据库存储配置">
|
||||
<div class="setup-section-heading">
|
||||
<strong>
|
||||
数据库存储
|
||||
<HelpTip>
|
||||
选择一种存储方式,验证连接和写权限后继续。不会清空已有数据。
|
||||
</HelpTip>
|
||||
</strong>
|
||||
</div>
|
||||
<div class="database-type-field">
|
||||
<label>
|
||||
<span>数据库类型</span>
|
||||
@ -32,14 +40,6 @@ const emit = defineEmits(["test"]);
|
||||
<span v-if="verified" role="status">数据库连接及写权限已验证。</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setup-section-heading">
|
||||
<strong>
|
||||
数据库存储
|
||||
<HelpTip>
|
||||
选择一种存储方式,验证连接和写权限后继续。不会清空已有数据。
|
||||
</HelpTip>
|
||||
</strong>
|
||||
</div>
|
||||
<div v-if="form.driver !== 'sqlite'" class="setup-grid two-columns database-connection-grid">
|
||||
<label>
|
||||
<span>数据库主机</span>
|
||||
|
||||
@ -131,7 +131,10 @@ const {
|
||||
<div class="setup-step-grid">
|
||||
<fieldset v-if="currentStep === 1" class="setup-step-card" :disabled="submitting || completed">
|
||||
<legend><span>01</span>超级管理员</legend>
|
||||
<div class="setup-grid two-columns">
|
||||
<div class="setup-section-heading admin-account-heading">
|
||||
<strong>用户信息</strong>
|
||||
</div>
|
||||
<div class="setup-grid two-columns admin-account-grid">
|
||||
<label
|
||||
><span>用户名</span
|
||||
><input
|
||||
@ -229,7 +232,7 @@ const {
|
||||
</HelpTip>
|
||||
</strong>
|
||||
</div>
|
||||
<div class="setup-grid service-access-grid" :class="{ 'has-database': isBootstrap }">
|
||||
<div class="setup-grid service-access-grid">
|
||||
<div class="access-target-field">
|
||||
<span>管理页面访问方式</span>
|
||||
<div class="target-switch" role="group" aria-label="管理页面访问方式">
|
||||
@ -288,15 +291,15 @@ const {
|
||||
type="number"
|
||||
/>
|
||||
</label>
|
||||
<DatabaseSetup
|
||||
v-if="isBootstrap"
|
||||
:form="databaseForm"
|
||||
:testing="databaseTesting"
|
||||
:verified="databaseVerified"
|
||||
:error="databaseError"
|
||||
@test="testDatabase"
|
||||
/>
|
||||
</div>
|
||||
<DatabaseSetup
|
||||
v-if="isBootstrap"
|
||||
:form="databaseForm"
|
||||
:testing="databaseTesting"
|
||||
:verified="databaseVerified"
|
||||
:error="databaseError"
|
||||
@test="testDatabase"
|
||||
/>
|
||||
<div class="provider-description reset-preview">
|
||||
<strong>密码重置地址预览</strong>
|
||||
<span>{{ resetURLPreview }}</span>
|
||||
|
||||
@ -120,10 +120,41 @@
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.access-shell--setup .setup-step-card:has(#admin-username) > .setup-grid:first-of-type {
|
||||
.access-shell--setup .admin-account-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.access-shell--setup .admin-account-heading {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.access-shell--setup .setup-step-card:has(.admin-account-grid) label,
|
||||
.access-shell--setup .setup-step-card:has(.admin-account-grid) .access-target-field {
|
||||
margin-top: 2px;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.access-shell--setup .setup-step-card:has(.admin-account-grid) label > span,
|
||||
.access-shell--setup .setup-step-card:has(.admin-account-grid) .access-target-field > span {
|
||||
min-height: 18px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.access-shell--setup .setup-step-card:has(.admin-account-grid) input,
|
||||
.access-shell--setup .setup-step-card:has(.admin-account-grid) select {
|
||||
height: 32px;
|
||||
min-height: 32px;
|
||||
padding-block: 4px;
|
||||
}
|
||||
|
||||
.access-shell--setup .setup-step-card:has(.admin-account-grid) .setup-grid {
|
||||
row-gap: 4px;
|
||||
}
|
||||
|
||||
.access-shell--setup .setup-step-card:has(.admin-account-grid) .setup-section-heading {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.access-shell--setup .email-input-group {
|
||||
grid-template-columns: minmax(0, 1fr) 96px;
|
||||
}
|
||||
@ -133,17 +164,16 @@
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.access-shell--setup .service-access-grid.has-database {
|
||||
grid-template-columns: minmax(168px, 0.85fr) minmax(160px, 1.1fr) minmax(140px, 0.8fr) minmax(310px, 1.8fr);
|
||||
}
|
||||
|
||||
.access-shell--setup .service-access-grid > .database-setup {
|
||||
display: contents;
|
||||
.access-shell--setup .database-setup {
|
||||
gap: 4px;
|
||||
margin-top: 6px;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.access-shell--setup .database-type-field {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
grid-template-columns: minmax(0, 420px) auto;
|
||||
justify-content: start;
|
||||
align-items: start;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
@ -156,8 +186,8 @@
|
||||
.access-shell--setup .database-type-field .dns-test-button {
|
||||
width: 92px;
|
||||
height: auto;
|
||||
min-height: 36px;
|
||||
margin-top: 28px;
|
||||
min-height: 32px;
|
||||
margin-top: 22px;
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
padding: 6px 10px;
|
||||
@ -180,8 +210,6 @@
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
gap: 4px 10px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px solid #e4ebf5;
|
||||
}
|
||||
|
||||
.access-shell--setup .database-connection-grid {
|
||||
@ -334,10 +362,6 @@
|
||||
}
|
||||
|
||||
@media (min-width: 901px) and (max-width: 1279px) {
|
||||
.access-shell--setup .service-access-grid.has-database {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.access-shell--setup .database-connection-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
55
frontend/src/views/SetupWizard/SetupWizardLayout.test.js
Normal file
55
frontend/src/views/SetupWizard/SetupWizardLayout.test.js
Normal file
@ -0,0 +1,55 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
import { baseParse } from "@vue/compiler-dom";
|
||||
import { parse } from "@vue/compiler-sfc";
|
||||
|
||||
function template(name) {
|
||||
const source = readFileSync(new URL(name, import.meta.url), "utf8");
|
||||
return baseParse(parse(source).descriptor.template.content);
|
||||
}
|
||||
|
||||
function find(node, predicate) {
|
||||
if (predicate(node)) return node;
|
||||
for (const child of node.children || []) {
|
||||
const result = find(child, predicate);
|
||||
if (result) return result;
|
||||
}
|
||||
}
|
||||
|
||||
function hasClass(name) {
|
||||
return (node) => node.props?.some((prop) => prop.name === "class"
|
||||
&& prop.value?.content.split(/\s+/).includes(name));
|
||||
}
|
||||
|
||||
test("account heading precedes the two-column account fields", () => {
|
||||
const root = template("./SetupWizard.vue");
|
||||
const card = find(root, (node) => node.tag === "fieldset"
|
||||
&& node.children.some(hasClass("admin-account-grid")));
|
||||
const heading = card.children.findIndex(hasClass("admin-account-heading"));
|
||||
const grid = card.children.findIndex(hasClass("admin-account-grid"));
|
||||
assert.ok(heading >= 0 && heading < grid);
|
||||
assert.equal(card.children[grid].children.filter((node) => node.tag === "label").length, 4);
|
||||
assert.ok(find(card.children[heading], (node) => node.tag === "strong"));
|
||||
});
|
||||
|
||||
test("database setup follows service access instead of occupying its grid", () => {
|
||||
const root = template("./SetupWizard.vue");
|
||||
const card = find(root, (node) => node.tag === "fieldset"
|
||||
&& node.children.some(hasClass("service-access-grid")));
|
||||
const service = card.children.findIndex(hasClass("service-access-grid"));
|
||||
const database = card.children.findIndex((node) => node.tag === "DatabaseSetup");
|
||||
assert.ok(service >= 0 && database > service);
|
||||
assert.equal(find(card.children[service], (node) => node.tag === "DatabaseSetup"), undefined);
|
||||
});
|
||||
|
||||
test("database heading precedes selection, verification and connection fields", () => {
|
||||
const section = find(template("./DatabaseSetup.vue"), hasClass("database-setup"));
|
||||
const heading = section.children.findIndex(hasClass("setup-section-heading"));
|
||||
const selection = section.children.findIndex(hasClass("database-type-field"));
|
||||
const connection = section.children.findIndex(hasClass("database-connection-grid"));
|
||||
assert.ok(heading >= 0 && selection > heading && connection > selection);
|
||||
assert.ok(find(section.children[selection], (node) => node.tag === "select"));
|
||||
assert.ok(find(section.children[selection], (node) => node.tag === "button"));
|
||||
assert.ok(find(section.children[heading], (node) => node.tag === "HelpTip"));
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user