Skip to content

Commit

Permalink
display calculated values (#588)
Browse files Browse the repository at this point in the history
* feat: display calculated values

Co-authored-by: Philippe Chevieux <[email protected]>
  • Loading branch information
evoiron and philippechevieux authored Oct 17, 2024
1 parent 2fe80c7 commit ecf1e09
Show file tree
Hide file tree
Showing 26 changed files with 1,229 additions and 149 deletions.
23 changes: 18 additions & 5 deletions apps/core/src/domain/actions/excelCalculationAction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('excelCalculationAction', () => {
ctx
);

expect(res).toEqual({errors: [], values: [{...mockResultValueBase, payload: '42'}]});
expect(res).toEqual({errors: [], values: [{...mockResultValueBase, payload: '42', raw_payload: '42'}]});
expect(
await action(
[],
Expand All @@ -61,7 +61,7 @@ describe('excelCalculationAction', () => {
},
ctx
)
).toEqual({errors: [], values: [{...mockResultValueBase, payload: '84'}]});
).toEqual({errors: [], values: [{...mockResultValueBase, payload: '84', raw_payload: '84'}]});
});

test('no formula', async () => {
Expand All @@ -74,7 +74,7 @@ describe('excelCalculationAction', () => {
},
ctx
);
expect(res).toEqual({errors: [], values: [{...mockResultValueBase, payload: ''}]});
expect(res).toEqual({errors: [], values: [{...mockResultValueBase, payload: '', raw_payload: ''}]});
});

