diff --git a/i18n/en.pot b/i18n/en.pot index e7344df04a..743ed3645c 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2024-02-16T10:12:05.207Z\n" -"PO-Revision-Date: 2024-02-16T10:12:05.207Z\n" +"POT-Creation-Date: 2024-02-20T11:20:56.384Z\n" +"PO-Revision-Date: 2024-02-20T11:20:56.384Z\n" msgid "All items" msgstr "All items" @@ -63,6 +63,13 @@ msgstr "" "'Scatter' is intended to show a single data item per axis. Only the first " "item will be used and saved." +msgid "" +"'Outlier table' can only use data elements. Only data elements will be used " +"and saved." +msgstr "" +"'Outlier table' can only use data elements. Only data elements will be used " +"and saved." + msgid "Vertical" msgstr "Vertical" diff --git a/src/components/DimensionsPanel/Dialogs/DialogManager.js b/src/components/DimensionsPanel/Dialogs/DialogManager.js index ccab6397f4..c72a331c4d 100644 --- a/src/components/DimensionsPanel/Dialogs/DialogManager.js +++ b/src/components/DimensionsPanel/Dialogs/DialogManager.js @@ -321,6 +321,7 @@ export class DialogManager extends Component { item.isActive = index < 1 }) } + let content = null if ( dialogId === DIMENSION_ID_DATA || @@ -353,6 +354,24 @@ export class DialogManager extends Component { }, }) } + + if (visType === VIS_TYPE_OUTLIER_TABLE) { + let showInfo = false + + selectedItems.forEach((item) => { + if (item.type !== DIMENSION_TYPE_DATA_ELEMENT) { + item.isActive = false + showInfo = true + } + }) + + if (showInfo) { + infoBoxMessage = i18n.t( + `'Outlier table' can only use data elements. Only data elements will be used and saved.` + ) + } + } + const dimensionSelector = ( ) - const isSplitAxis = - type === VIS_TYPE_SCATTER && dimensionId === DIMENSION_ID_DATA - const getMaxNumberOfItems = () => getAxisMaxNumberOfItems(type, axisId) || getDimensionMaxNumberOfItems(type, dimensionId) + let activeItemIds = getMaxNumberOfItems() + ? items.slice(0, getMaxNumberOfItems()) + : items + + // filter out non DATA_ELEMENT types for Outlier table vis type + if (type === VIS_TYPE_OUTLIER_TABLE && dimensionId === DIMENSION_ID_DATA) { + activeItemIds = activeItemIds.filter( + (id) => + metadata[id]?.dimensionItemType === DIMENSION_TYPE_DATA_ELEMENT + ) + } + + const hasWarning = + hasAxisTooManyItems(type, axisId, items.length) || + hasDimensionTooManyItems(type, dimensionId, items.length) || + items.length > activeItemIds.length + + const isSplitAxis = + type === VIS_TYPE_SCATTER && dimensionId === DIMENSION_ID_DATA + const handleClick = () => { if (!getPredefinedDimensionProp(dimensionId, DIMENSION_PROP_NO_ITEMS)) { onClick() @@ -124,9 +143,6 @@ const Chip = ({ } const renderTooltipContent = () => { - const activeItemIds = getMaxNumberOfItems() - ? items.slice(0, getMaxNumberOfItems()) - : items const lockedLabel = isLocked ? i18n.t( `{{dimensionName}} is locked to {{axisName}} for {{visTypeName}}`, @@ -162,9 +178,7 @@ const Chip = ({ {renderChipLabelSuffix()} - {(hasAxisTooManyItems(type, axisId, items.length) || - hasDimensionTooManyItems(type, dimensionId, items.length)) && - WarningIconWrapper} + {hasWarning && WarningIconWrapper} {isLocked && LockIconWrapper} ) diff --git a/src/components/Layout/TooltipContent.js b/src/components/Layout/TooltipContent.js index f1e2ed7b32..710b5b41ce 100644 --- a/src/components/Layout/TooltipContent.js +++ b/src/components/Layout/TooltipContent.js @@ -9,6 +9,7 @@ import { styles } from './styles/Tooltip.style.js' const labels = { noneSelected: () => i18n.t('None selected'), + noneInUse: () => i18n.t('None in use'), onlyOneInUse: (name) => i18n.t("Only '{{- name}}' in use", { name }), onlyLimitedNumberInUse: (number) => i18n.t("Only '{{number}}' in use", { number }), @@ -25,7 +26,9 @@ export const TooltipContent = ({ const hasAllItemsSelected = itemIds.includes(ALL_DYNAMIC_DIMENSION_ITEMS) const getWarningLabel = () => { const warningLabel = - itemIds.length === 1 + itemIds.length === 0 + ? labels.noneInUse() + : itemIds.length === 1 ? labels.onlyOneInUse( metadata[itemIds[0]] ? metadata[itemIds[0]].name diff --git a/src/modules/current.js b/src/modules/current.js index 85be0e6f2d..380191f4a7 100644 --- a/src/modules/current.js +++ b/src/modules/current.js @@ -6,6 +6,7 @@ import { AXIS_ID_FILTERS, DIMENSION_ID_DATA, DIMENSION_ID_PERIOD, + DIMENSION_TYPE_DATA_ELEMENT, VIS_TYPE_OUTLIER_TABLE, VIS_TYPE_SINGLE_VALUE, VIS_TYPE_PIE, @@ -139,7 +140,7 @@ export const getItemsByDimensionFromUi = (ui) => { return result } -export const getOutlierTableCurrentFromUi = (state, value) => { +export const getOutlierTableCurrentFromUi = (state, value, metadata) => { const ui = { ...value, layout: { @@ -150,13 +151,25 @@ export const getOutlierTableCurrentFromUi = (state, value) => { const axesFromUi = getAxesFromUi(ui) - // only save the first pe item const peItems = layoutGetDimensionItems(axesFromUi, DIMENSION_ID_PERIOD) - const outlierTableAxesFromUi = layoutReplaceDimension( - axesFromUi, - DIMENSION_ID_PERIOD, - [peItems[0]] - ) + const dxItems = layoutGetDimensionItems(axesFromUi, DIMENSION_ID_DATA) + + const outlierTableAxesFromUi = + // only save the first pe item + layoutReplaceDimension( + // only save data elements dx items + layoutReplaceDimension( + axesFromUi, + DIMENSION_ID_DATA, + dxItems.filter( + ({ id }) => + metadata[id]?.dimensionItemType === + DIMENSION_TYPE_DATA_ELEMENT + ) + ), + DIMENSION_ID_PERIOD, + [peItems[0]] + ) return { ...state, diff --git a/src/reducers/current.js b/src/reducers/current.js index 7a7fca686b..082d524db6 100644 --- a/src/reducers/current.js +++ b/src/reducers/current.js @@ -63,7 +63,11 @@ export default (state = DEFAULT_CURRENT, action) => { case VIS_TYPE_SCATTER: return getScatterCurrentFromUi(state, action.value.ui) case VIS_TYPE_OUTLIER_TABLE: - return getOutlierTableCurrentFromUi(state, action.value.ui) + return getOutlierTableCurrentFromUi( + state, + action.value.ui, + action.value.metadata + ) default: { return getDefaultFromUi( state,