diff --git a/webui/assets/css/piler.css b/webui/assets/css/piler.css index 7903315c..df4bec28 100644 --- a/webui/assets/css/piler.css +++ b/webui/assets/css/piler.css @@ -1,351 +1,294 @@ -html,body{height:auto !important;height:100%;min-height:100%;} -body{margin:0;padding-top: 0px;font-family:"Segoe UI","Segoe WP","Helvetica Neue",sans-serif;font-size:14px;line-height:25px;color:#333333;background-color:#ffffff;} -body#loginpage{background-color:#fcfcfc;padding-top:40px;padding-bottom:40px;} - -#header { height: 45px; align-items: center; display: flex; justify-content: center; width: 100%; background-color:#fcfcfc; text-transform:lowercase; position: absolute;} -#menu { background: #2c5fc4; color: #fcfcfc; font-family:"Segoe UI","Segoe WP","Helvetica Neue",sans-serif;font-size:25px;font-weight:100; text-transform:lowercase; position: fixed; top: 0; z-index: 1000;} - -.dropdown-menu {font-family:"Segoe UI","Segoe WP","Helvetica Neue",sans-serif;font-size:25px;font-weight:100; text-transform:lowercase;} -.dropdown-menu li.dropdown-item:hover, a.dropdown-item:hover { background-color: #2c5fc4; color: #fcfcfc; text-decoration:none;} -a.dropdown-item {font-weight:100; text-decoration:none;} - -.menulink{text-shadow:0 0px 0 rgba(0, 0, 0, 0);padding-bottom:10px;margin-left:15px;padding-top:10px;color:#ffffff;font-size:24px;} -.menulink:hover{color:#ffffff;text-decoration:none;background: #555;} - - +/* ========================================================================== + Piler UI theme + -------------------------------------------------------------------------- + Colour tokens + -------------------------------------------------------------------------- + Brand values live in custom properties so light and dark share the rest of + the stylesheet. Dark mode is driven by Bootstrap 5.3's native + `data-bs-theme="dark"` attribute (set by assets/js/dark-mode.js); Bootstrap + themes its own components from the --bs-* variables, so we only override + brand surfaces and the handful of custom classes below. + ========================================================================== */ +:root { + color-scheme: light; + + /* brand */ + --piler-primary: #3557c8; + --piler-primary-hover: #2b46a5; + --piler-primary-contrast: #ffffff; + --piler-navbar-bg: #3557c8; + --piler-navbar-fg: #eef2ff; + + /* links */ + --piler-link: #2f5fd0; + --piler-link-hover: #24499f; + + /* surfaces */ + --piler-surface: #ffffff; + --piler-surface-muted: #f5f7fb; + --piler-border: #e3e8f0; + --piler-text: #22252b; + --piler-text-muted: #5b6472; + + /* shape + rhythm */ + --piler-radius: 0.5rem; + --piler-radius-sm: 0.375rem; +} + +[data-bs-theme="dark"] { + --bs-body-bg: #14161c; + --bs-body-color: #e6e8ee; + --bs-secondary-bg: #1f232b; + --bs-tertiary-bg: #262b35; + --bs-border-color: #333a46; + --bs-emphasis-color: #ffffff; + + --piler-primary: #6b8cff; + --piler-primary-hover: #8aa4ff; + --piler-primary-contrast: #10131a; + --piler-navbar-bg: #1e2434; + --piler-navbar-fg: #dbe2f0; + + --piler-link: #7fa3ff; + --piler-link-hover: #a3bcff; + + --piler-surface: #1a1e26; + --piler-surface-muted: #1f232b; + --piler-border: #333a46; + --piler-text: #e6e8ee; + --piler-text-muted: #9aa4b5; +} -.container-panes { height: calc(95vh - 90px); /* Height of the screen minus the navbar */ display: flex; flex-direction: column; } -.pane { overflow-y: auto; flex-grow: 1; min-height: 300px; position: relative; } -.resizer { height: 5px; background: #333; cursor: row-resize; } -.pane-upper-content { height: calc(100% - 40px); /* 40px is the height of the fixed bottom row in the upper pane */ overflow-y: auto; border: 1px solid #ccc;} -.pane-upper-fixed { height: 40px; background: #f1f1f1; position: absolute; bottom: 0; width: 100%; border-top: 1px solid #ddd; } -#preview {height: 500px; border: 1px solid #ccc;} +html,body{height:auto !important;height:100%;min-height:100%;} +body{margin:0;padding-top:0;font-family:"Segoe UI","Segoe WP","Helvetica Neue",sans-serif;font-size:14px;line-height:1.55;color:var(--bs-body-color);background-color:var(--bs-body-bg);} +body#loginpage{background-color:var(--piler-surface-muted);padding-top:40px;padding-bottom:40px;} + +/* -------------------------------------------------------------------------- + Top navigation + -------------------------------------------------------------------------- */ +#header { height: 45px; align-items: center; display: flex; justify-content: center; width: 100%; background-color:var(--piler-surface); position: absolute;} +#menu { + background: var(--piler-navbar-bg); + color: var(--piler-navbar-fg); + font-family: inherit; + font-size: 15px; + font-weight: 400; + letter-spacing: .01em; + text-transform: lowercase; + position: fixed; + top: 0; + z-index: 1000; + min-height: 60px; + align-items: center; + border-bottom: 1px solid var(--piler-border); + box-shadow: 0 1px 2px rgba(15,23,42,.06); +} +#menu .menulink, +#menu .dropdown-toggle { + display: inline-flex; + align-items: center; + gap: .4rem; + padding: .5rem .9rem; + margin: 0 .1rem; + border-radius: var(--piler-radius-sm); + color: var(--piler-navbar-fg); + font-size: 15px; + font-weight: 400; + line-height: 1.4; + text-decoration: none; + transition: background-color .12s ease, color .12s ease; +} +#menu .menulink:hover, +#menu .menulink:focus-visible, +#menu .dropdown-toggle:hover, +#menu .dropdown-toggle:focus-visible { + background-color: rgba(255,255,255,.18); + color: #fff; + text-decoration: none; +} +#menu .menulink i { font-size: 1.05em; } + +/* Dropdown menus (both nav dropdowns and the search Options menu) */ +.dropdown-menu { + font-family: inherit; + font-size: 14px; + font-weight: 400; + text-transform: none; + padding: .35rem; + border: 1px solid var(--piler-border); + border-radius: var(--piler-radius-sm); + box-shadow: 0 8px 24px rgba(15,23,42,.14); +} +.dropdown-menu .dropdown-item, +a.dropdown-item { + border-radius: var(--piler-radius-sm); + padding: .45rem .65rem; + color: var(--bs-body-color); + font-weight: 400; + text-decoration: none; +} +.dropdown-menu .dropdown-item:hover, +.dropdown-menu .dropdown-item:focus, +a.dropdown-item:hover, +a.dropdown-item:focus { + background-color: var(--piler-primary); + color: var(--piler-primary-contrast); +} + +/* -------------------------------------------------------------------------- + Type + -------------------------------------------------------------------------- */ +h1,h2,h3,h4 {font-family:inherit;font-weight:600;text-transform:lowercase;letter-spacing:-.01em;color:var(--bs-body-color);} +h1 { font-size: 1.6rem; } +h2 { font-size: 1.35rem; } +h3 { font-size: 1.1rem; } +h4 { font-size: 1rem; } +h2 i {font-size:1.1em;} +small, .small { font-size: .85em; } +.text-muted, .muted { color: var(--piler-text-muted) !important; } + +a{color:var(--piler-link);text-decoration:none;} +a:hover{color:var(--piler-link-hover);text-decoration:underline;} +a.xxx{color:var(--piler-text-muted);text-decoration:underline;} +a.xxx:hover{color:var(--piler-text-muted);text-decoration:underline;} + +/* -------------------------------------------------------------------------- + Layout + -------------------------------------------------------------------------- */ +.container-panes { height: calc(95vh - 90px); display: flex; flex-direction: column; } +.pane { overflow-y: auto; flex: 1 1 0; min-height: 120px; position: relative; } +.resizer { height: 8px; background: var(--piler-border); cursor: row-resize; margin: .5rem 0; border-radius: 4px; flex: 0 0 auto; } +.pane-upper-content { height: calc(100% - 40px); overflow-y: auto; border: 1px solid var(--piler-border); border-radius: var(--piler-radius); } +#preview {height: 500px; border: 1px solid var(--piler-border); border-radius: var(--piler-radius);} .no-select { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } - .resizer-search-results { display: inline-block; width: 5px; height: 100%; position: absolute; right: 0; top: 0; cursor: col-resize; } -h1,h2,h3,h4 {font-family:"Segoe UI","Segoe WP","Helvetica Neue",sans-serif;font-weight:100;text-transform:lowercase;} -h2 i{font-size:60px;} - -.btn {border-radius:0;} +.btn {border-radius: var(--piler-radius-sm);} +.searchbuttons { gap: .5rem; } +.searchbuttons .btn { width: auto; flex: 1 1 0; } +.searchbuttons .btn-options { flex: 0 0 auto; } .btn-search {width: 33%;} .btn-options {width: 34%;} -.searchcontainer{padding-top: 65px; margin-left: 12px; margin-right: 12px;} +.searchcontainer{padding-top: 72px; margin-left: 12px; margin-right: 12px;} -input[type=text]{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +input[type=text]{-webkit-border-radius:var(--piler-radius-sm);-moz-border-radius:var(--piler-radius-sm);border-radius:var(--piler-radius-sm);} +.tagtext { width: 9rem; } #pagingrow{overflow:hidden;} -.functionbox{border-left:1px solid #ccc;height:30px;overflow:hidden;} +.functionbox{border-left:1px solid var(--piler-border);min-height:38px;} +#messagelistfooter .functionbox.justify-content-end{flex-wrap:nowrap;} +#messagelistfooter .functionbox.justify-content-end span{white-space:nowrap;} -.messageheader{background-color:#f6f6f6;padding:8px;border-bottom:1px solid #ccc;} -.messagecontents{background-color:#fff;padding:8px;} +.messageheader{background-color:var(--piler-surface-muted);padding:8px;border-bottom:1px solid var(--piler-border);} +.messagecontents{background-color:var(--piler-surface);padding:8px;} .resultrow{font-style:italic;cursor:pointer;} .resultrow.new{font-style:normal;} - -a{color:#2e8bcc;text-decoration:none;} -a:hover{color:#20608e;text-decoration:underline;} -a.xxx{color:#aaa;text-decoration:underline;} -a.xxx:hover{color:#aaa;text-decoration:underline;} +.resultrow:hover { background-color: var(--piler-surface-muted); } #logo-lg{width:300px;margin:0 auto 20px;} #logincontainer{text-transform:lowercase;} .compatibility {max-width: 300px;} -.form-signin{max-width:300px;padding:19px 29px 29px;margin:0 auto 20px;background-color:#fff;border:1px solid #e5e5e5;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);} -#compatibility{max-width:300px;margin:0 auto;color:#444;text-align:justify;} +.form-signin{max-width:320px;padding:24px 28px;margin:0 auto 20px;background-color:var(--piler-surface);border:1px solid var(--piler-border);border-radius:var(--piler-radius);box-shadow:0 1px 2px rgba(15,23,42,.06);} +#compatibility{max-width:320px;margin:0 auto;color:var(--piler-text-muted);text-align:justify;} .ps10 { padding-left: 10px; } .pe10 { padding-right: 10px; } -i.spam{color:#ffc40d;} -i.attachment{color:#2e8bcc;} -i.note{color:#00aba9;} -i.tag{color:#7b4f9d;} -i.verified{color:#339933;} -.private{color:red;} +i.spam{color:#e8a33d;} +i.attachment{color:var(--piler-link);} +i.note{color:#12a5a1;} +i.tag{color:#8b5cf6;} +i.verified{color:#2f9e44;} +.private{color:#e5484d;} -.xxx{color:#aaa;} +.xxx{color:var(--piler-text-muted);} .myspinner {width: 5rem; height: 5rem;} .middleofscreen {position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);} .hidden {visibility: hidden;} table { width: 100%; border-collapse: collapse; } -th { padding: 10px; border: 1px solid #ccc; position: relative; } +th { padding: 10px; border: 1px solid var(--piler-border); position: relative; } th.centered, td.centered { text-align: center; } th.auto-width, td.auto-width { width: 1%; white-space: nowrap; } -.tsa {border-top: 1px solid #ccc; border-bottom: 1px solid #ccc;} - -.branding_logo {max-height:25px;} - -/* Highlighted row (selected message) */ -.highlighted { - background-color: #d1ecf1 !important; -} - -.highlighted td { - background-color: #d1ecf1 !important; -} - -/* Dark mode styles */ -[data-theme="dark"] { - --bs-body-bg: #1a1a1a; - --bs-body-color: #e0e0e0; - --bs-border-color: #404040; -} - -[data-theme="dark"] body { - background-color: #1a1a1a; - color: #e0e0e0; -} - -[data-theme="dark"] body#loginpage { - background-color: #1a1a1a; -} - -[data-theme="dark"] #header { - background-color: #1a1a1a; -} - -[data-theme="dark"] #menu { - background: #1e3a8a; - color: #e0e0e0; -} - -[data-theme="dark"] .dropdown-menu { - background-color: #2a2a2a; - border-color: #404040; -} - -[data-theme="dark"] .dropdown-menu li.dropdown-item:hover, -[data-theme="dark"] a.dropdown-item:hover { - background-color: #1e3a8a; - color: #e0e0e0; -} - -[data-theme="dark"] a.dropdown-item { - color: #e0e0e0; -} - -[data-theme="dark"] .menulink { - color: #e0e0e0; -} +.tsa {border-top: 1px solid var(--piler-border); border-bottom: 1px solid var(--piler-border);} -[data-theme="dark"] .menulink:hover { - color: #e0e0e0; - background: #404040; -} +.branding_logo {max-height:24px;} -[data-theme="dark"] .pane { - background-color: #1a1a1a; -} +.health-refresh { height: 40px; background: #eef2ff; color: #2b46a5; } -[data-theme="dark"] .resizer { - background: #404040; -} - -[data-theme="dark"] .pane-upper-content { - border-color: #404040; - background-color: #1a1a1a; -} - -[data-theme="dark"] .pane-upper-fixed { - background: #2a2a2a; - border-top-color: #404040; -} - -[data-theme="dark"] #preview { - border-color: #404040; - background-color: #1a1a1a; -} - -[data-theme="dark"] .functionbox { - border-left-color: #404040; -} - -[data-theme="dark"] .messageheader { - background-color: #2a2a2a; - border-bottom-color: #404040; -} - -[data-theme="dark"] .messagecontents { - background-color: #1a1a1a; -} - -[data-theme="dark"] .form-signin { - background-color: #2a2a2a; - border-color: #404040; -} - -[data-theme="dark"] a { - color: #5fa3d8; -} - -[data-theme="dark"] a:hover { - color: #4a8fc2; -} - -[data-theme="dark"] .btn-primary { - background-color: #1e3a8a; - border-color: #1e3a8a; -} - -[data-theme="dark"] .btn-primary:hover { - background-color: #2563eb; - border-color: #2563eb; -} - -[data-theme="dark"] .form-control { - background-color: #2a2a2a; - border-color: #404040; - color: #e0e0e0; -} - -[data-theme="dark"] .form-control:focus { - background-color: #2a2a2a; - border-color: #5fa3d8; - color: #e0e0e0; -} - -[data-theme="dark"] input[type="text"], -[data-theme="dark"] input[type="email"], -[data-theme="dark"] input[type="password"], -[data-theme="dark"] textarea, -[data-theme="dark"] select { - background-color: #2a2a2a; - border-color: #404040; - color: #e0e0e0; -} - -[data-theme="dark"] input[type="text"]:focus, -[data-theme="dark"] input[type="email"]:focus, -[data-theme="dark"] input[type="password"]:focus, -[data-theme="dark"] textarea:focus, -[data-theme="dark"] select:focus { - background-color: #2a2a2a; - border-color: #5fa3d8; - color: #e0e0e0; -} - -[data-theme="dark"] .tagtext { - background-color: #2a2a2a; - border-color: #404040; - color: #e0e0e0; -} - -[data-theme="dark"] table th, -[data-theme="dark"] table td { - border-color: #404040; -} - -[data-theme="dark"] .tsa { - border-top-color: #404040; - border-bottom-color: #404040; -} - -[data-theme="dark"] .alert { - background-color: #2a2a2a; - border-color: #404040; - color: #e0e0e0; -} - -[data-theme="dark"] .modal-content { - background-color: #2a2a2a; - border-color: #404040; -} - -[data-theme="dark"] .modal-header, -[data-theme="dark"] .modal-footer { - border-color: #404040; -} - -[data-theme="dark"] .toast { - background-color: #2a2a2a; - border-color: #404040; -} - -[data-theme="dark"] .toast-header { - background-color: #333333; - border-bottom-color: #404040; - color: #e0e0e0; -} - -[data-theme="dark"] .toast-body { - color: #e0e0e0; -} - -[data-theme="dark"] .text-body-secondary { - color: #a0a0a0 !important; -} - -[data-theme="dark"] .text-bg-light { - background-color: #2a2a2a !important; - color: #e0e0e0 !important; -} - -[data-theme="dark"] .resultrow { - color: #c0c0c0; -} - -[data-theme="dark"] .resultrow.new { - color: #e0e0e0; -} - -[data-theme="dark"] .resultrow td { - color: #c0c0c0; -} - -[data-theme="dark"] .resultrow.new td { - color: #e0e0e0; -} - -[data-theme="dark"] .table-striped > tbody > tr:nth-of-type(odd) { - background-color: rgba(255, 255, 255, 0.02); -} - -[data-theme="dark"] .table-striped > tbody > tr:nth-of-type(even) { - background-color: rgba(0, 0, 0, 0.15); -} - -[data-theme="dark"] .table-secondary { - background-color: #2a2a2a !important; - border-color: #404040; -} - -[data-theme="dark"] .table { - color: #e0e0e0; - border-color: #404040; -} - -[data-theme="dark"] .table td, -[data-theme="dark"] .table th { - color: #e0e0e0; -} - -[data-theme="dark"] .form-label { - color: #e0e0e0; -} - -[data-theme="dark"] .highlighted { - background-color: #2c5282 !important; -} - -[data-theme="dark"] .highlighted td { - background-color: #2c5282 !important; - color: #e0e0e0 !important; -} +/* Highlighted row (selected message) */ +.highlighted { background-color: rgba(53,87,200,.14) !important; } +.highlighted td { background-color: rgba(53,87,200,.14) !important; } + +/* Dark mode: surfaces and custom classes Bootstrap knows nothing about. */ +[data-bs-theme="dark"] body#loginpage { background-color: var(--bs-body-bg); } +[data-bs-theme="dark"] #header { background-color: var(--piler-surface-muted); } +[data-bs-theme="dark"] .health-refresh { background: #1d2436; color: #a9bcff; } +[data-bs-theme="dark"] #menu { border-bottom-color: rgba(255,255,255,.09); } + +/* Bootstrap does not darken the .table-secondary contextual variant, which + leaves the search/audit/accounting headers light-on-light in dark mode. + Theme the variant's cells directly. */ +[data-bs-theme="dark"] .table-secondary th, +[data-bs-theme="dark"] .table-secondary td { + color: var(--bs-body-color); + background-color: var(--bs-tertiary-bg); + border-color: var(--bs-border-color); +} + +/* Bootstrap does not provide dark alert variants; map each onto its dark + subtle palette so alerts stop flashing light strips on dark pages. */ +[data-bs-theme="dark"] .alert { + --bs-alert-bg: var(--bs-secondary-bg); + --bs-alert-color: var(--bs-body-color); + --bs-alert-border-color: var(--bs-border-color); +} +[data-bs-theme="dark"] .alert-info { + --bs-alert-bg: var(--bs-info-bg-subtle); + --bs-alert-color: var(--bs-info-text-emphasis); + --bs-alert-border-color: var(--bs-info-border-subtle); +} +[data-bs-theme="dark"] .alert-success { + --bs-alert-bg: var(--bs-success-bg-subtle); + --bs-alert-color: var(--bs-success-text-emphasis); + --bs-alert-border-color: var(--bs-success-border-subtle); +} +[data-bs-theme="dark"] .alert-danger, +[data-bs-theme="dark"] .alert-error { + --bs-alert-bg: var(--bs-danger-bg-subtle); + --bs-alert-color: var(--bs-danger-text-emphasis); + --bs-alert-border-color: var(--bs-danger-border-subtle); +} + +[data-bs-theme="dark"] .text-bg-light { background-color: var(--bs-secondary-bg) !important; color: var(--bs-body-color) !important; } +[data-bs-theme="dark"] .pane-upper-content, [data-bs-theme="dark"] #preview { border-color: var(--piler-border); } +[data-bs-theme="dark"] .form-signin { background-color: var(--piler-surface); border-color: var(--piler-border); } +[data-bs-theme="dark"] .highlighted { background-color: rgba(107,140,255,.22) !important; } +[data-bs-theme="dark"] .highlighted td { background-color: rgba(107,140,255,.22) !important; color: var(--bs-body-color) !important; } /* Dark mode toggle button */ #theme-toggle { cursor: pointer; - padding: 10px; - margin-left: 10px; background: transparent; border: none; color: inherit; - font-size: 20px; + font-size: 1.05rem; +} + +/* Small screens: let wide data tables scroll inside their container instead of + stretching the page. This is the documented Bootstrap behaviour, applied + globally so no table has to opt in. */ +@media (max-width: 767.98px) { + table { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } } diff --git a/webui/assets/js/dark-mode.js b/webui/assets/js/dark-mode.js index 6868fa84..0c15c860 100644 --- a/webui/assets/js/dark-mode.js +++ b/webui/assets/js/dark-mode.js @@ -31,10 +31,12 @@ * Apply theme to document */ function applyTheme(theme) { + // Bootstrap 5.3 native colour mode. Bootstrap themes every component from + // this attribute, so piler.css only needs the brand-specific overrides. if (theme === THEME_DARK) { - document.documentElement.setAttribute('data-theme', 'dark'); + document.documentElement.setAttribute('data-bs-theme', 'dark'); } else { - document.documentElement.removeAttribute('data-theme'); + document.documentElement.removeAttribute('data-bs-theme'); } // Update icon diff --git a/webui/assets/js/resizer.js b/webui/assets/js/resizer.js index f40edbd8..0c43a80d 100644 --- a/webui/assets/js/resizer.js +++ b/webui/assets/js/resizer.js @@ -1,23 +1,52 @@ -const resizer = document.querySelector('.resizer'); -const upperPane = document.querySelector('.pane-upper'); -const lowerPane = document.querySelector('.pane-lower'); -const containerPanes = document.querySelector('.container-panes'); - -let isResizing = false; - -resizer.addEventListener('mousedown', (e) => { - isResizing = true; - document.body.classList.add('no-select'); -}); - -document.addEventListener('mousemove', (e) => { - if (!isResizing) return; - let offsetY = e.clientY - containerPanes.getBoundingClientRect().top; - upperPane.style.height = `${offsetY}px`; - lowerPane.style.height = `calc(100% - ${offsetY + resizer.offsetHeight}px)`; -}); - -document.addEventListener('mouseup', () => { - isResizing = false; - document.body.classList.remove('no-select'); -}); +/* Drag handle between the result list and the preview pane. + The panes live in a column flex container; once the user drags we take them + out of the flex-grow distribution (flex: 0 0 auto) and give each an explicit + height, otherwise the flex algorithm recalculates the inline height away and + the drag has no visible effect. */ +(function () { + const resizer = document.querySelector('.resizer'); + const upperPane = document.querySelector('.pane-upper'); + const lowerPane = document.querySelector('.pane-lower'); + const containerPanes = document.querySelector('.container-panes'); + + if (!resizer || !upperPane || !lowerPane || !containerPanes) return; + + const MIN_PANE = 120; + let isResizing = false; + + resizer.addEventListener('mousedown', (e) => { + isResizing = true; + document.body.classList.add('no-select'); + e.preventDefault(); + }); + + document.addEventListener('mousemove', (e) => { + if (!isResizing) return; + + const containerRect = containerPanes.getBoundingClientRect(); + const resizerRect = resizer.getBoundingClientRect(); + + // The handle has vertical margins too; count them so the explicit pane + // heights sum to exactly the container height. + const cs = getComputedStyle(resizer); + const marginTop = parseFloat(cs.marginTop) || 0; + const marginBottom = parseFloat(cs.marginBottom) || 0; + const resizerTotal = resizerRect.height + marginTop + marginBottom; + + let upperHeight = e.clientY - containerRect.top - marginTop; + const maxUpper = containerRect.height - resizerTotal - MIN_PANE; + + upperHeight = Math.max(MIN_PANE, Math.min(upperHeight, maxUpper)); + const lowerHeight = containerRect.height - upperHeight - resizerTotal; + + upperPane.style.flex = '0 0 auto'; + lowerPane.style.flex = '0 0 auto'; + upperPane.style.height = upperHeight + 'px'; + lowerPane.style.height = lowerHeight + 'px'; + }); + + document.addEventListener('mouseup', () => { + isResizing = false; + document.body.classList.remove('no-select'); + }); +})(); diff --git a/webui/templates/common/layout-search.tpl b/webui/templates/common/layout-search.tpl index e4c9fae9..9a527d7f 100644 --- a/webui/templates/common/layout-search.tpl +++ b/webui/templates/common/layout-search.tpl @@ -40,12 +40,12 @@ - +
-
- +
+ diff --git a/webui/templates/common/layout.tpl b/webui/templates/common/layout.tpl index d330be5c..d58fad93 100644 --- a/webui/templates/common/layout.tpl +++ b/webui/templates/common/layout.tpl @@ -21,9 +21,7 @@ - +
diff --git a/webui/templates/common/menu.tpl b/webui/templates/common/menu.tpl index 145dc280..c1bcb258 100644 --- a/webui/templates/common/menu.tpl +++ b/webui/templates/common/menu.tpl @@ -4,8 +4,8 @@
diff --git a/webui/templates/health/worker.tpl b/webui/templates/health/worker.tpl index de234284..f415d097 100644 --- a/webui/templates/health/worker.tpl +++ b/webui/templates/health/worker.tpl @@ -1,6 +1,6 @@
-
+
:  sec
diff --git a/webui/templates/login/login.tpl b/webui/templates/login/login.tpl index 5bce06dc..adb9a30a 100644 --- a/webui/templates/login/login.tpl +++ b/webui/templates/login/login.tpl @@ -35,12 +35,12 @@ " />
- - + +
- - + +
0 && $failed_login_count > CAPTCHA_FAILED_LOGIN_COUNT) { ?> diff --git a/webui/templates/search/helper.tpl b/webui/templates/search/helper.tpl index 22d54f8a..9034303e 100644 --- a/webui/templates/search/helper.tpl +++ b/webui/templates/search/helper.tpl @@ -131,7 +131,7 @@ - +