mirror of
https://github.com/wekan/wekan.git
synced 2026-11-08 19:35:19 -05:00
Move the board Status from a Board Settings sidebar popup into a full-width board VIEW alongside Swimlanes / Lists / Calendar / Gantt / Table in the board-view switcher. Named 'Statistics' (Finnish 'Tilastot'), translated to major languages (rest fall back to English). New statsView template/js/css rendered from boardBody (isViewStats), selectable via the switcher (js-open-stats-view -> board-view-stats, added to the profile.boardView schema allowedValues). Reuses the server boardStatus method so counts are accurate in lazy mode; shows the same counts + time-spent summary as before. Text is selectable with mouse (drag) and touch (long-press): the view stops pointer/touch events from reaching the canvas drag-to-scroll so native selection + copy work. Removed the old boardStatusPopup (template/handler/helpers/css) and its Board menu item. Added a Playwright test for the view. Design doc updated.
505 lines
13 KiB
CSS
505 lines
13 KiB
CSS
.sidebar {
|
|
position: absolute;
|
|
top: 0;
|
|
bottom: 0;
|
|
inset-inline-end: 0;
|
|
overflow-y: scroll;
|
|
}
|
|
.sidebar {
|
|
background: #f7f7f7;
|
|
box-shadow: -10px 0px 5px -10px #b3b3b3;
|
|
}
|
|
.sidebar-xmark {
|
|
position: absolute;
|
|
inset-inline-end: 0px;
|
|
top: 0px;
|
|
font-size: 25px;
|
|
padding: 10px;
|
|
}
|
|
.sidebar-xmark:hover {
|
|
background: rgba(0,0,0,0.15);
|
|
}
|
|
.sidebar-actions {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 10px 10px 0px 10px;
|
|
}
|
|
.sidebar .sidebar-content {
|
|
padding: 0 12px;
|
|
}
|
|
/* Sidebar text inputs (Filter List by Title, Filter by card title, advanced
|
|
filter, etc.) fill the padded content width, so there is equal empty space on
|
|
both sides (the .sidebar-content 12px padding) instead of the browser's
|
|
default narrow width that left a large gap on the right. box-sizing keeps the
|
|
border inside the width so it never overflows the panel. */
|
|
.sidebar .sidebar-content input[type="text"],
|
|
.sidebar .sidebar-content input[type="search"] {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
.sidebar .sidebar-content .hide-btn {
|
|
display: none;
|
|
}
|
|
.sidebar .sidebar-content h3 {
|
|
color: #808080;
|
|
font-size: 1em;
|
|
margin-bottom: 10px;
|
|
font-weight: bold;
|
|
}
|
|
.sidebar .sidebar-content h3 i.fa {
|
|
margin-inline-end: 3px;
|
|
}
|
|
.sidebar .sidebar-content hr {
|
|
margin: 13px 0;
|
|
}
|
|
.sidebar .sidebar-content ul.sidebar-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
/* Use checklist-style green checkboxes for all sidebar checkboxes */
|
|
.sidebar .materialCheckBox.is-checked,
|
|
.boardCardSettingsPopup .materialCheckBox.is-checked,
|
|
.boardSubtaskSettingsPopup .materialCheckBox.is-checked {
|
|
top: -4px !important;
|
|
inset-inline-start: -3px !important;
|
|
width: 7px !important;
|
|
height: 15px !important;
|
|
margin-inline-end: 6px !important;
|
|
border-top: 2px solid transparent !important;
|
|
border-inline-start: 2px solid transparent !important;
|
|
border-bottom: 2px solid #3cb500 !important;
|
|
border-inline-end: 2px solid #3cb500 !important;
|
|
transform: rotate(40deg) !important;
|
|
-webkit-backface-visibility: hidden !important;
|
|
backface-visibility: hidden !important;
|
|
transform-origin: 100% 100% !important;
|
|
}
|
|
|
|
/* Grey checkmarks when grey icons setting is enabled */
|
|
body.grey-icons-enabled .sidebar .materialCheckBox.is-checked,
|
|
body.grey-icons-enabled .boardCardSettingsPopup .materialCheckBox.is-checked,
|
|
body.grey-icons-enabled .boardSubtaskSettingsPopup .materialCheckBox.is-checked {
|
|
border-bottom: 2px solid #7a7a7a !important;
|
|
border-inline-end: 2px solid #7a7a7a !important;
|
|
}
|
|
|
|
/* Card Settings 3-column grid layout */
|
|
.card-settings-grid {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr 2fr;
|
|
gap: 10px;
|
|
margin-bottom: 10px;
|
|
/* Keep the "Show on Card / Show on Minicard / Description" titles visible
|
|
while the rows below scroll (the popup scrolls in .pop-over .content-wrapper). */
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 2;
|
|
background: #fff;
|
|
padding: 5px 0;
|
|
border-bottom: 2px solid #ddd;
|
|
}
|
|
|
|
.card-settings-row {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr 2fr;
|
|
gap: 10px;
|
|
align-items: center;
|
|
padding: 5px 0;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.card-settings-column {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.card-settings-column:last-child {
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
.card-settings-column h4 {
|
|
margin: 0;
|
|
font-size: 12px;
|
|
font-weight: bold;
|
|
text-align: center;
|
|
}
|
|
.sidebar .sidebar-content ul.sidebar-list li > a {
|
|
display: flex;
|
|
height: 30px;
|
|
margin: 0;
|
|
padding: 4px;
|
|
border-radius: 3px;
|
|
align-items: center;
|
|
}
|
|
.sidebar .sidebar-content ul.sidebar-list li > a:hover,
|
|
.sidebar .sidebar-content ul.sidebar-list li > a:hover i,
|
|
.sidebar .sidebar-content ul.sidebar-list li > a:hover .quiet {
|
|
color: #fff;
|
|
}
|
|
.sidebar .sidebar-content ul.sidebar-list li > a .member,
|
|
.sidebar .sidebar-content ul.sidebar-list li > a .card-label {
|
|
margin-inline-end: 7px;
|
|
margin-top: 5px;
|
|
}
|
|
.sidebar .sidebar-content ul.sidebar-list li > a .minicard-edit-button {
|
|
float: inline-end;
|
|
padding: 8px;
|
|
border-radius: 3px;
|
|
}
|
|
.sidebar .sidebar-content ul.sidebar-list li > a .sidebar-list-item-description {
|
|
flex: 1;
|
|
overflow: ellipsis;
|
|
}
|
|
.sidebar .sidebar-content ul.sidebar-list li > a .fa.fa-check {
|
|
margin: 0 4px;
|
|
color: #3cb500;
|
|
}
|
|
/* Grey check icons when grey icons setting is enabled */
|
|
body.grey-icons-enabled .sidebar .sidebar-content ul.sidebar-list li > a .fa.fa-check {
|
|
color: #7a7a7a;
|
|
}
|
|
.sidebar .sidebar-content ul.sidebar-list li .minicard {
|
|
padding: 6px 8px 4px;
|
|
}
|
|
.sidebar .sidebar-content ul.sidebar-list li .minicard .minicard-edit-button {
|
|
float: inline-end;
|
|
padding: 4px;
|
|
border-radius: 3px;
|
|
}
|
|
.sidebar .sidebar-content ul.sidebar-list li .minicard .minicard-edit-button:hover {
|
|
background: #dbdbdb;
|
|
}
|
|
.sidebar .sidebar-content .sidebar-btn {
|
|
display: block;
|
|
margin: 5px 0;
|
|
padding: 10px;
|
|
border-radius: 3px;
|
|
background: #e6e6e6;
|
|
}
|
|
.sidebar .sidebar-content .sidebar-btn * {
|
|
color: #fff;
|
|
}
|
|
.sidebar .sidebar-content .sidebar-btn:hover * {
|
|
color: #fff;
|
|
}
|
|
.sidebar .sidebar-content .sidebar-btn i.fa {
|
|
margin-inline-end: 10px;
|
|
}
|
|
.sidebar .sidebar-shortcuts {
|
|
top: 7px;
|
|
font-size: 1em;
|
|
line-height: 1.6em;
|
|
color: #000;
|
|
}
|
|
.sidebar .sidebar-shortcuts .sidebar-btn {
|
|
margin-inline-start: 3px;
|
|
margin-inline-end: 3px;
|
|
}
|
|
.board-sidebar {
|
|
display: none;
|
|
/* Keep a sensible sidebar width at every screen size. A bare 30vw scaled with
|
|
the viewport, so on very wide screens it grew to ~double the intended width
|
|
while looking right only at mid widths; clamp keeps the mid-width look and
|
|
caps it (and floors it) instead of scaling without bound. Phones (<800px)
|
|
are handled by the 100vw rule in the media query below. */
|
|
width: clamp(320px, 30vw, 560px);
|
|
z-index: 100;
|
|
transition: top 0.1s, right 0.1s, width 0.1s;
|
|
}
|
|
.board-sidebar.is-open {
|
|
display: block;
|
|
/* #6465 follow-up: the card details window docks to the right edge with
|
|
z-index 2001 — the same place this sidebar opens. When the user opens the
|
|
sidebar, the sidebar must win, or its content (e.g. the archives
|
|
Restore/Delete links) sits unreachable UNDER the card window. */
|
|
z-index: 2002;
|
|
}
|
|
/* Right sidebar resize handle: a thin grab strip on the LEFT edge of the open
|
|
sidebar; drag left/right to change the sidebar width. Desktop only (hidden on
|
|
phones by the media query below, where the sidebar is full width). */
|
|
.sidebar-resize-handle {
|
|
display: none;
|
|
}
|
|
.board-sidebar.is-open .sidebar-resize-handle {
|
|
display: block;
|
|
position: absolute;
|
|
top: 0;
|
|
bottom: 0;
|
|
inset-inline-start: -3px;
|
|
width: 6px;
|
|
cursor: col-resize;
|
|
z-index: 2003; /* above the open sidebar (2002) and its content */
|
|
background: transparent;
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
.sidebar-resize-handle:hover {
|
|
background: rgba(0, 123, 255, 0.4);
|
|
box-shadow: 0 0 4px rgba(0, 123, 255, 0.3);
|
|
}
|
|
.sidebar-resize-handle:active {
|
|
background: rgba(0, 123, 255, 0.6);
|
|
box-shadow: 0 0 6px rgba(0, 123, 255, 0.4);
|
|
}
|
|
body.sidebar-resizing-active {
|
|
user-select: none;
|
|
cursor: col-resize;
|
|
}
|
|
.board-widget h4 {
|
|
margin: 5px 0;
|
|
}
|
|
.board-widget-activity {
|
|
margin-inline-end: -4px;
|
|
}
|
|
.sidebar-tongue {
|
|
display: block;
|
|
width: 30px;
|
|
height: 30px;
|
|
inset-inline-start: -30px;
|
|
position: absolute;
|
|
top: 0px;
|
|
z-index: 15;
|
|
background: #f7f7f7;
|
|
border-bottom-left-radius: 3px;
|
|
box-shadow: -4px 0px 7px -4px #b3b3b3;
|
|
color: #808080;
|
|
transition: left 0.1s;
|
|
}
|
|
.sidebar-tongue i.fa {
|
|
padding: 3px 9px;
|
|
font-size: 24px;
|
|
transition: transform 0.5s;
|
|
}
|
|
.sidebar-accessibility {
|
|
color: #4d4d4d;
|
|
padding: 5px 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
text-decoration: none;
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
margin-inline-start: auto;
|
|
margin-inline-end: 30px;
|
|
}
|
|
.sidebar-accessibility:hover {
|
|
background-color: #d9d9d9;
|
|
}
|
|
.sidebar-accessibility span {
|
|
margin-inline-start: 5px;
|
|
}
|
|
.board-sidebar.is-open .sidebar-tongue {
|
|
inset-inline-start: -28px;
|
|
}
|
|
.board-sidebar.is-open .sidebar-tongue:hover {
|
|
inset-inline-start: -25px;
|
|
}
|
|
.board-sidebar.is-open .sidebar-tongue i.fa {
|
|
transform: rotate(180deg);
|
|
}
|
|
.sidebar-tongue.is-hidden,
|
|
.board-sidebar.is-open .sidebar-tongue.is-hidden {
|
|
z-index: 0;
|
|
inset-inline-start: 5px;
|
|
}
|
|
/* #3199: In the Archive sidebar's Cards tab each card's Restore/Delete links
|
|
used to sit BETWEEN two archived cards with near-equal spacing, so users
|
|
could not tell which card they belonged to. Group each card with its own
|
|
links: no gap between the card and its links, and a clear separator gap
|
|
below the whole group before the next card. Spacing-only, so it works in
|
|
every board color/theme; logical properties keep it RTL-safe. */
|
|
.archived-card-item {
|
|
margin-block-end: 1.6em;
|
|
}
|
|
.archived-card-item .minicard-wrapper {
|
|
margin-bottom: 0;
|
|
}
|
|
.archived-card-item p.quiet {
|
|
margin-block-start: 2px;
|
|
margin-block-end: 0;
|
|
padding-inline-start: 4px;
|
|
}
|
|
.archived-lists .archived-lists-item {
|
|
border-top: 1px solid #ccc;
|
|
clear: both;
|
|
padding: 5px 0;
|
|
}
|
|
.archived-lists .archived-lists-item:first-child {
|
|
border-top: none;
|
|
}
|
|
.archived-lists .archived-lists-item button {
|
|
float: inline-end;
|
|
margin: 0;
|
|
margin: 0 0 5px 5px;
|
|
padding: 0 10px 0 10px;
|
|
}
|
|
@media screen and (max-width: 800px) {
|
|
/* On phones (iPhone 12 mini, etc.) the right sidebar should be a full-width
|
|
panel at the top of the board, in BOTH mobile mode and desktop mode. The
|
|
sidebar lives inside .board-wrapper, which is wider than the viewport on a
|
|
phone, so an absolutely-positioned sidebar (inset-inline-end: 0) pins to the
|
|
far right of the wide board and shows as a narrow strip. Pin it to the
|
|
VIEWPORT instead (position: fixed + 100vw) so it spans the full screen
|
|
width. At 100% zoom .board-wrapper has no transform, so fixed resolves to
|
|
the viewport in desktop mode too. */
|
|
.board-sidebar.sidebar {
|
|
position: fixed;
|
|
top: 0;
|
|
bottom: 0;
|
|
inset-inline-start: 0;
|
|
inset-inline-end: 0;
|
|
/* !important so a desktop drag-resize inline width never leaks into mobile,
|
|
where the sidebar must stay full width. */
|
|
width: 100vw !important;
|
|
max-width: 100vw !important;
|
|
z-index: 1000;
|
|
}
|
|
/* No dragging to resize on phones — the sidebar is full width there. */
|
|
.board-sidebar .sidebar-resize-handle {
|
|
display: none;
|
|
}
|
|
/* Normalise sidebar text on phones so the headings are not oversized and the
|
|
small text is not tiny — keep them close to the board's text size so board
|
|
and sidebar read at one consistent size. */
|
|
.board-sidebar.sidebar .sidebar-content {
|
|
font-size: 14px;
|
|
}
|
|
.board-sidebar.sidebar .sidebar-content h2,
|
|
.board-sidebar.sidebar .sidebar-content h3 {
|
|
font-size: 16px;
|
|
}
|
|
.board-sidebar.sidebar .sidebar-content ul.sidebar-list li > a,
|
|
.board-sidebar.sidebar .sidebar-content .card-label,
|
|
.board-sidebar.sidebar .sidebar-content .card-label .card-label-name,
|
|
.board-sidebar.sidebar .sidebar-content p,
|
|
.board-sidebar.sidebar .sidebar-content span {
|
|
font-size: 14px;
|
|
}
|
|
.board-sidebar .sidebar-content .hide-btn {
|
|
width: 40px;
|
|
height: 40px;
|
|
position: absolute;
|
|
inset-inline-end: 5px;
|
|
top: 5px;
|
|
display: block;
|
|
z-index: 15;
|
|
background: #f7f7f7;
|
|
transition: left 0.1s;
|
|
color: #808080;
|
|
border-radius: 50%;
|
|
border: 1px solid #b3b3b3;
|
|
box-shadow: 0 1px 6px rgba(0,0,0,0.3);
|
|
color: #808080;
|
|
}
|
|
.board-sidebar .sidebar-content .hide-btn i.fa {
|
|
padding: 8px 16px;
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
}
|
|
.sidebar-tongue {
|
|
width: 40px;
|
|
height: 40px;
|
|
inset-inline-start: -47px;
|
|
top: 5px;
|
|
display: block;
|
|
border-radius: 50%;
|
|
border: 1px solid #b3b3b3;
|
|
box-shadow: 0 1px 6px rgba(0,0,0,0.3);
|
|
color: #808080;
|
|
}
|
|
.board-sidebar.is-open .sidebar-tongue {
|
|
display: none;
|
|
}
|
|
.sidebar-tongue i.fa {
|
|
padding: 8px 0px 8px 16px;
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
#jsBoardOrgs,
|
|
#jsBoardTeams {
|
|
width: 90%;
|
|
}
|
|
.leaveBoardBtn {
|
|
background-color: #008000 !important;
|
|
}
|
|
.cancelLeaveBoardBtn {
|
|
margin-inline-start: 5% !important;
|
|
background-color: #f00 !important;
|
|
}
|
|
.addTeamsLabel,
|
|
.addOrganizationsLabel {
|
|
font-weight: normal;
|
|
}
|
|
.js-manage-board-removeTeam:hover,
|
|
.js-manage-board-removeTeam.is-active,
|
|
.js-manage-board-removeOrg:hover,
|
|
.js-manage-board-removeOrg.is-active {
|
|
box-shadow: 0 0 0 2px #e23210 inset !important;
|
|
}
|
|
.js-manage-board-addTeam:hover,
|
|
.js-manage-board-addTeam.is-active,
|
|
.js-manage-board-addOrg:hover,
|
|
.js-manage-board-addOrg.is-active {
|
|
box-shadow: 0 0 0 2px #73ea10 inset !important;
|
|
}
|
|
.addTeamFaPlus {
|
|
color: #008000 !important;
|
|
}
|
|
.removeTeamFaMinus {
|
|
color: #f00 !important;
|
|
}
|
|
.divaddfaplusminus {
|
|
padding-top: 5px;
|
|
margin-inline-start: 40px;
|
|
}
|
|
|
|
/* Board backgrounds management popup */
|
|
.board-backgrounds-manage .board-backgrounds-grid {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
margin-top: 8px;
|
|
}
|
|
.board-bg-item {
|
|
width: 48%;
|
|
margin: 1%;
|
|
border: 2px solid transparent;
|
|
border-radius: 3px;
|
|
}
|
|
.board-bg-item.is-active {
|
|
border-color: #3cb500;
|
|
}
|
|
.board-bg-thumb {
|
|
height: 80px;
|
|
background-size: cover;
|
|
background-position: center;
|
|
border-radius: 3px;
|
|
position: relative;
|
|
}
|
|
.board-bg-active-check {
|
|
position: absolute;
|
|
top: 4px;
|
|
inset-inline-end: 4px;
|
|
color: #3cb500;
|
|
background: rgba(255, 255, 255, 0.85);
|
|
border-radius: 50%;
|
|
padding: 2px;
|
|
}
|
|
.board-bg-actions {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
padding: 4px 0;
|
|
}
|
|
.board-bg-actions a {
|
|
cursor: pointer;
|
|
color: #4d4d4d;
|
|
}
|
|
.board-bg-actions a:hover {
|
|
color: #000;
|
|
}
|
|
.js-bg-upload-button {
|
|
display: inline-block;
|
|
margin-bottom: 8px;
|
|
}
|