- Statuses can now be bulk-imported/updated via CSV (Name, Color columns; matches and updates existing statuses by name). New internal/statuses/csv.go, tested. - Icon fields (folder create/rename, item type form) are now a searchable dropdown of the 50 most common Bootstrap Icons instead of a free-text box, via a small reusable .icon-picker widget in app.js/app.css. - CSV asset import is now folder-scoped when triggered from the tree: right-click a folder (or its background) > Import CSV... imports every row directly into that folder, so the CSV needs no Folder column at all, and the option no longer appears at the top level. The original global, Folder-path-aware import (with auto-create-missing-folders) moved to a new admin-only Settings > Import / Export page, alongside the new Statuses import and format examples for both. assets.Import gained ImportOptions.TargetFolderID to drive the folder-scoped mode. - Site Name (Settings > General) now actually renders in the navbar brand and <title>, via a per-App "siteName" template func bound in loadTemplates. The brand is plain text now, not a link to /inventory.
259 lines
4.1 KiB
CSS
259 lines
4.1 KiB
CSS
:root {
|
|
--tree-indent: 1.15rem;
|
|
}
|
|
|
|
body {
|
|
background-color: #f7f8fa;
|
|
}
|
|
|
|
.app-navbar {
|
|
background-color: #fff;
|
|
}
|
|
|
|
.login-body {
|
|
min-height: 100vh;
|
|
background: linear-gradient(180deg, #eef1f6 0%, #f7f8fa 100%);
|
|
}
|
|
|
|
/* Admin-only UI: shown only when <body> carries the role-admin class. */
|
|
.admin-only { display: none !important; }
|
|
body.role-admin .admin-only { display: inherit !important; }
|
|
body.role-admin button.admin-only,
|
|
body.role-admin a.admin-only { display: inline-block !important; }
|
|
|
|
.inventory-shell {
|
|
height: calc(100vh - 56px);
|
|
min-height: 480px;
|
|
}
|
|
|
|
.tree-pane {
|
|
width: 340px;
|
|
min-width: 260px;
|
|
max-width: 45vw;
|
|
background-color: #fff;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.tree-scroll {
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.main-panel {
|
|
background-color: #fff;
|
|
}
|
|
|
|
ul.tree, ul.tree-children {
|
|
list-style: none;
|
|
margin: 0;
|
|
padding-left: 0;
|
|
}
|
|
|
|
ul.tree-children {
|
|
padding-left: var(--tree-indent);
|
|
}
|
|
|
|
.tree-node-root > .tree-row {
|
|
font-weight: 600;
|
|
}
|
|
|
|
.tree-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.35rem;
|
|
padding: 0.2rem 0.4rem;
|
|
border-radius: 0.25rem;
|
|
cursor: pointer;
|
|
white-space: nowrap;
|
|
user-select: none;
|
|
}
|
|
|
|
.tree-row:hover {
|
|
background-color: #f1f3f5;
|
|
}
|
|
|
|
.tree-row.selected {
|
|
background-color: #e7f1ff;
|
|
color: #0d6efd;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.tree-row.drop-target {
|
|
outline: 2px dashed #0d6efd;
|
|
outline-offset: -2px;
|
|
background-color: #e7f1ff;
|
|
}
|
|
|
|
.tree-row-more {
|
|
cursor: default;
|
|
}
|
|
|
|
.tree-toggle {
|
|
border: none;
|
|
background: none;
|
|
padding: 0;
|
|
width: 1.1rem;
|
|
height: 1.1rem;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
flex-shrink: 0;
|
|
color: #6c757d;
|
|
}
|
|
|
|
.tree-toggle i {
|
|
transition: transform 0.12s ease;
|
|
}
|
|
|
|
.tree-toggle.expanded i {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
.tree-toggle-spacer {
|
|
width: 1.1rem;
|
|
flex-shrink: 0;
|
|
display: inline-block;
|
|
}
|
|
|
|
.tree-icon {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.tree-label {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
flex: 1 1 auto;
|
|
}
|
|
|
|
.tree-status-badge {
|
|
font-size: 0.65rem;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.tree-node.dragging {
|
|
opacity: 0.4;
|
|
}
|
|
|
|
/* Generic right-click context menu (tree + panels feel like a native app:
|
|
most actions live here instead of on-screen buttons). */
|
|
.ctx-menu {
|
|
position: fixed;
|
|
z-index: 1080;
|
|
min-width: 190px;
|
|
display: none;
|
|
}
|
|
|
|
.ctx-menu .dropdown-item i {
|
|
width: 1.1rem;
|
|
display: inline-block;
|
|
text-align: center;
|
|
margin-right: 0.15rem;
|
|
}
|
|
|
|
[data-context="asset-header"],
|
|
[data-context="folder-header"] {
|
|
cursor: default;
|
|
}
|
|
|
|
.panel-content {
|
|
max-width: 1100px;
|
|
}
|
|
|
|
.panel-blank {
|
|
max-width: none;
|
|
}
|
|
|
|
/* Icon picker: a searchable dropdown of common Bootstrap Icons, standing
|
|
in for a free-text icon class field. */
|
|
.icon-picker {
|
|
position: relative;
|
|
}
|
|
|
|
.icon-picker-toggle {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
text-align: left;
|
|
}
|
|
|
|
.icon-picker-preview {
|
|
font-size: 1.1rem;
|
|
width: 1.1rem;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.icon-picker-label {
|
|
flex: 1 1 auto;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.icon-picker-caret {
|
|
flex-shrink: 0;
|
|
font-size: 0.75rem;
|
|
color: #6c757d;
|
|
}
|
|
|
|
.icon-picker-menu {
|
|
display: none;
|
|
position: absolute;
|
|
z-index: 1085;
|
|
top: 100%;
|
|
left: 0;
|
|
margin-top: 0.25rem;
|
|
width: 280px;
|
|
max-width: 90vw;
|
|
background-color: #fff;
|
|
border: 1px solid rgba(0, 0, 0, 0.15);
|
|
border-radius: 0.375rem;
|
|
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
|
padding: 0.5rem;
|
|
}
|
|
|
|
.icon-picker-menu.show {
|
|
display: block;
|
|
}
|
|
|
|
.icon-picker-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(6, 1fr);
|
|
gap: 0.25rem;
|
|
max-height: 190px;
|
|
overflow-y: auto;
|
|
margin-top: 0.5rem;
|
|
}
|
|
|
|
.icon-picker-item {
|
|
border: 1px solid transparent;
|
|
background: none;
|
|
border-radius: 0.25rem;
|
|
padding: 0.4rem;
|
|
font-size: 1.1rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #212529;
|
|
}
|
|
|
|
.icon-picker-item:hover,
|
|
.icon-picker-item:focus {
|
|
background-color: #f1f3f5;
|
|
border-color: rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.asset-row, .folder-link, .asset-link {
|
|
cursor: pointer;
|
|
}
|
|
|
|
@media (max-width: 767.98px) {
|
|
.inventory-shell {
|
|
flex-direction: column;
|
|
height: auto;
|
|
}
|
|
.tree-pane {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
max-height: 40vh;
|
|
}
|
|
}
|