mirror of
https://github.com/opf/openproject.git
synced 2026-06-13 19:20:00 +00:00
Apply differentiation between selected and pressed to WP table view
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 452 KiB |
+3
@@ -18,6 +18,9 @@
|
||||
display: flex
|
||||
align-items: center
|
||||
|
||||
:has(.op-ian-item_selected:first-child)
|
||||
border-top-color: var(--box-list-item-pressed-border-color)
|
||||
|
||||
&--viewport
|
||||
height: 100%
|
||||
// Avoid infinite horizontal scrolling on mobile iOS (#39849)
|
||||
|
||||
+8
-3
@@ -7,7 +7,9 @@ $ian-bg-read-color: var(--bgColor-muted)
|
||||
$ian-bg-read-hover-color: hsl(from var(--bgColor-muted) h s calc(l - 3.5))
|
||||
$ian-bg-selected-color: var(--box-list-item-selected-bg-color)
|
||||
$ian-bg-selected-hover-color: var(--box-list-item-selected-bg-hover-color)
|
||||
$ian-selected-border-color: var(--box-list-item-selected-border-color)
|
||||
// Notification center is special as it does not allow multi-select. So the selected element is always the pressed one.
|
||||
// We can therefore direclty set the pressed border color on the selected element
|
||||
$ian-active-border-color: var(--box-list-item-pressed-border-color)
|
||||
// This needs to be set in the itemSize of
|
||||
// the virtual scroller
|
||||
$ian-height: 100px
|
||||
@@ -33,14 +35,17 @@ $subject-font-size: 14px
|
||||
|
||||
&_selected
|
||||
background: $ian-bg-selected-color
|
||||
border-color: $ian-selected-border-color
|
||||
border-color: $ian-active-border-color
|
||||
&:hover
|
||||
background: $ian-bg-selected-hover-color
|
||||
|
||||
// Since the ian only have a top border, we need to highlight the next sibling as well to
|
||||
// create the impression that the selected ian has a top and bottom border
|
||||
& + .op-ian-item
|
||||
border-color: $ian-selected-border-color
|
||||
border-top-color: $ian-active-border-color
|
||||
|
||||
&:last-of-type
|
||||
border-bottom-color: $ian-active-border-color
|
||||
|
||||
&_read
|
||||
background: $ian-bg-read-color
|
||||
|
||||
+9
-1
@@ -13,7 +13,8 @@ import {
|
||||
} from 'core-app/features/work-packages/components/wp-fast-table/builders/internal-sort-columns';
|
||||
import { InjectField } from 'core-app/shared/helpers/angular/inject-field.decorator';
|
||||
import { debugLog } from 'core-app/shared/helpers/debug_output';
|
||||
import { checkedClassName } from '../ui-state-link-builder';
|
||||
import { checkedClassName, pressedClassName } from '../ui-state-link-builder';
|
||||
import { WorkPackageViewFocusService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-focus.service';
|
||||
import { RelationCellbuilder } from '../relation-cell-builder';
|
||||
import {
|
||||
CellBuilder,
|
||||
@@ -37,6 +38,8 @@ export class SingleRowBuilder {
|
||||
// Injections
|
||||
@InjectField() wpTableSelection:WorkPackageViewSelectionService;
|
||||
|
||||
@InjectField() wpTableFocus:WorkPackageViewFocusService;
|
||||
|
||||
@InjectField() wpTableColumns:WorkPackageViewColumnsService;
|
||||
|
||||
@InjectField() wpTableBaseline:WorkPackageViewBaselineService;
|
||||
@@ -251,6 +254,11 @@ export class SingleRowBuilder {
|
||||
row.classList.add(checkedClassName);
|
||||
}
|
||||
|
||||
// Mark the currently focused (details-panel) row as pressed
|
||||
if (this.wpTableFocus.isFocused(workPackage.id!)) {
|
||||
row.classList.add(pressedClassName);
|
||||
}
|
||||
|
||||
return [row, false];
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -6,6 +6,7 @@ import { InjectField } from 'core-app/shared/helpers/angular/inject-field.decora
|
||||
|
||||
export const uiStateLinkClass = '__ui-state-link';
|
||||
export const checkedClassName = '-checked';
|
||||
export const pressedClassName = '-pressed';
|
||||
|
||||
export class UiStateLinkBuilder {
|
||||
constructor(
|
||||
|
||||
+25
-1
@@ -9,7 +9,7 @@ import {
|
||||
} from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-selection.service';
|
||||
import { InjectField } from 'core-app/shared/helpers/angular/inject-field.decorator';
|
||||
import { tableRowClassName } from '../../builders/rows/single-row-builder';
|
||||
import { checkedClassName } from '../../builders/ui-state-link-builder';
|
||||
import { checkedClassName, pressedClassName } from '../../builders/ui-state-link-builder';
|
||||
import { locateTableRow, scrollTableRowIntoView } from '../../helpers/wp-table-row-helpers';
|
||||
import { WorkPackageTable } from '../../wp-fast-table';
|
||||
|
||||
@@ -48,6 +48,15 @@ export class SelectionTransformer {
|
||||
this.renderSelectionState(state);
|
||||
});
|
||||
|
||||
// Update pressed state when the focused (details-panel) WP changes
|
||||
this.wpTableFocus.whenChanged()
|
||||
.pipe(
|
||||
takeUntil(this.querySpace.stopAllSubscriptions),
|
||||
)
|
||||
.subscribe((focusedId:string) => {
|
||||
this.renderPressedState(focusedId);
|
||||
});
|
||||
|
||||
this.wpTableSelection.registerSelectAllListener(() => table.renderedRows);
|
||||
this.wpTableSelection.registerDeselectAllListener();
|
||||
}
|
||||
@@ -66,4 +75,19 @@ export class SelectionTransformer {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the pressed state to reflect the currently focused (details-panel) row.
|
||||
*/
|
||||
private renderPressedState(focusedId:string|null) {
|
||||
const context = this.table.tableAndTimelineContainer;
|
||||
|
||||
context.querySelectorAll(`.${tableRowClassName}.${pressedClassName}`).forEach((el) => el.classList.remove(pressedClassName));
|
||||
|
||||
if (focusedId) {
|
||||
context.querySelectorAll(`.${tableRowClassName}[data-work-package-id="${focusedId}"]`).forEach((el) => {
|
||||
el.classList.add(pressedClassName);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,6 +106,7 @@ th.hidden
|
||||
tr.context-menu-selection,
|
||||
tr.-checked
|
||||
background-color: var(--box-list-item-selected-bg-color) !important
|
||||
border-bottom: 1px solid var(--box-list-item-selected-border-color) !important
|
||||
&[class*=__hl_background]
|
||||
outline: var(--bgColor-accent-emphasis) solid 2px
|
||||
|
||||
@@ -113,12 +114,19 @@ tr.-checked
|
||||
background-color: var(--box-list-item-selected-bg-hover-color) !important
|
||||
|
||||
td
|
||||
border-top: 1px solid var(--box-list-item-selected-border-color) !important
|
||||
border-bottom: 1px solid var(--box-list-item-selected-border-color) !important
|
||||
color: var(--body-font-color) !important
|
||||
a
|
||||
color: var(--body-font-color) !important
|
||||
|
||||
tr.-pressed
|
||||
border-bottom: 1px solid var(--box-list-item-pressed-border-color) !important
|
||||
|
||||
tr:not(.-pressed):has(+ tr.-checked)
|
||||
border-bottom: 1px solid var(--box-list-item-selected-border-color) !important
|
||||
|
||||
tr:not(.-pressed):has(+ tr.-pressed)
|
||||
border-bottom: 1px solid var(--box-list-item-pressed-border-color) !important
|
||||
|
||||
#custom-options-table
|
||||
.custom-option-value
|
||||
display: inline-block
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
List items can have three visual states. The states are expressed via CSS classes on the row element (`<tr>` or equivalent) and are driven by CSS custom properties defined in `_variable_defaults.scss`.
|
||||
|
||||
 %>)
|
||||
|
||||
## States
|
||||
|
||||
### Default
|
||||
|
||||
The item uses the base background (`--box-list-item-bg-color`) and a neutral border (`--box-list-item-border-color`).
|
||||
|
||||
### Selected
|
||||
|
||||
Applied when an item is part of the active **(multi-)selection** - e.g. for bulk actions or drag & drop. The background is blue (`--box-list-item-selected-bg-color`). A subtle blue border is added at the top and the bottom (`--box-list-item-selected-border-color`).
|
||||
|
||||
### Pressed
|
||||
|
||||
Applied to the item that is currently **open in the split-screen**. A stronger blue border is added at the top and bottom (`--box-list-item-pressed-border-color`) to indicate the active detail context. The background colour remains unchanged.
|
||||
|
||||
An item can carry both states simultaneously when it is selected *and* currently shown in the detail panel.
|
||||
|
||||
## CSS custom properties
|
||||
|
||||
| Property | Used by |
|
||||
|---|---|
|
||||
| `--box-list-item-bg-color` | default background |
|
||||
| `--box-list-item-bg-hover-color` | hover background |
|
||||
| `--box-list-item-border-color` | default border |
|
||||
| `--box-list-item-selected-bg-color` | `selected` background |
|
||||
| `--box-list-item-selected-bg-hover-color` | `selected` hover background |
|
||||
| `--box-list-item-selected-border-color` | `selected` border |
|
||||
| `--box-list-item-pressed-border-color` | `pressed` border |
|
||||
|
||||
## Usages
|
||||
|
||||
This pattern is currently used in:
|
||||
|
||||
* WorkPackage list
|
||||
* Notification center
|
||||
* Backlogs
|
||||
Reference in New Issue
Block a user