Skip to content

Commit

Permalink
feat(@leav/ui): adapt multivalue to ds (#636)
Browse files Browse the repository at this point in the history
* feat(@leav/ui): Adapt multivalue to DS
* feat(@leav/ui): Remove StandardFieldValueRead and use StandardField even for formated values

---------

Co-authored-by: Philippe Chevieux <[email protected]>
  • Loading branch information
renaudAmsellem and philippechevieux authored Nov 28, 2024
1 parent 810391e commit 7338b86
Show file tree
Hide file tree
Showing 45 changed files with 1,418 additions and 3,762 deletions.
2 changes: 1 addition & 1 deletion apps/data-studio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"antd": "5.15.3",
"apollo-cache-inmemory": "1.6.6",
"apollo-upload-client": "14.1.3",
"aristid-ds": "10.1.0-b8e3d81",
"aristid-ds": "10.1.0-449b3e9",
"dayjs": "1.11.10",
"graphql": "15.0.0",
"graphql-tag": "2.12.6",
Expand Down
2 changes: 1 addition & 1 deletion apps/login/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"@ant-design/icons": "5.2.6",
"@leav/ui": "workspace:libs/ui",
"antd": "5.15.3",
"aristid-ds": "10.1.0-b8e3d81",
"aristid-ds": "10.1.0-449b3e9",
"i18next": "22.5.0",
"i18next-browser-languagedetector": "7.0.2",
"i18next-http-backend": "2.1.1",
Expand Down
2 changes: 1 addition & 1 deletion apps/portal/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"@leav/ui": "workspace:libs/ui",
"@leav/utils": "workspace:libs/utils",
"antd": "5.15.3",
"aristid-ds": "10.1.0-b8e3d81",
"aristid-ds": "10.1.0-449b3e9",
"cross-fetch": "3.1.5",
"graphql-ws": "5.12.0",
"i18next": "22.5.0",
Expand Down
2 changes: 1 addition & 1 deletion libs/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"@ant-design/icons": ">=5.2",
"@apollo/client": ">=3.8.1",
"antd": "5.15.3",
"aristid-ds": "10.1.0-b8e3d81",
"aristid-ds": "10.1.0-449b3e9",
"dayjs": "^1.11.10",
"i18next": "22.5",
"react": "18.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ export const EditRecord: FunctionComponent<IEditRecordProps> = ({
return savableValue as IValueToSubmit;
}),
version,
true // deleteEmpty
false // deleteEmpty
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,20 @@ export interface ISubmittedValueBase {
metadata?: IKeyValue<AnyPrimitive>;
}

export interface IFormElementProps<SettingsType> {
element: FormElement<SettingsType>;
export interface IFormElementProps<SettingsType, RecordFormElements = RecordFormElementsValue> {
element: FormElement<SettingsType, RecordFormElements>;
onValueSubmit?: SubmitValueFunc;
onValueDelete?: DeleteValueFunc;
onDeleteMultipleValues?: DeleteMultipleValuesFunc;
metadataEdit?: boolean;
}

export type FormElement<SettingsType> = Override<
export type FormElement<SettingsType, RecordFormElements = RecordFormElementsValue> = Override<
RecordFormElementFragment,
{
settings: SettingsType;
uiElementType: FormUIElementTypes | FormFieldTypes;
values: RecordFormElementsValue[];
values: RecordFormElements[];
}
> & {
uiElement: (props: IFormElementProps<unknown> & {antdForm?: FormInstance}) => JSX.Element;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,50 @@ describe('getAntdFormInitialValues', () => {
});
});

describe('Advanced standard field with multiple values', () => {
test('Should initialize antd form with given value', async () => {
const elementFormId = 'elementFormId';
const yetAnotherElementFormId = 'yetAnotherElementFormId';
const standardAttributeId = 'standardAttributeId';
const standardElement = {
attribute: {
type: AttributeType.advanced,
format: AttributeFormat.text,
multiple_values: true,
id: standardAttributeId
},
values: [{raw_payload: elementFormId}, {raw_payload: yetAnotherElementFormId}]
};
const recordForm = {elements: [standardElement]};

const antdFormInitialValues = getAntdFormInitialValues(recordForm as any);

expect(antdFormInitialValues).toEqual({
[standardAttributeId]: [elementFormId, yetAnotherElementFormId]
});
});

test('Should initialize antd form with array containing null for standard field when value is not set', async () => {
const standardAttributeId = 'standardAttributeId';
const standardElement = {
attribute: {
type: AttributeType.advanced,
format: AttributeFormat.text,
multiple_values: true,
id: standardAttributeId
},
values: []
};
const recordForm = {elements: [standardElement]};

const antdFormInitialValues = getAntdFormInitialValues(recordForm as any);

expect(antdFormInitialValues).toEqual({
[standardAttributeId]: [null]
});
});
});

