Skip to content

Commit

Permalink
JNG-4838 fix row operation calls, simplify error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
noherczeg committed Oct 27, 2023
1 parent 8508c0f commit 073d365
Show file tree
Hide file tree
Showing 16 changed files with 830 additions and 833 deletions.
1,524 changes: 762 additions & 762 deletions judo-ui-react-itest/ActionGroupTest/model/ActionGroupTest-ui.model

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -194,33 +194,42 @@ public static String getServiceMethodSuffix(Action action) {
}

public static String getDialogOpenParameters(PageDefinition pageDefinition) {
Set<String> result = new TreeSet<>();

if (pageDefinition.getContainer().isView()) {
result.add("targetData: JudoIdentifiable<any>");
}
List<String> result = new ArrayList<>();
result.add("ownerData: any");
if (pageDefinition.getContainer().isIsRelationSelector()) {
result.add("alreadySelected: " + classDataName(getReferenceClassType(pageDefinition), "Stored") + "[]");
}

return String.join(", ", result);
}

public static String getSelectorOpenActionParameters(Action action, PageContainer container) {
List<String> tokens = new ArrayList<>();
if (container.isTable()) {
return "[]";
if (action.getTargetPageDefinition().getContainer().isIsRelationSelector()) {
tokens.add("{ __signedIdentifier: signedIdentifier }");
} else {
tokens.add("[]");
}
} else {
tokens.add("data");
}

if (action.getTargetPageDefinition().getContainer().isIsRelationSelector()) {
if (action.getTargetDataElement() instanceof RelationType check) {
String result = "data." + check.getName();
boolean isCollection = check.isIsCollection();
if (isCollection) {
return result + " ?? []";
if (container.isTable()) {
tokens.add("[]");
} else {
String result = "data." + check.getName();
boolean isCollection = check.isIsCollection();
if (isCollection) {
tokens.add(result + " ?? []");
} else {
tokens.add(result + "? [" + result + "] : []");
}
}
return result + "? [" + result + "] : []";
}
}
return "";
return String.join(", ", tokens);
}

public static boolean isActionAddOrSet(ActionDefinition actionDefinition) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
mapFilterToFilterModel,
useErrorHandler,
processQueryCustomizer,
ERROR_PROCESSOR_HOOK_INTERFACE_KEY,
mapFiltersToQueryCustomizerProperty,
isRowSelectable,
} from '~/utilities';
Expand Down Expand Up @@ -75,7 +74,7 @@ export const RangeDialog = <T extends JudoStored<T>, U extends QueryCustomizer<T
const { openFilterDialog } = useFilterDialog();
const { t } = useTranslation();
const descriptionElementRef = useRef<HTMLElement>(null);
const handleFetchError = useErrorHandler(`(&(${OBJECTCLASS}=${ERROR_PROCESSOR_HOOK_INTERFACE_KEY})(operation=Fetch))`);
const handleError = useErrorHandler();
const { enqueueSnackbar } = useSnackbar();
const [isLoading, setIsLoading] = useState<boolean>(false);
const [rowCount, setRowCount] = useState<number>(0);
Expand Down Expand Up @@ -129,7 +128,7 @@ export const RangeDialog = <T extends JudoStored<T>, U extends QueryCustomizer<T
setLastItem(res[res.length - 1]);
setRowCount(res.length || 0);
} catch (error) {
handleFetchError(error);
handleError(error);
}
setIsLoading(false);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ import {
mapAllFiltersToQueryCustomizerProperties,
processQueryCustomizer,
useErrorHandler,
ERROR_PROCESSOR_HOOK_INTERFACE_KEY,
} from '~/utilities';
import type { TableRowAction } from '~/utilities';
import { useDataStore } from '~/hooks';
Expand Down Expand Up @@ -126,7 +125,7 @@ export function {{ tableComponentName table }}(props: {{ tableComponentName tabl
const { locale: l10nLocale } = useL10N();
const { downloadFile, extractFileNameFromToken } = fileHandling();
const { t } = useTranslation();
const handleFetchError = useErrorHandler(`(&(${OBJECTCLASS}=${ERROR_PROCESSOR_HOOK_INTERFACE_KEY})(operation=Fetch))`);
const handleError = useErrorHandler();

{{# if (stringValueIsTrue useTableRowHighlighting) }}
const { service: rowHighlightingHook } = useTrackService<TableRowHighlightingHook<{{ classDataName (getReferenceClassType table) 'Stored' }}>>(`(&(${OBJECTCLASS}=${TABLE_ROW_HIGHLIGHTING_HOOK_INTERFACE_KEY})(component={{~ tableComponentName table ~}}))`);
Expand Down Expand Up @@ -393,7 +392,7 @@ export function {{ tableComponentName table }}(props: {{ tableComponentName tabl
setLastItem(res[res.length - 1]);
setRowCount(res.length || 0);
} catch (error) {
handleFetchError(error);
handleError(error);
} finally {
setIsLoading(false);
}
Expand Down
16 changes: 4 additions & 12 deletions judo-ui-react/src/main/resources/actor/src/dialogs/index.tsx.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { useCallback, useEffect, useRef, useState, lazy, Suspense } from 'react'
uiDateToServiceDate,
uiTimeToServiceTime,
useErrorHandler,
ERROR_PROCESSOR_HOOK_INTERFACE_KEY,
} from '~/utilities';
import type {
DialogResult,
Expand All @@ -41,7 +40,7 @@ import { useCallback, useEffect, useRef, useState, lazy, Suspense } from 'react'
{{/ unless }}

{{# unless (containerIsEmptyDashboard page.container) }}
export const use{{ pageName page }} = (ownerData: any): ({{{ getDialogOpenParameters page }}}) => Promise<DialogResult<{{# if page.container.table }}Array<{{/ if }}{{ classDataName (getReferenceClassType page) 'Stored' }}{{# if page.container.table }}>{{/ if }}>> => {
export const use{{ pageName page }} = (): ({{{ getDialogOpenParameters page }}}) => Promise<DialogResult<{{# if page.container.table }}Array<{{/ if }}{{ classDataName (getReferenceClassType page) 'Stored' }}{{# if page.container.table }}>{{/ if }}>> => {
const [createDialog, closeDialog] = useDialog();

return ({{{ getDialogOpenParameters page }}}) => new Promise((resolve) => {
Expand All @@ -61,9 +60,6 @@ import { useCallback, useEffect, useRef, useState, lazy, Suspense } from 'react'
children: (
<{{ pageName page }}
ownerData={ownerData}
{{# if page.container.view}}
targetData={targetData}
{{/ if }}
{{# if page.container.isRelationSelector}}
alreadySelected={alreadySelected}
{{/ if }}
Expand Down Expand Up @@ -96,15 +92,14 @@ import { useCallback, useEffect, useRef, useState, lazy, Suspense } from 'react'

export interface {{ pageName page }}Props {
ownerData: any;
{{# if page.container.view}}targetData: JudoIdentifiable<any>{{/ if }}
{{# if page.container.isRelationSelector }}alreadySelected: {{ classDataName (getReferenceClassType page) 'Stored' }}[]{{/ if }}
onClose: () => void;
onSubmit: (result: {{# if page.container.table }}Array<{{/ if }}{{ classDataName (getReferenceClassType page) 'Stored' }}{{# if page.container.table }}>{{/ if }}) => void;
}

// Name: {{ page.name }}
export default function {{ pageName page }}(props: {{ pageName page }}Props) {
const { ownerData, {{# if page.container.view}}targetData, {{/ if }}{{# if page.container.isRelationSelector }}alreadySelected, {{/ if }}onClose, onSubmit } = props;
const { ownerData, {{# if page.container.isRelationSelector }}alreadySelected, {{/ if }}onClose, onSubmit } = props;

{{# unless (containerIsEmptyDashboard page.container) }}
// Hooks section
Expand All @@ -113,10 +108,7 @@ export default function {{ pageName page }}(props: {{ pageName page }}Props) {
const { navigate, back } = useJudoNavigation();
const { openFilterDialog } = useFilterDialog();
const { openConfirmDialog } = useConfirmDialog();
const handleFetchError = useErrorHandler(`(&(${OBJECTCLASS}=${ERROR_PROCESSOR_HOOK_INTERFACE_KEY})(operation=Fetch))`);
const handleCreateError = useErrorHandler<{{ classDataName (getReferenceClassType page) '' }}>(`(&(${OBJECTCLASS}=${ERROR_PROCESSOR_HOOK_INTERFACE_KEY})(operation=Create)(component={{ pageName page }}))`);
const handleUpdateError = useErrorHandler<{{ classDataName (getReferenceClassType page) '' }}>(`(&(${OBJECTCLASS}=${ERROR_PROCESSOR_HOOK_INTERFACE_KEY})(operation=Update)(component={{ pageName page }}))`);
const handleDeleteError = useErrorHandler(`(&(${OBJECTCLASS}=${ERROR_PROCESSOR_HOOK_INTERFACE_KEY})(operation=Delete)(component={{ pageName page }}))`);
const handleError = useErrorHandler();
const [createDialog, closeDialog] = useDialog();

// State section
Expand Down Expand Up @@ -162,7 +154,7 @@ export default function {{ pageName page }}(props: {{ pageName page }}Props) {

// Dialog hooks
{{# each (getRelatedDialogs page) as |relatedDialog| }}
const open{{ pageName relatedDialog }} = use{{ pageName relatedDialog }}({{# unless page.container.table }}data{{ else }}{}{{/ unless }});
const open{{ pageName relatedDialog }} = use{{ pageName relatedDialog }}();
{{/ each }}

// Calculated section
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ const {{ simpleActionDefinitionName action.actionDefinition }} = async (queryCus
{{# with (getLinkParentForActionDefinition action.actionDefinition) as |link| }}
try {
return {{ getServiceImplForPage page }}.getRangeFor{{ firstToUpper link.dataElement.name }}(data, queryCustomizer);
} catch (e) {
handleFetchError(e);
} catch (error) {
handleError(error);
return Promise.resolve([]);
}
{{/ with }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,12 @@ const {{ simpleActionDefinitionName action.actionDefinition }} = async ({{# if a
setRefreshCounter((prev) => prev + 1);
{{/ if }}
{{/ if }}
} catch (e) {
console.error(e);
} catch (error) {
{{# unless page.container.table }}
handleError<{{ classDataName (getReferenceClassType page) '' }}>(error, { setValidation }, data);
{{ else }}
handleError(error);
{{/ unless }}
} finally {
setIsLoading(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const {{ simpleActionDefinitionName action.actionDefinition }} = async () => {

onSubmit(res);
} catch (error) {
handleCreateError(error, { setValidation }, data);
handleError<{{ classDataName (getReferenceClassType page) '' }}>(error, { setValidation }, data);
} finally {
setIsLoading(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ const {{ simpleActionDefinitionName action.actionDefinition }} = async ({{# if a
{{/ if }}
}
} catch(error) {
handleDeleteError(error, undefined, {{# if action.actionDefinition.targetType }}target{{ else }}data{{/ if }});
{{# if action.actionDefinition.targetType }}
handleError<{{ classDataName action.actionDefinition.targetType '' }}>(error, undefined, target);
{{ else }}
handleError(error, undefined, data);
{{/ if }}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ const {{ simpleActionDefinitionName action.actionDefinition }} = async (): Promi
setData(result as {{ classDataName action.actionDefinition.targetType 'Stored' }});

return result;
} catch (e) {
handleFetchError(e);
return Promise.reject(e);
} catch (error) {
handleError(error);
return Promise.reject(error);
} finally {
setIsLoading(false);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const {{ simpleActionDefinitionName action.actionDefinition }} = async () => {
const { result, data: returnedData } = await open{{ pageName action.targetPageDefinition }}();
const {{ simpleActionDefinitionName action.actionDefinition }} = async ({{# if action.actionDefinition.targetType }}target: {{ classDataName action.actionDefinition.targetType 'Stored' }}{{/ if}}) => {
const { result, data: returnedData } = await open{{ pageName action.targetPageDefinition }}({{# if action.actionDefinition.targetType }}target{{ else }}data{{/ if }});
{{# with (getRefreshActionDefinitionForContainer page.container) as |actionDefinition| }}
{{# if page.container.view }}
if (!editMode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const {{ simpleActionDefinitionName action.actionDefinition }} = async (queryCus
const result = await {{ getServiceImplForPage page }}.refresh(
{{# if (pageHasSignedId page) }}
{{# if page.openInDialog }}
targetData
ownerData
{{ else }}
{ __signedIdentifier: signedIdentifier } as JudoIdentifiable<any>
{{/ if }}
Expand All @@ -34,9 +34,9 @@ const {{ simpleActionDefinitionName action.actionDefinition }} = async (queryCus

return result;
{{/ if }}
} catch (e) {
handleFetchError(e);
return Promise.reject(e);
} catch (error) {
handleError(error);
return Promise.reject(error);
} finally {
setIsLoading(false);
setRefreshCounter((prevCounter) => prevCounter + 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ const {{ simpleActionDefinitionName action.actionDefinition }} = async (queryCus
{{ else }}
return {{ getServiceImplForPage page }}.getRangeFor{{ firstToUpper action.ownerDataElement.name }}(ownerData, queryCustomizer);
{{/ if }}
} catch (e) {
handleFetchError(e);
} catch (error) {
handleError(error);
return Promise.resolve([]);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const {{ simpleActionDefinitionName action.actionDefinition }} = async () => {
setEditMode(false);
}
} catch (error) {
handleUpdateError(error, { setValidation }, data);
handleError<{{ classDataName (getReferenceClassType page) '' }}>(error, { setValidation }, data);
} finally {
setIsLoading(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { useCallback, useEffect, useRef, useState, lazy, Suspense } from 'react'
uiDateToServiceDate,
uiTimeToServiceTime,
useErrorHandler,
ERROR_PROCESSOR_HOOK_INTERFACE_KEY,
} from '~/utilities';
import { PageContainerTransition } from '~/theme/animations';
{{# each (getRelatedPages page) as |relatedPage| }}
Expand Down Expand Up @@ -61,9 +60,7 @@ export default function {{ pageName page }}() {
const { navigate, back } = useJudoNavigation();
const { openFilterDialog } = useFilterDialog();
const { openConfirmDialog } = useConfirmDialog();
const handleFetchError = useErrorHandler(`(&(${OBJECTCLASS}=${ERROR_PROCESSOR_HOOK_INTERFACE_KEY})(operation=Fetch))`);
const handleUpdateError = useErrorHandler<{{ classDataName (getReferenceClassType page) '' }}>(`(&(${OBJECTCLASS}=${ERROR_PROCESSOR_HOOK_INTERFACE_KEY})(operation=Update)(component={{ pageName page }}))`);
const handleDeleteError = useErrorHandler(`(&(${OBJECTCLASS}=${ERROR_PROCESSOR_HOOK_INTERFACE_KEY})(operation=Delete)(component={{ pageName page }}))`);
const handleError = useErrorHandler();
const [createDialog, closeDialog] = useDialog();

// State section
Expand Down Expand Up @@ -112,7 +109,7 @@ export default function {{ pageName page }}() {

// Dialog hooks
{{# each (getRelatedDialogs page) as |relatedDialog| }}
const open{{ pageName relatedDialog }} = use{{ pageName relatedDialog }}({{# if page.container.table }}{{# if (pageHasSignedId page) }}{ __signedIdentifier: signedIdentifier }{{ else }}{}{{/ if }}{{ else }}data{{/ if }});
const open{{ pageName relatedDialog }} = use{{ pageName relatedDialog }}();
{{/ each }}

// Calculated section
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,6 @@ import { toastConfig } from '../config';
type EnqueueSnackbarCallback = (message: SnackbarMessage, options?: OptionsObject | undefined) => SnackbarKey;

export interface ErrorHandlingOption<T> {

/**
* Duration to use for potential toasts, could be ignored in actual implementations.
*/
duration?: number;

/**
* Callback from a component owning the form data used to set error messages on form inputs. Key-value pair is for
* form field name and validation error message. Should be called only once per error handler call!
Expand Down Expand Up @@ -45,23 +39,23 @@ export type ErrorProcessor<T> = (error: any, defaultResults: ErrorProcessResult<

export const ERROR_PROCESSOR_HOOK_INTERFACE_KEY = 'ErrorProcessorHook';

export type ErrorProcessorHook<T> = () => ErrorProcessor<T>;
export type ErrorProcessorHook = () => ErrorProcessor<any>;

export type ErrorHandler<T> = (error: any, options?: ErrorHandlingOption<T>, payload?: T) => void;
// export type ErrorHandler<T> = (error: any, options?: ErrorHandlingOption<T>, payload?: T) => void;

export interface ErrorProcessResult<T> {
errorToastConfig: OptionsObject,
toastMessage?: string | undefined;
validation?: Map<keyof T, string>;
}

export const useErrorHandler = <T>(filter: string): ErrorHandler<T> => {
export const useErrorHandler = () => {
const { t } = useTranslation();
const { enqueueSnackbar } = useSnackbar();
const { service: processorHook } = useTrackService<ErrorProcessorHook<T>>(filter);
const customErrorProcessor = processorHook && processorHook();
// const { service: processorHook } = useTrackService<ErrorProcessorHook<T>>(filter);
// const customErrorProcessor = processorHook && processorHook();

return (error: any, options?: ErrorHandlingOption<T>, payload?: T) => {
return <T>(error: any, options?: ErrorHandlingOption<T>, payload?: T) => {
console.error(error);
const errorResults: ErrorProcessResult<T> = {
errorToastConfig: {
Expand Down Expand Up @@ -101,7 +95,6 @@ export const useErrorHandler = <T>(filter: string): ErrorHandler<T> => {
const errorList = response.data as ServerError<T>[];
errorResults.errorToastConfig = {
...errorResults.errorToastConfig,
autoHideDuration: options?.duration ?? undefined,
};
errorResults.toastMessage = t('judo.error.validation-failed', { defaultValue: 'Please make sure all fields are filled in correctly.', error, payload }) as string;

Expand All @@ -118,10 +111,10 @@ export const useErrorHandler = <T>(filter: string): ErrorHandler<T> => {
}
}

if (typeof customErrorProcessor === 'function') {
customErrorProcessor(error, errorResults, options, payload);
return;
}
// if (typeof customErrorProcessor === 'function') {
// customErrorProcessor(error, errorResults, options, payload);
// return;
// }

if (errorResults.toastMessage) {
enqueueSnackbar(errorResults.toastMessage, errorResults.errorToastConfig);
Expand Down

0 comments on commit 073d365

Please sign in to comment.