Skip to content

Commit

Permalink
JNG-4838 bulk save state
Browse files Browse the repository at this point in the history
  • Loading branch information
noherczeg committed Oct 30, 2023
1 parent 073d365 commit a8cbb28
Show file tree
Hide file tree
Showing 10 changed files with 851 additions and 765 deletions.
1,460 changes: 730 additions & 730 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 @@ -27,6 +27,7 @@

import java.util.Collection;
import java.util.Comparator;
import java.util.Optional;

@Slf4j
@TemplateHelper
Expand Down Expand Up @@ -230,8 +231,7 @@ public static String getSortDirection(Column column) {
}

public static java.util.List<ActionDefinition> getBulkOperationActionDefinitionsForTable(Table table) {
return table.getRowActionDefinitions().stream()
.filter(a ->((ActionDefinition) a).getIsCallOperationAction())
return table.getTableActionDefinitions().stream()
.filter(a -> ((ActionDefinition) a).isIsBulk())
.sorted(Comparator.comparing(NamedElement::getFQName))
.toList();
Expand All @@ -242,8 +242,16 @@ public static boolean tableHasBulkOperations(Table table) {
}

public static boolean tableHasSelectorColumn(Table table) {
return table.isIsSelectorTable() || !getBulkOperationActionDefinitionsForTable(table).isEmpty()
return table.isIsSelectorTable()
|| table.getRowActionDefinitions().stream().anyMatch(a -> ((ActionDefinition) a).isIsBulkCapable())
|| table.getRowActionDefinitions().stream().anyMatch(a -> ((ActionDefinition) a).getIsDeleteAction())
|| table.getRowActionDefinitions().stream().anyMatch(a -> ((ActionDefinition) a).getIsRemoveAction());
}

public static Column getFirstTitleColumnForTable(Table table) {
Optional<Column> column = table.getColumns().stream()
.filter(c -> c.getAttributeType().getDataType() instanceof StringType && !c.getAttributeType().getIsMemberTypeTransient())
.findFirst();
return column.orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -307,11 +307,7 @@ public static String tableButtonVisibilityConditions(Button button, Table table,
return "data.length";
}
if (button.getActionDefinition().isIsBulk()) {
String condition = "selectionModel.length > 0";
if (button.getHiddenBy() != null) {
condition += "&& !ownerData?." + button.getHiddenBy().getName();
}
return condition;
return "selectionModel.length > 0";
}
return "true";
}
Expand All @@ -328,6 +324,9 @@ public static String tableToolbarButtonDisabledConditions(Button button, Table t
}
}
}
if (button.getActionDefinition().isIsBulk() && button.getHiddenBy() != null) {
result += "!selectedRows.current.every(s => !s." + button.getHiddenBy().getName() + ") ||";
}

