Files
gott/wwwroot/css/file-explorer.css
T
Meleki 8e7bda50f9 feat: Ordner erstellen/löschen im File Explorer
Backend (WorkspaceEndpoint.cs):
- POST /api/workspace/mkdir – Ordner im Session-Workspace erstellen
- DELETE /api/workspace/dir – Leeren Ordner im Session-Workspace löschen
- POST /api/workspace/agent/mkdir – Ordner im Agent-Memory erstellen
- DELETE /api/workspace/agent/dir – Leeren Ordner im Agent-Memory löschen
- POST /api/workspace/browse/mkdir – Ordner im Folder-Browser erstellen
- Sicherheit: Path-Traversal-Schutz, Root nicht löschbar, nicht-leer → 409

Frontend (file-explorer.js):
- 📁+ Button im Header für neuen Ordner (File Explorer + Folder Browser)
- 🗑️ Button bei jedem Ordner (erscheint on hover, nur File Explorer)
- Validierung: ungültige Zeichen werden abgelehnt

CSS:
- base.css: Icon-Button mit zwei Icons (folder + plus)
- file-explorer.css: Ordner-Zeile als Flex (Label + Delete-Button)
2026-03-05 21:01:09 +01:00

374 lines
7.9 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ── File Explorer Modal ── */
.fe-overlay {
position: fixed;
inset: 0;
background: rgb(from var(--f1-bg) r g b / var(--semi-transparent));
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.fe-modal {
background: var(--f2-bg);
border: var(--border-width) solid var(--f2-border);
border-radius: var(--border-radius);
overflow: hidden;
width: 90vw;
height: 80vh;
display: flex;
flex-direction: column;
}
.fe-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: .5em;
border-bottom: var(--border-width) solid var(--f1-border);
background: var(--f1-bg);
flex-shrink: 0;
}
.fe-nav {
display: flex;
align-items: center;
gap: .5em;
flex: 1;
overflow: hidden;
}
.fe-path {
opacity: var(--semi-transparent);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.fe-body {
display: flex;
flex: 1;
overflow: hidden;
}
.fe-sidebar {
width: 280px;
min-width: 200px;
border-right: var(--border-width) solid var(--f1-border);
overflow-y: auto;
background: var(--f1-bg);
flex-shrink: 0;
padding-block: var(--box-spacing);
}
.fe-sidebar-full {
width: 100%;
}
.fe-main {
flex: 1;
overflow: hidden;
display: flex;
min-width: 0;
}
.fe-item {
padding: .5em 1em;
cursor: pointer;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.fe-item:hover {
background: var(--f2-bg);
}
.fe-item.active {
background: var(--f3-bg);
border-left: 2px solid var(--primary);
}
.fe-dir {
color: var(--text);
display: flex;
align-items: center;
justify-content: space-between;
}
.fe-dir-label {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
}
.fe-dir-del {
opacity: 0;
color: var(--text) !important;
padding: 2px 6px !important;
font-size: .8em;
transition: opacity .15s;
flex-shrink: 0;
}
.fe-dir:hover .fe-dir-del {
opacity: var(--semi-transparent);
}
.fe-dir-del:hover {
opacity: 1 !important;
color: var(--error) !important;
}
.fe-file {
color: var(--text);
}
.fe-loading, .fe-error, .fe-empty, .fe-placeholder {
padding: 1em;
text-align: center;
opacity: var(--semi-transparent);
align-self: center;
margin: auto;
}
.fe-image-preview {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
padding: 1em;
overflow: auto;
}
.fe-image-preview img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
border-radius: 4px;
}
/* ── CodeMirror / EasyMDE gemeinsame Wrapper-Basis ── */
.fe-cm-wrap,
.fe-mde-wrap {
display: flex;
flex: 1;
overflow: hidden;
height: 100%;
min-width: 0;
}
.fe-cm-wrap > div {
display: flex;
flex: 1;
/* kein overflow:hidden – CodeMirror positioniert sein internes textarea
mit negativem Offset; overflow:hidden würde es clippen → kein Input */
position: relative;
height: 100%;
min-width: 0;
}
.fe-mde-wrap .EasyMDEContainer {
display: flex;
flex: 1;
flex-direction: column;
overflow: hidden;
height: 100%;
}
.fe-cm-wrap .CodeMirror,
.fe-mde-wrap .CodeMirror,
.fe-mde-wrap .EasyMDEContainer .CodeMirror {
flex: 1;
height: 100% !important;
min-width: 0;
font-family: var(--mono) !important;
line-height: 1.5;
background: var(--f2-bg) !important;
color: var(--text) !important;
border: none !important;
border-radius: 0 !important;
padding: 0 !important;
}
/* CodeMirror-scroll: Default (overflow: scroll !important) reicht aus.
Horizontaler Scroll funktioniert über min-width: 0 auf den Flex-Eltern. */
.fe-cm-wrap .CodeMirror-gutters,
.fe-mde-wrap .CodeMirror-gutters {
background: var(--f1-bg) !important;
border-right: var(--border-width) solid var(--f1-border) !important;
}
.fe-cm-wrap .CodeMirror-linenumber,
.fe-mde-wrap .CodeMirror-linenumber {
color: var(--text) !important;
opacity: var(--semi-transparent);
}
.fe-cm-wrap .CodeMirror-cursor,
.fe-mde-wrap .CodeMirror-cursor {
border-left-color: var(--primary) !important;
}
.fe-cm-wrap .CodeMirror-selected,
.fe-mde-wrap .CodeMirror-selected {
background: rgba(180, 68, 17, 0.3) !important;
}
/* ── Syntax Highlighting (theme: default übersteuern) ── */
.fe-cm-wrap .cm-keyword,
.fe-mde-wrap .cm-keyword { color: #c678dd !important; }
.fe-cm-wrap .cm-def,
.fe-mde-wrap .cm-def { color: #61afef !important; }
.fe-cm-wrap .cm-variable,
.fe-mde-wrap .cm-variable { color: var(--text) !important; }
.fe-cm-wrap .cm-variable-2,
.fe-mde-wrap .cm-variable-2 { color: #e06c75 !important; }
.fe-cm-wrap .cm-variable-3,
.fe-mde-wrap .cm-variable-3 { color: #56b6c2 !important; }
.fe-cm-wrap .cm-property,
.fe-mde-wrap .cm-property { color: #e06c75 !important; }
.fe-cm-wrap .cm-operator,
.fe-mde-wrap .cm-operator { color: #56b6c2 !important; }
.fe-cm-wrap .cm-string,
.fe-mde-wrap .cm-string { color: #98c379 !important; }
.fe-cm-wrap .cm-string-2,
.fe-mde-wrap .cm-string-2 { color: #98c379 !important; }
.fe-cm-wrap .cm-number,
.fe-mde-wrap .cm-number { color: #d19a66 !important; }
.fe-cm-wrap .cm-atom,
.fe-mde-wrap .cm-atom { color: #d19a66 !important; }
.fe-cm-wrap .cm-comment,
.fe-mde-wrap .cm-comment { color: #5c6370 !important; font-style: italic; }
.fe-cm-wrap .cm-meta,
.fe-mde-wrap .cm-meta { color: #c678dd !important; }
.fe-cm-wrap .cm-qualifier,
.fe-mde-wrap .cm-qualifier { color: #e5c07b !important; }
.fe-cm-wrap .cm-builtin,
.fe-mde-wrap .cm-builtin { color: #e5c07b !important; }
.fe-cm-wrap .cm-tag,
.fe-mde-wrap .cm-tag { color: #e06c75 !important; }
.fe-cm-wrap .cm-attribute,
.fe-mde-wrap .cm-attribute { color: #d19a66 !important; }
.fe-cm-wrap .cm-type,
.fe-mde-wrap .cm-type { color: #56b6c2 !important; }
.fe-cm-wrap .cm-error,
.fe-mde-wrap .cm-error { color: #f44 !important; }
/* Markdown spezifisch (EasyMDE) */
.fe-mde-wrap .cm-header { color: #e5c07b !important; font-weight: bold; }
.fe-mde-wrap .cm-strong { color: var(--text-accent) !important; font-weight: bold; }
.fe-mde-wrap .cm-em { color: #c678dd !important; font-style: italic; }
.fe-mde-wrap .cm-link { color: #61afef !important; }
.fe-mde-wrap .cm-url { color: #98c379 !important; }
.fe-mde-wrap .cm-quote { color: #5c6370 !important; font-style: italic; }
/* EasyMDE Toolbar */
.fe-mde-wrap .editor-toolbar {
background: var(--f1-bg) !important;
border: none !important;
border-bottom: var(--border-width) solid var(--f1-border) !important;
padding: 4px !important;
opacity: 1 !important;
}
.fe-mde-wrap .editor-toolbar button {
color: var(--text) !important;
border: none !important;
border-radius: 3px !important;
opacity: var(--semi-transparent);
}
.fe-mde-wrap .editor-toolbar button:hover {
background: var(--f3-bg) !important;
opacity: 1;
}
.fe-mde-wrap .editor-toolbar button.active {
background: var(--f3-bg) !important;
opacity: 1;
}
.fe-mde-wrap .editor-toolbar i.separator {
border-left-color: var(--f1-border) !important;
border-right: none !important;
}
/* EasyMDE Statusbar ausblenden */
.fe-mde-wrap .editor-statusbar {
display: none !important;
}
/* EasyMDE Preview */
.fe-mde-wrap .editor-preview,
.fe-mde-wrap .editor-preview-side {
background: var(--f2-bg) !important;
color: var(--text) !important;
font-family: var(--font) !important;
}
.fe-mde-wrap .editor-preview-active-side {
border-left: var(--border-width) solid var(--f1-border);
}
/* Footer */
.fe-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: .5em .5em .5em 1em;
border-top: var(--border-width) solid var(--f1-border);
background: var(--f1-bg);
flex-shrink: 0;
gap: .5em;
}
.fe-info {
opacity: var(--semi-transparent);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
}
.fe-footer-actions {
display: flex;
gap: .5em;
flex-shrink: 0;
}
.fe-save-btn:not(:disabled) {
background: var(--primary);
color: #fff;
border-color: var(--primary);
}
.fe-save-btn:not(:disabled):hover {
opacity: var(--semi-transparent);
}