mirror of
https://github.com/strapi/strapi.git
synced 2025-12-26 06:35:47 +00:00
Add select one relation
Signed-off-by: soupette <cyril@strapi.io>
This commit is contained in:
parent
c078f81823
commit
03e11f2b13
@ -31,6 +31,20 @@
|
||||
"relation": "manyToMany",
|
||||
"target": "api::address.address",
|
||||
"mappedBy": "categories"
|
||||
},
|
||||
"temps": {
|
||||
"type": "relation",
|
||||
"relation": "manyToMany",
|
||||
"target": "api::temp.temp",
|
||||
"mappedBy": "categories"
|
||||
},
|
||||
"date": {
|
||||
"pluginOptions": {
|
||||
"i18n": {
|
||||
"localized": true
|
||||
}
|
||||
},
|
||||
"type": "date"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
"description": ""
|
||||
},
|
||||
"options": {
|
||||
"draftAndPublish": false
|
||||
"draftAndPublish": true
|
||||
},
|
||||
"pluginOptions": {},
|
||||
"attributes": {
|
||||
@ -17,35 +17,16 @@
|
||||
"type": "string",
|
||||
"pluginOptions": {}
|
||||
},
|
||||
"simple": {
|
||||
"pluginOptions": {},
|
||||
"type": "uid"
|
||||
"category": {
|
||||
"type": "relation",
|
||||
"relation": "oneToOne",
|
||||
"target": "api::category.category"
|
||||
},
|
||||
"attached": {
|
||||
"pluginOptions": {},
|
||||
"type": "uid",
|
||||
"targetField": "name"
|
||||
},
|
||||
"attached_req": {
|
||||
"pluginOptions": {},
|
||||
"type": "uid",
|
||||
"targetField": "name",
|
||||
"required": true
|
||||
},
|
||||
"req": {
|
||||
"pluginOptions": {},
|
||||
"type": "uid",
|
||||
"required": true
|
||||
},
|
||||
"default_val": {
|
||||
"pluginOptions": {},
|
||||
"type": "uid",
|
||||
"default": "to",
|
||||
"minLength": 4
|
||||
},
|
||||
"date": {
|
||||
"type": "date",
|
||||
"required": true
|
||||
"categories": {
|
||||
"type": "relation",
|
||||
"relation": "manyToMany",
|
||||
"target": "api::category.category",
|
||||
"inversedBy": "temps"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ const LabelAction = styled(Box)`
|
||||
|
||||
const Label = ({ intlLabel, id, labelAction, name, numberOfEntries, showNumberOfEntries }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const label = intlLabel?.id ? formatMessage(intlLabel) : '';
|
||||
const label = intlLabel?.id ? formatMessage(intlLabel) : name;
|
||||
|
||||
return (
|
||||
<Row>
|
||||
|
||||
@ -1,46 +1,53 @@
|
||||
import React from 'react';
|
||||
import { components } from 'react-select';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get, has, isEmpty } from 'lodash';
|
||||
import { Flex, Padded, Text } from '@buffetjs/core';
|
||||
import { RelationDPState } from '@strapi/helper-plugin';
|
||||
import { getDisplayedValue } from '../../utils';
|
||||
import styled from 'styled-components';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { pxToRem } from '@strapi/helper-plugin';
|
||||
import { Row } from '@strapi/parts/Row';
|
||||
import { Text } from '@strapi/parts/Text';
|
||||
import get from 'lodash/get';
|
||||
import has from 'lodash/has';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import { getTrad } from '../../utils';
|
||||
|
||||
const StyledBullet = styled.div`
|
||||
width: ${pxToRem(6)};
|
||||
height: ${pxToRem(6)};
|
||||
margin-right: ${({ theme }) => theme.spaces[2]};
|
||||
background: ${({ theme, isDraft }) => theme.colors[isDraft ? 'secondary700' : 'success200']};
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
const SingleValue = props => {
|
||||
const { formatMessage } = useIntl();
|
||||
const Component = components.SingleValue;
|
||||
const hasDraftAndPublish = has(get(props, 'data.value'), 'publishedAt');
|
||||
const isDraft = isEmpty(get(props, 'data.value.publishedAt'));
|
||||
const mainField = get(props, ['selectProps', 'mainField'], {});
|
||||
const value = getDisplayedValue(mainField.schema.type, props.data.label, mainField.name);
|
||||
|
||||
if (hasDraftAndPublish) {
|
||||
const draftMessage = {
|
||||
id: getTrad('components.Select.draft-info-title'),
|
||||
defaultMessage: 'State: Draft',
|
||||
};
|
||||
const publishedMessage = {
|
||||
id: getTrad('components.Select.publish-info-title'),
|
||||
defaultMessage: 'State: Published',
|
||||
};
|
||||
const title = isDraft ? formatMessage(draftMessage) : formatMessage(publishedMessage);
|
||||
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Padded left size="sm" right>
|
||||
<Flex>
|
||||
<RelationDPState
|
||||
marginLeft="0"
|
||||
marginTop="1px"
|
||||
marginRight="10px"
|
||||
isDraft={isDraft}
|
||||
marginBottom="0"
|
||||
/>
|
||||
<div>
|
||||
<Text ellipsis>{value}</Text>
|
||||
</div>
|
||||
</Flex>
|
||||
</Padded>
|
||||
<Row>
|
||||
<StyledBullet title={title} isDraft={isDraft} />
|
||||
<Text ellipsis>{props.data.label || '-'}</Text>
|
||||
</Row>
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Padded left right size="sm">
|
||||
{value}
|
||||
</Padded>
|
||||
</Component>
|
||||
);
|
||||
return <Component {...props}>{props.data.label || '-'}</Component>;
|
||||
};
|
||||
|
||||
SingleValue.propTypes = {
|
||||
|
||||
@ -22,7 +22,10 @@ function SelectOne({
|
||||
}) {
|
||||
return (
|
||||
<Select
|
||||
components={{ ...components, SingleValue }}
|
||||
components={{
|
||||
...components,
|
||||
SingleValue,
|
||||
}}
|
||||
id={name}
|
||||
isClearable
|
||||
isDisabled={isDisabled}
|
||||
@ -43,6 +46,7 @@ function SelectOne({
|
||||
|
||||
SelectOne.defaultProps = {
|
||||
components: {},
|
||||
placeholder: null,
|
||||
value: null,
|
||||
};
|
||||
|
||||
@ -63,7 +67,10 @@ SelectOne.propTypes = {
|
||||
onMenuOpen: PropTypes.func.isRequired,
|
||||
onMenuScrollToBottom: PropTypes.func.isRequired,
|
||||
options: PropTypes.array.isRequired,
|
||||
placeholder: PropTypes.node.isRequired,
|
||||
placeholder: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
defaultMessage: PropTypes.string.isRequired,
|
||||
}),
|
||||
styles: PropTypes.object.isRequired,
|
||||
value: PropTypes.object,
|
||||
};
|
||||
|
||||
@ -1,13 +1,16 @@
|
||||
import React from 'react';
|
||||
import { Remove } from '@buffetjs/icons';
|
||||
import { components } from 'react-select';
|
||||
import CloseAlertIcon from '@strapi/icons/CloseAlertIcon';
|
||||
import IconBox from './IconBox';
|
||||
|
||||
const ClearIndicator = props => {
|
||||
const Component = components.ClearIndicator;
|
||||
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Remove width="11px" height="11px" fill="#9EA7B8" />
|
||||
<IconBox as="button" type="button">
|
||||
<CloseAlertIcon />
|
||||
</IconBox>
|
||||
</Component>
|
||||
);
|
||||
};
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import DropdownIcon from '@strapi/icons/FilterDropdownIcon';
|
||||
import IconBox from './IconBox';
|
||||
|
||||
export const CaretBox = styled(IconBox)`
|
||||
display: flex;
|
||||
background: none;
|
||||
border: none;
|
||||
|
||||
svg {
|
||||
width: ${6 / 16}rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const DropdownIndicator = () => {
|
||||
return (
|
||||
<CaretBox as="button" type="button" paddingRight={3}>
|
||||
<DropdownIcon />
|
||||
</CaretBox>
|
||||
);
|
||||
};
|
||||
|
||||
export default DropdownIndicator;
|
||||
@ -0,0 +1,20 @@
|
||||
import styled from 'styled-components';
|
||||
import { Box } from '@strapi/parts/Box';
|
||||
|
||||
export const IconBox = styled(Box)`
|
||||
background: transparent;
|
||||
border: none;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
svg {
|
||||
height: ${11 / 16}rem;
|
||||
width: ${11 / 16}rem;
|
||||
}
|
||||
|
||||
svg path {
|
||||
fill: ${({ theme }) => theme.colors.neutral600};
|
||||
}
|
||||
`;
|
||||
|
||||
export default IconBox;
|
||||
@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useIntl } from 'react-intl';
|
||||
import styled from 'styled-components';
|
||||
import { Box } from '@strapi/parts/Box';
|
||||
import { Row } from '@strapi/parts/Row';
|
||||
import { Text } from '@strapi/parts/Text';
|
||||
|
||||
const LabelAction = styled(Box)`
|
||||
svg path {
|
||||
fill: ${({ theme }) => theme.colors.neutral500};
|
||||
}
|
||||
`;
|
||||
|
||||
const Label = ({ intlLabel, id, labelAction, link, name, numberOfEntries, isSingle }) => {
|
||||
const { formatMessage } = useIntl();
|
||||
const label = intlLabel?.id ? formatMessage(intlLabel) : name;
|
||||
|
||||
return (
|
||||
<Row justifyContent="space-between">
|
||||
<Row>
|
||||
<Text textColor="neutral800" htmlFor={id || name} small bold as="label">
|
||||
{label}
|
||||
{!isSingle && <> ({numberOfEntries})</>}
|
||||
</Text>
|
||||
{labelAction && <LabelAction paddingLeft={1}>{labelAction}</LabelAction>}
|
||||
</Row>
|
||||
{link}
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
Label.defaultProps = {
|
||||
id: undefined,
|
||||
labelAction: undefined,
|
||||
link: null,
|
||||
numberOfEntries: 0,
|
||||
};
|
||||
|
||||
Label.propTypes = {
|
||||
id: PropTypes.string,
|
||||
intlLabel: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
defaultMessage: PropTypes.string.isRequired,
|
||||
values: PropTypes.object,
|
||||
}).isRequired,
|
||||
isSingle: PropTypes.bool.isRequired,
|
||||
labelAction: PropTypes.element,
|
||||
link: PropTypes.element,
|
||||
name: PropTypes.string.isRequired,
|
||||
numberOfEntries: PropTypes.number,
|
||||
};
|
||||
|
||||
export default Label;
|
||||
@ -4,12 +4,18 @@ import { components } from 'react-select';
|
||||
import { useIntl } from 'react-intl';
|
||||
import PropTypes from 'prop-types';
|
||||
import { get, has, isEmpty } from 'lodash';
|
||||
import { Flex, Text } from '@buffetjs/core';
|
||||
import { RelationDPState } from '@strapi/helper-plugin';
|
||||
import { getDisplayedValue, getTrad } from '../../utils';
|
||||
import { Row } from '@strapi/parts/Row';
|
||||
import { Text } from '@strapi/parts/Text';
|
||||
import { pxToRem } from '@strapi/helper-plugin';
|
||||
import { getTrad } from '../../utils';
|
||||
|
||||
const TextGrow = styled(Text)`
|
||||
flex-grow: 2;
|
||||
const StyledBullet = styled.div`
|
||||
width: ${pxToRem(6)};
|
||||
height: ${pxToRem(6)};
|
||||
margin-right: ${({ theme }) => theme.spaces[2]};
|
||||
background: ${({ theme, isDraft }) => theme.colors[isDraft ? 'secondary700' : 'success200']};
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
const Option = props => {
|
||||
@ -17,42 +23,31 @@ const Option = props => {
|
||||
const Component = components.Option;
|
||||
const hasDraftAndPublish = has(get(props, 'data.value'), 'publishedAt');
|
||||
const isDraft = isEmpty(get(props, 'data.value.publishedAt'));
|
||||
const titleLabelID = isDraft
|
||||
? 'components.Select.draft-info-title'
|
||||
: 'components.Select.publish-info-title';
|
||||
const title = formatMessage({ id: getTrad(titleLabelID) });
|
||||
const fontWeight = props.isFocused ? 'bold' : 'regular';
|
||||
const mainField = get(props, ['selectProps', 'mainField'], {});
|
||||
const value = getDisplayedValue(mainField.schema.type, props.label, mainField.name);
|
||||
|
||||
if (hasDraftAndPublish) {
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Flex>
|
||||
<RelationDPState
|
||||
marginLeft="0"
|
||||
marginTop="1px"
|
||||
marginRight="10px"
|
||||
isDraft={isDraft}
|
||||
marginBottom="0"
|
||||
title={title}
|
||||
/>
|
||||
if (hasDraftAndPublish) {
|
||||
const draftMessage = {
|
||||
id: getTrad('components.Select.draft-info-title'),
|
||||
defaultMessage: 'State: Draft',
|
||||
};
|
||||
const publishedMessage = {
|
||||
id: getTrad('components.Select.publish-info-title'),
|
||||
defaultMessage: 'State: Published',
|
||||
};
|
||||
const title = isDraft ? formatMessage(draftMessage) : formatMessage(publishedMessage);
|
||||
|
||||
<TextGrow ellipsis as="div" fontWeight={fontWeight} title={value}>
|
||||
{value}
|
||||
</TextGrow>
|
||||
</Flex>
|
||||
</Component>
|
||||
);
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Row>
|
||||
<StyledBullet title={title} isDraft={isDraft} />
|
||||
<Text ellipsis>{props.label || '-'}</Text>
|
||||
</Row>
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Component {...props}>
|
||||
<Text ellipsis fontWeight={fontWeight} title={value}>
|
||||
{value}
|
||||
</Text>
|
||||
</Component>
|
||||
);
|
||||
return <Component {...props}>{props.label || '-'}</Component>;
|
||||
};
|
||||
|
||||
Option.defaultProps = {
|
||||
|
||||
@ -4,34 +4,35 @@ import {
|
||||
// FormattedMessage,
|
||||
useIntl,
|
||||
} from 'react-intl';
|
||||
// import { Link, useLocation } from 'react-router-dom';
|
||||
// import { findIndex, get, isArray, isEmpty, set } from 'lodash';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { Link } from '@strapi/parts/Link';
|
||||
import { Stack } from '@strapi/parts/Stack';
|
||||
import { useTheme } from 'styled-components';
|
||||
import findIndex from 'lodash/findIndex';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
import {
|
||||
// DropdownIndicator,
|
||||
|
||||
NotAllowedInput,
|
||||
useCMEditViewDataManager,
|
||||
// useQueryParams,
|
||||
} from '@strapi/helper-plugin';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import set from 'lodash/set';
|
||||
import { NotAllowedInput, useCMEditViewDataManager, useQueryParams } from '@strapi/helper-plugin';
|
||||
// import { Flex, Text, Padded } from '@buffetjs/core';
|
||||
// import { stringify } from 'qs';
|
||||
import { stringify } from 'qs';
|
||||
import axios from 'axios';
|
||||
import { axiosInstance } from '../../../core/utils';
|
||||
// import { getTrad } from '../../utils';
|
||||
import ComingSoonInput from '../Inputs/ComingSoonInput';
|
||||
// import SelectOne from '../SelectOne';
|
||||
// import SelectMany from '../SelectMany';
|
||||
// import ClearIndicator from './ClearIndicator';
|
||||
// import IndicatorSeparator from './IndicatorSeparator';
|
||||
// import Option from './Option';
|
||||
import { getTrad } from '../../utils';
|
||||
import Label from './Label';
|
||||
import SelectOne from '../SelectOne';
|
||||
import SelectMany from '../SelectMany';
|
||||
import ClearIndicator from './ClearIndicator';
|
||||
import DropdownIndicator from './DropdownIndicator';
|
||||
import IndicatorSeparator from './IndicatorSeparator';
|
||||
import Option from './Option';
|
||||
// import { A, BaselineAlignment } from './components';
|
||||
import {
|
||||
connect,
|
||||
select,
|
||||
// styles
|
||||
} from './utils';
|
||||
import getSelectStyles from './utils/getSelectStyles';
|
||||
|
||||
const initialPaginationState = {
|
||||
_contains: '',
|
||||
@ -39,24 +40,24 @@ const initialPaginationState = {
|
||||
_start: 0,
|
||||
};
|
||||
|
||||
// const buildParams = (query, paramsToKeep) => {
|
||||
// if (!paramsToKeep) {
|
||||
// return {};
|
||||
// }
|
||||
const buildParams = (query, paramsToKeep) => {
|
||||
if (!paramsToKeep) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// return paramsToKeep.reduce((acc, current) => {
|
||||
// const value = get(query, current, null);
|
||||
return paramsToKeep.reduce((acc, current) => {
|
||||
const value = get(query, current, null);
|
||||
|
||||
// if (value) {
|
||||
// set(acc, current, value);
|
||||
// }
|
||||
if (value) {
|
||||
set(acc, current, value);
|
||||
}
|
||||
|
||||
// return acc;
|
||||
// }, {});
|
||||
// };
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
function SelectWrapper({
|
||||
description,
|
||||
// editable,
|
||||
// description,
|
||||
editable,
|
||||
labelAction,
|
||||
intlLabel,
|
||||
isCreatingEntry,
|
||||
@ -65,63 +66,52 @@ function SelectWrapper({
|
||||
mainField,
|
||||
name,
|
||||
relationType,
|
||||
// targetModel,
|
||||
// placeholder,
|
||||
targetModel,
|
||||
placeholder,
|
||||
queryInfos,
|
||||
}) {
|
||||
const { formatMessage } = useIntl();
|
||||
// const [{ query }] = useQueryParams();
|
||||
const [{ query }] = useQueryParams();
|
||||
// Disable the input in case of a polymorphic relation
|
||||
const isMorph = useMemo(() => relationType.toLowerCase().includes('morph'), [relationType]);
|
||||
const {
|
||||
// addRelation,
|
||||
addRelation,
|
||||
modifiedData,
|
||||
// moveRelation,
|
||||
// onChange,
|
||||
// onRemoveRelation,
|
||||
moveRelation,
|
||||
onChange,
|
||||
onRemoveRelation,
|
||||
} = useCMEditViewDataManager();
|
||||
// const { pathname } = useLocation();
|
||||
const { pathname } = useLocation();
|
||||
const theme = useTheme();
|
||||
|
||||
const value = get(modifiedData, name, null);
|
||||
const [
|
||||
state,
|
||||
// setState
|
||||
] = useState(initialPaginationState);
|
||||
const [
|
||||
// options,
|
||||
setOptions,
|
||||
] = useState([]);
|
||||
const [
|
||||
// isLoading,
|
||||
setIsLoading,
|
||||
] = useState(false);
|
||||
const [
|
||||
isOpen,
|
||||
// setIsOpen
|
||||
] = useState(false);
|
||||
const [state, setState] = useState(initialPaginationState);
|
||||
const [options, setOptions] = useState([]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
// const filteredOptions = useMemo(() => {
|
||||
// return options.filter(option => {
|
||||
// if (!isEmpty(value)) {
|
||||
// // SelectMany
|
||||
// if (Array.isArray(value)) {
|
||||
// return findIndex(value, o => o.id === option.value.id) === -1;
|
||||
// }
|
||||
const filteredOptions = useMemo(() => {
|
||||
return options.filter(option => {
|
||||
if (!isEmpty(value)) {
|
||||
// SelectMany
|
||||
if (Array.isArray(value)) {
|
||||
return findIndex(value, o => o.id === option.value.id) === -1;
|
||||
}
|
||||
|
||||
// // SelectOne
|
||||
// return get(value, 'id', '') !== option.value.id;
|
||||
// }
|
||||
// SelectOne
|
||||
return get(value, 'id', '') !== option.value.id;
|
||||
}
|
||||
|
||||
// return true;
|
||||
// });
|
||||
// }, [options, value]);
|
||||
return true;
|
||||
});
|
||||
}, [options, value]);
|
||||
|
||||
const {
|
||||
endPoint,
|
||||
containsKey,
|
||||
defaultParams,
|
||||
// shouldDisplayRelationLink,
|
||||
// paramsToKeep,
|
||||
shouldDisplayRelationLink,
|
||||
paramsToKeep,
|
||||
} = queryInfos;
|
||||
|
||||
const isSingle = ['oneWay', 'oneToOne', 'manyToOne', 'oneToManyMorph', 'oneToOneMorph'].includes(
|
||||
@ -217,91 +207,71 @@ function SelectWrapper({
|
||||
return () => source.cancel('Operation canceled by the user.');
|
||||
}, [getData, isOpen]);
|
||||
|
||||
// const handleInputChange = (inputValue, { action }) => {
|
||||
// if (action === 'input-change') {
|
||||
// setState(prevState => {
|
||||
// if (prevState._contains === inputValue) {
|
||||
// return prevState;
|
||||
// }
|
||||
const handleInputChange = (inputValue, { action }) => {
|
||||
if (action === 'input-change') {
|
||||
setState(prevState => {
|
||||
if (prevState._contains === inputValue) {
|
||||
return prevState;
|
||||
}
|
||||
|
||||
// return { ...prevState, _contains: inputValue, _start: 0 };
|
||||
// });
|
||||
// }
|
||||
return { ...prevState, _contains: inputValue, _start: 0 };
|
||||
});
|
||||
}
|
||||
|
||||
// return inputValue;
|
||||
// };
|
||||
return inputValue;
|
||||
};
|
||||
|
||||
// const handleMenuScrollToBottom = () => {
|
||||
// setState(prevState => ({ ...prevState, _limit: prevState._limit + 20 }));
|
||||
// };
|
||||
const handleMenuScrollToBottom = () => {
|
||||
setState(prevState => ({ ...prevState, _limit: prevState._limit + 20 }));
|
||||
};
|
||||
|
||||
// const handleMenuClose = () => {
|
||||
// setState(initialPaginationState);
|
||||
// setIsOpen(false);
|
||||
// };
|
||||
const handleMenuClose = () => {
|
||||
setState(initialPaginationState);
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
// const handleChange = value => {
|
||||
// onChange({ target: { name, value: value ? value.value : value } });
|
||||
// };
|
||||
const handleChange = value => {
|
||||
onChange({ target: { name, value: value ? value.value : value } });
|
||||
};
|
||||
|
||||
// const handleAddRelation = value => {
|
||||
// if (!isEmpty(value)) {
|
||||
// addRelation({ target: { name, value } });
|
||||
// }
|
||||
// };
|
||||
const handleAddRelation = value => {
|
||||
if (!isEmpty(value)) {
|
||||
addRelation({ target: { name, value } });
|
||||
}
|
||||
};
|
||||
|
||||
// const handleMenuOpen = () => {
|
||||
// setIsOpen(true);
|
||||
// };
|
||||
const handleMenuOpen = () => {
|
||||
setIsOpen(true);
|
||||
};
|
||||
|
||||
// const to = `/content-manager/collectionType/${targetModel}/${value ? value.id : null}`;
|
||||
const to = `/content-manager/collectionType/${targetModel}/${value ? value.id : null}`;
|
||||
|
||||
// const searchToPersist = stringify(buildParams(query, paramsToKeep), { encode: false });
|
||||
const searchToPersist = stringify(buildParams(query, paramsToKeep), { encode: false });
|
||||
|
||||
// const link = useMemo(() => {
|
||||
// if (!value) {
|
||||
// return null;
|
||||
// }
|
||||
let link = null;
|
||||
|
||||
// if (!shouldDisplayRelationLink) {
|
||||
// return null;
|
||||
// }
|
||||
if (isSingle && value && shouldDisplayRelationLink) {
|
||||
link = (
|
||||
<Link to={{ pathname: to, state: { from: pathname }, search: searchToPersist }}>
|
||||
{formatMessage({ id: getTrad('containers.Edit.seeDetails'), defaultMessage: 'Details' })}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
// return (
|
||||
// <Link to={{ pathname: to, state: { from: pathname }, search: searchToPersist }}>
|
||||
// <FormattedMessage id="content-manager.containers.Edit.seeDetails">
|
||||
// {msg => <A color="mediumBlue">{msg}</A>}
|
||||
// </FormattedMessage>
|
||||
// </Link>
|
||||
// );
|
||||
// }, [shouldDisplayRelationLink, pathname, to, value, searchToPersist]);
|
||||
|
||||
// const Component = isSingle ? SelectOne : SelectMany;
|
||||
const Component = isSingle ? SelectOne : SelectMany;
|
||||
const associationsLength = isArray(value) ? value.length : 0;
|
||||
|
||||
// const isDisabled = useMemo(() => {
|
||||
// if (isMorph) {
|
||||
// return true;
|
||||
// }
|
||||
const isDisabled = useMemo(() => {
|
||||
if (isMorph) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// if (!isCreatingEntry) {
|
||||
// return (!isFieldAllowed && isFieldReadable) || !editable;
|
||||
// }
|
||||
if (!isCreatingEntry) {
|
||||
return (!isFieldAllowed && isFieldReadable) || !editable;
|
||||
}
|
||||
|
||||
// return !editable;
|
||||
// }, [isMorph, isCreatingEntry, editable, isFieldAllowed, isFieldReadable]);
|
||||
|
||||
const multipleLabel = intlLabel.id
|
||||
? formatMessage({ id: intlLabel.id, defaultMessage: intlLabel.defaultMessage })
|
||||
: name;
|
||||
const formattedLabel = isSingle
|
||||
? intlLabel
|
||||
: {
|
||||
// Custom trad id in order to add the label count
|
||||
id: 'relations-label',
|
||||
defaultMessage: '{label} ({count})',
|
||||
values: { label: multipleLabel, count: associationsLength },
|
||||
};
|
||||
return !editable;
|
||||
}, [isMorph, isCreatingEntry, editable, isFieldAllowed, isFieldReadable]);
|
||||
|
||||
if (!isFieldAllowed && isCreatingEntry) {
|
||||
return <NotAllowedInput intlLabel={intlLabel} labelAction={labelAction} />;
|
||||
@ -311,13 +281,68 @@ function SelectWrapper({
|
||||
return <NotAllowedInput intlLabel={intlLabel} labelAction={labelAction} />;
|
||||
}
|
||||
|
||||
const styles = getSelectStyles(theme);
|
||||
|
||||
// const temp = [
|
||||
// {
|
||||
// label: 'un',
|
||||
// value: {
|
||||
// id: 2,
|
||||
// name: 'un',
|
||||
// publishedAt: null,
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// label: 'deux',
|
||||
// value: {
|
||||
// id: 2,
|
||||
// name: 'deux',
|
||||
// publishedAt: null,
|
||||
// },
|
||||
// },
|
||||
// ];
|
||||
|
||||
return (
|
||||
<ComingSoonInput
|
||||
intlLabel={formattedLabel}
|
||||
labelAction={labelAction}
|
||||
description={description}
|
||||
name={name}
|
||||
/>
|
||||
<Stack size={1}>
|
||||
<Label
|
||||
intlLabel={intlLabel}
|
||||
isSingle={isSingle}
|
||||
labelAction={labelAction}
|
||||
link={link}
|
||||
name={name}
|
||||
numberOfEntries={associationsLength}
|
||||
/>
|
||||
<Component
|
||||
addRelation={handleAddRelation}
|
||||
components={{
|
||||
ClearIndicator,
|
||||
DropdownIndicator,
|
||||
IndicatorSeparator,
|
||||
Option,
|
||||
}}
|
||||
displayNavigationLink={shouldDisplayRelationLink}
|
||||
id={name}
|
||||
isDisabled={isDisabled}
|
||||
isLoading={isLoading}
|
||||
isClearable
|
||||
mainField={mainField}
|
||||
move={moveRelation}
|
||||
name={name}
|
||||
options={filteredOptions}
|
||||
// options={temp}
|
||||
onChange={handleChange}
|
||||
onInputChange={handleInputChange}
|
||||
onMenuClose={handleMenuClose}
|
||||
onMenuOpen={handleMenuOpen}
|
||||
onMenuScrollToBottom={handleMenuScrollToBottom}
|
||||
onRemove={onRemoveRelation}
|
||||
placeholder={placeholder}
|
||||
searchToPersist={searchToPersist}
|
||||
styles={styles}
|
||||
targetModel={targetModel}
|
||||
value={value}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
|
||||
// return (
|
||||
@ -352,36 +377,36 @@ function SelectWrapper({
|
||||
// <Padded top size="sm">
|
||||
// <BaselineAlignment />
|
||||
|
||||
// <Component
|
||||
// addRelation={handleAddRelation}
|
||||
// components={{ ClearIndicator, DropdownIndicator, IndicatorSeparator, Option }}
|
||||
// displayNavigationLink={shouldDisplayRelationLink}
|
||||
// id={name}
|
||||
// isDisabled={isDisabled}
|
||||
// isLoading={isLoading}
|
||||
// isClearable
|
||||
// mainField={mainField}
|
||||
// move={moveRelation}
|
||||
// name={name}
|
||||
// options={filteredOptions}
|
||||
// onChange={handleChange}
|
||||
// onInputChange={handleInputChange}
|
||||
// onMenuClose={handleMenuClose}
|
||||
// onMenuOpen={handleMenuOpen}
|
||||
// onMenuScrollToBottom={handleMenuScrollToBottom}
|
||||
// onRemove={onRemoveRelation}
|
||||
// placeholder={
|
||||
// isEmpty(placeholder) ? (
|
||||
// <FormattedMessage id={getTrad('containers.Edit.addAnItem')} />
|
||||
// ) : (
|
||||
// placeholder
|
||||
// )
|
||||
// }
|
||||
// searchToPersist={searchToPersist}
|
||||
// styles={styles}
|
||||
// targetModel={targetModel}
|
||||
// value={value}
|
||||
// />
|
||||
// <Component
|
||||
// addRelation={handleAddRelation}
|
||||
// components={{ ClearIndicator, DropdownIndicator, IndicatorSeparator, Option }}
|
||||
// displayNavigationLink={shouldDisplayRelationLink}
|
||||
// id={name}
|
||||
// isDisabled={isDisabled}
|
||||
// isLoading={isLoading}
|
||||
// isClearable
|
||||
// mainField={mainField}
|
||||
// move={moveRelation}
|
||||
// name={name}
|
||||
// options={filteredOptions}
|
||||
// onChange={handleChange}
|
||||
// onInputChange={handleInputChange}
|
||||
// onMenuClose={handleMenuClose}
|
||||
// onMenuOpen={handleMenuOpen}
|
||||
// onMenuScrollToBottom={handleMenuScrollToBottom}
|
||||
// onRemove={onRemoveRelation}
|
||||
// placeholder={
|
||||
// isEmpty(placeholder) ? (
|
||||
// <FormattedMessage id={getTrad('containers.Edit.addAnItem')} />
|
||||
// ) : (
|
||||
// placeholder
|
||||
// )
|
||||
// }
|
||||
// searchToPersist={searchToPersist}
|
||||
// styles={styles}
|
||||
// targetModel={targetModel}
|
||||
// value={value}
|
||||
// />
|
||||
// </Padded>
|
||||
// <div style={{ marginBottom: 28 }} />
|
||||
// </Padded>
|
||||
@ -389,20 +414,20 @@ function SelectWrapper({
|
||||
}
|
||||
|
||||
SelectWrapper.defaultProps = {
|
||||
// editable: true,
|
||||
description: '',
|
||||
editable: true,
|
||||
// description: '',
|
||||
labelAction: null,
|
||||
isFieldAllowed: true,
|
||||
// placeholder: null,
|
||||
placeholder: null,
|
||||
};
|
||||
|
||||
SelectWrapper.propTypes = {
|
||||
// editable: PropTypes.bool,
|
||||
description: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
defaultMessage: PropTypes.string.isRequired,
|
||||
values: PropTypes.object,
|
||||
}),
|
||||
editable: PropTypes.bool,
|
||||
// description: PropTypes.shape({
|
||||
// id: PropTypes.string.isRequired,
|
||||
// defaultMessage: PropTypes.string.isRequired,
|
||||
// values: PropTypes.object,
|
||||
// }),
|
||||
intlLabel: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
defaultMessage: PropTypes.string.isRequired,
|
||||
@ -419,13 +444,13 @@ SelectWrapper.propTypes = {
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
// placeholder: PropTypes.shape({
|
||||
// id: PropTypes.string.isRequired,
|
||||
// defaultMessage: PropTypes.string.isRequired,
|
||||
// values: PropTypes.object,
|
||||
// }),
|
||||
placeholder: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
defaultMessage: PropTypes.string.isRequired,
|
||||
values: PropTypes.object,
|
||||
}),
|
||||
relationType: PropTypes.string.isRequired,
|
||||
// targetModel: PropTypes.string.isRequired,
|
||||
targetModel: PropTypes.string.isRequired,
|
||||
queryInfos: PropTypes.shape({
|
||||
containsKey: PropTypes.string.isRequired,
|
||||
defaultParams: PropTypes.object,
|
||||
|
||||
@ -0,0 +1,191 @@
|
||||
// const styles = {
|
||||
// container: base => ({ ...base, background: '#ffffff' }),
|
||||
// control: (base, state) => {
|
||||
// const borderRadiusStyle = state.selectProps.menuIsOpen
|
||||
// ? {
|
||||
// borderBottomLeftRadius: '0 !important',
|
||||
// borderBottomRightRadius: '0 !important',
|
||||
// }
|
||||
// : {};
|
||||
|
||||
// const {
|
||||
// selectProps: { error, value },
|
||||
// } = state;
|
||||
|
||||
// let border;
|
||||
// let borderBottom;
|
||||
// let backgroundColor;
|
||||
|
||||
// if (state.isFocused) {
|
||||
// border = '1px solid #78caff !important';
|
||||
// } else if (error && !value.length) {
|
||||
// border = '1px solid #f64d0a !important';
|
||||
// } else {
|
||||
// border = '1px solid #e3e9f3 !important';
|
||||
// }
|
||||
|
||||
// if (state.menuIsOpen === true) {
|
||||
// borderBottom = '1px solid #e3e9f3 !important';
|
||||
// }
|
||||
|
||||
// if (state.isDisabled) {
|
||||
// backgroundColor = '#fafafb !important';
|
||||
// }
|
||||
|
||||
// return {
|
||||
// ...base,
|
||||
// fontSize: 13,
|
||||
// height: 34,
|
||||
// minHeight: 34,
|
||||
// border,
|
||||
// outline: 0,
|
||||
// boxShadow: 0,
|
||||
// borderRadius: '2px !important',
|
||||
// ...borderRadiusStyle,
|
||||
// borderBottom,
|
||||
// backgroundColor,
|
||||
// };
|
||||
// },
|
||||
// input: base => ({ ...base, marginLeft: 10 }),
|
||||
// menu: base => {
|
||||
// return {
|
||||
// ...base,
|
||||
// width: '100%',
|
||||
// margin: '0',
|
||||
// paddingTop: 0,
|
||||
// borderRadius: '2px !important',
|
||||
// borderTopLeftRadius: '0 !important',
|
||||
// borderTopRightRadius: '0 !important',
|
||||
// border: '1px solid #78caff !important',
|
||||
// boxShadow: 0,
|
||||
// borderTop: '0 !important',
|
||||
// fontSize: '13px',
|
||||
// };
|
||||
// },
|
||||
// menuList: base => ({
|
||||
// ...base,
|
||||
// maxHeight: '112px',
|
||||
// paddingTop: 2,
|
||||
// }),
|
||||
// option: (base, state) => {
|
||||
// return {
|
||||
// ...base,
|
||||
// height: 36,
|
||||
// backgroundColor: state.isFocused ? '#f6f6f6' : '#fff',
|
||||
// ':active': {
|
||||
// ...base[':active'],
|
||||
// backgroundColor: '#f6f6f6',
|
||||
// },
|
||||
// color: '#333740',
|
||||
// fontWeight: state.isFocused ? '600' : '400',
|
||||
// cursor: 'pointer',
|
||||
// WebkitFontSmoothing: 'antialiased',
|
||||
// };
|
||||
// },
|
||||
// placeholder: base => ({
|
||||
// ...base,
|
||||
// marginTop: 0,
|
||||
// marginLeft: 10,
|
||||
// color: '#aaa',
|
||||
// overflow: 'hidden',
|
||||
// whiteSpace: 'nowrap',
|
||||
// textOverflow: 'ellipsis',
|
||||
// maxWidth: 'calc(100% - 32px)',
|
||||
// }),
|
||||
// valueContainer: base => ({
|
||||
// ...base,
|
||||
// padding: '2px 0px 4px 0px',
|
||||
// lineHeight: '18px',
|
||||
// }),
|
||||
// };
|
||||
|
||||
// export default styles;
|
||||
|
||||
const getSelectStyles = theme => {
|
||||
return {
|
||||
clearIndicator: base => ({ ...base, padding: 0, paddingRight: theme.spaces[3] }),
|
||||
container: base => ({
|
||||
...base,
|
||||
background: theme.colors.neutral0,
|
||||
fontFamily: 'Arial',
|
||||
lineHeight: 'normal',
|
||||
}),
|
||||
control: (base, state) => {
|
||||
let border;
|
||||
let borderBottom;
|
||||
let backgroundColor;
|
||||
|
||||
if (state.isFocused) {
|
||||
border = `1px solid ${theme.colors.primary600} !important`;
|
||||
} else {
|
||||
border = `1px solid ${theme.colors.neutral200} !important`;
|
||||
}
|
||||
|
||||
if (state.menuIsOpen === true) {
|
||||
borderBottom = `1px solid ${theme.colors.primary600} !important`;
|
||||
}
|
||||
|
||||
if (state.isDisabled) {
|
||||
backgroundColor = '#fafafb !important';
|
||||
}
|
||||
|
||||
return {
|
||||
...base,
|
||||
fontSize: 14,
|
||||
height: 40,
|
||||
border,
|
||||
outline: 0,
|
||||
boxShadow: 0,
|
||||
borderRadius: '2px !important',
|
||||
borderBottom,
|
||||
backgroundColor,
|
||||
borderTopLeftRadius: '4px !important',
|
||||
borderTopRightRadius: '4px !important',
|
||||
borderBottomLeftRadius: '4px !important',
|
||||
borderBottomRightRadius: '4px !important',
|
||||
};
|
||||
},
|
||||
indicatorContainer: base => ({ ...base, padding: 0, paddingRight: theme.spaces[3] }),
|
||||
input: base => ({ ...base, margin: 0, padding: 0 }),
|
||||
menu: base => {
|
||||
return {
|
||||
...base,
|
||||
width: '100%',
|
||||
marginTop: theme.spaces[1],
|
||||
borderRadius: '4px !important',
|
||||
borderTopLeftRadius: '4px !important',
|
||||
borderTopRightRadius: '4px !important',
|
||||
border: `1px solid ${theme.colors.neutral200} !important`,
|
||||
boxShadow: 0,
|
||||
fontSize: '14px',
|
||||
fontFamily: 'Arial',
|
||||
};
|
||||
},
|
||||
menuList: base => ({
|
||||
...base,
|
||||
paddingLeft: theme.spaces[1],
|
||||
paddingTop: theme.spaces[1],
|
||||
paddingRight: theme.spaces[1],
|
||||
paddingBottom: theme.spaces[1],
|
||||
}),
|
||||
option: (base, state) => {
|
||||
let backgroundColor = base.backgroundColor;
|
||||
|
||||
if (state.isFocused) {
|
||||
backgroundColor = theme.colors.primary100;
|
||||
}
|
||||
|
||||
return { ...base, lineHeight: theme.spaces[5], backgroundColor, borderRadius: 4 };
|
||||
},
|
||||
singleValue: base => ({ ...base, marginLeft: 0 }),
|
||||
valueContainer: base => ({
|
||||
...base,
|
||||
padding: 0,
|
||||
paddingLeft: theme.spaces[4],
|
||||
marginLeft: 0,
|
||||
marginRight: 0,
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
export default getSelectStyles;
|
||||
Loading…
x
Reference in New Issue
Block a user