From 14f72af15dbbc6aae86d5b23c1ca77f83acfe305 Mon Sep 17 00:00:00 2001 From: ashklianko Date: Fri, 5 Apr 2024 18:49:41 +0200 Subject: [PATCH] Non-selectable options in dropdowns should not be interactable #3521 --- .../common/js/ui/selector/DropdownGrid.ts | 12 -------- .../common/js/ui/selector/DropdownList.ts | 2 -- .../common/js/ui/selector/DropdownListGrid.ts | 29 ++++++++++++++++++ .../ui/selector/combobox/ComboBoxDropdown.ts | 12 -------- .../js/ui/selector/dropdown/Dropdown.ts | 4 --- .../styles/api/ui/selector/dropdown-grid.less | 30 ++++++++++++++----- 6 files changed, 52 insertions(+), 37 deletions(-) diff --git a/src/main/resources/assets/admin/common/js/ui/selector/DropdownGrid.ts b/src/main/resources/assets/admin/common/js/ui/selector/DropdownGrid.ts index 39b9d62f7..14f4077f0 100644 --- a/src/main/resources/assets/admin/common/js/ui/selector/DropdownGrid.ts +++ b/src/main/resources/assets/admin/common/js/ui/selector/DropdownGrid.ts @@ -254,18 +254,6 @@ export abstract class DropdownGrid { } } - markReadOnly(selectedOptions: Option[]) { - - let stylesHash: Slick.CellCssStylesHash = {}; - selectedOptions.forEach((selectedOption: Option) => { - if (selectedOption.isReadOnly()) { - let row = this.getRowByValue(selectedOption.getValue()); - stylesHash[row] = {_checkbox_selector: 'readonly', option: 'readonly'}; - } - }); - this.getGrid().setCellCssStyles('readonly', stylesHash); - } - hasActiveRow(): boolean { return !!this.getGrid().getActiveCell(); } diff --git a/src/main/resources/assets/admin/common/js/ui/selector/DropdownList.ts b/src/main/resources/assets/admin/common/js/ui/selector/DropdownList.ts index ef53de15e..24bbf1cb7 100644 --- a/src/main/resources/assets/admin/common/js/ui/selector/DropdownList.ts +++ b/src/main/resources/assets/admin/common/js/ui/selector/DropdownList.ts @@ -127,8 +127,6 @@ export class DropdownList { if (selectedOptions) { this.dropdownGrid.markSelections(selectedOptions); if (selectedOptions.length > 0) { - this.dropdownGrid.markReadOnly(selectedOptions); - if (!isShown) { this.navigateToRowIfNotActive(selectedOptions[0]); } diff --git a/src/main/resources/assets/admin/common/js/ui/selector/DropdownListGrid.ts b/src/main/resources/assets/admin/common/js/ui/selector/DropdownListGrid.ts index 3ba8c3226..4944e8cee 100644 --- a/src/main/resources/assets/admin/common/js/ui/selector/DropdownListGrid.ts +++ b/src/main/resources/assets/admin/common/js/ui/selector/DropdownListGrid.ts @@ -3,6 +3,8 @@ import {Grid} from '../grid/Grid'; import {DataView} from '../grid/DataView'; import {DropdownGrid, DropdownGridConfig} from './DropdownGrid'; import {Option} from './Option'; +import {i18n} from '../../util/Messages'; +import {StringHelper} from '../../util/StringHelper'; export class DropdownListGrid extends DropdownGrid { @@ -31,10 +33,37 @@ export class DropdownListGrid this.grid = new Grid>(this.gridData, this.createColumns(), this.createOptions()); + this.gridData.setItemMetadataHandler(this.handleItemMetadata.bind(this)); + this.gridData.onRowCountChanged(() => this.notifyRowCountChanged()); } protected getGridData(): DataView> { return this.gridData; } + + protected handleItemMetadata(row: number) { + let option = this.gridData.getItem(row); + let cssClasses = ''; + let title = ''; + + if (option.isReadOnly()) { + cssClasses += ' readonly'; + title = i18n('field.readOnly'); + } + + if (option.isSelectable()) { + cssClasses += ' selectable'; + } + + if (option.isExpandable()) { + cssClasses += ' expandable'; + } + + if (!StringHelper.isBlank(cssClasses) || !StringHelper.isBlank(title)) { + return {cssClasses: cssClasses, title: title}; + } + + return null; + } } diff --git a/src/main/resources/assets/admin/common/js/ui/selector/combobox/ComboBoxDropdown.ts b/src/main/resources/assets/admin/common/js/ui/selector/combobox/ComboBoxDropdown.ts index 23239d6a4..f8f7bed69 100644 --- a/src/main/resources/assets/admin/common/js/ui/selector/combobox/ComboBoxDropdown.ts +++ b/src/main/resources/assets/admin/common/js/ui/selector/combobox/ComboBoxDropdown.ts @@ -7,18 +7,6 @@ export class ComboBoxDropdown setOptions(options: Option[], noOptionsText: string, selectedOptions: Option[] = [], saveSelection?: boolean) { - - selectedOptions.forEach((selectedOption: Option) => { - if (selectedOption.isReadOnly()) { - for (const option of options) { - if (selectedOption.getValue() === option.getValue()) { - option.setReadOnly(true); - break; - } - } - } - }); - // `from` is used to determine, from which point should selection be updated const from = this.getDropdownGrid().getOptionCount(); diff --git a/src/main/resources/assets/admin/common/js/ui/selector/dropdown/Dropdown.ts b/src/main/resources/assets/admin/common/js/ui/selector/dropdown/Dropdown.ts index 6debb661d..93860480b 100644 --- a/src/main/resources/assets/admin/common/js/ui/selector/dropdown/Dropdown.ts +++ b/src/main/resources/assets/admin/common/js/ui/selector/dropdown/Dropdown.ts @@ -431,10 +431,6 @@ export class Dropdown return this.input.getValue() === ''; } - markReadOnly(options: Option[]) { - this.dropdownList.getDropdownGrid().markReadOnly(options); - } - private setupListeners() { AppHelper.focusInOut(this, () => { if (this.isVisible()) { diff --git a/src/main/resources/assets/admin/common/styles/api/ui/selector/dropdown-grid.less b/src/main/resources/assets/admin/common/styles/api/ui/selector/dropdown-grid.less index ed0820f48..65daa6670 100644 --- a/src/main/resources/assets/admin/common/styles/api/ui/selector/dropdown-grid.less +++ b/src/main/resources/assets/admin/common/styles/api/ui/selector/dropdown-grid.less @@ -1,14 +1,30 @@ .dropdown-grid { - .slick-row .slick-cell { - .compact-option-viewer(); + .slick-row { + .slick-cell { + .compact-option-viewer(); - &:first-child { - flex-grow: 1; + &:first-child { + flex-grow: 1; + } + + &:not(:first-child) { + flex-basis: 50px; + flex-shrink: 0; + } } - &:not(:first-child) { - flex-basis: 50px; - flex-shrink: 0; + &.readonly { + .slick-cell { + pointer-events: none; + + > *:not(.toggle) { + opacity: 0.5; + } + + .toggle { + pointer-events: all; + } + } } } }