New theme for web UI (#957)
* Docker environment fixes * New theme for web UI * Apply breaking wrap to filenames only * Reduce font sizes, whitespace and padding * Right align action fields/buttons * Improve mobile header, hide superfluous UI elements when logged out, drop placeholders from login labels, various other adjustments * Force footer to bottom of screen * Show manual link to logged out users * Reduce header text size on desktop * Fix incorrect selector ID * Fix selector referencing old class name * Fix right-aligned message when images table empty * Add CSS linter/auto-formatter * Run Stylelint + Prettier against modern theme CSS * Select default theme based on browser’s user agent * Style inputs on mobile/tablet devices * Fixes for Safari 14 on iOS + iPad OS * Explicitly define mobile browser support, switch to bare ua-parser without user-agent wrapper * Add LICENSE file for modern theme icons * Improve theme selection query string/field naming. * Remove patch workaround from Docker build * Update log level for UAs to info * Move Bootstrap Reboot CSS to CDN * Account for LUN column in attached devices table * Prevent wrapping of config forms on small viewports * Fix Stylelint issues * Auto-format CSS with Prettier
@ -7,11 +7,10 @@
|
||||
!/docker/rascsi-web/start.sh
|
||||
!/doc
|
||||
!/python
|
||||
!/src
|
||||
!/cpp
|
||||
!/test
|
||||
!/easyinstall.sh
|
||||
!/LICENCE
|
||||
!/lido-driver.img
|
||||
!/README.md
|
||||
|
||||
# From .gitignore
|
||||
|
1
.gitignore
vendored
@ -11,6 +11,7 @@ rascsi_interface_pb2.py
|
||||
messages.pot
|
||||
messages.mo
|
||||
report.xml
|
||||
node_modules
|
||||
|
||||
# Intermediate files from astyle
|
||||
*.orig
|
||||
|
@ -6,19 +6,27 @@ FROM "${OS_ARCH}/${OS_DISTRO}:${OS_VERSION}"
|
||||
EXPOSE 80 443
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends sudo systemd rsyslog procps man-db man2html
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
sudo \
|
||||
systemd \
|
||||
rsyslog \
|
||||
procps \
|
||||
man-db \
|
||||
wget \
|
||||
git
|
||||
|
||||
RUN groupadd pi
|
||||
RUN useradd --create-home --shell /bin/bash -g pi pi
|
||||
RUN echo "pi ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
RUN echo "pi:rascsi" | chpasswd
|
||||
|
||||
RUN mkdir /home/pi/afpshare
|
||||
RUN mkdir /home/pi/shared_files
|
||||
RUN touch /etc/dhcpcd.conf
|
||||
RUN mkdir -p /etc/network/interfaces.d/
|
||||
|
||||
WORKDIR /home/pi/RASCSI
|
||||
USER pi
|
||||
WORKDIR /home/pi/RASCSI
|
||||
COPY --chown=pi:pi . .
|
||||
|
||||
# Install standalone RaSCSI web UI
|
||||
|
@ -6,20 +6,16 @@ FROM "${OS_ARCH}/${OS_DISTRO}:${OS_VERSION}"
|
||||
EXPOSE 6868
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends sudo systemd rsyslog patch
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends sudo systemd rsyslog patch wget
|
||||
|
||||
RUN groupadd pi
|
||||
RUN useradd --create-home --shell /bin/bash -g pi pi
|
||||
RUN echo "pi ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||
|
||||
WORKDIR /home/pi/RASCSI
|
||||
USER pi
|
||||
WORKDIR /home/pi/RASCSI
|
||||
COPY --chown=pi:pi . .
|
||||
|
||||
# Workaround for Bullseye amd64 compilation error
|
||||
# https://github.com/akuker/RASCSI/issues/821
|
||||
RUN patch -p0 < docker/rascsi/cfilesystem.patch
|
||||
|
||||
# Install RaSCSI standalone
|
||||
RUN ./easyinstall.sh --run_choice=10 --cores=`nproc`
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
--- src/raspberrypi/devices/cfilesystem.cpp 2022-09-08 12:07:14.000000000 +0100
|
||||
+++ src/raspberrypi/devices/cfilesystem.cpp.patched 2022-09-08 12:12:55.000000000 +0100
|
||||
@@ -1075,12 +1075,15 @@
|
||||
m_dirHuman.name[i] = ' ';
|
||||
}
|
||||
|
||||
- for (i = 0; i < 10; i++) {
|
||||
- if (p < m_pszHumanExt)
|
||||
- m_dirHuman.add[i] = *p++;
|
||||
- else
|
||||
- m_dirHuman.add[i] = '\0';
|
||||
- }
|
||||
+ // This code causes a compilation error on Debian "bullseye" (amd64)
|
||||
+ // https://github.com/akuker/RASCSI/issues/821
|
||||
+ //
|
||||
+ // for (i = 0; i < 10; i++) {
|
||||
+ // if (p < m_pszHumanExt)
|
||||
+ // m_dirHuman.add[i] = *p++;
|
||||
+ // else
|
||||
+ // m_dirHuman.add[i] = '\0';
|
||||
+ // }
|
||||
|
||||
if (*p == '.')
|
||||
p++;
|
3
python/web/.prettierrc.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"printWidth": 100
|
||||
}
|
6
python/web/.stylelintrc.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": ["stylelint-config-standard", "stylelint-config-prettier"],
|
||||
"rules": {
|
||||
"no-descending-specificity": null
|
||||
}
|
||||
}
|
3343
python/web/package-lock.json
generated
Normal file
8
python/web/package.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"devDependencies": {
|
||||
"prettier": "2.7.1",
|
||||
"stylelint": "^14.14.1",
|
||||
"stylelint-config-prettier": "^9.0.3",
|
||||
"stylelint-config-standard": "^29.0.0"
|
||||
}
|
||||
}
|
@ -5,3 +5,4 @@ protobuf==3.20.2
|
||||
requests==2.28.1
|
||||
simplepam==0.1.5
|
||||
flask_babel==2.0.0
|
||||
ua-parser==0.16.1
|
@ -22,3 +22,12 @@ AUTH_GROUP = "rascsi"
|
||||
|
||||
# The language locales supported by RaSCSI
|
||||
LANGUAGES = ["en", "de", "sv", "fr", "es"]
|
||||
|
||||
# Available themes
|
||||
TEMPLATE_THEMES = ["classic", "modern"]
|
||||
|
||||
# Default theme for modern browsers
|
||||
TEMPLATE_THEME_DEFAULT = "modern"
|
||||
|
||||
# Fallback theme for older browsers
|
||||
TEMPLATE_THEME_LEGACY = "classic"
|
BIN
python/web/src/static/logo.png
Normal file
After Width: | Height: | Size: 59 KiB |
@ -47,11 +47,15 @@ div.footer {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
div.logged_in {
|
||||
div.footer div.theme-change-hint {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
div.logged-in {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
div.logged_out {
|
||||
div.logged-out {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
@ -66,9 +70,12 @@ div.flash {
|
||||
|
||||
div.flash div {
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
white-space: pre-line;
|
||||
padding: 2px 5px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
div.flash div div {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
div.flash div.success {
|
26
python/web/src/static/themes/modern/icons/LICENSE
Normal file
@ -0,0 +1,26 @@
|
||||
Feather Icons
|
||||
https://github.com/feathericons/feather
|
||||
|
||||
---
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2017 Cole Bemis
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-hard-drive"><line x1="22" y1="12" x2="2" y2="12"></line><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path><line x1="6" y1="16" x2="6.01" y2="16"></line><line x1="10" y1="16" x2="10.01" y2="16"></line></svg>
|
After Width: | Height: | Size: 484 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-globe"><circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path></svg>
|
After Width: | Height: | Size: 409 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-disc"><circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="3"></circle></svg>
|
After Width: | Height: | Size: 295 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-server"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6.01" y2="6"></line><line x1="6" y1="18" x2="6.01" y2="18"></line></svg>
|
After Width: | Height: | Size: 431 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-printer"><polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect></svg>
|
After Width: | Height: | Size: 407 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-save"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path><polyline points="17 21 17 13 7 13 7 21"></polyline><polyline points="7 3 7 8 15 8"></polyline></svg>
|
After Width: | Height: | Size: 392 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-slash"><circle cx="12" cy="12" r="10"></circle><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"></line></svg>
|
After Width: | Height: | Size: 312 B |
1
python/web/src/static/themes/modern/icons/error.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-alert-octagon"><polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>
|
After Width: | Height: | Size: 409 B |
1
python/web/src/static/themes/modern/icons/file-copy.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-copy"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
|
After Width: | Height: | Size: 351 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-trash"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg>
|
After Width: | Height: | Size: 356 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-link"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>
|
After Width: | Height: | Size: 371 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-zap"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon></svg>
|
After Width: | Height: | Size: 282 B |
1
python/web/src/static/themes/modern/icons/file-info.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-search"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>
|
After Width: | Height: | Size: 308 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-edit"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
|
After Width: | Height: | Size: 365 B |
1
python/web/src/static/themes/modern/icons/info.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-info"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>
|
After Width: | Height: | Size: 347 B |
1
python/web/src/static/themes/modern/icons/log-out.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-log-out"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
|
After Width: | Height: | Size: 360 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-book"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg>
|
After Width: | Height: | Size: 345 B |
1
python/web/src/static/themes/modern/icons/manual.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-book"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg>
|
After Width: | Height: | Size: 345 B |
1
python/web/src/static/themes/modern/icons/success.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check"><polyline points="20 6 9 17 4 12"></polyline></svg>
|
After Width: | Height: | Size: 255 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="red" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x-circle"><circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>
|
After Width: | Height: | Size: 337 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-up-circle"><circle cx="12" cy="12" r="10"></circle><polyline points="16 12 12 8 8 12"></polyline><line x1="12" y1="16" x2="12" y2="8"></line></svg>
|
After Width: | Height: | Size: 357 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-pause-circle"><circle cx="12" cy="12" r="10"></circle><line x1="10" y1="15" x2="10" y2="9"></line><line x1="14" y1="15" x2="14" y2="9"></line></svg>
|
After Width: | Height: | Size: 352 B |
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="green" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-check-circle"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>
|
After Width: | Height: | Size: 321 B |
1
python/web/src/static/themes/modern/icons/warning.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-alert-triangle"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
|
After Width: | Height: | Size: 424 B |
890
python/web/src/static/themes/modern/style.css
Normal file
@ -0,0 +1,890 @@
|
||||
@import url("//cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.2/css/bootstrap-reboot.min.css");
|
||||
|
||||
:root {
|
||||
--success: var(--bs-success);
|
||||
--danger: var(--bs-danger);
|
||||
--info: #80eaff;
|
||||
--warning: var(--bs-warning);
|
||||
--dark: var(--bs-dark);
|
||||
--light: var(--bs-light);
|
||||
--primary: var(--bs-primary);
|
||||
--secondary: var(--bs-secondary);
|
||||
--text-color: var(--bs-body-color);
|
||||
--border-radius: 0.2rem;
|
||||
--input-padding: 0.25rem 0.5rem;
|
||||
--font-size: 0.85rem;
|
||||
--icon-size: 1.2rem;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
General layout
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: var(--font-size);
|
||||
}
|
||||
|
||||
div.content {
|
||||
flex-grow: 1;
|
||||
padding: 1rem;
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
hr {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Tables
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
table {
|
||||
width: 100%;
|
||||
border: 1px solid var(--dark);
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table th,
|
||||
table td {
|
||||
padding: 0.5rem;
|
||||
text-align: left;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
table th {
|
||||
background: var(--dark);
|
||||
border: 1px solid var(--dark);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
table td {
|
||||
border: 1px solid #ccc;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Forms
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
form {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
button,
|
||||
label {
|
||||
margin: 0.15rem 0;
|
||||
}
|
||||
|
||||
input,
|
||||
select,
|
||||
button {
|
||||
border-radius: var(--border-radius);
|
||||
border: 1px solid #ccc;
|
||||
font-size: var(--font-size);
|
||||
font-weight: 400;
|
||||
line-height: 1.25;
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
input[type="submit"],
|
||||
button {
|
||||
padding: var(--input-padding);
|
||||
background-color: #efefef;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="number"],
|
||||
input[type="url"],
|
||||
input[type="password"] {
|
||||
display: inline-block;
|
||||
padding: var(--input-padding);
|
||||
background-color: #fff;
|
||||
background-clip: padding-box;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
select {
|
||||
display: inline-block;
|
||||
padding: 0.275rem 2.25rem 0.275em 0.75rem;
|
||||
-moz-padding-start: calc(0.75rem - 3px);
|
||||
background-color: #fff;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right 0.75rem center;
|
||||
background-size: 16px 12px;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Dropzone
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
.dropzone {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.dropzone p,
|
||||
.dropzone .dz-default {
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
|
||||
.dropzone .dz-button {
|
||||
width: 100%;
|
||||
padding: 2rem 4rem;
|
||||
border: 2px dashed darkcyan;
|
||||
background: lightcyan;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-image,
|
||||
.dropzone .dz-preview .dz-success-mark,
|
||||
.dropzone .dz-preview .dz-error-mark {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview {
|
||||
display: inline-block;
|
||||
background: var(--light) url("icons/upload-queued.svg") no-repeat 1rem center;
|
||||
padding: 1rem 1rem 1rem 3.5rem;
|
||||
margin: 1rem 1rem 0 0;
|
||||
border-radius: var(--border-radius);
|
||||
}
|
||||
|
||||
.dropzone .dz-preview.dz-processing {
|
||||
background: #ededbe url("icons/upload-in-progress.svg") no-repeat 1rem center;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview.dz-success {
|
||||
background: #e0f5df url("icons/upload-success.svg") no-repeat 1rem center;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview.dz-error {
|
||||
background: #fae2e2 url("icons/upload-error.svg") no-repeat 1rem center;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-error-message {
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.dropzone .dz-preview.dz-processing .dz-progress {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview.dz-error .dz-progress,
|
||||
.dropzone .dz-preview:not(.dz-processing) .dz-progress {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dropzone .dz-preview .dz-progress .dz-upload {
|
||||
width: 1px;
|
||||
background: var(--dark);
|
||||
display: block;
|
||||
height: 0.5rem;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Header
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
div.header {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
div.header div.title {
|
||||
order: 1;
|
||||
text-align: left;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
div.header div.title h1 {
|
||||
margin: 0;
|
||||
color: #f9f9f9;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
div.header div.title a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
div.header div.hostname {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.header div.login-status {
|
||||
order: 10;
|
||||
}
|
||||
|
||||
div.header div.login-status form {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
div.header span.logged-in-as-text em {
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
div.header div.login-form-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.header div.authentication-disabled {
|
||||
background: var(--danger);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
div.header {
|
||||
min-height: 3.5rem; /* Safari 14 iOS and iPad OS */
|
||||
}
|
||||
|
||||
body:not(.logged-in) div.header {
|
||||
flex-wrap: wrap;
|
||||
min-height: 8.875rem; /* Safari 14 iOS and iPad OS */
|
||||
}
|
||||
|
||||
div.header div.title {
|
||||
background: var(--dark);
|
||||
}
|
||||
|
||||
div.header div.title a {
|
||||
display: block;
|
||||
background: url("/static/logo.png") no-repeat;
|
||||
background-size: auto 2rem;
|
||||
background-position: 1rem center;
|
||||
padding: 1rem 1rem 1rem 3.5rem;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-out {
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-out form {
|
||||
align-items: end;
|
||||
padding: 1rem;
|
||||
background: var(--light);
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-out form span {
|
||||
display: block;
|
||||
padding: 0 0.1rem;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-out form label {
|
||||
display: block;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-out form input[type="submit"] {
|
||||
flex-grow: 0.5;
|
||||
margin-top: auto; /* Safari 14 iOS and iPad OS */
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-out form input:not([type="submit"]) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-in {
|
||||
background: var(--dark);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-in span.logged-in-as-text,
|
||||
div.header div.login-status.logged-in span.separator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-in a {
|
||||
margin-right: 1rem;
|
||||
color: var(--secondary);
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 821px) {
|
||||
div.header {
|
||||
background: var(--dark);
|
||||
align-items: center;
|
||||
padding: 0.5rem 1.25rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div.header div.title a {
|
||||
display: inline-block;
|
||||
background: url("/static/logo.png") no-repeat;
|
||||
background-size: auto 40px;
|
||||
background-position: left center;
|
||||
padding-left: 3rem;
|
||||
}
|
||||
|
||||
div.header div.title a h1 {
|
||||
font-size: 1.5rem;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
@supports (-webkit-background-clip: text) {
|
||||
div.header div.title a:hover h1 {
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
rgb(101 204 51 / 100%) 0%,
|
||||
rgb(255 204 51 / 100%) 10%,
|
||||
rgb(255 153 51 / 100%) 20%,
|
||||
rgb(205 51 50 / 100%) 55%,
|
||||
rgb(152 50 153 / 100%) 100%
|
||||
);
|
||||
|
||||
-webkit-background-clip: text; /* stylelint-disable-line */
|
||||
-webkit-text-fill-color: transparent; /* stylelint-disable-line */
|
||||
}
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-out form label,
|
||||
div.header div.login-status.logged-out form input {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-out form input:not([type="submit"]) {
|
||||
width: 8rem;
|
||||
background: var(--dark);
|
||||
border-color: var(--secondary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-out form input::-webkit-credentials-auto-fill-button {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-out form input[type="submit"] {
|
||||
background: var(--secondary);
|
||||
border-color: var(--secondary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-in a {
|
||||
background: var(--danger) url("icons/log-out.svg") no-repeat right 0.5rem center;
|
||||
background-size: var(--icon-size);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.25rem 2.25rem 0.25rem 0.75rem;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-in span.logged-in-as-text {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
div.header div.login-status.logged-in span.separator {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Footer
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
div.footer {
|
||||
flex-shrink: 0;
|
||||
background: var(--dark);
|
||||
padding: 1rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div.footer a {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
div.footer div.theme-change-hint {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
div.footer div.theme-change-hint a {
|
||||
color: yellow;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Flash messages
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
div.flash > div {
|
||||
margin: 1rem 1rem 0;
|
||||
padding: 0.5rem 0.75rem 0.5rem 3rem;
|
||||
border-radius: var(--border-radius);
|
||||
background-color: #efefef;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 1rem center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.flash > div a {
|
||||
display: inline-block !important;
|
||||
padding: 0.25rem 0.75rem;
|
||||
margin-left: auto;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.flash > div a::before {
|
||||
content: "×";
|
||||
}
|
||||
|
||||
div.flash > div.info {
|
||||
background-color: var(--info);
|
||||
background-image: url("icons/info.svg");
|
||||
}
|
||||
|
||||
div.flash > div.error {
|
||||
background-color: var(--danger);
|
||||
background-image: url("icons/error.svg");
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div.flash > div.success {
|
||||
background-color: var(--success);
|
||||
background-image: url("icons/success.svg");
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div.flash > div.warning {
|
||||
background-color: var(--warning);
|
||||
background-image: url("icons/warning.svg");
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Section headings
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
section > details {
|
||||
margin: 1rem auto;
|
||||
}
|
||||
|
||||
div.content > section:first-child > details {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
section > details summary {
|
||||
background: var(--secondary);
|
||||
border-radius: var(--border-radius);
|
||||
padding: 0.5rem 1rem;
|
||||
color: #fff;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
section > details ul {
|
||||
background-color: lightcyan;
|
||||
border: 2px solid var(--secondary);
|
||||
padding: 1rem 1rem 1rem 2rem;
|
||||
margin-top: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
section > details summary {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Index > Section: Current RaSCSI configuration
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
body:not(.logged-in) section:not(#current-config, #manual) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body:not(.logged-in) section#current-config form#config-actions,
|
||||
body:not(.logged-in) section#current-config form#config-save {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body:not(.logged-in) section#current-config table#attached-devices th.actions,
|
||||
body:not(.logged-in) section#current-config table#attached-devices td.actions,
|
||||
body:not(.logged-in) section#current-config table#attached-devices form {
|
||||
display: none;
|
||||
}
|
||||
|
||||
body:not(.logged-in) section#current-config form#detach-all-devices {
|
||||
display: none;
|
||||
}
|
||||
|
||||
section#current-config form#config-actions select,
|
||||
section#current-config form#config-save input[type="text"] {
|
||||
max-width: 10rem;
|
||||
}
|
||||
|
||||
table#attached-devices th.id,
|
||||
table#attached-devices td.id,
|
||||
table#attached-devices th.unit,
|
||||
table#attached-devices td.unit {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table#attached-devices th.actions,
|
||||
table#attached-devices td.actions {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table#attached-devices td.parameters form {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
table#attached-devices td.parameters form label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
table#attached-devices td.parameters form select {
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
table#attached-devices span.filename {
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
table#attached-devices tr.reserved td {
|
||||
background-color: #ffe9e9;
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
table#attached-devices th.product,
|
||||
table#attached-devices td.product {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 625px) {
|
||||
table#attached-devices td.parameters form {
|
||||
display: block;
|
||||
max-width: none;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
table#attached-devices td.parameters form select {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 821px) {
|
||||
section#current-config form#config-actions {
|
||||
float: left;
|
||||
height: 2.75rem;
|
||||
}
|
||||
|
||||
section#current-config form#config-save {
|
||||
float: right;
|
||||
height: 2.75rem;
|
||||
}
|
||||
|
||||
section#current-config form#config-save input[type="text"] {
|
||||
width: 10rem;
|
||||
}
|
||||
|
||||
table#attached-devices tr.device-assigned td.name,
|
||||
table#attached-devices tr.reserved td.name {
|
||||
background-image: url("icons/device-other.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-position: 1rem center;
|
||||
background-size: var(--icon-size);
|
||||
padding-left: 3rem;
|
||||
}
|
||||
|
||||
table#attached-devices tr.reserved td.name {
|
||||
background-image: url("icons/device-reserved.svg");
|
||||
}
|
||||
|
||||
table#attached-devices tr.device-sccd td.name,
|
||||
table#attached-devices tr.device-scmo td.name {
|
||||
background-image: url("icons/device-optical.svg");
|
||||
}
|
||||
|
||||
table#attached-devices tr.device-scdp td.name {
|
||||
background-image: url("icons/device-network.svg");
|
||||
}
|
||||
|
||||
table#attached-devices tr.device-schd td.name {
|
||||
background-image: url("icons/device-hard-drive.svg");
|
||||
}
|
||||
|
||||
table#attached-devices tr.device-scrm td.name {
|
||||
background-image: url("icons/device-removable.svg");
|
||||
}
|
||||
|
||||
table#attached-devices tr.device-sclp td.name {
|
||||
background-image: url("icons/device-printer.svg");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Index > Section:Image/file management
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
section#files table#images td:first-child {
|
||||
word-break: break-all;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
section#files table#images th:last-child,
|
||||
section#files table#images td:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
section#files table#images tr.directory-empty td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
section#files p {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
section#files table#images tr th:nth-child(2),
|
||||
section#files table#images tr td:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
section#files table#images form.file-attach {
|
||||
width: 100%;
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px dotted #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 821px) {
|
||||
section#files table#images form.file-copy input[type="submit"],
|
||||
section#files table#images form.file-rename input[type="submit"],
|
||||
section#files table#images form.file-delete input[type="submit"],
|
||||
section#files table#images form.file-info input[type="submit"] {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 1rem;
|
||||
text-indent: -1000px;
|
||||
width: 2.5rem;
|
||||
}
|
||||
|
||||
section#files table#images form.file-attach input[type="submit"],
|
||||
section#attach-devices form.device-attach input[type="submit"] {
|
||||
background: #efefef url("icons/file-device-attach.svg") no-repeat 0.5rem center;
|
||||
background-size: 1rem;
|
||||
padding-left: 2rem;
|
||||
}
|
||||
|
||||
section#files table#images form.file-copy input[type="submit"] {
|
||||
background-image: url("icons/file-copy.svg");
|
||||
}
|
||||
|
||||
section#files table#images form.file-rename input[type="submit"] {
|
||||
background-image: url("icons/file-rename.svg");
|
||||
}
|
||||
|
||||
section#files table#images form.file-delete input[type="submit"] {
|
||||
background-image: url("icons/file-delete.svg");
|
||||
}
|
||||
|
||||
section#files table#images form.file-info input[type="submit"] {
|
||||
background-image: url("icons/file-info.svg");
|
||||
}
|
||||
|
||||
section#files table#images form.file-extract input[type="submit"] {
|
||||
background: #efefef url("icons/file-extract.svg") no-repeat 0.5rem center;
|
||||
background-size: 1rem;
|
||||
padding-left: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Index > Section: Attach peripheral devices
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
section#attach-devices table th:last-child,
|
||||
section#attach-devices table td:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
section#attach-devices form {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
section#attach-devices table tr th:nth-child(2),
|
||||
section#attach-devices table tr td:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
section#attach-devices form label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
section#attach-devices form select {
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Index > Section: Create image
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
section#create-image > p a {
|
||||
display: block;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Index > Section: Logging
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
section#logging div:first-of-type {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Index > Section: System
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
@media (min-width: 821px) {
|
||||
section#system input[type="submit"] {
|
||||
background: var(--danger);
|
||||
border-color: var(--danger);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Index > Section: Manual
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
section#manual {
|
||||
margin: 2rem 0 1rem;
|
||||
}
|
||||
|
||||
section#manual a {
|
||||
margin: auto;
|
||||
display: block;
|
||||
padding: 0 0 0 2rem;
|
||||
background: url("icons/manual.svg") no-repeat left center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
section#manual a p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Drives page
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
body.page-drives div.content h2:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
body.page-drives div.content h2 {
|
||||
margin: 2rem 0 1rem;
|
||||
}
|
||||
|
||||
body.page-drives div.content p:first-of-type {
|
||||
background: lightcyan;
|
||||
border: 2px solid darkcyan;
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
body.page-drives div.content p:nth-of-type(3) {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
body.page-drives div.content p.home {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Disk info page
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
body.page-diskinfo div.content p.home {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Device info page
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
body.page-deviceinfo div.content table th {
|
||||
background: #efefef;
|
||||
color: var(--text-color);
|
||||
border-color: #ccc;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
body.page-deviceinfo div.content p.home {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Logs page
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
body.page-logs div.content p.home {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
Manual page
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
body.page-manpage div#manpage-content {
|
||||
font-family: monospace;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
body.page-manpage div#manpage-content h2 {
|
||||
margin: 2rem 0 0.5rem;
|
||||
}
|
||||
|
||||
body.page-manpage div.content p.home {
|
||||
margin-top: 2rem;
|
||||
font-weight: bold;
|
||||
}
|
@ -22,16 +22,16 @@
|
||||
<meta name="msapplication-TileImage" content="/pwa/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename=current_theme_stylesheet) }}">
|
||||
|
||||
<script type="application/javascript">
|
||||
var processNotify = function(Notification) {
|
||||
document.getElementById("flash").innerHTML = "<div class=\"info\">" + Notification + "{{ _(" This process may take a while, and will continue in the background if you navigate away from this page.") }}</div>";
|
||||
document.getElementById("flash").innerHTML = "<div class=\"info\"><div>" + Notification + "{{ _(" This process may take a while, and will continue in the background if you navigate away from this page.") }}</div></div>";
|
||||
window.scrollTo(0,0);
|
||||
}
|
||||
|
||||
var shutdownNotify = function(Notification) {
|
||||
document.getElementById("flash").innerHTML = "<div class=\"info\">" + Notification + "{{ _(" The Web Interface will become unresponsive momentarily. Reload this page after the Pi has started up again.") }}</div>";
|
||||
document.getElementById("flash").innerHTML = "<div class=\"warning\"><div>" + Notification + "{{ _(" The Web Interface will become unresponsive momentarily. Reload this page after the Pi has started up again.") }}</div></div>";
|
||||
window.scrollTo(0,0);
|
||||
}
|
||||
</script>
|
||||
@ -39,52 +39,77 @@
|
||||
<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/min/dropzone.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body class="{{ body_class }}{% if env["logged_in"] %} logged-in{% endif %}">
|
||||
<div class="header">
|
||||
{% if env["auth_active"] %}
|
||||
{% if env["username"] %}
|
||||
<div align="center" class="logged_in">
|
||||
{{ _("Logged in as <em>%(username)s</em>", username=env["username"]) }} - <a href="/logout">{{ _("Log Out") }}</a>
|
||||
</div>
|
||||
{% if env["logged_in"] %}
|
||||
<div align="center" class="login-status logged-in">
|
||||
<span class="logged-in-as-text">{{ _("Logged in as <em>%(username)s</em>", username=env["username"]) }}</span>
|
||||
<span class="separator">-</span>
|
||||
<a href="/logout">{{ _("Log Out") }}</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div align="center" class="login-status logged-out">
|
||||
<form method="POST" action="/login">
|
||||
<div class="login-form-title">{{ _("Log In to Use Web Interface") }}</div>
|
||||
<span>
|
||||
<label for="username">{{ _("Username") }}</label>
|
||||
<input type="text" name="username" id="username">
|
||||
</span>
|
||||
<span>
|
||||
<label for="password">{{ _("Password") }}</label>
|
||||
<input type="password" name="password" id="password">
|
||||
</span>
|
||||
<input type="submit" value="Login">
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div align="center" class="logged_out">
|
||||
<form method="POST" action="/login">
|
||||
<div>{{ _("Log In to Use Web Interface") }}</div>
|
||||
<label for="username">{{ _("Username") }}</label>
|
||||
<input type="text" name="username" id="username">
|
||||