Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/7.3' into 8.0
Browse files Browse the repository at this point in the history
  • Loading branch information
markusguenther committed Dec 18, 2023
2 parents cce5fb4 + faa448a commit 1b3b36e
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 8 deletions.
4 changes: 2 additions & 2 deletions packages/neos-ui-editors/src/Editors/AssetEditor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export default class AssetEditor extends PureComponent {
<SelectBox
optionValueField="identifier"
loadingLabel={this.props.i18nRegistry.translate('Neos.Neos:Main:loading')}
displaySearchBox={true}
displaySearchBox={this.isFeatureEnabled('mediaBrowser')}
ListPreviewElement={AssetOption}
placeholder={this.props.i18nRegistry.translate(this.props.placeholder)}
options={this.props.value ? this.state.options : this.state.searchOptions}
Expand All @@ -265,7 +265,7 @@ export default class AssetEditor extends PureComponent {
dndType={dndTypes.MULTISELECT}
optionValueField="identifier"
loadingLabel={this.props.i18nRegistry.translate('Neos.Neos:Main:loading')}
displaySearchBox={true}
displaySearchBox={this.isFeatureEnabled('mediaBrowser')}
ListPreviewElement={AssetOption}
placeholder={this.props.i18nRegistry.translate(this.props.placeholder)}
options={this.state.options || []}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import MultiSelectBox from '@neos-project/react-ui-components/src/MultiSelectBox
import {selectors} from '@neos-project/neos-ui-redux-store';
import {neos} from '@neos-project/neos-ui-decorators';
import {shouldDisplaySearchBox, searchOptions, processSelectBoxOptions} from './SelectBoxHelpers';
import {createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue} from './createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue';
import PreviewOption from '../../Library/PreviewOption';

const getDataLoaderOptionsForProps = props => ({
Expand All @@ -30,7 +31,17 @@ export default class DataSourceBasedSelectBoxEditor extends PureComponent {
className: PropTypes.string,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.arrayOf(PropTypes.string)
PropTypes.arrayOf(PropTypes.string),
PropTypes.shape({
__identity: PropTypes.string.isRequired,
__type: PropTypes.string
}),
PropTypes.arrayOf(
PropTypes.shape({
__identity: PropTypes.string.isRequired,
__type: PropTypes.string
})
)
]),
options: PropTypes.shape({
allowEmpty: PropTypes.bool,
Expand Down Expand Up @@ -101,8 +112,23 @@ export default class DataSourceBasedSelectBoxEditor extends PureComponent {
});
}

get valueForSingleSelect() {
const {value} = this.props;
return createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue(value);
}

get valueForMultiSelect() {
const {value} = this.props;

if (Array.isArray(value)) {
return value.map(createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue);
}

return value ? [createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue(value)] : [];
}

render() {
const {commit, value, i18nRegistry, className} = this.props;
const {commit, i18nRegistry, className} = this.props;
const options = Object.assign({}, this.constructor.defaultOptions, this.props.options);

const processedSelectBoxOptions = processSelectBoxOptions(i18nRegistry, this.state.selectBoxOptions);
Expand All @@ -115,7 +141,7 @@ export default class DataSourceBasedSelectBoxEditor extends PureComponent {
return (<MultiSelectBox
className={className}
options={processedSelectBoxOptions}
values={value || []}
values={this.valueForMultiSelect}
onValuesChange={commit}
loadingLabel={loadingLabel}
ListPreviewElement={PreviewOption}
Expand All @@ -136,7 +162,7 @@ export default class DataSourceBasedSelectBoxEditor extends PureComponent {
return (<SelectBox
className={className}
options={this.state.searchTerm ? searchOptions(this.state.searchTerm, processedSelectBoxOptions) : processedSelectBoxOptions}
value={value}
value={this.valueForSingleSelect}
onValueChange={commit}
loadingLabel={loadingLabel}
ListPreviewElement={PreviewOption}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue} from './createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue';

describe('createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue', () => {
it('accepts value of type "string" and returns a "string"', () => {
const value =
createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue(
'I am already a valid select box value, believe it or not.'
);

expect(value).toEqual(
'I am already a valid select box value, believe it or not.'
);
});

it('accepts an object identity DTO and returns a "string"', () => {
const value =
createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue({
__identity: 'de93b358-cb77-422e-b295-2f219bfc4dfb',
__type: 'Neos\\Media\\Domain\\Model\\Tag',
});

expect(value).toEqual('de93b358-cb77-422e-b295-2f219bfc4dfb');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* @TODO I am a cry for help!
*
* This is an ad-hoc solution to the problem that properties of a PHP class type
* (like "Neos\Media\Domain\Model\Tag" for example) may or may not be persisted
* as object identity DTOs.
*
* The function name is intentionally kept vague to allow bugfixes to capture
* more, potentially obscure cases in which the persisted property value needs
* to be filtered before the select box receives it.
*
* A proper way to handle this would be to define precisely what kind of values
* the select box editor is going to accept and simply reject everything that
* violates that definition. Errors would need to be handled in way that
* indicates to editors that there's a problem that an integrator needs to fix.
* Furthermore the error handling should make it easy for integrators to figure
* out what value has been provided to the select box and why it has been
* rejected.
*
* That however would constitute a breaking change and that's how we end up
* with with this function.
*/
export const createSelectBoxValueStringFromPossiblyStrangeNodePropertyValue = (
value: unknown
) => {
if (typeof value === 'object' && value !== null) {
if (
'__identity' in value &&
typeof (value as Record<'__identity', any>).__identity === 'string'
) {
return (value as Record<'__identity', string>).__identity;
}
}

return value;
};
2 changes: 1 addition & 1 deletion packages/react-ui-components/src/DropDown/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
position: absolute;
top: 100%;
left: 0;
z-index: var(--zIndex-DropdownContents-Context);
z-index: var(--zIndex-SecondaryInspectorElevated-DropDownContents);
display: none;
width: 100%;
margin: 0;
Expand Down
2 changes: 1 addition & 1 deletion packages/react-ui-components/src/SelectBox/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
.selectBox__contents {
min-width: 160px;
box-shadow: 0 5px 5px rgba(#000, .2);
z-index: var(--zIndex-SelectBoxContents);
z-index: var(--zIndex-SecondaryInspectorElevated-DropDownContents);
margin-top: -2px;
}

Expand Down

0 comments on commit 1b3b36e

Please sign in to comment.