From de2184b6e3f79f45484da0f2d2aa05db0f7f08de Mon Sep 17 00:00:00 2001 From: Arnaud <52196301+fatb38@users.noreply.github.com> Date: Wed, 17 Apr 2024 14:47:09 +0200 Subject: [PATCH] =?UTF-8?q?xstream-452/506=20adapter=20le=20design=20d'un?= =?UTF-8?q?=20attribut=20liaison=20mono-valu=C3=A9e=20(#445)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(@leav/ui): design system Select to mono value link field --- apps/data-studio/package.json | 4 +- apps/login/package.json | 4 +- apps/portal/package.json | 4 +- libs/ui/package.json | 4 +- libs/ui/src/_tests/testUtils.tsx | 24 +- .../EditRecordContent.test.tsx | 13 +- .../EditRecordContent/EditRecordContent.tsx | 57 +-- .../EditRecordContent/antdUtils.test.tsx | 142 ++++++ .../EditRecordContent/antdUtils.tsx | 59 +++ .../uiElements/LinkField/LinkField.test.tsx | 82 ++- .../uiElements/LinkField/LinkField.tsx | 97 ++-- .../MonoValueSelect/MonoValueSelect.test.tsx | 219 ++++++++ .../MonoValueSelect/MonoValueSelect.tsx | 75 +++ .../useGetOptionsQuery.test.tsx | 257 ++++++++++ .../MonoValueSelect/useGetOptionsQuery.tsx | 88 ++++ .../DSInputWrapper.test.tsx | 1 + .../StandardFieldValue/DSInputWrapper.tsx | 1 - .../DSRangePickerWrapper.tsx | 1 - libs/ui/src/locales/en/shared.json | 3 +- libs/ui/src/locales/fr/shared.json | 5 +- yarn.lock | 466 +++--------------- 21 files changed, 1088 insertions(+), 518 deletions(-) create mode 100644 libs/ui/src/components/RecordEdition/EditRecordContent/antdUtils.test.tsx create mode 100644 libs/ui/src/components/RecordEdition/EditRecordContent/antdUtils.tsx create mode 100644 libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/MonoValueSelect.test.tsx create mode 100644 libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/MonoValueSelect.tsx create mode 100644 libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/useGetOptionsQuery.test.tsx create mode 100644 libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/useGetOptionsQuery.tsx diff --git a/apps/data-studio/package.json b/apps/data-studio/package.json index 4ff173e1d..520df1bac 100644 --- a/apps/data-studio/package.json +++ b/apps/data-studio/package.json @@ -10,10 +10,10 @@ "@leav/ui": "workspace:libs/ui", "@leav/utils": "workspace:libs/utils", "@reduxjs/toolkit": "1.9.2", - "antd": "5.14.0", + "antd": "5.15.3", "apollo-cache-inmemory": "1.6.6", "apollo-upload-client": "14.1.3", - "aristid-ds": "4.0.0-3ef6e97", + "aristid-ds": "4.0.0-8683c72", "dayjs": "1.11.10", "graphql": "15.0.0", "graphql-tag": "2.12.6", diff --git a/apps/login/package.json b/apps/login/package.json index b333c7b64..b2affd5e6 100644 --- a/apps/login/package.json +++ b/apps/login/package.json @@ -6,8 +6,8 @@ "dependencies": { "@ant-design/icons": "5.2.6", "@leav/ui": "workspace:libs/ui", - "antd": "5.14.0", - "aristid-ds": "4.0.0-3ef6e97", + "antd": "5.15.3", + "aristid-ds": "4.0.0-8683c72", "i18next": "22.5.0", "i18next-browser-languagedetector": "7.0.2", "i18next-http-backend": "2.1.1", diff --git a/apps/portal/package.json b/apps/portal/package.json index fd1d3683a..019636524 100644 --- a/apps/portal/package.json +++ b/apps/portal/package.json @@ -7,8 +7,8 @@ "@apollo/client": "3.8.1", "@leav/ui": "workspace:libs/ui", "@leav/utils": "workspace:libs/utils", - "antd": "5.14.0", - "aristid-ds": "4.0.0-3ef6e97", + "antd": "5.15.3", + "aristid-ds": "4.0.0-8683c72", "cross-fetch": "3.1.5", "graphql-ws": "5.12.0", "i18next": "22.5.0", diff --git a/libs/ui/package.json b/libs/ui/package.json index cef01e42e..da46edc34 100644 --- a/libs/ui/package.json +++ b/libs/ui/package.json @@ -49,7 +49,7 @@ "peerDependencies": { "@ant-design/icons": ">=5.2", "@apollo/client": ">=3.8.1", - "antd": "5.9.1", + "antd": "5.15.3", "i18next": "22.5", "react": "18.2.0", "react-dom": "18.2.0", @@ -62,7 +62,7 @@ "@ckeditor/ckeditor5-build-inline": "39.0.1", "@ckeditor/ckeditor5-react": "6.1.0", "@leav/utils": "0.0.1", - "aristid-ds": "4.0.0-3ef6e97", + "aristid-ds": "4.0.0-8683c72", "dayjs": "1.11.10", "dompurify": "3.0.5", "html-react-parser": "4.2.2", diff --git a/libs/ui/src/_tests/testUtils.tsx b/libs/ui/src/_tests/testUtils.tsx index 2275d4368..aa0304741 100644 --- a/libs/ui/src/_tests/testUtils.tsx +++ b/libs/ui/src/_tests/testUtils.tsx @@ -4,19 +4,29 @@ // License text available at https://www.gnu.org/licenses/lgpl-3.0.txt import {InMemoryCache, InMemoryCacheConfig} from '@apollo/client'; import {MockedProvider, MockedResponse} from '@apollo/client/testing'; -import {render, RenderOptions, RenderResult} from '@testing-library/react'; +import {Queries, render, renderHook, RenderHookOptions, RenderOptions, RenderResult} from '@testing-library/react'; import {KitApp} from 'aristid-ds'; import {PropsWithChildren, ReactElement} from 'react'; import {MemoryRouter, MemoryRouterProps} from 'react-router-dom'; import {gqlPossibleTypes} from '_ui/gqlPossibleTypes'; import MockedUserContextProvider from '_ui/testing/MockedUserContextProvider'; import MockedLangContextProvider from '../testing/MockedLangContextProvider'; +import {queries} from '@testing-library/dom'; export interface ICustomRenderOptions extends RenderOptions { mocks?: readonly MockedResponse[]; [key: string]: any; } +export interface ICustomRenderHookOptions< + Props, + Q extends Queries = typeof queries, + Container extends Element | DocumentFragment = HTMLElement, + BaseElement extends Element | DocumentFragment = Container +> extends RenderHookOptions { + mocks?: readonly MockedResponse[]; +} + interface IProvidersProps { mocks?: readonly MockedResponse[]; cacheSettings?: InMemoryCacheConfig; @@ -44,7 +54,19 @@ const renderWithProviders = (ui: ReactElement, options?: ICustomRenderOptions): return render(ui, {wrapper: props => , ...options}); }; +const renderHookWithProviders = < + Result, + Props, + Q extends Queries = typeof queries, + Container extends Element | DocumentFragment = HTMLElement, + BaseElement extends Element | DocumentFragment = Container +>( + hook: (initialProps: Props) => Result, + options?: ICustomRenderHookOptions +) => renderHook(hook, {wrapper: props => , ...options}); + // Re-export everything from testing-library to improve DX. You can everything you need from this file when you use this // custom render export * from '@testing-library/react'; export {renderWithProviders as render}; +export {renderHookWithProviders as renderHook}; diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/EditRecordContent.test.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/EditRecordContent.test.tsx index dc77493f8..600524f2d 100644 --- a/libs/ui/src/components/RecordEdition/EditRecordContent/EditRecordContent.test.tsx +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/EditRecordContent.test.tsx @@ -8,17 +8,16 @@ import {mockRecord} from '_ui/__mocks__/common/record'; import {render, screen} from '../../../_tests/testUtils'; import EditRecordContent from './EditRecordContent'; import {Form} from 'antd'; +import {ComponentProps, FunctionComponent} from 'react'; -jest.mock('./uiElements/StandardField', () => { - return function StandardField() { - return
StandardField
; - }; -}); +jest.mock('./uiElements/StandardField', () => () =>
StandardField
); -const EditRecordContentWithForm = props => { +const EditRecordContentWithForm: FunctionComponent< + Omit, 'antdForm'> +> = props => { const [form] = Form.useForm(); - return ; + return ; }; describe('EditRecordContent', () => { diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/EditRecordContent.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/EditRecordContent.tsx index e02b5ef0c..7b62da93a 100644 --- a/libs/ui/src/components/RecordEdition/EditRecordContent/EditRecordContent.tsx +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/EditRecordContent.tsx @@ -1,15 +1,15 @@ // Copyright LEAV Solutions 2017 // This file is released under LGPL V3 // License text available at https://www.gnu.org/licenses/lgpl-3.0.txt -import {FormUIElementTypes, FORM_ROOT_CONTAINER_ID, simpleStringHash, IDateRangeValue} from '@leav/utils'; -import {useEffect, useMemo} from 'react'; +import {FORM_ROOT_CONTAINER_ID, FormUIElementTypes, simpleStringHash} from '@leav/utils'; +import {FunctionComponent, useEffect, useMemo} from 'react'; import {ErrorDisplay} from '_ui/components'; -import useGetRecordForm, {RecordFormElementsValueStandardValue} from '_ui/hooks/useGetRecordForm'; +import useGetRecordForm from '_ui/hooks/useGetRecordForm'; import {useGetRecordUpdatesSubscription} from '_ui/hooks/useGetRecordUpdatesSubscription'; import useRecordsConsultationHistory from '_ui/hooks/useRecordsConsultationHistory'; import {useSharedTranslation} from '_ui/hooks/useSharedTranslation'; import {IRecordIdentityWhoAmI} from '_ui/types/records'; -import {AttributeFormat, FormElementTypes} from '_ui/_gqlTypes'; +import {FormElementTypes} from '_ui/_gqlTypes'; import {EditRecordReducerActionsTypes} from '../editRecordReducer/editRecordReducer'; import {useEditRecordReducer} from '../editRecordReducer/useEditRecordReducer'; import EditRecordSkeleton from './EditRecordSkeleton'; @@ -18,9 +18,8 @@ import {RecordEditionContext} from './hooks/useRecordEditionContext'; import {formComponents} from './uiElements'; import {DeleteMultipleValuesFunc, DeleteValueFunc, FormElement, SubmitValueFunc} from './_types'; import {Form, FormInstance} from 'antd'; -import {Store} from 'antd/lib/form/interface'; -import dayjs from 'dayjs'; import {EDIT_OR_CREATE_RECORD_FORM_ID} from './formConstants'; +import {getAntdFormInitialValues} from '_ui/components/RecordEdition/EditRecordContent/antdUtils'; interface IEditRecordContentProps { antdForm: FormInstance; @@ -33,7 +32,7 @@ interface IEditRecordContentProps { readonly: boolean; } -function EditRecordContent({ +const EditRecordContent: FunctionComponent = ({ antdForm, record, library, @@ -42,15 +41,13 @@ function EditRecordContent({ onValueDelete, onDeleteMultipleValues, readonly -}: IEditRecordContentProps): JSX.Element { +}) => { const formId = record ? 'edition' : 'creation'; const {t} = useSharedTranslation(); const {state, dispatch} = useEditRecordReducer(); useRecordsConsultationHistory(record?.library?.id ?? null, record?.id ?? null); - const forminstance = Form.useFormInstance(); - const {data: recordUpdateData} = useGetRecordUpdatesSubscription( {records: [record?.id], ignoreOwnEvents: true}, !record?.id @@ -133,43 +130,8 @@ function EditRecordContent({ uiElement: formComponents[FormUIElementTypes.FIELDS_CONTAINER] }; - const hasDateRangeValues = (dateRange: unknown): dateRange is IDateRangeValue => - (dateRange as IDateRangeValue).from !== undefined && (dateRange as IDateRangeValue).to !== undefined; - - const antdFormInitialValues = recordForm.elements.reduce((acc, {attribute, values}) => { - if (!attribute) { - return acc; - } - - const fieldValue = values[0] as RecordFormElementsValueStandardValue; - - if (attribute.format === AttributeFormat.text) { - acc[attribute.id] = fieldValue?.raw_value ?? ''; - } - - if (attribute.format === AttributeFormat.date_range) { - if (!fieldValue?.raw_value) { - return acc; - } - - if (hasDateRangeValues(fieldValue.raw_value)) { - acc[attribute.id] = [ - dayjs.unix(Number(fieldValue.raw_value.from)), - dayjs.unix(Number(fieldValue.raw_value.to)) - ]; - } else if (typeof fieldValue.raw_value === 'string') { - const convertedFieldValue = JSON.parse(fieldValue.raw_value); - acc[attribute.id] = [ - dayjs.unix(Number(convertedFieldValue.from)), - dayjs.unix(Number(convertedFieldValue.to)) - ]; - } - } + const antdFormInitialValues = getAntdFormInitialValues(recordForm); - return acc; - }, {}); - - // Use a hash of record form as a key to force a full re-render when the form changes return (
); -} +}; export default EditRecordContent; diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/antdUtils.test.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/antdUtils.test.tsx new file mode 100644 index 000000000..e485dc941 --- /dev/null +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/antdUtils.test.tsx @@ -0,0 +1,142 @@ +import {getAntdFormInitialValues} from '_ui/components/RecordEdition/EditRecordContent/antdUtils'; +import {AttributeFormat, AttributeType} from '_ui/_gqlTypes'; + +jest.mock('dayjs', () => ({ + unix: jest.fn(t => t) +})); + +describe('getAntdFormInitialValues', () => { + test('Should return empty object on empty elements', async () => { + const recordForm = {elements: []}; + + const antdFormInitialValues = getAntdFormInitialValues(recordForm as any); + + expect(antdFormInitialValues).toEqual({}); + }); + + test('Should skip if attribute is undefined', async () => { + const elementWithoutAttribute = {values: []}; + const recordForm = {elements: [elementWithoutAttribute]}; + + const antdFormInitialValues = getAntdFormInitialValues(recordForm as any); + + expect(antdFormInitialValues).toEqual({}); + }); + + describe.each([{type: AttributeType.simple_link}, {type: AttributeType.advanced_link, multiple_values: false}])( + 'links', + attributeProperties => { + test('Should initialize antd form with given value for links (advanced and simple)', async () => { + const elementFormId = 'elementFormId'; + const linkAttributeId = 'linkAttributeId'; + const linkElement = { + attribute: {...attributeProperties, id: linkAttributeId}, + values: [{linkValue: {id: elementFormId}}] + }; + const recordForm = {elements: [linkElement]}; + + const antdFormInitialValues = getAntdFormInitialValues(recordForm as any); + + expect(antdFormInitialValues).toEqual({ + [linkAttributeId]: 'elementFormId' + }); + }); + + test('Should initialize antd form with undefined for links (advanced and simple) when linkValue is not set', async () => { + const linkAttributeId = 'linkAttributeId'; + const linkElement = { + attribute: {...attributeProperties, id: linkAttributeId}, + values: [{}] + }; + const recordForm = {elements: [linkElement]}; + + const antdFormInitialValues = getAntdFormInitialValues(recordForm as any); + + expect(antdFormInitialValues).toEqual({ + [linkAttributeId]: undefined + }); + }); + } + ); + + describe('AttributeFormat.text', () => { + test('Should initialize antd form with given value for text attribute', async () => { + const rawValue = 'rawValue'; + const textAttributeId = 'textAttributeId'; + const textElement = { + attribute: {format: AttributeFormat.text, id: textAttributeId}, + values: [{raw_value: rawValue}] + }; + const recordForm = {elements: [textElement]}; + + const antdFormInitialValues = getAntdFormInitialValues(recordForm as any); + + expect(antdFormInitialValues).toEqual({ + [textAttributeId]: rawValue + }); + }); + + test('Should initialize antd form with given empty string for text when raw_value is not set', async () => { + const textAttributeId = 'textAttributeId'; + const textElement = { + attribute: {format: AttributeFormat.text, id: textAttributeId}, + values: [{}] + }; + const recordForm = {elements: [textElement]}; + + const antdFormInitialValues = getAntdFormInitialValues(recordForm as any); + + expect(antdFormInitialValues).toEqual({ + [textAttributeId]: '' + }); + }); + }); + + describe('AttributeFormat.date_range', () => { + test('Should skip when raw_value is not set', async () => { + const dateRangeElementWithoutRawValue = { + attribute: {format: AttributeFormat.date_range}, + values: [{}] + }; + const recordForm = {elements: [dateRangeElementWithoutRawValue]}; + + const antdFormInitialValues = getAntdFormInitialValues(recordForm as any); + + expect(antdFormInitialValues).toEqual({}); + }); + + test('Should initialize antd form with dayjs formatted value for date_range attribute', async () => { + const from = '1000'; + const to = '2000'; + const dateRangeAttributeId = 'dateRangeAttributeId'; + const strcturedDateRangeElement = { + attribute: {format: AttributeFormat.date_range, id: dateRangeAttributeId}, + values: [{raw_value: {from, to}}] + }; + const recordForm = {elements: [strcturedDateRangeElement]}; + + const antdFormInitialValues = getAntdFormInitialValues(recordForm as any); + + expect(antdFormInitialValues).toEqual({ + [dateRangeAttributeId]: [Number(from), Number(to)] + }); + }); + + test('Should initialize antd form with dayjs formatted value for stringified date_range attribute', async () => { + const from = '1000'; + const to = '2000'; + const dateRangeAttributeId = 'dateRangeAttributeId'; + const strcturedDateRangeElement = { + attribute: {format: AttributeFormat.date_range, id: dateRangeAttributeId}, + values: [{raw_value: JSON.stringify({from, to})}] + }; + const recordForm = {elements: [strcturedDateRangeElement]}; + + const antdFormInitialValues = getAntdFormInitialValues(recordForm as any); + + expect(antdFormInitialValues).toEqual({ + [dateRangeAttributeId]: [Number(from), Number(to)] + }); + }); + }); +}); diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/antdUtils.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/antdUtils.tsx new file mode 100644 index 000000000..61b97a98a --- /dev/null +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/antdUtils.tsx @@ -0,0 +1,59 @@ +import { + IRecordForm, + RecordFormElementsValue, + RecordFormElementsValueLinkValue, + RecordFormElementsValueStandardValue +} from '_ui/hooks/useGetRecordForm'; +import {AttributeFormat, AttributeType} from '_ui/_gqlTypes'; +import {IDateRangeValue} from '@leav/utils'; +import {Store} from 'antd/lib/form/interface'; +import dayjs from 'dayjs'; + +const hasDateRangeValues = (dateRange: unknown): dateRange is IDateRangeValue => + (dateRange as IDateRangeValue).from !== undefined && (dateRange as IDateRangeValue).to !== undefined; + +const isRecordFormElementsValueLinkValue = ( + value: RecordFormElementsValue, + attribute: IRecordForm['elements'][0]['attribute'] +): value is RecordFormElementsValueLinkValue => + attribute.type === AttributeType.simple_link || + (attribute.type === AttributeType.advanced_link && attribute.multiple_values === false); + +export const getAntdFormInitialValues = (recordForm: IRecordForm) => + recordForm.elements.reduce((acc, {attribute, values}) => { + if (!attribute) { + return acc; + } + const value = values[0]; + + if (isRecordFormElementsValueLinkValue(value, attribute)) { + acc[attribute.id] = value?.linkValue?.id; + return acc; + } + + const fieldValue = value as RecordFormElementsValueStandardValue; + if (attribute.format === AttributeFormat.text) { + acc[attribute.id] = fieldValue?.raw_value ?? ''; + } + + if (attribute.format === AttributeFormat.date_range) { + if (!fieldValue?.raw_value) { + return acc; + } + + if (hasDateRangeValues(fieldValue.raw_value)) { + acc[attribute.id] = [ + dayjs.unix(Number(fieldValue.raw_value.from)), + dayjs.unix(Number(fieldValue.raw_value.to)) + ]; + } else if (typeof fieldValue.raw_value === 'string') { + const convertedFieldValue = JSON.parse(fieldValue.raw_value); + acc[attribute.id] = [ + dayjs.unix(Number(convertedFieldValue.from)), + dayjs.unix(Number(convertedFieldValue.to)) + ]; + } + } + + return acc; + }, {}); diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/LinkField.test.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/LinkField.test.tsx index 6dccc939b..382f7c387 100644 --- a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/LinkField.test.tsx +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/LinkField.test.tsx @@ -134,7 +134,15 @@ describe('LinkField', () => { beforeEach(() => jest.clearAllMocks()); test('Display list of values', async () => { - _renderLinkField({element: mockFormElementLink}); + _renderLinkField({ + element: { + ...mockFormElementLink, + attribute: { + ...mockFormElementLink.attribute, + multiple_values: true + } + } + }); expect(screen.getByRole('table')).toBeInTheDocument(); expect(screen.getAllByRole('row')).toHaveLength(1); @@ -171,7 +179,16 @@ describe('LinkField', () => { } ]; - _renderLinkField({element: {...mockFormElementLinkWithColumns, values: recordValuesWithColumns}}); + _renderLinkField({ + element: { + ...mockFormElementLinkWithColumns, + values: recordValuesWithColumns, + attribute: { + ...mockFormElementLink.attribute, + multiple_values: true + } + } + }); expect(screen.getByRole('table')).toBeInTheDocument(); expect(screen.getAllByRole('cell')).toHaveLength(3); @@ -180,7 +197,16 @@ describe('LinkField', () => { }); test('If no value, display a button to add a value', async () => { - _renderLinkField({element: {...mockFormElementLink, values: []}}); + _renderLinkField({ + element: { + ...mockFormElementLink, + values: [], + attribute: { + ...mockFormElementLink.attribute, + multiple_values: true + } + } + }); expect(screen.getAllByRole('table').length).toBeGreaterThanOrEqual(1); expect(screen.getByRole('button', {name: /add/, hidden: true})).toBeInTheDocument(); @@ -188,14 +214,26 @@ describe('LinkField', () => { test('If no value and cannot add, display a message', async () => { _renderLinkField({ - element: {...mockFormElementLink, attribute: {...mockFormElementLink.attribute, readonly: true}, values: []} + element: { + ...mockFormElementLink, + attribute: {...mockFormElementLink.attribute, readonly: true, multiple_values: true}, + values: [] + } }); expect(screen.getByText('record_edition.no_value')).toBeInTheDocument(); }); test('Can edit and delete linked record', async () => { - _renderLinkField({element: {...mockFormElementLink}}); + _renderLinkField({ + element: { + ...mockFormElementLink, + attribute: { + ...mockFormElementLink.attribute, + multiple_values: true + } + } + }); const row = screen.getByRole('row', {name: /record/}); userEvent.hover(row); @@ -205,7 +243,15 @@ describe('LinkField', () => { }); test('Can delete all values', async () => { - _renderLinkField({element: {...mockFormElementLink}}); + _renderLinkField({ + element: { + ...mockFormElementLink, + attribute: { + ...mockFormElementLink.attribute, + multiple_values: true + } + } + }); const deleteAllValuesButton = screen.getByRole('button', {name: /delete-all-values/, hidden: true}); expect(deleteAllValuesButton).toBeInTheDocument(); @@ -245,7 +291,15 @@ describe('LinkField', () => { }); test('Can display value details', async () => { - _renderLinkField({element: {...mockFormElementLink}}); + _renderLinkField({ + element: { + ...mockFormElementLink, + attribute: { + ...mockFormElementLink.attribute, + multiple_values: true + } + } + }); const valueDetailsButtons = screen.getAllByRole('button', {name: /info/, hidden: true}); expect(valueDetailsButtons).toHaveLength(2); @@ -255,6 +309,20 @@ describe('LinkField', () => { expect(mockEditRecordDispatch.mock.calls[0][0].type).toBe(EditRecordReducerActionsTypes.SET_ACTIVE_VALUE); }); + it('should render MonoValueSelect', () => { + const mockFormElementLinkNoMultivalue: FormElement<{}> = { + ...mockFormElementLink, + attribute: { + ...mockFormElementLink.attribute, + multiple_values: false + } + }; + + _renderLinkField({element: {...mockFormElementLinkNoMultivalue}}); + + expect(screen.getByRole('combobox')).toBeVisible(); + }); + describe('Values list', () => { const mockFormElementLinkMultivalue: FormElement<{}> = { ...mockFormElementLink, diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/LinkField.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/LinkField.tsx index 01fe9e2f7..d72d4e1b0 100644 --- a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/LinkField.tsx +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/LinkField.tsx @@ -52,6 +52,8 @@ import ValuesVersionIndicator from '../../shared/ValuesVersionIndicator'; import {APICallStatus, FieldScope, IFormElementProps} from '../../_types'; import FloatingMenuHandler from './FloatingMenuHandler'; import ValuesAdd from './ValuesAdd'; +import {MonoValueSelect} from '_ui/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/MonoValueSelect'; +import {AntForm} from 'aristid-ds'; const TableWrapper = styled.div<{$isValuesAddVisible: boolean; $themeToken: AntdThemeToken}>` position: relative; @@ -69,6 +71,7 @@ const TableWrapper = styled.div<{$isValuesAddVisible: boolean; $themeToken: Antd } // Disable some unwanted antd styles + && table > thead > tr:first-child { th:first-child, th:last-child { @@ -112,10 +115,11 @@ export interface IRowData { key: string; whoAmI: IRecordIdentityWhoAmI; value: RecordFormElementsValueLinkValue; + [columnName: string]: unknown; } -type LinkFieldReducerState = ILinkFieldState; +export type LinkFieldReducerState = ILinkFieldState; type LinkFieldReducerAction = LinkFieldReducerActions; function LinkField({ @@ -222,7 +226,7 @@ function LinkField({ }); }; - const _handleDeleteValue = async (value: IRecordPropertyLink) => { + const _handleDeleteValue = async (value: IRecordPropertyLink, fetchFreshValues: boolean = true) => { const deleteRes = await onValueDelete({value: value.linkValue.id, id_value: value.id_value}, attribute.id); if (deleteRes.status === APICallStatus.SUCCESS) { @@ -231,7 +235,7 @@ function LinkField({ idValue: value.id_value }); - if (!isInCreationMode) { + if (!isInCreationMode && fetchFreshValues) { const freshValues = await fetchValues(state.values[state.activeScope].version); dispatch({ @@ -455,37 +459,64 @@ function LinkField({ return ( <> - {state.isValuesAddVisible && } - - - {element.settings.label} - {editRecordState.externalUpdate.updatedValues[attribute?.id] && } - {state.activeScope === FieldScope.INHERITED && ( - + {attribute.multiple_values ? ( + <> + {state.isValuesAddVisible && } + + + {element.settings.label} + {editRecordState.externalUpdate.updatedValues[attribute?.id] && } + {state.activeScope === FieldScope.INHERITED && ( + + )} + + + }} + data-testid="linked-field-values" + footer={tableFooter} + scroll={{y: 280}} + /> + {state.isValuesAddVisible && canAddValue && ( + + )} + + {state.errorMessage && ( + } + /> )} - -
- }} - data-testid="linked-field-values" - footer={tableFooter} - scroll={{y: 280}} - /> - {state.isValuesAddVisible && canAddValue && ( - - )} - - {state.errorMessage && ( - } - > + + ) : ( + + + )} ); diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/MonoValueSelect.test.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/MonoValueSelect.test.tsx new file mode 100644 index 000000000..65962a41f --- /dev/null +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/MonoValueSelect.test.tsx @@ -0,0 +1,219 @@ +import {render, screen} from '_ui/_tests/testUtils'; +import {MonoValueSelect} from './MonoValueSelect'; +import {mockFormElementInput, mockFormElementLink} from '_ui/__mocks__/common/form'; +import {LinkFieldReducerState} from '../LinkField'; +import {mockAttributeLink} from '_ui/__mocks__/common/attribute'; +import {APICallStatus, FieldScope} from '../../../_types'; +import {mockRecord} from '_ui/__mocks__/common/record'; +import {AntForm} from 'aristid-ds'; +import userEvent from '@testing-library/user-event'; +import {getRecordsFromLibraryQuery} from '_ui/_queries/records/getRecordsFromLibraryQuery'; +import {AttributeType, SortOrder} from '_ui/_gqlTypes'; +import {MockedResponse} from '@apollo/client/testing'; +import {RecordFormElementsValueLinkValue} from '_ui/hooks/useGetRecordForm'; + +describe('', () => { + const onSelectChangeMock = jest.fn(); + const onClearSelectMock = jest.fn(); + + const records = { + __typename: 'RecordList', + list: [ + { + id: '28121951', + _id: '28121951', + whoAmI: { + id: '28121951', + label: 'Danette pistache', + subLabel: null, + preview: null, + library: { + id: 'id_library', + label: null + }, + color: null + }, + __typename: 'Record' + }, + { + id: '15061943', + _id: '15061943', + whoAmI: { + id: '15061943', + label: 'Danette chocolat', + subLabel: null, + preview: null, + library: { + id: 'id_library', + label: null + }, + color: null + }, + __typename: 'Record' + } + ], + totalCount: 2 + }; + + const mocks: MockedResponse[] = [ + { + request: { + query: getRecordsFromLibraryQuery(), + variables: {library: 'test_lib', limit: 20, sort: {field: 'label', order: SortOrder.asc}} + }, + result: {data: {records}} + } + ]; + + const state: LinkFieldReducerState = { + errorMessage: 'This is an error message', + isValuesAddVisible: false, + record: mockRecord, + formElement: { + ...mockFormElementInput, + settings: { + label: 'label', + required: true + } + }, + attribute: mockAttributeLink, + isReadOnly: false, + activeScope: FieldScope.CURRENT, + values: { + [FieldScope.CURRENT]: null, + [FieldScope.INHERITED]: null + } + }; + + afterEach(() => { + onSelectChangeMock.mockClear(); + onClearSelectMock.mockClear(); + }); + + it('should display MonoValueSelect with no active value', async () => { + render( + + + + + , + {mocks} + ); + + expect(screen.queryByText('Danette pistache')).not.toBeInTheDocument(); + expect(screen.queryByText('Danette chocolat')).not.toBeInTheDocument(); + + const select = screen.getByRole('combobox'); + await userEvent.click(select); + + const options = screen.getAllByRole('option'); + expect(options.length).toBe(records.list.length); + + const danettePistache = screen.getByText('Danette pistache'); + expect(danettePistache).toBeVisible(); + + const danetteChocolat = screen.getByText('Danette chocolat'); + expect(danetteChocolat).toBeVisible(); + await userEvent.click(danetteChocolat); + + expect(onSelectChangeMock).toBeCalledTimes(1); + expect(onSelectChangeMock).toHaveBeenCalledWith([records.list[1]]); + }); + + it('should display MonoValueSelect with active value', async () => { + onClearSelectMock.mockResolvedValueOnce({res: {status: APICallStatus.SUCCESS}}); + const id_value = '11051999'; + + render( + + + + + , + {mocks} + ); + + // const defaultValue = await screen.findByText('Danette chocolat'); // TODO uncomment and remove next line when select defaultValue is fixed in DS + const defaultValue = await screen.findByText('15061943'); + expect(defaultValue).toBeVisible(); + + const select = screen.getByRole('combobox'); + await userEvent.click(select); + + const options = screen.getAllByRole('option'); + expect(options.length).toBe(records.list.length); + + const danettePistache = screen.getByText('Danette pistache'); + expect(danettePistache).toBeVisible(); + await userEvent.click(danettePistache); + + expect(onSelectChangeMock).toBeCalledTimes(1); + expect(onSelectChangeMock).toHaveBeenCalledWith([records.list[0]]); + }); + + it('should be able to clear selection when attribute is not required', async () => { + const id_value = '23051985'; + const activeValue = { + id_value, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + linkValue: { + id: records.list[1].id, + whoAmI: {} + } as RecordFormElementsValueLinkValue['linkValue'], + attribute: { + id: mockFormElementLink.attribute.id, + type: AttributeType.simple_link, + system: false + } + }; + render( + + + + + , + {mocks} + ); + + // const defaultValue = await screen.findByText('Danette chocolat'); // TODO uncomment and remove next line when select defaultValue is fixed in DS + const defaultValue = await screen.findByText('15061943'); + expect(defaultValue).toBeVisible(); + + const clearIcon = screen.getByLabelText('clear'); + await userEvent.click(clearIcon); + expect(onClearSelectMock).toHaveBeenCalledWith(activeValue, false); + }); +}); diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/MonoValueSelect.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/MonoValueSelect.tsx new file mode 100644 index 000000000..cb34476fe --- /dev/null +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/MonoValueSelect.tsx @@ -0,0 +1,75 @@ +import {FunctionComponent} from 'react'; +import {AntForm, KitSelect} from 'aristid-ds'; +import {RecordFormElementsValueLinkValue} from '_ui/hooks/useGetRecordForm'; +import useSharedTranslation from '_ui/hooks/useSharedTranslation/useSharedTranslation'; +import {RecordFormAttributeLinkAttributeFragment, SortOrder} from '_ui/_gqlTypes'; +import {SelectProps} from 'antd'; +import {DefaultOptionType} from 'antd/es/select'; +import {useGetOptionsQuery} from './useGetOptionsQuery'; +import {IRecordIdentity} from '_ui/types'; +import {IRecordPropertyLink} from '_ui/_queries/records/getRecordPropertiesQuery'; + +interface IMonoValueSelectProps { + activeValue: RecordFormElementsValueLinkValue | undefined; + value?: SelectProps['value']; + onChange?: SelectProps['onChange']; + attribute: RecordFormAttributeLinkAttributeFragment; + label: string; + onSelectClear: (value: IRecordPropertyLink, fetchFreshValues: boolean) => void; + onSelectChange: (values: IRecordIdentity[]) => void; + required: boolean; +} + +export const MonoValueSelect: FunctionComponent = ({ + activeValue, + value, + onChange, + attribute, + label, + onSelectChange, + onSelectClear, + required +}) => { + if (!onChange) { + throw Error('MonoValueSelect should be used inside a antd Form.Item'); + } + + const {t} = useSharedTranslation(); + const {errors} = AntForm.Item.useStatus(); + const form = AntForm.useFormInstance(); + + const {loading, selectOptions, updateLeavField} = useGetOptionsQuery({ + activeValue, + linkedLibraryId: attribute.linked_library.id, + onSelectChange + }); + + const handleSelect = (optionValue: string, ...antOnChangeParams: DefaultOptionType[]) => { + onChange(optionValue, antOnChangeParams); + + updateLeavField(optionValue); + }; + + const handleClear = () => { + form.setFieldValue(attribute.id, undefined); + + onSelectClear(activeValue, false); + }; + + return ( + 0 && 'error'} + showSearch + optionFilterProp="label" + placeholder={t('record_edition.record_select')} + onSelect={handleSelect} + onClear={required ? undefined : handleClear} + allowClear={!required} + /> + ); +}; diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/useGetOptionsQuery.test.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/useGetOptionsQuery.test.tsx new file mode 100644 index 000000000..df3c04347 --- /dev/null +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/useGetOptionsQuery.test.tsx @@ -0,0 +1,257 @@ +import {IGetRecordsFromLibraryQuery, getRecordsFromLibraryQuery} from '_ui/_queries/records/getRecordsFromLibraryQuery'; +import {SortOrder} from '_ui/_gqlTypes'; +import {MockedResponse} from '@apollo/client/testing'; +import {useGetOptionsQuery} from './useGetOptionsQuery'; +import {renderHook, waitFor} from '_ui/_tests/testUtils'; + +describe('useGetOptionsQuery', () => { + const onSelectChangeMock = jest.fn(); + + const records = { + __typename: 'RecordList', + list: [ + { + id: '28121951', + _id: '28121951', + whoAmI: { + id: '28121951', + label: 'Danette pistache', + subLabel: null, + preview: null, + library: { + id: 'id_library', + label: null + }, + color: null + }, + __typename: 'Record' + }, + { + id: '15061943', + _id: '15061943', + whoAmI: { + id: '15061943', + label: 'Danette chocolat', + subLabel: null, + preview: null, + library: { + id: 'id_library', + label: null + }, + color: null + }, + __typename: 'Record' + } + ], + totalCount: 2 + }; + + const linkedLibraryId = 'linkedLibraryId'; + const mockFactory: (data: IGetRecordsFromLibraryQuery) => MockedResponse[] = data => [ + { + request: { + query: getRecordsFromLibraryQuery(), + variables: {library: linkedLibraryId, limit: 20, sort: {field: 'label', order: SortOrder.asc}} + }, + result: {data} + } + ]; + + beforeEach(() => { + onSelectChangeMock.mockClear(); + }); + + test('Should set loading to false once data is loaded', async () => { + const mock = mockFactory({records: {list: [], totalCount: 0}}); + + const {result} = renderHook((...props) => useGetOptionsQuery(...props), { + initialProps: { + activeValue: undefined, + linkedLibraryId, + onSelectChange: onSelectChangeMock + }, + mocks: mock + }); + + expect(result.current.loading).toBe(true); + + await waitFor(() => expect(result.current.loading).toBe(false)); + }); + + test('Should expose selectOptions ready to display', async () => { + const mock = mockFactory({records}); + + const {result} = renderHook( + () => + useGetOptionsQuery({ + activeValue: undefined, + linkedLibraryId, + onSelectChange: onSelectChangeMock + }), + {mocks: mock} + ); + + expect(result.current.selectOptions).toEqual([]); + + await waitFor(() => + expect(result.current.selectOptions).toEqual([ + { + idCard: { + avatar: expect.anything(), + title: 'Danette pistache' + }, + label: 'Danette pistache', + value: '28121951' + }, + { + idCard: { + avatar: expect.anything(), + title: 'Danette chocolat' + }, + label: 'Danette chocolat', + value: '15061943' + } + ]) + ); + }); + + test('Should augment selectOptions with activeValue', async () => { + const mock = mockFactory({records}); + const activeValue = { + linkValue: { + id: '1000', + whoAmI: { + id: '2000', + label: 'une danette à la prune', + library: { + id: 'id_library', + label: null + } + } + } + }; + + const {result} = renderHook( + () => + useGetOptionsQuery({ + activeValue, + linkedLibraryId, + onSelectChange: onSelectChangeMock + }), + {mocks: mock} + ); + + expect(result.current.selectOptions).toEqual([ + { + idCard: { + avatar: expect.anything(), + title: 'une danette à la prune' + }, + label: 'une danette à la prune', + value: '2000' + } + ]); + + await waitFor(() => + expect(result.current.selectOptions).toEqual([ + { + idCard: { + avatar: expect.anything(), + title: 'Danette pistache' + }, + label: 'Danette pistache', + value: '28121951' + }, + { + idCard: { + avatar: expect.anything(), + title: 'Danette chocolat' + }, + label: 'Danette chocolat', + value: '15061943' + }, + { + idCard: { + avatar: expect.anything(), + title: 'une danette à la prune' + }, + label: 'une danette à la prune', + value: '2000' + } + ]) + ); + }); + + describe('updateLeavField', () => { + const attribute = { + id: '12' + } as any; + const idValue = '12'; + + test('Should call onSelectChange with linkValue if record not in list', async () => { + const mock = mockFactory({records}); + const activeValue = { + linkValue: { + id: '1000', + whoAmI: { + id: '2000', + label: 'une danette à la prune', + library: { + id: 'id_library', + label: null + } + } + } + }; + + const {result} = renderHook( + () => + useGetOptionsQuery({ + activeValue, + linkedLibraryId, + onSelectChange: onSelectChangeMock + }), + {mocks: mock} + ); + + await waitFor(() => result.current.selectOptions.length === 3); + result.current.updateLeavField('notFound'); + + expect(onSelectChangeMock).toHaveBeenCalledWith([activeValue.linkValue]); + }); + + test('Should call onSelectChange with selectedLinkValue if record in list', async () => { + const mock = mockFactory({records}); + const activeValue = { + linkValue: { + id: '1000', + whoAmI: { + id: '2000', + label: 'une danette à la prune', + library: { + id: 'id_library', + label: null + } + } + } + }; + + const {result} = renderHook( + () => + useGetOptionsQuery({ + activeValue, + linkedLibraryId, + onSelectChange: onSelectChangeMock + }), + {mocks: mock} + ); + + await waitFor(() => result.current.selectOptions.length === 3); + + const selectedRecord = records.list[0]; + result.current.updateLeavField(selectedRecord.id); + + expect(onSelectChangeMock).toHaveBeenCalledWith([records.list[0]]); + }); + }); +}); diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/useGetOptionsQuery.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/useGetOptionsQuery.tsx new file mode 100644 index 000000000..8ff412ce1 --- /dev/null +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/LinkField/MonoValueSelect/useGetOptionsQuery.tsx @@ -0,0 +1,88 @@ +import {useQuery} from '@apollo/client'; +import {SortOrder} from '_ui/_gqlTypes'; +import { + IGetRecordsFromLibraryQuery, + IGetRecordsFromLibraryQueryVariables, + getRecordsFromLibraryQuery +} from '_ui/_queries/records/getRecordsFromLibraryQuery'; +import {KitAvatar, KitSelect} from 'aristid-ds'; +import {ComponentProps, useMemo} from 'react'; +import {RecordFormElementsValueLinkValue} from '_ui/hooks/useGetRecordForm'; +import {IRecordIdentity} from '_ui/types'; + +export const useGetOptionsQuery = ({ + activeValue, + linkedLibraryId, + onSelectChange +}: { + activeValue: RecordFormElementsValueLinkValue | undefined; + linkedLibraryId: string; + onSelectChange: (values: IRecordIdentity[]) => void; +}) => { + const {loading, data} = useQuery( + getRecordsFromLibraryQuery(), + { + fetchPolicy: 'network-only', + variables: { + library: linkedLibraryId, + limit: 20, + sort: { + field: 'label', + order: SortOrder.asc + } + } + } + ); + + const recordList = useMemo(() => data?.records?.list ?? [], [data]); + + const selectOptions = useMemo['options']>( + () => + recordList.map(recordItem => ({ + value: recordItem.whoAmI.id, + label: recordItem.whoAmI.label, + idCard: { + title: recordItem.whoAmI.label, + avatar: ( + + ) + } + })), + [recordList] + ); + + const augmentedSelectOptionsWithActive = selectOptions; + + if (activeValue && recordList.findIndex(record => record.id === activeValue.linkValue.id) === -1) { + augmentedSelectOptionsWithActive.push({ + value: activeValue.linkValue.whoAmI.id, + label: activeValue.linkValue.whoAmI.label, + idCard: { + title: activeValue.linkValue.whoAmI.label, + avatar: ( + + ) + } + }); + } + + const updateLeavField = (value: string) => { + const selectedLinkValue = recordList.find(record => record.id === value); + + return onSelectChange([selectedLinkValue ?? activeValue.linkValue]); + }; + + return {loading, selectOptions: augmentedSelectOptionsWithActive, updateLeavField}; +}; diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSInputWrapper.test.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSInputWrapper.test.tsx index c99fc9d6a..5de68f1b7 100644 --- a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSInputWrapper.test.tsx +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSInputWrapper.test.tsx @@ -14,6 +14,7 @@ import {mockAttributeLink} from '_ui/__mocks__/common/attribute'; import userEvent from '@testing-library/user-event'; import {Form} from 'antd'; import {RecordFormElementsValueStandardValue} from '_ui/hooks/useGetRecordForm'; +import {useForm} from 'antd/lib/form/Form'; const label = 'label'; const idValue = '123'; diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSInputWrapper.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSInputWrapper.tsx index bf2817491..611c529c0 100644 --- a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSInputWrapper.tsx +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSInputWrapper.tsx @@ -5,7 +5,6 @@ import {KitInput, KitInputWrapper} from 'aristid-ds'; import {FocusEvent, FunctionComponent, ReactNode} from 'react'; import {IStandardFieldReducerState} from '../../../reducers/standardFieldReducer/standardFieldReducer'; import {Form, InputProps} from 'antd'; -import styled from 'styled-components'; import {RecordFormElementsValueStandardValue} from '_ui/hooks/useGetRecordForm'; interface IDSInputWrapperProps { diff --git a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSRangePickerWrapper.tsx b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSRangePickerWrapper.tsx index fd5bd7f9c..f1fcfa47d 100644 --- a/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSRangePickerWrapper.tsx +++ b/libs/ui/src/components/RecordEdition/EditRecordContent/uiElements/StandardField/StandardFieldValue/DSRangePickerWrapper.tsx @@ -7,7 +7,6 @@ import {IStandardFieldReducerState} from '../../../reducers/standardFieldReducer import {Form} from 'antd'; import dayjs from 'dayjs'; import {StandardValueTypes} from '../../../_types'; -import {styled} from 'styled-components'; import {RangePickerProps} from 'antd/lib/date-picker'; interface IDSRangePickerWrapperProps { diff --git a/libs/ui/src/locales/en/shared.json b/libs/ui/src/locales/en/shared.json index 669fc79a7..3acaa21e3 100644 --- a/libs/ui/src/locales/en/shared.json +++ b/libs/ui/src/locales/en/shared.json @@ -452,7 +452,8 @@ "create_and_edit": "Create and edit", "cancel_confirm_modal_title": "Confirm cancellation?", "cancel_confirm_modal_content": "You are about to cancel the creation.", - "cancel_confirm_modal_question": "Are you sure?" + "cancel_confirm_modal_question": "Are you sure?", + "record_select": "Select a record" }, "record_summary": { "preview_title": "Click here to visualize preview.", diff --git a/libs/ui/src/locales/fr/shared.json b/libs/ui/src/locales/fr/shared.json index 21bd631a4..cebe0c657 100644 --- a/libs/ui/src/locales/fr/shared.json +++ b/libs/ui/src/locales/fr/shared.json @@ -40,7 +40,7 @@ "invalid_endpoint_format": "Le point d'accès peut être composé uniquement de lettres minuscules, de chiffres et du caractère \"-\" (ex: \"mon-app\")", "id_already_exists": "Cet identifiant existe déjà", "endpoint_already_used": "Ce point d'accès est déjà utilisé", - "invalid_url_format": "L'URL n'est pas valide" + "invalid_url_format": "L’URL n’est pas valide" }, "applications": { "id": "Identifiant", @@ -452,7 +452,8 @@ "create_and_edit": "Créer et éditer", "cancel_confirm_modal_title": "Confirmer l'abandon?", "cancel_confirm_modal_content": "Vous êtes sur le point d'abandonner la création.", - "cancel_confirm_modal_question": "Êtes-vous sûr(e)?" + "cancel_confirm_modal_question": "Êtes-vous sûr(e) ?", + "record_select": "Sélectionnez un élément" }, "record_summary": { "preview_title": "Cliquez ici pour voir l’aperçu.", diff --git a/yarn.lock b/yarn.lock index bbcb9e753..6f5510e9a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -126,9 +126,9 @@ __metadata: languageName: node linkType: hard -"@ant-design/icons@npm:^5.3.0": - version: 5.3.0 - resolution: "@ant-design/icons@npm:5.3.0" +"@ant-design/icons@npm:^5.3.3": + version: 5.3.6 + resolution: "@ant-design/icons@npm:5.3.6" dependencies: "@ant-design/colors": "npm:^7.0.0" "@ant-design/icons-svg": "npm:^4.4.0" @@ -138,7 +138,7 @@ __metadata: peerDependencies: react: ">=16.0.0" react-dom: ">=16.0.0" - checksum: f63bfc39876008e18d4c6ae98ea61835b30738b8dc054084a77629a6f108ae227457de8f684df092bf0ae5f7bd919d9708792a45399397f69e0897a63b784535 + checksum: 5fe41720dd07324a31b2743dc2b558e6eea241afe2c1af623f6f9d45c7fb6051e4178e96f4bf344c76adc5549d53fcd57fe4abb38142108c24e95c4e17b0f8f3 languageName: node linkType: hard @@ -4893,6 +4893,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.24.0": + version: 7.24.4 + resolution: "@babel/runtime@npm:7.24.4" + dependencies: + regenerator-runtime: "npm:^0.14.0" + checksum: 8ec8ce2c145bc7e31dd39ab66df124f357f65c11489aefacb30f431bae913b9aaa66aa5efe5321ea2bf8878af3fcee338c87e7599519a952e3a6f83aa1b03308 + languageName: node + linkType: hard + "@babel/runtime@npm:^7.24.1": version: 7.24.1 resolution: "@babel/runtime@npm:7.24.1" @@ -8091,7 +8100,7 @@ __metadata: "@types/react-beautiful-dnd": "npm:13.1.2" "@types/react-table": "npm:7.7.12" "@types/uuid": "npm:^9" - aristid-ds: "npm:4.0.0-3ef6e97" + aristid-ds: "npm:4.0.0-8683c72" babel-jest: "npm:29.3.1" commander: "npm:9.5.0" dayjs: "npm:1.11.10" @@ -8117,7 +8126,7 @@ __metadata: peerDependencies: "@ant-design/icons": ">=5.2" "@apollo/client": ">=3.8.1" - antd: 5.9.1 + antd: 5.15.3 i18next: 22.5 react: 18.2.0 react-dom: 18.2.0 @@ -8614,21 +8623,6 @@ __metadata: languageName: node linkType: hard -"@rc-component/color-picker@npm:~1.5.1": - version: 1.5.1 - resolution: "@rc-component/color-picker@npm:1.5.1" - dependencies: - "@babel/runtime": "npm:^7.23.6" - "@ctrl/tinycolor": "npm:^3.6.1" - classnames: "npm:^2.2.6" - rc-util: "npm:^5.38.1" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: b8997f4844e6dcd6b5e66a2ed2d17d0906642a155a0e8d6e276d1b9c0bb052d7336a3ca1dd990e9ed7e10345cb266eeb7e56c7030b6be0e0aca211b04e5876a1 - languageName: node - linkType: hard - "@rc-component/color-picker@npm:~1.5.3": version: 1.5.3 resolution: "@rc-component/color-picker@npm:1.5.3" @@ -8708,22 +8702,6 @@ __metadata: languageName: node linkType: hard -"@rc-component/tour@npm:~1.12.3": - version: 1.12.3 - resolution: "@rc-component/tour@npm:1.12.3" - dependencies: - "@babel/runtime": "npm:^7.18.0" - "@rc-component/portal": "npm:^1.0.0-9" - "@rc-component/trigger": "npm:^1.3.6" - classnames: "npm:^2.3.2" - rc-util: "npm:^5.24.4" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 650f7e5c3567e1910ec6a6c312632937aa041ac0008568290385be07384469ddc482aeb517d88f59d66377579adbab25585364a4c21d416a10a1c2c80e3436a7 - languageName: node - linkType: hard - "@rc-component/tour@npm:~1.14.2": version: 1.14.2 resolution: "@rc-component/tour@npm:1.14.2" @@ -8740,41 +8718,6 @@ __metadata: languageName: node linkType: hard -"@rc-component/trigger@npm:^1.17.0, @rc-component/trigger@npm:^1.18.0, @rc-component/trigger@npm:^1.18.3": - version: 1.18.3 - resolution: "@rc-component/trigger@npm:1.18.3" - dependencies: - "@babel/runtime": "npm:^7.23.2" - "@rc-component/portal": "npm:^1.1.0" - classnames: "npm:^2.3.2" - rc-motion: "npm:^2.0.0" - rc-resize-observer: "npm:^1.3.1" - rc-util: "npm:^5.38.0" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 1db49fa11a9c5a87def9b1ebd9e1f1401f21a1e6c7f84195138ae7ad3e65e240b7848ed16682bba91837e1ecca8f6fa0c58076564dbe00f55a63c7672b2cbc66 - languageName: node - linkType: hard - -"@rc-component/trigger@npm:^1.3.6, @rc-component/trigger@npm:^1.5.0, @rc-component/trigger@npm:^1.6.2, @rc-component/trigger@npm:^1.7.0": - version: 1.14.1 - resolution: "@rc-component/trigger@npm:1.14.1" - dependencies: - "@babel/runtime": "npm:^7.18.3" - "@rc-component/portal": "npm:^1.1.0" - classnames: "npm:^2.3.2" - rc-align: "npm:^4.0.0" - rc-motion: "npm:^2.0.0" - rc-resize-observer: "npm:^1.3.1" - rc-util: "npm:^5.33.0" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 01f3a31380412a26d523cdc8d16dce2337746ca387bb51c244b09631bf4e597b9bced732167b7019b348af54f7b81f730fc583a9570cd0d8176d14d683d248fb - languageName: node - linkType: hard - "@rc-component/trigger@npm:^2.0.0": version: 2.0.0 resolution: "@rc-component/trigger@npm:2.0.0" @@ -11423,61 +11366,62 @@ __metadata: languageName: node linkType: hard -"antd@npm:5.14.0": - version: 5.14.0 - resolution: "antd@npm:5.14.0" +"antd@npm:5.15.3": + version: 5.15.3 + resolution: "antd@npm:5.15.3" dependencies: "@ant-design/colors": "npm:^7.0.2" "@ant-design/cssinjs": "npm:^1.18.4" - "@ant-design/icons": "npm:^5.3.0" + "@ant-design/icons": "npm:^5.3.3" "@ant-design/react-slick": "npm:~1.0.2" + "@babel/runtime": "npm:^7.24.0" "@ctrl/tinycolor": "npm:^3.6.1" - "@rc-component/color-picker": "npm:~1.5.1" + "@rc-component/color-picker": "npm:~1.5.3" "@rc-component/mutate-observer": "npm:^1.1.0" - "@rc-component/tour": "npm:~1.12.3" - "@rc-component/trigger": "npm:^1.18.3" + "@rc-component/tour": "npm:~1.14.2" + "@rc-component/trigger": "npm:^2.0.0" classnames: "npm:^2.5.1" copy-to-clipboard: "npm:^3.3.3" dayjs: "npm:^1.11.10" qrcode.react: "npm:^3.1.0" - rc-cascader: "npm:~3.21.2" - rc-checkbox: "npm:~3.1.0" + rc-cascader: "npm:~3.24.0" + rc-checkbox: "npm:~3.2.0" rc-collapse: "npm:~3.7.2" - rc-dialog: "npm:~9.3.4" - rc-drawer: "npm:~7.0.0" - rc-dropdown: "npm:~4.1.0" - rc-field-form: "npm:~1.41.0" - rc-image: "npm:~7.5.1" - rc-input: "npm:~1.4.3" + rc-dialog: "npm:~9.4.0" + rc-drawer: "npm:~7.1.0" + rc-dropdown: "npm:~4.2.0" + rc-field-form: "npm:~1.42.1" + rc-image: "npm:~7.6.0" + rc-input: "npm:~1.4.5" rc-input-number: "npm:~9.0.0" - rc-mentions: "npm:~2.10.1" - rc-menu: "npm:~9.12.4" + rc-mentions: "npm:~2.11.1" + rc-menu: "npm:~9.13.0" rc-motion: "npm:^2.9.0" rc-notification: "npm:~5.3.0" rc-pagination: "npm:~4.0.4" - rc-picker: "npm:~4.0.0-alpha.43" + rc-picker: "npm:~4.3.0" rc-progress: "npm:~3.5.1" rc-rate: "npm:~2.12.0" rc-resize-observer: "npm:^1.4.0" rc-segmented: "npm:~2.3.0" - rc-select: "npm:~14.11.0" + rc-select: "npm:~14.13.0" rc-slider: "npm:~10.5.0" rc-steps: "npm:~6.0.1" rc-switch: "npm:~4.1.0" - rc-table: "npm:~7.39.0" - rc-tabs: "npm:~14.0.0" + rc-table: "npm:~7.42.0" + rc-tabs: "npm:~14.1.1" rc-textarea: "npm:~1.6.3" - rc-tooltip: "npm:~6.1.3" + rc-tooltip: "npm:~6.2.0" rc-tree: "npm:~5.8.5" - rc-tree-select: "npm:~5.17.0" + rc-tree-select: "npm:~5.19.0" rc-upload: "npm:~4.5.2" - rc-util: "npm:^5.38.1" + rc-util: "npm:^5.39.1" scroll-into-view-if-needed: "npm:^3.1.0" throttle-debounce: "npm:^5.0.0" peerDependencies: react: ">=16.9.0" react-dom: ">=16.9.0" - checksum: c9cdfb4cf922d37a63f4ec54fa285047414411679b374d24211fbfb96d316029869e80dde0cc96ee15af267a65aa57475321d5f7e2f91e43239a17e4d4163a18 + checksum: ae0e487fe448f4316066a34786c4536a936c65500dd3388a42c26c1cc659e70fadb0186a4b44519611964ecde5b526551f600aeb3ffe795ce3564b6224639bfb languageName: node linkType: hard @@ -12095,9 +12039,9 @@ __metadata: languageName: node linkType: hard -"aristid-ds@npm:4.0.0-3ef6e97": - version: 4.0.0-3ef6e97 - resolution: "aristid-ds@npm:4.0.0-3ef6e97" +"aristid-ds@npm:4.0.0-8683c72": + version: 4.0.0-8683c72 + resolution: "aristid-ds@npm:4.0.0-8683c72" dependencies: "@dnd-kit/core": "npm:^6.1.0" "@dnd-kit/modifiers": "npm:^7.0.0" @@ -12142,7 +12086,7 @@ __metadata: react-uuid: ^2.0.0 remark-gfm: ^3.0.1 styled-components: ^6.0.7 - checksum: e0a42d38bfd45dcf99d003cb07d331856e5782cd21a85f2c64bad36b924f7dbd2373c8c0c55a024f648a274e3e1cf21618ea6c46d9dc57affc1388cf58260460 + checksum: 10ccf546a505a3494fac6de3f3771ce549db8fed9f7450d0817da29b48ba3dbe585949566115d50a08650c27db4179b70a6a56232be576ae9c6b5e425d693659 languageName: node linkType: hard @@ -15196,11 +15140,11 @@ __metadata: "@types/redux-mock-store": "npm:1.0.3" "@types/styled-components": "npm:5.1.26" "@vitejs/plugin-react": "npm:3.1.0" - antd: "npm:5.14.0" + antd: "npm:5.15.3" apollo: "npm:2.34.0" apollo-cache-inmemory: "npm:1.6.6" apollo-upload-client: "npm:14.1.3" - aristid-ds: "npm:4.0.0-3ef6e97" + aristid-ds: "npm:4.0.0-8683c72" commander: "npm:5.1.0" dayjs: "npm:1.11.10" graphql: "npm:15.0.0" @@ -15692,13 +15636,6 @@ __metadata: languageName: node linkType: hard -"dom-align@npm:^1.7.0": - version: 1.12.2 - resolution: "dom-align@npm:1.12.2" - checksum: 4659909b9ab48de2976f0668220289e3835490537b1ce834b7f2dd3189b21e0996011ec8826a2789c9597729bbb457f6e54f07787a00774e3ce04b15fcbfa636 - languageName: node - linkType: hard - "dom-helpers@npm:^5.1.3": version: 5.2.1 resolution: "dom-helpers@npm:5.2.1" @@ -23191,8 +23128,8 @@ __metadata: "@types/react": "npm:18.2.14" "@types/react-dom": "npm:18.2.6" "@vitejs/plugin-react": "npm:3.1.0" - antd: "npm:5.14.0" - aristid-ds: "npm:4.0.0-3ef6e97" + antd: "npm:5.15.3" + aristid-ds: "npm:4.0.0-8683c72" i18next: "npm:22.5.0" i18next-browser-languagedetector: "npm:7.0.2" i18next-http-backend: "npm:2.1.1" @@ -24520,11 +24457,11 @@ __metadata: linkType: hard "nan@npm:^2.15.0": - version: 2.17.0 - resolution: "nan@npm:2.17.0" + version: 2.19.0 + resolution: "nan@npm:2.19.0" dependencies: node-gyp: "npm:latest" - checksum: bba1efee2475afb0cce154300b554863fb4bb0a683a28f5d0fa7390794b3b4381356aabeab6472c70651d9c8a2830e7595963f3ec0aa2008e5c4d83dbeb820fa + checksum: b97f680753113bcd803cb174e40baa01e04aa4cb95ee62b48841336d9c48b278a2eeff71a4a0d7315b8f639fb1e38049925d3be1c6e266c158dc8f7d95d67eaa languageName: node linkType: hard @@ -25839,9 +25776,9 @@ __metadata: "@types/react": "npm:18.2.14" "@types/react-dom": "npm:18.2.6" "@vitejs/plugin-react": "npm:3.1.0" - antd: "npm:5.14.0" + antd: "npm:5.15.3" apollo: "npm:2.34.0" - aristid-ds: "npm:4.0.0-3ef6e97" + aristid-ds: "npm:4.0.0-8683c72" commander: "npm:10.0.0" cross-fetch: "npm:3.1.5" graphql-ws: "npm:5.12.0" @@ -26392,40 +26329,6 @@ __metadata: languageName: node linkType: hard -"rc-align@npm:^4.0.0": - version: 4.0.11 - resolution: "rc-align@npm:4.0.11" - dependencies: - "@babel/runtime": "npm:^7.10.1" - classnames: "npm:2.x" - dom-align: "npm:^1.7.0" - lodash: "npm:^4.17.21" - rc-util: "npm:^5.3.0" - resize-observer-polyfill: "npm:^1.5.1" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 3cb909011d8236f63a513d1e03dca9711eeb53043cd44cf421157a9a0ce93c8021cb60cd8c43c08bc671825bad54519fd7dfb89e45435b2e6631c55bac907a55 - languageName: node - linkType: hard - -"rc-cascader@npm:~3.21.2": - version: 3.21.2 - resolution: "rc-cascader@npm:3.21.2" - dependencies: - "@babel/runtime": "npm:^7.12.5" - array-tree-filter: "npm:^2.1.0" - classnames: "npm:^2.3.1" - rc-select: "npm:~14.11.0" - rc-tree: "npm:~5.8.1" - rc-util: "npm:^5.37.0" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 2640379d9a896586e429f94d8cab9503b52336d841ec1694d5d62eb91ed8137795c3fba8380efb43d7333a917f08d698984143e6cef7cbdd0662cba00866992a - languageName: node - linkType: hard - "rc-cascader@npm:~3.24.0": version: 3.24.0 resolution: "rc-cascader@npm:3.24.0" @@ -26443,20 +26346,6 @@ __metadata: languageName: node linkType: hard -"rc-checkbox@npm:~3.1.0": - version: 3.1.0 - resolution: "rc-checkbox@npm:3.1.0" - dependencies: - "@babel/runtime": "npm:^7.10.1" - classnames: "npm:^2.3.2" - rc-util: "npm:^5.25.2" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: f15dd3e3e3120567b633392e37c6d904f2b3c32eb752f4197231b6d79bfa257bde9cd32616ad08c0ad5b053d7b197c9e0684479053b4dea384e466ab53f5c7b4 - languageName: node - linkType: hard - "rc-checkbox@npm:~3.2.0": version: 3.2.0 resolution: "rc-checkbox@npm:3.2.0" @@ -26501,22 +26390,6 @@ __metadata: languageName: node linkType: hard -"rc-dialog@npm:~9.3.4": - version: 9.3.4 - resolution: "rc-dialog@npm:9.3.4" - dependencies: - "@babel/runtime": "npm:^7.10.1" - "@rc-component/portal": "npm:^1.0.0-8" - classnames: "npm:^2.2.6" - rc-motion: "npm:^2.3.0" - rc-util: "npm:^5.21.0" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 3b6a322b31cdfe868da727845e0eeed780c293e447d908a2ae61457f987ac192525ad8ca1d082ba174a424fc27ca2732e98a0654ea8d55daeb965fce852c53c5 - languageName: node - linkType: hard - "rc-dialog@npm:~9.4.0": version: 9.4.0 resolution: "rc-dialog@npm:9.4.0" @@ -26533,22 +26406,6 @@ __metadata: languageName: node linkType: hard -"rc-drawer@npm:~7.0.0": - version: 7.0.0 - resolution: "rc-drawer@npm:7.0.0" - dependencies: - "@babel/runtime": "npm:^7.10.1" - "@rc-component/portal": "npm:^1.1.1" - classnames: "npm:^2.2.6" - rc-motion: "npm:^2.6.1" - rc-util: "npm:^5.36.0" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 6396ddd14d7bf8916eb37749f33e50cb1f74bc937513a353bbbcfdcf9c03ef970e6ae941cf2232e4495cc7e77a5cd911489bd3fdfe8d19570fcd699c98b22af3 - languageName: node - linkType: hard - "rc-drawer@npm:~7.1.0": version: 7.1.0 resolution: "rc-drawer@npm:7.1.0" @@ -26565,21 +26422,6 @@ __metadata: languageName: node linkType: hard -"rc-dropdown@npm:~4.1.0": - version: 4.1.0 - resolution: "rc-dropdown@npm:4.1.0" - dependencies: - "@babel/runtime": "npm:^7.18.3" - "@rc-component/trigger": "npm:^1.7.0" - classnames: "npm:^2.2.6" - rc-util: "npm:^5.17.0" - peerDependencies: - react: ">=16.11.0" - react-dom: ">=16.11.0" - checksum: b9d65a4deda9dda043c54630ca000f847ff257c1433f3cbf19c81bef1dbfb005528583078976a17ea3dfaca550a267dade39fb0f9aa4b7a17cc76dff1ba30c45 - languageName: node - linkType: hard - "rc-dropdown@npm:~4.2.0": version: 4.2.0 resolution: "rc-dropdown@npm:4.2.0" @@ -26595,20 +26437,6 @@ __metadata: languageName: node linkType: hard -"rc-field-form@npm:~1.41.0": - version: 1.41.0 - resolution: "rc-field-form@npm:1.41.0" - dependencies: - "@babel/runtime": "npm:^7.18.0" - async-validator: "npm:^4.1.0" - rc-util: "npm:^5.32.2" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 62a7c47a4426050d113caae087b56396736a1d4518c98a9fe2c604314ab8779a3b4b2a12fdc960f64c933051f36bdad1f2049b6318e06d00d71de1824818fe7d - languageName: node - linkType: hard - "rc-field-form@npm:~1.42.1": version: 1.42.1 resolution: "rc-field-form@npm:1.42.1" @@ -26623,23 +26451,6 @@ __metadata: languageName: node linkType: hard -"rc-image@npm:~7.5.1": - version: 7.5.1 - resolution: "rc-image@npm:7.5.1" - dependencies: - "@babel/runtime": "npm:^7.11.2" - "@rc-component/portal": "npm:^1.0.2" - classnames: "npm:^2.2.6" - rc-dialog: "npm:~9.3.4" - rc-motion: "npm:^2.6.2" - rc-util: "npm:^5.34.1" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: c9d5f8fe1ba5db4f51e4dd527a996ec93eb85b970b3fc0e3dc327665edd06fd2ed169161c1276aa1e798dc9d1bcf7a011baf10c5b34445d907922d3ae79bc403 - languageName: node - linkType: hard - "rc-image@npm:~7.6.0": version: 7.6.0 resolution: "rc-image@npm:7.6.0" @@ -26673,7 +26484,7 @@ __metadata: languageName: node linkType: hard -"rc-input@npm:~1.4.0, rc-input@npm:~1.4.3": +"rc-input@npm:~1.4.0": version: 1.4.3 resolution: "rc-input@npm:1.4.3" dependencies: @@ -26701,24 +26512,6 @@ __metadata: languageName: node linkType: hard -"rc-mentions@npm:~2.10.1": - version: 2.10.1 - resolution: "rc-mentions@npm:2.10.1" - dependencies: - "@babel/runtime": "npm:^7.22.5" - "@rc-component/trigger": "npm:^1.5.0" - classnames: "npm:^2.2.6" - rc-input: "npm:~1.4.0" - rc-menu: "npm:~9.12.0" - rc-textarea: "npm:~1.6.1" - rc-util: "npm:^5.34.1" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 597b440e96e0d5f411928088262423e2725c48c3ba34096cf62a843fe79d98c93e81f471cad40dc68435b97053c3c80f22dbc03ef0520224d610874e259c9af4 - languageName: node - linkType: hard - "rc-mentions@npm:~2.11.1": version: 2.11.1 resolution: "rc-mentions@npm:2.11.1" @@ -26737,40 +26530,6 @@ __metadata: languageName: node linkType: hard -"rc-menu@npm:~9.12.0": - version: 9.12.0 - resolution: "rc-menu@npm:9.12.0" - dependencies: - "@babel/runtime": "npm:^7.10.1" - "@rc-component/trigger": "npm:^1.6.2" - classnames: "npm:2.x" - rc-motion: "npm:^2.4.3" - rc-overflow: "npm:^1.3.1" - rc-util: "npm:^5.27.0" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 32138cc378286da89a8f40f43c203db0c67089c3ab08bf0a40130412171dbd9ac8688792f488e8215a34ddd5065228790f275c7cbb3d5096902fc9598a786be0 - languageName: node - linkType: hard - -"rc-menu@npm:~9.12.4": - version: 9.12.4 - resolution: "rc-menu@npm:9.12.4" - dependencies: - "@babel/runtime": "npm:^7.10.1" - "@rc-component/trigger": "npm:^1.17.0" - classnames: "npm:2.x" - rc-motion: "npm:^2.4.3" - rc-overflow: "npm:^1.3.1" - rc-util: "npm:^5.27.0" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 5c4b5a4e8afb6f6fed20f483023e9ca7bca814b183deeac49b7a94ae6adc1934de38d7ffd205258b70c26eeb0e945f543ce3d60b83e8c4c10037043166a6cbd0 - languageName: node - linkType: hard - "rc-menu@npm:~9.13.0": version: 9.13.0 resolution: "rc-menu@npm:9.13.0" @@ -26889,36 +26648,6 @@ __metadata: languageName: node linkType: hard -"rc-picker@npm:~4.0.0-alpha.43": - version: 4.0.0-alpha.44 - resolution: "rc-picker@npm:4.0.0-alpha.44" - dependencies: - "@babel/runtime": "npm:^7.10.1" - "@rc-component/trigger": "npm:^1.5.0" - classnames: "npm:^2.2.1" - rc-overflow: "npm:^1.3.2" - rc-resize-observer: "npm:^1.4.0" - rc-util: "npm:^5.38.1" - peerDependencies: - date-fns: ">= 2.x" - dayjs: ">= 1.x" - luxon: ">= 3.x" - moment: ">= 2.x" - react: ">=16.9.0" - react-dom: ">=16.9.0" - peerDependenciesMeta: - date-fns: - optional: true - dayjs: - optional: true - luxon: - optional: true - moment: - optional: true - checksum: b41325e9f4204bf3e86ebd2b4677d405d1149eb7a444f62ca8fe4919c82d067b322681afd18e4b4a2dd171857ca5304767ce57ab392087d8db8abd3888852a0b - languageName: node - linkType: hard - "rc-picker@npm:~4.3.0": version: 4.3.0 resolution: "rc-picker@npm:4.3.0" @@ -27037,24 +26766,6 @@ __metadata: languageName: node linkType: hard -"rc-select@npm:~14.11.0, rc-select@npm:~14.11.0-0": - version: 14.11.0 - resolution: "rc-select@npm:14.11.0" - dependencies: - "@babel/runtime": "npm:^7.10.1" - "@rc-component/trigger": "npm:^1.5.0" - classnames: "npm:2.x" - rc-motion: "npm:^2.0.1" - rc-overflow: "npm:^1.3.1" - rc-util: "npm:^5.16.1" - rc-virtual-list: "npm:^3.5.2" - peerDependencies: - react: "*" - react-dom: "*" - checksum: 2d0cbb41c50c7f1bbee0787b93e5879a683db6b9e609754d8b6c468592db504a34c3618b1d3bbdead9ae9084439454a36d06ca5bbfc9098ac70c6146a3478fd2 - languageName: node - linkType: hard - "rc-select@npm:~14.13.0": version: 14.13.0 resolution: "rc-select@npm:14.13.0" @@ -27115,23 +26826,6 @@ __metadata: languageName: node linkType: hard -"rc-table@npm:~7.39.0": - version: 7.39.0 - resolution: "rc-table@npm:7.39.0" - dependencies: - "@babel/runtime": "npm:^7.10.1" - "@rc-component/context": "npm:^1.4.0" - classnames: "npm:^2.2.5" - rc-resize-observer: "npm:^1.1.0" - rc-util: "npm:^5.37.0" - rc-virtual-list: "npm:^3.11.1" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 75367bf3a7fcedbcbe103b020c4622d7e2c3f2ff087c80b16a49bacd25af3acb68907fa9d3c7d66556ae698a187c5aa5795abd2340e32d536fe64e5c20012951 - languageName: node - linkType: hard - "rc-table@npm:~7.42.0": version: 7.42.0 resolution: "rc-table@npm:7.42.0" @@ -27149,24 +26843,6 @@ __metadata: languageName: node linkType: hard -"rc-tabs@npm:~14.0.0": - version: 14.0.0 - resolution: "rc-tabs@npm:14.0.0" - dependencies: - "@babel/runtime": "npm:^7.11.2" - classnames: "npm:2.x" - rc-dropdown: "npm:~4.1.0" - rc-menu: "npm:~9.12.0" - rc-motion: "npm:^2.6.2" - rc-resize-observer: "npm:^1.0.0" - rc-util: "npm:^5.34.1" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: 2749eace691dd1344a92e465b24304feb6d34746f99c7f388cb4d226a63caded397ffb97398def753c1ddead801b613804cf3fe5e6acf1d62159066cd59c7ca0 - languageName: node - linkType: hard - "rc-tabs@npm:~14.1.1": version: 14.1.1 resolution: "rc-tabs@npm:14.1.1" @@ -27201,20 +26877,6 @@ __metadata: languageName: node linkType: hard -"rc-tooltip@npm:~6.1.3": - version: 6.1.3 - resolution: "rc-tooltip@npm:6.1.3" - dependencies: - "@babel/runtime": "npm:^7.11.2" - "@rc-component/trigger": "npm:^1.18.0" - classnames: "npm:^2.3.1" - peerDependencies: - react: ">=16.9.0" - react-dom: ">=16.9.0" - checksum: cf98afe8ad44d5fa9e68ba33e58a763d63a66239c947a2a4ef90bd74ec480466ed876bb2c29b9e1203ff35e728f2b641aa8067fcbfd21fdbbb37b1a7b13d55dc - languageName: node - linkType: hard - "rc-tooltip@npm:~6.2.0": version: 6.2.0 resolution: "rc-tooltip@npm:6.2.0" @@ -27229,22 +26891,6 @@ __metadata: languageName: node linkType: hard -"rc-tree-select@npm:~5.17.0": - version: 5.17.0 - resolution: "rc-tree-select@npm:5.17.0" - dependencies: - "@babel/runtime": "npm:^7.10.1" - classnames: "npm:2.x" - rc-select: "npm:~14.11.0-0" - rc-tree: "npm:~5.8.1" - rc-util: "npm:^5.16.1" - peerDependencies: - react: "*" - react-dom: "*" - checksum: b9b22057265812837655ba4938fcbe550bfc987715053f0cf6ea1f8ced1b1b5c3da1bc4d7e4e64f2bf1bc5b079e1bc412aa3e42c763fe80165638bed8b89053f - languageName: node - linkType: hard - "rc-tree-select@npm:~5.19.0": version: 5.19.0 resolution: "rc-tree-select@npm:5.19.0" @@ -27291,7 +26937,7 @@ __metadata: languageName: node linkType: hard -"rc-util@npm:^5.0.1, rc-util@npm:^5.15.0, rc-util@npm:^5.16.1, rc-util@npm:^5.17.0, rc-util@npm:^5.18.1, rc-util@npm:^5.19.2, rc-util@npm:^5.2.0, rc-util@npm:^5.20.1, rc-util@npm:^5.21.0, rc-util@npm:^5.24.4, rc-util@npm:^5.25.2, rc-util@npm:^5.27.0, rc-util@npm:^5.28.0, rc-util@npm:^5.3.0, rc-util@npm:^5.30.0, rc-util@npm:^5.31.1, rc-util@npm:^5.32.2, rc-util@npm:^5.33.0, rc-util@npm:^5.34.1, rc-util@npm:^5.35.0": +"rc-util@npm:^5.0.1, rc-util@npm:^5.15.0, rc-util@npm:^5.16.1, rc-util@npm:^5.17.0, rc-util@npm:^5.18.1, rc-util@npm:^5.19.2, rc-util@npm:^5.2.0, rc-util@npm:^5.20.1, rc-util@npm:^5.21.0, rc-util@npm:^5.24.4, rc-util@npm:^5.25.2, rc-util@npm:^5.27.0, rc-util@npm:^5.28.0, rc-util@npm:^5.30.0, rc-util@npm:^5.31.1, rc-util@npm:^5.32.2, rc-util@npm:^5.34.1, rc-util@npm:^5.35.0": version: 5.36.0 resolution: "rc-util@npm:5.36.0" dependencies: