refactor(frontend): extract controllers, repo styles + dashboard.css

This commit is contained in:
Lewis
2026-03-18 10:43:02 +00:00
committed by Tangled
parent 76dc3b125a
commit 14bac09cb1
3 changed files with 2547 additions and 811 deletions
@@ -626,461 +626,3 @@
</section>
{/if}
</div>
<style>
.controllers {
max-width: var(--width-lg);
}
.loading,
.empty {
color: var(--text-secondary);
padding: var(--space-4);
text-align: center;
}
.section {
background: var(--bg-secondary);
padding: var(--space-5);
border-radius: var(--radius-lg);
margin-bottom: var(--space-5);
}
.section-header {
margin-bottom: var(--space-4);
}
.section-header h3 {
margin: 0 0 var(--space-1) 0;
font-size: var(--text-base);
}
.section-description {
color: var(--text-secondary);
margin: 0;
font-size: var(--text-sm);
}
.constraint-notice {
background: var(--bg-tertiary);
border: 1px solid var(--border-color);
border-radius: var(--radius-md);
padding: var(--space-4);
margin-top: var(--space-4);
}
.constraint-notice p {
margin: 0;
color: var(--text-secondary);
font-size: var(--text-sm);
}
.items-list {
display: flex;
flex-direction: column;
gap: var(--space-4);
margin-bottom: var(--space-4);
}
.item-card {
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: var(--radius-lg);
padding: var(--space-4);
display: flex;
justify-content: space-between;
align-items: center;
gap: var(--space-4);
flex-wrap: wrap;
}
.item-card.inactive {
opacity: 0.6;
}
.item-info {
flex: 1;
min-width: 200px;
}
.item-header {
margin-bottom: var(--space-2);
display: flex;
align-items: center;
gap: var(--space-2);
flex-wrap: wrap;
}
.item-handle {
font-weight: var(--font-semibold);
color: var(--text-primary);
}
.badge {
display: inline-block;
padding: var(--space-1) var(--space-2);
border-radius: var(--radius-md);
font-size: var(--text-xs);
font-weight: var(--font-medium);
}
.badge.scope {
background: var(--accent);
color: var(--text-inverse);
}
.badge.inactive {
background: var(--error-bg);
color: var(--error-text);
border: 1px solid var(--error-border);
}
.item-details {
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.detail {
font-size: var(--text-sm);
}
.detail .label {
color: var(--text-secondary);
margin-right: var(--space-2);
}
.detail .value {
color: var(--text-primary);
}
.detail .value.did {
font-family: var(--font-mono);
font-size: var(--text-xs);
word-break: break-all;
}
.item-actions {
display: flex;
gap: var(--space-2);
}
.btn-link {
display: inline-block;
padding: var(--space-2) var(--space-4);
border: 1px solid var(--accent);
border-radius: var(--radius-md);
background: transparent;
color: var(--accent);
font-size: var(--text-sm);
font-weight: var(--font-medium);
text-decoration: none;
}
.btn-link:hover {
background: var(--accent);
color: var(--text-inverse);
}
.danger-outline {
padding: var(--space-2) var(--space-4);
border: 1px solid var(--error-text);
border-radius: var(--radius-md);
background: transparent;
color: var(--error-text);
font-size: var(--text-sm);
cursor: pointer;
}
.danger-outline:hover {
background: var(--error-bg);
}
.ghost {
background: transparent;
border: 1px solid var(--border-color);
color: var(--text-primary);
}
.ghost:hover {
border-color: var(--accent);
}
.full-width {
width: 100%;
}
.form-card {
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: var(--radius-lg);
padding: var(--space-5);
margin-top: var(--space-4);
}
.form-card h4 {
margin: 0 0 var(--space-4) 0;
font-size: var(--text-base);
}
.warning-box {
background: var(--warning-bg);
border: 1px solid var(--warning-border);
border-radius: var(--radius-md);
padding: var(--space-4);
margin-bottom: var(--space-5);
}
.warning-header {
font-weight: var(--font-semibold);
color: var(--warning-text);
margin-bottom: var(--space-2);
}
.warning-text {
margin: 0 0 var(--space-3) 0;
color: var(--warning-text);
font-size: var(--text-sm);
line-height: 1.5;
}
.warning-bullets {
margin: 0;
padding-left: var(--space-5);
color: var(--warning-text);
font-size: var(--text-sm);
line-height: 1.6;
}
.confirm-checkbox {
display: flex;
align-items: flex-start;
gap: var(--space-2);
cursor: pointer;
padding: var(--space-3);
background: var(--bg-tertiary);
border: 1px solid var(--border-color);
border-radius: var(--radius-md);
margin-bottom: var(--space-4);
}
.confirm-checkbox input {
width: 18px;
height: 18px;
flex-shrink: 0;
margin-top: 2px;
}
.confirm-checkbox span {
font-size: var(--text-sm);
font-weight: var(--font-medium);
color: var(--text-primary);
line-height: 1.4;
}
.field {
margin-bottom: var(--space-4);
}
.field label {
display: block;
font-size: var(--text-sm);
font-weight: var(--font-medium);
margin-bottom: var(--space-1);
}
.field input,
.field select {
width: 100%;
}
.form-actions {
display: flex;
gap: var(--space-3);
justify-content: flex-end;
}
.controller-search {
position: relative;
}
.search-wrapper {
position: relative;
}
.typeahead-dropdown {
position: absolute;
top: 100%;
left: 0;
right: 0;
z-index: 10;
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: var(--radius-md);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
max-height: 240px;
overflow-y: auto;
}
.typeahead-item {
display: flex;
align-items: center;
gap: var(--space-2);
width: 100%;
padding: var(--space-2) var(--space-3);
border: none;
background: transparent;
cursor: pointer;
text-align: left;
color: var(--text-primary);
}
.typeahead-item:hover {
background: var(--bg-tertiary);
}
.typeahead-avatar {
width: 28px;
height: 28px;
border-radius: 50%;
flex-shrink: 0;
}
.typeahead-text {
display: flex;
flex-direction: column;
min-width: 0;
}
.typeahead-name {
font-size: var(--text-sm);
font-weight: var(--font-medium);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.typeahead-handle {
font-size: var(--text-xs);
color: var(--text-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.resolve-status {
display: block;
font-size: var(--text-xs);
color: var(--text-secondary);
margin-top: var(--space-1);
}
.resolve-status.error {
color: var(--error-text);
}
.resolved-info {
display: flex;
align-items: center;
gap: var(--space-2);
flex-wrap: wrap;
margin-top: var(--space-2);
padding: var(--space-2) var(--space-3);
background: var(--bg-tertiary);
border-radius: var(--radius-md);
font-size: var(--text-xs);
}
.resolved-did {
font-family: var(--font-mono);
color: var(--text-secondary);
word-break: break-all;
}
.resolved-handle {
color: var(--text-primary);
font-weight: var(--font-medium);
}
.badge.external {
background: var(--info-bg, var(--bg-tertiary));
color: var(--info-text, var(--text-secondary));
border: 1px solid var(--info-border, var(--border-color));
}
.audit-entries {
display: flex;
flex-direction: column;
gap: var(--space-3);
}
.audit-entry {
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: var(--radius-lg);
padding: var(--space-4);
}
.audit-entry-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: var(--space-3);
}
.action-type {
font-weight: var(--font-medium);
padding: var(--space-1) var(--space-2);
background: var(--accent);
color: var(--text-inverse);
border-radius: var(--radius-md);
font-size: var(--text-sm);
}
.audit-entry-date {
font-size: var(--text-sm);
color: var(--text-secondary);
}
.audit-entry-details {
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.audit-details-value {
font-family: var(--font-mono);
font-size: var(--text-xs);
word-break: break-word;
}
@media (max-width: 600px) {
.item-card {
flex-direction: column;
align-items: stretch;
}
.item-actions {
width: 100%;
}
.item-actions button,
.item-actions a {
width: 100%;
text-align: center;
}
.audit-entry-header {
flex-direction: column;
align-items: flex-start;
gap: var(--space-2);
}
.audit-entry-details .value.did {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 60vw;
}
}
</style>
@@ -419,7 +419,7 @@
{:else if view === 'create'}
<form class="create-form" onsubmit={handleCreate}>
<div class="field">
<div>
<label for="collection">{$_('repoExplorer.collectionNsid')}</label>
<input
id="collection"
@@ -430,7 +430,7 @@
required
/>
</div>
<div class="field">
<div>
<label for="rkey">{$_('repoExplorer.recordKeyOptional')}</label>
<input
id="rkey"
@@ -465,354 +465,3 @@
</form>
{/if}
</div>
<style>
.repo-explorer {
max-width: var(--width-xl);
}
.breadcrumb {
display: flex;
align-items: center;
gap: var(--space-2);
font-size: var(--text-sm);
margin-bottom: var(--space-4);
padding: var(--space-3) var(--space-4);
background: var(--bg-secondary);
border-radius: var(--radius-md);
}
.breadcrumb-sep {
color: var(--text-muted);
}
.breadcrumb-link {
all: unset;
color: var(--text-secondary);
cursor: pointer;
font-size: inherit;
padding: var(--space-1) var(--space-2);
border-radius: var(--radius-sm);
transition: color var(--transition-normal), background var(--transition-normal);
}
.breadcrumb-link:hover {
color: var(--text-primary);
background: var(--bg-hover);
}
.breadcrumb-current {
color: var(--text-primary);
font-weight: var(--font-medium);
}
.message {
padding: var(--space-4);
border-radius: var(--radius-lg);
margin-bottom: var(--space-4);
}
.message.error {
background: var(--error-bg);
border: 1px solid var(--error-border);
color: var(--error-text);
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.error-code {
font-family: var(--font-mono);
font-size: var(--text-sm);
}
.error-message {
font-size: var(--text-sm);
}
.message.success {
background: var(--success-bg);
border: 1px solid var(--success-border);
color: var(--success-text);
}
.loading {
color: var(--text-secondary);
padding: var(--space-6);
text-align: center;
}
.toolbar {
display: flex;
gap: var(--space-2);
margin-bottom: var(--space-4);
}
.filter-input {
flex: 1;
padding: var(--space-2) var(--space-3);
border: 1px solid var(--border-color);
border-radius: var(--radius-md);
font-size: var(--text-sm);
background: var(--bg-input);
color: var(--text-primary);
}
.filter-input:focus {
outline: none;
border-color: var(--accent);
}
.empty {
text-align: center;
color: var(--text-secondary);
padding: var(--space-8);
background: var(--bg-secondary);
border-radius: var(--radius-lg);
}
.collections {
display: flex;
flex-direction: column;
gap: var(--space-4);
}
.collection-group {
background: var(--bg-secondary);
border-radius: var(--radius-lg);
padding: var(--space-4);
}
.authority {
margin: 0 0 var(--space-3) 0;
font-size: var(--text-sm);
color: var(--text-secondary);
font-weight: var(--font-medium);
}
.nsid-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: var(--space-1);
}
.collection-link {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: var(--space-3);
background: var(--bg-card);
border: 1px solid var(--border-color);
border-radius: var(--radius-md);
cursor: pointer;
text-align: left;
color: var(--text-primary);
transition: background var(--transition-normal), border-color var(--transition-normal);
}
.collection-link:hover {
background: var(--bg-hover);
border-color: var(--accent);
}
.nsid {
font-weight: var(--font-medium);
color: var(--accent);
}
.arrow {
color: var(--text-muted);
}
.collection-link:hover .arrow {
color: var(--accent);
}
.record-list {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
gap: var(--space-2);
}
.record-item {
display: block;
width: 100%;
padding: var(--space-4);
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: var(--radius-lg);
cursor: pointer;
text-align: left;
color: var(--text-primary);
transition: background var(--transition-normal), border-color var(--transition-normal);
}
.record-item:hover {
background: var(--bg-hover);
border-color: var(--accent);
}
.record-info {
display: flex;
justify-content: space-between;
margin-bottom: var(--space-2);
}
.rkey {
font-family: var(--font-mono);
font-weight: var(--font-medium);
color: var(--accent);
}
.cid {
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--text-muted);
}
.record-preview {
margin: 0;
padding: var(--space-2);
background: var(--bg-card);
border-radius: var(--radius-md);
font-family: var(--font-mono);
font-size: var(--text-xs);
color: var(--text-secondary);
white-space: pre-wrap;
word-break: break-word;
max-height: 100px;
overflow: hidden;
}
.record-detail {
display: flex;
flex-direction: column;
gap: var(--space-5);
}
.record-meta {
background: var(--bg-secondary);
padding: var(--space-4);
border-radius: var(--radius-lg);
}
.record-meta dl {
display: grid;
grid-template-columns: auto 1fr;
gap: var(--space-2) var(--space-4);
margin: 0;
}
.record-meta dt {
font-weight: var(--font-medium);
color: var(--text-secondary);
}
.record-meta dd {
margin: 0;
}
.mono {
font-family: var(--font-mono);
font-size: var(--text-xs);
word-break: break-all;
}
.field {
margin-bottom: var(--space-4);
}
.field label {
display: block;
font-size: var(--text-sm);
font-weight: var(--font-medium);
margin-bottom: var(--space-1);
}
.field input {
width: 100%;
}
.hint {
font-size: var(--text-xs);
color: var(--text-muted);
margin: var(--space-1) 0 0 0;
}
.editor-container {
margin-bottom: var(--space-4);
}
.editor-container label {
display: block;
font-size: var(--text-sm);
font-weight: var(--font-medium);
margin-bottom: var(--space-1);
}
textarea {
width: 100%;
min-height: 300px;
padding: var(--space-4);
border: 1px solid var(--border-color);
border-radius: var(--radius-md);
font-family: var(--font-mono);
font-size: var(--text-sm);
background: var(--bg-input);
color: var(--text-primary);
resize: vertical;
box-sizing: border-box;
}
textarea:focus {
outline: none;
border-color: var(--accent);
}
textarea.has-error {
border-color: var(--error-text);
}
.json-error {
margin: var(--space-1) 0 0 0;
font-size: var(--text-xs);
color: var(--error-text);
}
.actions {
display: flex;
gap: var(--space-2);
}
.create-form {
background: var(--bg-secondary);
padding: var(--space-5);
border-radius: var(--radius-lg);
}
@media (max-width: 600px) {
.toolbar {
flex-direction: column;
}
.record-meta dl {
grid-template-columns: 1fr;
}
.actions {
flex-direction: column;
}
.actions button {
width: 100%;
}
}
</style>
File diff suppressed because it is too large Load Diff