diff --git a/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/DimensionSelector.js b/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/DimensionSelector.js
index 084874e4eb..4ec9816566 100644
--- a/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/DimensionSelector.js
+++ b/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/DimensionSelector.js
@@ -2,7 +2,7 @@ import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import SelectBox from '@neos-project/react-ui-components/src/SelectBox/';
import style from './style.module.css';
-import {$get, $transform} from 'plow-js';
+import {$transform} from 'plow-js';
import mapValues from 'lodash.mapvalues';
import sortBy from 'lodash.sortby';
import {neos} from '@neos-project/neos-ui-decorators';
@@ -48,9 +48,11 @@ export default class DimensionSelector extends PureComponent {
(presetConfiguration, presetName) => {
return $transform(
{
- label: $get('label'),
+ label: presetConfiguration?.label,
value: presetName,
- disallowed: $get('disallowed')
+ disallowed: presetConfiguration?.disallowed,
+ existing: presetConfiguration?.existing,
+ url: presetConfiguration?.url
},
presetConfiguration
);
diff --git a/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/DimensionSelectorOption.js b/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/DimensionSelectorOption.js
index e580931b2f..ea8e0402f6 100644
--- a/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/DimensionSelectorOption.js
+++ b/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/DimensionSelectorOption.js
@@ -1,25 +1,51 @@
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import style from './style.module.css';
-// eslint-disable-next-line camelcase
+import SelectBox_Option_SingleLineLink from '@neos-project/react-ui-components/src/SelectBox_Option_SingleLineLink/index';
import SelectBox_Option_SingleLine from '@neos-project/react-ui-components/src/SelectBox_Option_SingleLine/index';
+import mergeClassNames from 'classnames';
export default class DimensionSelectorOption extends PureComponent {
static propTypes = {
option: PropTypes.shape({
label: PropTypes.string.isRequired,
- disallowed: PropTypes.bool
+ disallowed: PropTypes.bool,
+ existing: PropTypes.bool,
+ url: PropTypes.string
})
};
render() {
const {option} = this.props;
+ const className = mergeClassNames({
+ [style.lighter]: !option.existing,
+ [style.strikethrough]: option.disallowed
+ });
+
+ if (option.existing) {
+ const linkOptions = {
+ className: style.whiteLink,
+ href: option.url,
+ target: '_blank',
+ rel: 'noopener noreferrer',
+ onClick: (event) => event.preventDefault()
+ }
+
+ return (
+
+ );
+ }
+
return (
- // eslint-disable-next-line camelcase
);
diff --git a/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/index.js b/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/index.js
index 1c71e90942..3ecf7ac612 100644
--- a/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/index.js
+++ b/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/index.js
@@ -33,7 +33,9 @@ SelectedPreset.propTypes = {
@connect($transform({
contentDimensions: selectors.CR.ContentDimensions.byName,
allowedPresets: selectors.CR.ContentDimensions.allowedPresets,
- activePresets: selectors.CR.ContentDimensions.activePresets
+ activePresets: selectors.CR.ContentDimensions.activePresets,
+ getNodeByContextPath: selectors.CR.Nodes.nodeByContextPath,
+ documentNode: selectors.CR.Nodes.documentNodeSelector
}), {
selectPreset: actions.CR.ContentDimensions.selectPreset,
setAllowed: actions.CR.ContentDimensions.setAllowed
@@ -255,15 +257,58 @@ export default class DimensionSwitcher extends PureComponent {
return null;
}
+ getExistingDimensions() {
+ const allowed = this.props.allowedPresets
+ const currentDocumentNode = this.props.getNodeByContextPath(this.props.documentNode.contextPath)
+ const dimensionsWithVariants = currentDocumentNode?.otherNodeVariants;
+ if (!dimensionsWithVariants) {
+ return [currentDocumentNode.dimensions]
+ }
+
+ const existingDimensions = {};
+ Object.keys(allowed).forEach((dimensionName) => {
+ const dimensionValues = allowed[dimensionName];
+
+ existingDimensions[dimensionName] = [];
+ Array.from(dimensionValues).forEach((dimensionValue) => {
+ const result = [...dimensionsWithVariants, currentDocumentNode.dimensions].find((dimension) => {
+ return dimension[dimensionName] === dimensionValue;
+ });
+ if (result) {
+ existingDimensions[dimensionName].push(dimensionValue);
+ }
+ });
+ });
+
+ return existingDimensions;
+ }
+
presetsForDimension(dimensionName) {
const {contentDimensions, allowedPresets, i18nRegistry} = this.props;
const dimensionConfiguration = $get(dimensionName, contentDimensions);
+ const existingDimensions = this.getExistingDimensions();
return mapValues(dimensionConfiguration.presets,
(presetConfiguration, presetName) => {
+ // if we do not know which dimensions exist, show all as existing
+ let existing = existingDimensions.length === 1 && existingDimensions[0] === undefined;
+ for (const value of presetConfiguration.values) {
+ if (existingDimensions[dimensionName]?.includes(value)) {
+ existing = true;
+ }
+ }
+
+ const uri = new URL(window.location.href);
+ const contextPathWithoutDimensions = this.props.documentNode.contextPath.split(';')[0];
+ const uriDimension = ';' + dimensionName + '=' + presetConfiguration.values.join(',')
+ uri.searchParams.set('node', contextPathWithoutDimensions + uriDimension);
+ const url = uri.toString();
+
return Object.assign({}, presetConfiguration, {
label: i18nRegistry.translate(presetConfiguration.label),
- disallowed: !(allowedPresets[dimensionName] && allowedPresets[dimensionName].includes(presetName))
+ disallowed: !(allowedPresets[dimensionName] && allowedPresets[dimensionName].includes(presetName)),
+ existing,
+ url
});
});
}
diff --git a/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/style.module.css b/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/style.module.css
index d3a87a2db3..3ca0316d25 100644
--- a/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/style.module.css
+++ b/packages/neos-ui/src/Containers/PrimaryToolbar/DimensionSwitcher/style.module.css
@@ -60,8 +60,16 @@
}
}
-.dimmed {
- filter: opacity(50%);
+.strikethrough {
+ text-decoration: line-through;
+}
+
+.lighter {
+ filter: opacity(75%);
+}
+
+.whiteLink {
+ color: white;
}
.selectPreset + .selectPreset {
diff --git a/packages/react-ui-components/src/SelectBox_Option_SingleLineLink/index.js b/packages/react-ui-components/src/SelectBox_Option_SingleLineLink/index.js
new file mode 100644
index 0000000000..555e6811d6
--- /dev/null
+++ b/packages/react-ui-components/src/SelectBox_Option_SingleLineLink/index.js
@@ -0,0 +1,4 @@
+/* eslint-disable camelcase, react/jsx-pascal-case */
+import SelectBox_Option_SingleLineLink from './selectBox_Option_SingleLineLink';
+
+export default SelectBox_Option_SingleLineLink;
diff --git a/packages/react-ui-components/src/SelectBox_Option_SingleLineLink/selectBox_Option_SingleLineLink.js b/packages/react-ui-components/src/SelectBox_Option_SingleLineLink/selectBox_Option_SingleLineLink.js
new file mode 100644
index 0000000000..e822fa58d3
--- /dev/null
+++ b/packages/react-ui-components/src/SelectBox_Option_SingleLineLink/selectBox_Option_SingleLineLink.js
@@ -0,0 +1,39 @@
+/* eslint-disable camelcase, react/jsx-pascal-case */
+import React, {PureComponent} from 'react';
+import PropTypes from 'prop-types';
+import ListPreviewElement from '../ListPreviewElement';
+import mergeClassNames from 'classnames';
+
+class SelectBox_Option_SingleLineLink extends PureComponent {
+ static propTypes = {
+ option: PropTypes.shape({
+ label: PropTypes.string.isRequired,
+ icon: PropTypes.string,
+ disabled: PropTypes.bool
+ }).isRequired,
+
+ disabled: PropTypes.bool,
+
+ className: PropTypes.string
+ }
+
+ render() {
+ const {option, className, disabled, icon, linkOptions} = this.props;
+
+ const isDisabled = disabled || option.disabled;
+
+ const finalClassNames = mergeClassNames({
+ [className]: className
+ });
+
+ const previewElementIcon = option.icon ? option.icon : (icon ? icon : null);
+
+ return (
+
+ {option.label}
+
+ );
+ }
+}
+
+export default SelectBox_Option_SingleLineLink;