mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 21:00:41 +00:00
feat: add domain rules management feature
- Introduced a new DomainRulesPage component for managing custom and global equivalent domains. - Updated AppMainRoutes to include a route for domain rules. - Added API functions to fetch and save domain rules. - Enhanced localization with new strings for domain rules in multiple languages. - Updated styles for the new domain rules interface and ensured responsiveness. - Added types for domain rules in the TypeScript definitions.
This commit is contained in:
@@ -2,6 +2,13 @@
|
||||
@apply grid gap-3;
|
||||
}
|
||||
|
||||
.domain-rules-route {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
grid-template-rows: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.import-export-page {
|
||||
@apply grid gap-3;
|
||||
}
|
||||
@@ -19,9 +26,8 @@
|
||||
.backup-operations-sidebar,
|
||||
.backup-destination-sidebar,
|
||||
.backup-detail-panel {
|
||||
@apply min-w-0 rounded-xl bg-white p-3;
|
||||
border: 1px solid #d8dee8;
|
||||
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05);
|
||||
@apply min-w-0 rounded-2xl border bg-panel p-3 shadow-soft;
|
||||
border-color: var(--line);
|
||||
}
|
||||
|
||||
.backup-actions-stack {
|
||||
@@ -305,7 +311,7 @@
|
||||
}
|
||||
|
||||
.backup-browser-list {
|
||||
@apply overflow-hidden rounded-xl bg-white;
|
||||
@apply overflow-hidden rounded-xl border bg-white;
|
||||
border: 1px solid var(--line);
|
||||
}
|
||||
|
||||
@@ -875,3 +881,275 @@
|
||||
background: #e2e8f0;
|
||||
color: #475569;
|
||||
}
|
||||
|
||||
.section-heading-row {
|
||||
@apply mb-3.5 flex items-center justify-between gap-3;
|
||||
}
|
||||
|
||||
.section-heading-row h3 {
|
||||
@apply mb-0;
|
||||
}
|
||||
|
||||
.domain-rules-page {
|
||||
@apply grid min-h-0 gap-3.5;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
grid-template-rows: auto minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.domain-rules-toolbar {
|
||||
@apply flex flex-wrap items-start justify-between gap-3;
|
||||
}
|
||||
|
||||
.domain-rules-toolbar-copy {
|
||||
max-width: 760px;
|
||||
}
|
||||
|
||||
.domain-rules-toolbar-title {
|
||||
@apply text-base font-bold;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.domain-rules-toolbar-copy p {
|
||||
@apply mt-1.5 text-sm leading-6;
|
||||
color: var(--muted-strong);
|
||||
}
|
||||
|
||||
.domain-rules-grid {
|
||||
min-height: 0;
|
||||
grid-template-columns: minmax(380px, 1fr) minmax(420px, 1.08fr);
|
||||
}
|
||||
|
||||
.domain-rules-custom,
|
||||
.domain-rules-global {
|
||||
@apply flex min-h-0 flex-col rounded-2xl border bg-panel shadow-soft;
|
||||
border-color: var(--line);
|
||||
}
|
||||
|
||||
.domain-rules-heading-actions {
|
||||
@apply flex flex-wrap items-center justify-end gap-2;
|
||||
}
|
||||
|
||||
.domain-rules-filter {
|
||||
width: min(240px, 100%);
|
||||
}
|
||||
|
||||
.domain-rules-table {
|
||||
@apply grid min-h-0 flex-1 content-start gap-2 overflow-auto pr-0.5;
|
||||
overflow-anchor: none;
|
||||
}
|
||||
|
||||
.domain-rule-row {
|
||||
@apply grid items-center gap-2.5 rounded-md px-2.5 py-2.5;
|
||||
grid-template-columns: 18px minmax(0, 1fr) auto auto;
|
||||
border: 1px solid var(--line);
|
||||
background: var(--panel);
|
||||
}
|
||||
|
||||
.domain-rule-row > input[type='checkbox'] {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.domain-rule-readonly-row {
|
||||
grid-template-columns: 18px minmax(0, 1fr) auto;
|
||||
}
|
||||
|
||||
.domain-rule-editing-row {
|
||||
@apply items-start;
|
||||
grid-template-columns: minmax(360px, 1fr) auto;
|
||||
column-gap: 12px;
|
||||
}
|
||||
|
||||
.domain-rule-domains {
|
||||
display: block;
|
||||
line-height: 20px;
|
||||
min-width: 0;
|
||||
max-height: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
transition:
|
||||
max-height 180ms var(--ease-out-soft),
|
||||
opacity 140ms var(--ease-smooth);
|
||||
}
|
||||
|
||||
.domain-rule-row-expanded {
|
||||
@apply items-start;
|
||||
}
|
||||
|
||||
.domain-rule-row-expanded > input[type='checkbox'],
|
||||
.domain-rule-row-expanded .domain-rule-expand-btn,
|
||||
.domain-rule-row-expanded .domain-rule-row-actions {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.domain-rule-row-expanded .domain-rule-domains {
|
||||
overflow: visible;
|
||||
text-overflow: clip;
|
||||
white-space: normal;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.domain-rule-domains-expanded {
|
||||
max-height: 220px;
|
||||
}
|
||||
|
||||
.domain-rule-expand-btn {
|
||||
@apply flex h-8 w-8 cursor-pointer items-center justify-center rounded-full border-0 p-0;
|
||||
background: transparent;
|
||||
color: var(--muted-strong);
|
||||
transition:
|
||||
background-color var(--dur-fast) var(--ease-smooth),
|
||||
color var(--dur-fast) var(--ease-smooth),
|
||||
transform var(--dur-fast) var(--ease-out-soft);
|
||||
}
|
||||
|
||||
.domain-rule-expand-btn:hover {
|
||||
background: var(--panel-soft);
|
||||
color: var(--primary);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.domain-rule-main {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.domain-rule-inputs {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 8px 18px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.domain-rule-input-piece {
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
@apply flex items-center;
|
||||
}
|
||||
|
||||
.domain-rule-inline-input {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding-right: 52px;
|
||||
}
|
||||
|
||||
.domain-rule-inline-input.domain-rule-input-invalid {
|
||||
border-color: rgba(217, 45, 87, 0.78);
|
||||
background: color-mix(in srgb, var(--danger) 5%, var(--panel));
|
||||
box-shadow: 0 0 0 3px rgba(217, 45, 87, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.72);
|
||||
}
|
||||
|
||||
.domain-rule-inline-input.domain-rule-input-invalid:focus {
|
||||
border-color: rgba(217, 45, 87, 0.86);
|
||||
box-shadow: 0 0 0 4px rgba(217, 45, 87, 0.14), inset 0 1px 0 rgba(255, 255, 255, 0.78);
|
||||
}
|
||||
|
||||
.domain-rule-operator {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: -12px;
|
||||
transform: translateY(-50%);
|
||||
color: var(--muted);
|
||||
font-weight: 700;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.domain-rule-input-piece:nth-child(even) .domain-rule-operator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.domain-rule-mini-btn,
|
||||
.domain-rule-icon-btn {
|
||||
@apply h-9 w-9 justify-center p-0;
|
||||
}
|
||||
|
||||
.domain-rule-input-remove {
|
||||
@apply absolute top-1/2 flex h-7 w-7 -translate-y-1/2 items-center justify-center rounded-full border-0 p-0;
|
||||
right: 1rem;
|
||||
background: var(--panel-soft);
|
||||
color: var(--primary);
|
||||
transition:
|
||||
background-color var(--dur-fast) var(--ease-smooth),
|
||||
color var(--dur-fast) var(--ease-smooth),
|
||||
transform var(--dur-fast) var(--ease-out-soft);
|
||||
}
|
||||
|
||||
.domain-rule-input-remove:hover {
|
||||
background: color-mix(in srgb, var(--danger) 12%, var(--panel));
|
||||
color: var(--danger);
|
||||
transform: translateY(-50%) scale(1.04);
|
||||
}
|
||||
|
||||
.domain-rule-row-actions {
|
||||
@apply flex items-center self-center gap-2;
|
||||
}
|
||||
|
||||
.domain-rule-row-actions .btn {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.domain-rule-editing-row .domain-rule-row-actions {
|
||||
align-self: start;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.domain-rule-new-row {
|
||||
@apply mb-2;
|
||||
background: var(--panel-soft);
|
||||
}
|
||||
|
||||
@media (max-width: 1180px) {
|
||||
.route-stage-fixed {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.domain-rules-route {
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
grid-template-rows: auto;
|
||||
}
|
||||
|
||||
.domain-rules-page {
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.domain-rules-grid {
|
||||
grid-auto-rows: minmax(320px, min(54vh, 560px));
|
||||
}
|
||||
|
||||
.domain-rules-table {
|
||||
max-height: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
.domain-rules-page {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.domain-rules-grid {
|
||||
grid-auto-rows: auto;
|
||||
}
|
||||
|
||||
.domain-rules-table {
|
||||
max-height: 56vh;
|
||||
}
|
||||
|
||||
.domain-rule-editing-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.domain-rule-inputs {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.domain-rule-operator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.domain-rule-editing-row .domain-rule-row-actions {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user