return result + "isLoading";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import { useL10N } from '~/l10n/l10n-context';
import {
{{# if container.isSelector }}
isRowSelectable,
{{ else }}
getUpdatedRowsSelected,
{{/ if }}
applyInMemoryFilters,
fileHandling,
Expand All @@ -49,7 +51,7 @@ import {
useErrorHandler,
} from '~/utilities';
import type { TableRowAction } from '~/utilities';
import { useDataStore } from '~/hooks';
import { {{# if (tableHasBulkOperations table) }}useCRUDDialog, {{/ if }}useDataStore } from '~/hooks';
import { OBJECTCLASS } from '@pandino/pandino-api';
{{# if (stringValueIsTrue useTableRowHighlighting) }}
import { useTrackService } from '@pandino/react-hooks';
Expand All @@ -75,7 +77,7 @@ export interface {{ tableComponentName table }}ActionDefinitions {
{{/ if }}
{{/ each }}
{{# each table.rowActionDefinitions as |actionDefinition| }}
{{ simpleActionDefinitionName actionDefinition }}?: (row: {{ classDataName (getReferenceClassType table) 'Stored' }}) => Promise<void>;
{{ simpleActionDefinitionName actionDefinition }}?: (row: {{ classDataName (getReferenceClassType table) 'Stored' }}{{# if actionDefinition.isBulkCapable }}, silentMode?: boolean{{/ if }}) => Promise<void>;
{{/ each }}
}

Expand Down Expand Up @@ -126,6 +128,9 @@ export function {{ tableComponentName table }}(props: {{ tableComponentName tabl
const { downloadFile, extractFileNameFromToken } = fileHandling();
const { t } = useTranslation();
const handleError = useErrorHandler();
{{# if (tableHasBulkOperations table) }}
const openCRUDDialog = useCRUDDialog();
{{/ if }}

{{# 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 @@ -166,6 +171,9 @@ export function {{ tableComponentName table }}(props: {{ tableComponentName tabl
const [isNextButtonEnabled, setIsNextButtonEnabled] = useState<boolean>(true);
{{/ unless }}

{{# unless container.isSelector }}
const selectedRows = useRef<{{ classDataName (getReferenceClassType table) 'Stored' }}[]>([]);
{{/ unless }}
{{# if (stringValueIsTrue useTableContextMenus) }}
const contextMenuRef = useRef<ContextMenuApi>(null);

Expand Down Expand Up @@ -358,6 +366,10 @@ export function {{ tableComponentName table }}(props: {{ tableComponentName tabl
setSelectionDiff([data.find((value) => value.__identifier === lastId)!]);
{{/ if }}
};
{{ else }}
useEffect(() => {
selectedRows.current = getUpdatedRowsSelected(selectedRows, data, selectionModel);
}, [selectionModel]);
{{/ if }}

{{# unless table.isEager }}
Expand Down Expand Up @@ -518,7 +530,35 @@ export function {{ tableComponentName table }}(props: {{ tableComponentName tabl
{{# if actionDefinition.isSelectorRangeAction }}
await actions.{{ simpleActionDefinitionName actionDefinition }}!(processQueryCustomizer(queryCustomizer));
{{ else }}
await actions.{{ simpleActionDefinitionName actionDefinition }}!();
{{# if actionDefinition.isBulk }}
openCRUDDialog<{{ classDataName (getReferenceClassType table) 'Stored' }}>({
dialogTitle: t('TMP', { defaultValue: '{{ button.label }}' }),
{{# with (getFirstTitleColumnForTable table) as |column| }}
itemTitleFn: (item) => item.{{ column.attributeType.name }}!,
{{ else }}
itemTitleFn: (item) => t('judo.placeholder', { defaultValue: 'placeholder' }) as string,
{{/ with }}
selectedItems: selectedRows.current,
action: async (item, successHandler: () => void, errorHandler: (error: any) => void) => {
try {
await actions.{{ simpleActionDefinitionName actionDefinition.bulkOf }}!(item, true);
successHandler();
} catch (error) {
errorHandler(error);
}
},
onClose: async (needsRefresh) => {
if (needsRefresh) {
{{# with (getRefreshActionDefinitionForTable table) as |refreshActionDefinition| }}
await actions.{{ simpleActionDefinitionName refreshActionDefinition }}!(processQueryCustomizer(queryCustomizer));
{{/ with }}
setSelectionModel([]); // not resetting on refreshes because refreshes would always remove selections...
}
},
});
{{ else }}
await actions.{{ simpleActionDefinitionName actionDefinition }}!();
{{/ if }}
{{/ if }}
{{/ if }}
{{/ if }}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const {{ simpleActionDefinitionName action.actionDefinition }} = async (selectedRows: {{ classDataName action.actionDefinition.bulkOf.targetType 'Stored' }}[]) => {
alert('BulkCallOperationAction');
console.info(selectedRows);
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const {{ simpleActionDefinitionName action.actionDefinition }} = async () => {
alert('BulkDeleteAction');
// alert('BulkDeleteAction');
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const {{ simpleActionDefinitionName action.actionDefinition }} = async () => {
alert('BulkRemoveAction');
// alert('BulkRemoveAction');
};
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
const {{ simpleActionDefinitionName action.actionDefinition }} = async ({{# if action.actionDefinition.targetType }}target: {{ classDataName action.actionDefinition.targetType 'Stored' }}{{/ if}}) => {
const {{ simpleActionDefinitionName action.actionDefinition }} = async ({{# if action.actionDefinition.targetType }}target: {{ classDataName action.actionDefinition.targetType 'Stored' }}{{# if action.actionDefinition.isBulkCapable }}, silentMode?: boolean{{/ if }}{{/ if}}) => {
try {
const confirmed = await openConfirmDialog(
const confirmed = {{# if action.actionDefinition.isBulkCapable }}!silentMode ? {{/ if }}await openConfirmDialog(
'row-delete-action',
t('judo.modal.confirm.confirm-delete', { defaultValue: 'Are you sure you would like to delete the selected element?' }),
t('judo.modal.confirm.confirm-title', { defaultValue: 'Confirm action' }),
);
){{# if action.actionDefinition.isBulkCapable }} : true{{/ if }};
if (confirmed) {
await {{ getServiceImplForPage page }}.delete{{# if action.targetDataElement }}{{ firstToUpper action.targetDataElement.name }}{{/ if }}({{# if action.actionDefinition.targetType }}target{{ else }}data{{/ if }});

{{# if action.actionDefinition.isBulkCapable }}
if (!silentMode) {
{{/ if }}
enqueueSnackbar(t('judo.action.delete.success', { defaultValue: 'Delete successful' }), {
variant: 'success',
...toastConfig.success,
Expand All @@ -32,12 +35,22 @@ const {{ simpleActionDefinitionName action.actionDefinition }} = async ({{# if a
{{/ if }}
{{/ unless }}
{{/ if }}

{{# if action.actionDefinition.isBulkCapable }}
}
{{/ if }}
}
} catch(error) {
{{# if action.actionDefinition.targetType }}
handleError<{{ classDataName action.actionDefinition.targetType '' }}>(error, undefined, target);
{{ else }}
handleError(error, undefined, data);
{{# if action.actionDefinition.isBulkCapable }}
if (!silentMode) {
{{/ if }}
{{# if action.actionDefinition.targetType }}
handleError<{{ classDataName action.actionDefinition.targetType '' }}>(error, undefined, target);
{{ else }}
handleError(error, undefined, data);
{{/ if }}
{{# if action.actionDefinition.isBulkCapable }}
}
{{/ if }}
}
};
Original file line number Diff line number Diff line change
@@ -1,27 +1,49 @@
const {{ simpleActionDefinitionName action.actionDefinition }} = async (target?: {{ classDataName action.actionDefinition.targetType 'Stored' }}) => {
const {{ simpleActionDefinitionName action.actionDefinition }} = async (target?: {{ classDataName action.actionDefinition.targetType 'Stored' }}{{# if action.actionDefinition.isBulkCapable }}, silentMode?: boolean{{/ if }}) => {
{{# with (getTableParentForActionDefinition action.actionDefinition) as |table| }}
if (target) {
{{# if table.isEager }}
const newList = (data?.{{ table.dataElement.name }} ?? []).filter(c => c.__identifier !== target!.__identifier);
storeDiff('{{ table.dataElement.name }}', newList);
{{ else }}
try {
setIsLoading(true);
await {{ getServiceImplForPage page }}.remove{{ firstToUpper action.ownerDataElement.name }}({{# if page.container.table }}{ __signedIdentifier: signedIdentifier } as JudoIdentifiable<any>{{ else }}data{{/ if }}, [target!]);
{{# if page.container.table }}
setRefreshCounter((prev) => prev + 1);
{{/ if }}
{{# if page.container.view }}
if (!editMode) {
{{# with (getRefreshActionDefinitionForContainer page.container) as |actionDefinition| }}
await actions.{{ simpleActionDefinitionName actionDefinition }}!(processQueryCustomizer(pageQueryCustomizer));
{{/ with }}
{{# if action.actionDefinition.isBulkCapable }}
if (!silentMode) {
await {{ getServiceImplForPage page }}.remove{{ firstToUpper action.ownerDataElement.name }}({{# if page.container.table }}{ __signedIdentifier: signedIdentifier } as JudoIdentifiable<any>{{ else }}data{{/ if }}, [target!]);
}
{{ else }}
setIsLoading(true);
await {{ getServiceImplForPage page }}.remove{{ firstToUpper action.ownerDataElement.name }}({{# if page.container.table }}{ __signedIdentifier: signedIdentifier } as JudoIdentifiable<any>{{ else }}data{{/ if }}, [target!]);
{{# if page.container.table }}
setRefreshCounter((prev) => prev + 1);
{{/ if }}
{{# if page.container.view }}
if (!editMode) {
{{# with (getRefreshActionDefinitionForContainer page.container) as |actionDefinition| }}
await actions.{{ simpleActionDefinitionName actionDefinition }}!(processQueryCustomizer(pageQueryCustomizer));
{{/ with }}
}
{{/ if }}
{{/ if }}
} catch(error) {
{{# if action.actionDefinition.isBulkCapable }}
if (!silentMode) {
{{/ if }}
{{# if action.actionDefinition.targetType }}
handleError<{{ classDataName action.actionDefinition.targetType '' }}>(error, undefined, target);
{{ else }}
handleError(error, undefined, data);
{{/ if }}
{{# if action.actionDefinition.isBulkCapable }}
}
{{/ if }}
} catch(e) {
console.error(e);
} finally {
setIsLoading(false);
{{# if action.actionDefinition.isBulkCapable }}
if (!silentMode) {
{{/ if }}
setIsLoading(false);
{{# if action.actionDefinition.isBulkCapable }}
}
{{/ if }}
}
{{/ if }}
}
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
<node-version>18.14.2</node-version>
<pnpm-version>8.9.2</pnpm-version>

<judo-meta-ui-version>1.1.0.20231024_175354_d92dd516_feature_JNG_4838_SeparatePageContainerAndDefinition</judo-meta-ui-version>
<judo-meta-ui-version>1.1.0-SNAPSHOT</judo-meta-ui-version>
<judo-generator-commons-version>1.0.0.20230826_230139_c0dd2610_develop</judo-generator-commons-version>
<judo-ui-typescript-rest-version>1.0.0.20231026_150611_b39a761b_feature_JNG_4838_SeparatePageContainerAndDefinition</judo-ui-typescript-rest-version>

Expand Down

0 comments on commit a8cbb28

Please sign in to comment.