describe('AttributeFormat.text', () => {
test('Should initialize antd form with given value for text attribute', async () => {
const rawValue = 'rawValue';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// License text available at https://www.gnu.org/licenses/lgpl-3.0.txt
import {
IRecordForm,
RecordFormElementAttribute,
RecordFormElementsValue,
RecordFormElementsValueLinkValue,
RecordFormElementsValueStandardValue
Expand All @@ -18,24 +19,60 @@ const hasDateRangeValues = (dateRange: unknown): dateRange is IDateRangeValue =>
const getCalculatedValue = values => values.find(value => value.isCalculated);

const getInheritedValue = values => values.find(value => value.isInherited);
const getNotInheritedOrOverrideValue = values => values.find(value => !value.isInherited && value.raw_payload !== null);

const getUserInputValue = values =>
values.find(value => !value.isInherited && !value.isCalculated && value.raw_value !== null);

const isRecordFormElementsValueLinkValue = (
value: RecordFormElementsValue,
attribute: IRecordForm['elements'][0]['attribute']
attribute: RecordFormElementAttribute
): value is RecordFormElementsValueLinkValue =>
attribute.type === AttributeType.simple_link ||
(attribute.type === AttributeType.advanced_link && attribute.multiple_values === false);

const isRecordFormElementsValueLinkValues = (
values: RecordFormElementsValue[],
attribute: IRecordForm['elements'][0]['attribute']
attribute: RecordFormElementAttribute
): values is RecordFormElementsValueLinkValue[] =>
attribute.type === AttributeType.advanced_link && attribute.multiple_values === true;

const isRecordFormElementsMultipleValues = (attribute: RecordFormElementAttribute) =>
attribute.type === AttributeType.advanced && attribute.multiple_values === true;

const formatStandardInitialValue = (
standardValue: RecordFormElementsValueStandardValue,
attribute: RecordFormElementAttribute
) => {
if (!standardValue?.raw_payload) {
if (attribute.format === AttributeFormat.date_range) {
return undefined;
}
return '';
}

switch (attribute.format) {
case AttributeFormat.color:
case AttributeFormat.text:
case AttributeFormat.rich_text:
case AttributeFormat.boolean:
return standardValue.raw_payload;
case AttributeFormat.numeric:
return Number(standardValue.raw_payload);
case AttributeFormat.date:
return dayjs.unix(Number(standardValue.raw_payload));
case AttributeFormat.date_range:
if (hasDateRangeValues(standardValue.raw_payload)) {
return [
dayjs.unix(Number(standardValue.raw_payload.from)),
dayjs.unix(Number(standardValue.raw_payload.to))
];
} else if (typeof standardValue.raw_payload === 'string') {
const convertedFieldValue = JSON.parse(standardValue.raw_payload) as any;
return [dayjs.unix(Number(convertedFieldValue.from)), dayjs.unix(Number(convertedFieldValue.to))];
}
}
};

export const getAntdFormInitialValues = (recordForm: IRecordForm) =>
recordForm.elements.reduce<Store>((acc, {attribute, values}) => {
if (!attribute) {
Expand All @@ -54,46 +91,19 @@ export const getAntdFormInitialValues = (recordForm: IRecordForm) =>
return acc;
}

const standardValue = value as RecordFormElementsValueStandardValue;

if (!standardValue?.raw_payload) {
if (attribute.format === AttributeFormat.date_range) {
return acc;
}

acc[attribute.id] = '';
if (isRecordFormElementsMultipleValues(attribute)) {
acc[attribute.id] =
values.length === 0
? [null]
: values
.sort((a, b) => Number(a.id_value) - Number(b.id_value))
.map(val => formatStandardInitialValue(val, attribute));
return acc;
}

switch (attribute.format) {
case AttributeFormat.color:
case AttributeFormat.text:
case AttributeFormat.rich_text:
case AttributeFormat.boolean:
acc[attribute.id] = standardValue.raw_payload;
break;
case AttributeFormat.numeric:
acc[attribute.id] = Number(standardValue.raw_payload);
break;
case AttributeFormat.date:
acc[attribute.id] = dayjs.unix(Number(standardValue.raw_payload));
break;
case AttributeFormat.date_range:
if (hasDateRangeValues(standardValue.raw_payload)) {
acc[attribute.id] = [
dayjs.unix(Number(standardValue.raw_payload.from)),
dayjs.unix(Number(standardValue.raw_payload.to))
];
break;
} else if (typeof standardValue.raw_payload === 'string') {
const convertedFieldValue = JSON.parse(standardValue.raw_payload) as any;
acc[attribute.id] = [
dayjs.unix(Number(convertedFieldValue.from)),
dayjs.unix(Number(convertedFieldValue.to))
];
break;
}
}
const standardValue = value as RecordFormElementsValueStandardValue;

acc[attribute.id] = formatStandardInitialValue(standardValue, attribute);

return acc;
}, {});
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ describe('standardFieldReducer', () => {
element: {
values: [
{isInherited: true, value: 'testValue', raw_value: 'testRawValue'},
{isInherited: false, value: null, raw_value: null}
{isInherited: false, value: null, raw_value: null, payload: null}
],
attribute: {
format: AttributeFormat.date_range
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ const _computeInheritedFlags = (fieldValues: RecordFormElementsValueStandardValu

const isInheritedValue = true;

if (!overrideValue || overrideValue.value === null) {
if (!overrideValue || overrideValue.payload === null) {
return {
inheritedValue,
isInheritedValue,
Expand Down Expand Up @@ -342,7 +342,7 @@ const _computeCalculatedFlags = (fieldValues: RecordFormElementsValueStandardVal

const isCalculatedValue = true;

if (!overrideValue || overrideValue.value === null) {
if (!overrideValue || overrideValue.payload === null) {
return {
calculatedValue,
isCalculatedValue,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const MonoValueSelect: FunctionComponent<IMonoValueSelectProps> = ({
status={errors.length > 0 && 'error'}
showSearch
optionFilterProp="label"
placeholder={t('record_edition.record_select')}
placeholder={t('record_edition.placeholder.record_select')}
onSelect={handleSelect}
onChange={onChange}
onClear={required ? undefined : handleClear}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export const MultiValueSelect: FunctionComponent<IMultiValueSelectProps> = ({
options={selectOptions}
showSearch
optionFilterProp="label"
placeholder={t('record_edition.record_select')}
placeholder={t('record_edition.placeholder.record_select')}
onSelect={_handleSelect}
onClear={_clearValues}
onBlur={_handleBlur}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright LEAV Solutions 2017 until 2023/11/05, Copyright Aristid from 2023/11/06
// This file is released under LGPL V3
// License text available at https://www.gnu.org/licenses/lgpl-3.0.txt
import {useSharedTranslation} from '_ui/hooks/useSharedTranslation';
import {KitButton, KitModal} from 'aristid-ds';
import {FunctionComponent} from 'react';

export const DeleteAllValuesButton: FunctionComponent<{handleDelete: () => Promise<void>}> = ({handleDelete}) => {
const {t} = useSharedTranslation();

const _confirmDeleteAllValues = () => {
KitModal.confirm({
title: t('record_edition.delete_all_values'),
content: t('record_edition.delete_all_values_confirm'),
icon: false,
showSecondaryCta: true,
showCloseIcon: false,
dangerConfirm: true,
type: 'confirm',
okText: t('global.confirm'),
cancelText: t('global.cancel'),
onOk: handleDelete
});
};

return (
<KitButton type="tertiary" size="s" onClick={_confirmDeleteAllValues}>
{t('record_edition.delete_all')}
</KitButton>
);
};
Loading

0 comments on commit 7338b86

Please sign in to comment.