test('Replace variables', async () => {
Expand All @@ -92,7 +92,13 @@ describe('excelCalculationAction', () => {

expect(res).toEqual({
errors: [],
values: [{...mockResultValueBase, payload: 'resultat totoValue tataValue titiValue'}]
values: [
{
...mockResultValueBase,
payload: 'resultat totoValue tataValue titiValue',
raw_payload: 'resultat totoValue tataValue titiValue'
}
]
});
});

Expand All @@ -111,7 +117,14 @@ describe('excelCalculationAction', () => {

expect(res).toEqual({
errors: [],
values: [mockStandardValue, {...mockResultValueBase, payload: 'resultat totoValue tataValue titiValue'}]
values: [
mockStandardValue,
{
...mockResultValueBase,
payload: 'resultat totoValue tataValue titiValue',
raw_payload: 'resultat totoValue tataValue titiValue'
}
]
});
});

Expand Down
3 changes: 2 additions & 1 deletion apps/core/src/domain/actions/excelCalculationAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ export default function ({
modified_by: null,
created_at: null,
created_by: null,
payload: String(result)
payload: String(result),
raw_payload: String(result)
};

return {values: [...values, finalResult], errors: []};
Expand Down
5 changes: 3 additions & 2 deletions apps/core/src/domain/actionsList/actionsListDomain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export default function ({'core.depsManager': depsManager, translator}: IActions
async runActionsList(actions, values, ctx) {
const availActions: IActionsListFunction[] = this.getAvailableActions();
let resultAction = values;

for (const action of actions) {
const params: ActionsListParams<string> = !!action.params
? action.params.reduce((all, p) => {
Expand All @@ -100,7 +101,7 @@ export default function ({'core.depsManager': depsManager, translator}: IActions
? action.error_message[ctx.defaultLang]
: '';
if (customMessage) {
customMessage += ': ' + errors.map(error => error.attributeValue.payload).join(', ');
customMessage += ': ' + errors.map(error => error.attributeValue?.payload).join(', ');
throw new ValidationError({[ctx.attribute.id]: customMessage}, customMessage, true);
} else {
const errorsByType = errors.reduce<
Expand All @@ -117,7 +118,7 @@ export default function ({'core.depsManager': depsManager, translator}: IActions
(message, [errorType, {attributeValues, message: optionalMessage}]) => {
const messageText = optionalMessage ?? translator.t(`error.${errorType}`);
message.push(
`${messageText}: ${(attributeValues ?? []).map(value => value.payload).join(', ')}`
`${messageText}: ${(attributeValues ?? []).map(value => value?.payload).join(', ')}`
);
return message;
},
Expand Down
20 changes: 9 additions & 11 deletions libs/ui/src/_gqlTypes/index.ts

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions libs/ui/src/_queries/records/getRecordsFromLibraryQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const _handleType = (field: IField): string => {
${field.id}: property(attribute: "${field.id}") {
${typePart.trim()}
isInherited
isCalculated
}
`;
};
Expand Down
1 change: 1 addition & 0 deletions libs/ui/src/_queries/values/valueDetailsFragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export const valueDetailsFragment = gql`
fragment ValueDetails on GenericValue {
id_value
isInherited
isCalculated
modified_at
modified_by {
...RecordIdentity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@ import dayjs from 'dayjs';
const hasDateRangeValues = (dateRange: unknown): dateRange is IDateRangeValue =>
(dateRange as IDateRangeValue).from !== undefined && (dateRange as IDateRangeValue).to !== undefined;

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']
Expand All @@ -37,7 +42,7 @@ export const getAntdFormInitialValues = (recordForm: IRecordForm) =>
return acc;
}

const value = getNotInheritedOrOverrideValue(values) ?? getInheritedValue(values) ?? null;
const value = getUserInputValue(values) ?? getInheritedValue(values) ?? getCalculatedValue(values) ?? null;

if (isRecordFormElementsValueLinkValue(value, attribute)) {
acc[attribute.id] = value?.linkValue?.id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,11 @@ describe('standardFieldReducer', () => {
inheritedValue: null,
isInheritedValue: false,
isInheritedNotOverrideValue: false,
isInheritedOverrideValue: false
isInheritedOverrideValue: false,
calculatedValue: null,
isCalculatedNotOverrideValue: false,
isCalculatedOverrideValue: false,
isCalculatedValue: false
};

const _getInitialStateWithValues = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,33 @@ interface INotInherited {

export type InheritedFlags = INotInherited | IInheritedOverride | IInheritedNotOverride;

interface ICalculatedNotOverride {
isCalculatedValue: true;
isCalculatedOverrideValue: false;
isCalculatedNotOverrideValue: true;
calculatedValue: RecordFormElementsValueStandardValue;
}

interface ICalculatedOverride {
isCalculatedValue: true;
isCalculatedOverrideValue: true;
isCalculatedNotOverrideValue: false;
calculatedValue: RecordFormElementsValueStandardValue;
}

interface INotCalculated {
isCalculatedValue: false;
isCalculatedOverrideValue: false;
isCalculatedNotOverrideValue: false;
calculatedValue: null;
}

export type CalculatedFlags = INotCalculated | ICalculatedOverride | ICalculatedNotOverride;

export type IStandardFieldReducerState = ICommonFieldsReducerState<StandardFieldReducerValues> & {
metadataEdit: boolean;
} & InheritedFlags;
} & InheritedFlags &
CalculatedFlags;

export enum StandardFieldReducerActionsTypes {
ADD_VALUE = 'ADD_VALUE',
Expand Down Expand Up @@ -190,8 +214,10 @@ const _updateValueData = (
};

const getInheritedValue = (values: RecordFormElementsValueStandardValue[]) => values.filter(value => value.isInherited);
const getNotInheritedOrOverrideValue = (values: RecordFormElementsValueStandardValue[]) =>
values.filter(value => !value.isInherited && value.raw_value !== null);
const getCalculatedValue = (values: RecordFormElementsValueStandardValue[]) =>
values.filter(value => value.isCalculated);
const getUserInputValue = (values: RecordFormElementsValueStandardValue[]) =>
values.filter(value => !value.isInherited && !value.isCalculated && value.raw_value !== null);

/**
* For given list of values, determine if there is inherited values, inherited/current version and default active scope
Expand All @@ -204,9 +230,12 @@ const _computeScopeAndValues = (params: {
const {attribute, values, formVersion} = params;

// Get override or inhertied values
let valuesToHandle = getNotInheritedOrOverrideValue(values);
let valuesToHandle = getUserInputValue(values);
if (!valuesToHandle.length) {
valuesToHandle = getInheritedValue(values);
valuesToHandle = getCalculatedValue(values);
if (!valuesToHandle.length) {
valuesToHandle = getInheritedValue(values);
}
}

const preparedValues = valuesToHandle.length
Expand Down Expand Up @@ -266,7 +295,7 @@ const _computeScopeAndValues = (params: {

const _computeInheritedFlags = (fieldValues: RecordFormElementsValueStandardValue[]): InheritedFlags => {
const inheritedValue = fieldValues.find(fieldValue => fieldValue.isInherited);
const overrideValue = fieldValues.find(fieldValue => !fieldValue.isInherited);
const overrideValue = fieldValues.find(fieldValue => !fieldValue.isInherited && !fieldValue.isCalculated);

if (inheritedValue === undefined) {
return {
Expand Down Expand Up @@ -296,6 +325,38 @@ const _computeInheritedFlags = (fieldValues: RecordFormElementsValueStandardValu
};
};

const _computeCalculatedFlags = (fieldValues: RecordFormElementsValueStandardValue[]): CalculatedFlags => {
const calculatedValue = fieldValues.find(fieldValue => fieldValue.isCalculated);
const overrideValue = fieldValues.find(fieldValue => !fieldValue.isCalculated && !fieldValue.isInherited);

if (calculatedValue === undefined) {
return {
calculatedValue: null,
isCalculatedValue: false,
isCalculatedOverrideValue: false,
isCalculatedNotOverrideValue: false
};
}

const isCalculatedValue = true;

if (overrideValue.value === null) {
return {
calculatedValue,
isCalculatedValue,
isCalculatedNotOverrideValue: true,
isCalculatedOverrideValue: false
};
}

return {
calculatedValue,
isCalculatedValue,
isCalculatedNotOverrideValue: false,
isCalculatedOverrideValue: true
};
};

export const computeInitialState = (params: {
element: FormElement<unknown>;
record: IRecordIdentityWhoAmI;
Expand All @@ -315,7 +376,8 @@ export const computeInitialState = (params: {
isReadOnly: attribute?.readonly || isRecordReadOnly || !attribute?.permissions?.edit_value,
metadataEdit,
..._computeScopeAndValues({attribute, values: fieldValues, formVersion}),
..._computeInheritedFlags(fieldValues)
..._computeInheritedFlags(fieldValues),
..._computeCalculatedFlags(fieldValues)
};
};

Expand Down Expand Up @@ -413,7 +475,11 @@ const standardFieldReducer = (
{
...state,
isInheritedOverrideValue: state.isInheritedValue ? true : state.isInheritedOverrideValue,
isInheritedNotOverrideValue: state.isInheritedValue ? false : state.isInheritedNotOverrideValue
isInheritedNotOverrideValue: state.isInheritedValue ? false : state.isInheritedNotOverrideValue,
isCalculatedOverrideValue: state.isCalculatedValue ? true : state.isCalculatedOverrideValue,
isCalculatedNotOverrideValue: state.isCalculatedValue
? false
: state.isCalculatedNotOverrideValue
} as IStandardFieldReducerState,
newValueData
);
Expand All @@ -424,6 +490,10 @@ const standardFieldReducer = (
};
newState.isInheritedOverrideValue = state.isInheritedValue ? true : state.isInheritedOverrideValue;
newState.isInheritedNotOverrideValue = state.isInheritedValue ? false : state.isInheritedNotOverrideValue;
newState.isCalculatedOverrideValue = state.isCalculatedValue ? true : state.isCalculatedOverrideValue;
newState.isCalculatedNotOverrideValue = state.isCalculatedValue
? false
: state.isCalculatedNotOverrideValue;

const newStateActiveValues = newState.values[newState.activeScope].values;

Expand All @@ -442,7 +512,9 @@ const standardFieldReducer = (
const newState = {
...state,
isInheritedOverrideValue: state.isInheritedValue ? false : state.isInheritedOverrideValue,
isInheritedNotOverrideValue: state.isInheritedValue ? true : state.isInheritedNotOverrideValue
isInheritedNotOverrideValue: state.isInheritedValue ? true : state.isInheritedNotOverrideValue,
isCalculatedOverrideValue: state.isCalculatedValue ? false : state.isCalculatedOverrideValue,
isCalculatedNotOverrideValue: state.isCalculatedValue ? true : state.isCalculatedNotOverrideValue
};
const newStateActiveValues = newState.values[newState.activeScope].values;

Expand Down Expand Up @@ -479,7 +551,9 @@ const standardFieldReducer = (
const newState = {
...state,
isInheritedOverrideValue: state.isInheritedValue ? false : state.isInheritedOverrideValue,
isInheritedNotOverrideValue: state.isInheritedValue ? true : state.isInheritedNotOverrideValue
isInheritedNotOverrideValue: state.isInheritedValue ? true : state.isInheritedNotOverrideValue,
isCalculatedOverrideValue: state.isCalculatedValue ? false : state.isCalculatedOverrideValue,
isCalculatedNotOverrideValue: state.isCalculatedValue ? true : state.isCalculatedNotOverrideValue
};

delete newState.values[newState.activeScope].values[newValueId];
Expand Down
Loading

0 comments on commit ecf1e09

Please sign in to comment.