From 4ce602b72478b0986907e89b56f846ed47502450 Mon Sep 17 00:00:00 2001 From: Lukasz Ostafin Date: Wed, 8 Jan 2025 13:01:21 +0100 Subject: [PATCH] After QA --- .../scripts/fieldType/ezobjectrelationlist.js | 1 + .../_selected.locations.item.scss | 6 ++ .../components/finder/finder.leaf.js | 12 ++- .../components/grid-view/grid.view.item.js | 10 ++- .../selected.locations.item.js | 4 + .../tree.item.toggle.selection.js | 20 +++-- .../hooks/useSelectedLocationsHelpers.js | 9 ++ .../universal.discovery.module.js | 90 +++++++++++-------- 8 files changed, 104 insertions(+), 48 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/fieldType/ezobjectrelationlist.js b/src/bundle/Resources/public/js/scripts/fieldType/ezobjectrelationlist.js index c8bab7a840..ff4b349a52 100644 --- a/src/bundle/Resources/public/js/scripts/fieldType/ezobjectrelationlist.js +++ b/src/bundle/Resources/public/js/scripts/fieldType/ezobjectrelationlist.js @@ -159,6 +159,7 @@ title, startingLocationId, selectedLocations, + isInitLocationsDeselectionBlocked: true, ...config, multiple: isSingle ? false : selectedItemsLimit !== 1, multipleItemsLimit: selectedItemsLimit > 1 ? selectedItemsLimit - selectedItems.length : selectedItemsLimit, diff --git a/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_selected.locations.item.scss b/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_selected.locations.item.scss index e117b7fd2f..60fbd5a185 100644 --- a/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_selected.locations.item.scss +++ b/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_selected.locations.item.scss @@ -52,5 +52,11 @@ .ibexa-icon { fill: $ibexa-color-dark; } + + &:disabled { + .ibexa-icon { + fill: $ibexa-color-dark-300; + } + } } } diff --git a/src/bundle/ui-dev/src/modules/universal-discovery/components/finder/finder.leaf.js b/src/bundle/ui-dev/src/modules/universal-discovery/components/finder/finder.leaf.js index 08f1530919..ae4dce3916 100644 --- a/src/bundle/ui-dev/src/modules/universal-discovery/components/finder/finder.leaf.js +++ b/src/bundle/ui-dev/src/modules/universal-discovery/components/finder/finder.leaf.js @@ -24,10 +24,11 @@ const FinderLeaf = ({ location }) => { const contentTypesMap = useContext(ContentTypesMapContext); const [, dispatchSelectedLocationsAction] = useContext(SelectedLocationsContext); const [multiple] = useContext(MultipleConfigContext); - const { checkIsSelectable, checkIsSelected, checkIsSelectionBlocked } = useSelectedLocationsHelpers(); + const { checkIsSelectable, checkIsSelected, checkIsSelectionBlocked, checkIsDeselectionBlocked } = useSelectedLocationsHelpers(); const isSelected = checkIsSelected(location); const isNotSelectable = !checkIsSelectable(location); const isSelectionBlocked = checkIsSelectionBlocked(location); + const isDeselectionBlocked = checkIsDeselectionBlocked(location); const markLocation = ({ nativeEvent }) => { const isSelectionButtonClicked = nativeEvent.target.closest('.c-udw-toggle-selection'); const isMarkedLocationClicked = location.id === markedLocationId; @@ -49,7 +50,14 @@ const FinderLeaf = ({ location }) => { } }; const renderToggleSelection = () => { - return ; + return ( + + ); }; const className = createCssClassNames({ 'c-finder-leaf': true, diff --git a/src/bundle/ui-dev/src/modules/universal-discovery/components/grid-view/grid.view.item.js b/src/bundle/ui-dev/src/modules/universal-discovery/components/grid-view/grid.view.item.js index 45abf7930e..9c7611282e 100644 --- a/src/bundle/ui-dev/src/modules/universal-discovery/components/grid-view/grid.view.item.js +++ b/src/bundle/ui-dev/src/modules/universal-discovery/components/grid-view/grid.view.item.js @@ -30,10 +30,11 @@ const GridViewItem = ({ location, version }) => { const containersOnly = useContext(ContainersOnlyContext); const contentTypeInfo = contentTypesMap[location.ContentInfo.Content.ContentType._href]; const { isContainer } = contentTypeInfo; - const { checkIsSelectable, checkIsSelected, checkIsSelectionBlocked } = useSelectedLocationsHelpers(); + const { checkIsSelectable, checkIsSelected, checkIsSelectionBlocked, checkIsDeselectionBlocked } = useSelectedLocationsHelpers(); const isSelected = checkIsSelected(location); const isNotSelectable = !checkIsSelectable(location); const isSelectionBlocked = checkIsSelectionBlocked(location); + const isDeselectionBlocked = checkIsDeselectionBlocked(location); const className = createCssClassNames({ 'ibexa-grid-view-item': true, 'ibexa-grid-view-item--marked': markedLocationId === location.id, @@ -68,7 +69,12 @@ const GridViewItem = ({ location, version }) => { const renderToggleSelection = () => { return (
- +
); }; diff --git a/src/bundle/ui-dev/src/modules/universal-discovery/components/selected-locations/selected.locations.item.js b/src/bundle/ui-dev/src/modules/universal-discovery/components/selected-locations/selected.locations.item.js index 010f4b082d..b458a0ad03 100644 --- a/src/bundle/ui-dev/src/modules/universal-discovery/components/selected-locations/selected.locations.item.js +++ b/src/bundle/ui-dev/src/modules/universal-discovery/components/selected-locations/selected.locations.item.js @@ -11,12 +11,15 @@ import Thumbnail from '../../../common/thumbnail/thumbnail'; import { SelectedLocationsContext, ContentTypesMapContext } from '../../universal.discovery.module'; import { getAdminUiConfig, getTranslator } from '@ibexa-admin-ui/src/bundle/Resources/public/js/scripts/helpers/context.helper'; +import { useSelectedLocationsHelpers } from '../../hooks/useSelectedLocationsHelpers'; const SelectedLocationsItem = ({ location, permissions }) => { const adminUiConfig = getAdminUiConfig(); const Translator = getTranslator(); const refSelectedLocationsItem = useRef(null); const [, dispatchSelectedLocationsAction] = useContext(SelectedLocationsContext); + const { checkIsDeselectionBlocked } = useSelectedLocationsHelpers(); + const isDeselectionBlocked = checkIsDeselectionBlocked(location); const contentTypesMap = useContext(ContentTypesMapContext); const clearLabel = Translator.trans( /*@Desc("Clear selection")*/ 'selected_locations.clear_selection', @@ -65,6 +68,7 @@ const SelectedLocationsItem = ({ location, permissions }) => { onClick={removeFromSelection} title={clearLabel} data-tooltip-container-selector=".c-udw-tab" + disabled={isDeselectionBlocked} > diff --git a/src/bundle/ui-dev/src/modules/universal-discovery/components/tree-item-toggle-selection/tree.item.toggle.selection.js b/src/bundle/ui-dev/src/modules/universal-discovery/components/tree-item-toggle-selection/tree.item.toggle.selection.js index 04b21ffe80..ab28da4e5b 100644 --- a/src/bundle/ui-dev/src/modules/universal-discovery/components/tree-item-toggle-selection/tree.item.toggle.selection.js +++ b/src/bundle/ui-dev/src/modules/universal-discovery/components/tree-item-toggle-selection/tree.item.toggle.selection.js @@ -5,6 +5,7 @@ import { parse as parseTooltip } from '@ibexa-admin-ui/src/bundle/Resources/publ import { UDWContext, + SelectionConfigContext, SelectedLocationsContext, RestInfoContext, MultipleConfigContext, @@ -23,19 +24,23 @@ const TreeItemToggleSelection = ({ locationId, isContainer, contentTypeIdentifie parseTooltip(document.querySelector('.c-list')); }, []); - if (!isUDW) { - return null; - } - + const { isInitLocationsDeselectionBlocked, initSelectedLocations } = useContext(SelectionConfigContext); const [selectedLocations, dispatchSelectedLocationsAction] = useContext(SelectedLocationsContext); const [multiple, multipleItemsLimit] = useContext(MultipleConfigContext); const containersOnly = useContext(ContainersOnlyContext); const allowedContentTypes = useContext(AllowedContentTypesContext); const restInfo = useContext(RestInfoContext); + + if (!isUDW) { + return null; + } + const isSelected = selectedLocations.some((selectedLocation) => selectedLocation.location.id === locationId); const isNotSelectable = (containersOnly && !isContainer) || (allowedContentTypes && !allowedContentTypes.includes(contentTypeIdentifier)); const isSelectionBlocked = multipleItemsLimit !== 0 && !isSelected && selectedLocations.length >= multipleItemsLimit; + const isInitSelectedLocation = initSelectedLocations.includes(locationId); + const isDeselectionBlocked = isSelected && isInitSelectedLocation && isInitLocationsDeselectionBlocked; const location = { id: locationId, }; @@ -51,7 +56,12 @@ const TreeItemToggleSelection = ({ locationId, isContainer, contentTypeIdentifie return ( - + {isNotSelectable &&
} ); diff --git a/src/bundle/ui-dev/src/modules/universal-discovery/hooks/useSelectedLocationsHelpers.js b/src/bundle/ui-dev/src/modules/universal-discovery/hooks/useSelectedLocationsHelpers.js index b8400a849c..bd08d0567d 100644 --- a/src/bundle/ui-dev/src/modules/universal-discovery/hooks/useSelectedLocationsHelpers.js +++ b/src/bundle/ui-dev/src/modules/universal-discovery/hooks/useSelectedLocationsHelpers.js @@ -7,12 +7,14 @@ import { ContentTypesMapContext, MultipleConfigContext, SelectedLocationsContext, + SelectionConfigContext, } from '../universal.discovery.module'; export const useSelectedLocationsHelpers = () => { const [, multipleItemsLimit] = useContext(MultipleConfigContext); const contentTypesMap = useContext(ContentTypesMapContext); const [selectedLocations] = useContext(SelectedLocationsContext); + const { isInitLocationsDeselectionBlocked, initSelectedLocations } = useContext(SelectionConfigContext); const containersOnly = useContext(ContainersOnlyContext); const allowedContentTypes = useContext(AllowedContentTypesContext); const checkIsSelectableWrapped = useCallback( @@ -24,10 +26,17 @@ export const useSelectedLocationsHelpers = () => { (location) => checkIsSelectionBlocked({ location, selectedLocations, multipleItemsLimit }), [selectedLocations, multipleItemsLimit], ); + const checkIsDeselectionBlockedWrapped = (location) => { + const isLocationSelected = checkIsSelected({ location, selectedLocations }); + const isInitSelectedLocation = initSelectedLocations.includes(location.id); + + return isLocationSelected && isInitSelectedLocation && isInitLocationsDeselectionBlocked; + }; return { checkIsSelectable: checkIsSelectableWrapped, checkIsSelected: checkIsSelectedWrapped, checkIsSelectionBlocked: checkIsSelectionBlockedWrapped, + checkIsDeselectionBlocked: checkIsDeselectionBlockedWrapped, }; }; diff --git a/src/bundle/ui-dev/src/modules/universal-discovery/universal.discovery.module.js b/src/bundle/ui-dev/src/modules/universal-discovery/universal.discovery.module.js index cec9ce9c2b..d4b5a27d26 100644 --- a/src/bundle/ui-dev/src/modules/universal-discovery/universal.discovery.module.js +++ b/src/bundle/ui-dev/src/modules/universal-discovery/universal.discovery.module.js @@ -186,6 +186,7 @@ export const StartingLocationIdContext = createContext(); export const LoadedLocationsMapContext = createContext(); export const RootLocationIdContext = createContext(); export const SelectedLocationsContext = createContext(); +export const SelectionConfigContext = createContext(); export const CreateContentWidgetContext = createContext(); export const ContentOnTheFlyDataContext = createContext(); export const ContentOnTheFlyConfigContext = createContext(); @@ -518,61 +519,70 @@ const UniversalDiscoveryModule = (props) => { - - - - - - - - - - - - - - - - - + + + + + + + + + + + @@ -633,6 +643,7 @@ UniversalDiscoveryModule.propTypes = { }), ).isRequired, selectedLocations: PropTypes.array, + isInitLocationsDeselectionBlocked: PropTypes.bool, allowRedirects: PropTypes.bool.isRequired, allowConfirmation: PropTypes.bool.isRequired, restInfo: PropTypes.shape({ @@ -656,6 +667,7 @@ UniversalDiscoveryModule.defaultProps = { activeSortOrder: 'ascending', activeView: 'finder', selectedLocations: [], + isInitLocationsDeselectionBlocked: false, restInfo: defaultRestInfo, snackbarEnabledActions: Object.values(SNACKBAR_ACTIONS), };