Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: sync changes from v2 to v2-develop #862

Merged
merged 28 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c520994
fix: improve action separator and treeactions bar
mguellsegarra Jan 22, 2025
1600b5c
feat: extract toolbar behaviour to hooks
mguellsegarra Jan 22, 2025
4e8627e
feat: improve actionbar components with react best practices
mguellsegarra Jan 22, 2025
0081027
feat: add new localization strings and improve One2many top bar
mguellsegarra Jan 22, 2025
4d82eac
feat: improve form handling and toolbar integration in One2many compo…
mguellsegarra Jan 22, 2025
0419afe
feat: allow use of hooks from one2many's
mguellsegarra Jan 23, 2025
36913b2
Merge branch 'v2' into feat/add-toolbar-buttons-to-x2many
mguellsegarra Jan 23, 2025
b91ffeb
Merge branch 'v2' into feat/add-toolbar-buttons-to-x2many
mguellsegarra Jan 23, 2025
6c09769
fix: bad conflict resolution
mguellsegarra Jan 23, 2025
b9f3d30
fix: adjust sharebutton for formactionbar
mguellsegarra Jan 23, 2025
c68ec43
fix: remove unused function
mguellsegarra Jan 24, 2025
2563045
Merge branch 'v2' into feat/add-toolbar-buttons-to-x2many
mguellsegarra Jan 24, 2025
9fd9d6a
fix: adjust value key filtering in URL sharing
mguellsegarra Jan 24, 2025
1b5d7dd
fix: improve value merging logic in useUrlFromCurrentTab
mguellsegarra Jan 24, 2025
c79c3e0
fix: improve and export parameter filtering
mguellsegarra Jan 25, 2025
28fff0a
fix: transform initialView to initialViewId
mguellsegarra Jan 25, 2025
bf072e5
fix: also clear url when closing all tabs
mguellsegarra Jan 26, 2025
68d42f0
fix: clear title when no tabs
mguellsegarra Jan 28, 2025
c0e6959
Merge pull request #857 from gisce/fix/clear-title-when-no-tabs
mguellsegarra Jan 28, 2025
b46cf2f
chore(release): 2.58.1 [skip ci]
semantic-release-bot Jan 28, 2025
6251874
feat: fetch toolbar if needed and if view of one2many is hardcoded
mguellsegarra Jan 28, 2025
85f1f6e
Merge branch 'v2' into feat/add-toolbar-buttons-to-x2many
mguellsegarra Jan 28, 2025
7470e76
fix: temporally disable toolbar in one2many's until we decide which d…
mguellsegarra Jan 28, 2025
8a4745d
Merge branch 'feat/add-toolbar-buttons-to-x2many' into v2
mguellsegarra Jan 28, 2025
5a59093
chore(release): 2.59.0 [skip ci]
semantic-release-bot Jan 28, 2025
fd9d10f
fix: restore bad conflict resolution
mguellsegarra Jan 28, 2025
f89c7b1
chore(release): 2.59.1 [skip ci]
semantic-release-bot Jan 28, 2025
202f05b
Merge remote-tracking branch 'origin/v2' into sync/v2-to-v2-develop-2…
github-actions[bot] Jan 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@gisce/react-ooui",
"version": "2.59.0-rc.1",
"version": "2.59.1",
"engines": {
"node": "20.5.0"
},
Expand Down
6 changes: 6 additions & 0 deletions src/actionbar/ActionBarSeparator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { memo } from "react";

export const ActionBarSeparator = memo(() => (
<div className="inline-block w-2" />
));
ActionBarSeparator.displayName = "ActionBarSeparator";
1 change: 0 additions & 1 deletion src/actionbar/ActionButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from "react";
import ButtonWithTooltip from "@/common/ButtonWithTooltip";
import { LoadingOutlined } from "@ant-design/icons";
import { ButtonProps } from "antd";
Expand Down
6 changes: 1 addition & 5 deletions src/actionbar/DashboardActionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,8 @@ import {
BorderOuterOutlined,
} from "@ant-design/icons";
import { useLocale } from "@gisce/react-formiga-components";
import {
ActionViewContext,
ActionViewContextType,
} from "@/context/ActionViewContext";
import { ActionBarSeparator } from "./ActionBarSeparator";
import { ShareUrlButton } from "./ShareUrlButton";
import { ActionBarSeparator } from "./FormActionBar";

function DashboardActionBar() {
const { isLoading, dashboardRef, moveItemsEnabled, setMoveItemsEnabled } =
Expand Down
261 changes: 116 additions & 145 deletions src/actionbar/FormActionBar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useContext, useCallback } from "react";
import { useContext, useCallback, memo, useMemo } from "react";
import { Space, Spin } from "antd";
import {
SaveOutlined,
Expand Down Expand Up @@ -27,19 +27,17 @@ import {
TabManagerContext,
TabManagerContextType,
} from "@/context/TabManagerContext";
import {
ContentRootContext,
ContentRootContextType,
} from "@/context/ContentRootContext";
import AttachmentsButton from "./AttachmentsButton";
import { Attachment } from "./AttachmentsButtonWrapper";
import { useNextPrevious } from "./useNextPrevious";
import {
saveDocument,
useFormToolbarButtons,
} from "@/hooks/useFormToolbarButtons";
import { ActionBarSeparator } from "./ActionBarSeparator";
import { ShareUrlButton } from "./ShareUrlButton";

function FormActionBar({ toolbar }: { toolbar: any }) {
const contentRootContext = useContext(
ContentRootContext,
) as ContentRootContextType;
function FormActionBarComponent({ toolbar }: { toolbar: any }) {
const tabManagerContext = useContext(
TabManagerContext,
) as TabManagerContextType;
Expand Down Expand Up @@ -74,11 +72,12 @@ function FormActionBar({ toolbar }: { toolbar: any }) {
isActive,
} = useActionViewContext();

const { processAction } = contentRootContext || {};
const { openRelate, openDefaultActionForModel } = tabManagerContext || {};
const { openDefaultActionForModel } = tabManagerContext || {};

const mustDisableButtons =
formIsSaving || removingItem || formIsLoading || duplicatingItem;
const mustDisableButtons = useMemo(
() => formIsSaving || removingItem || formIsLoading || duplicatingItem,
[formIsSaving, removingItem, formIsLoading, duplicatingItem],
);

const tryAction = useCallback(
(action: () => void) => {
Expand All @@ -91,6 +90,18 @@ function FormActionBar({ toolbar }: { toolbar: any }) {
[formHasChanges, t],
);

const handleRefresh = useCallback(() => {
tryAction(() => (formRef.current as any).fetchValues());
}, [tryAction, formRef]);

const { actionButtonProps, printButtonProps, relateButtonProps } =
useFormToolbarButtons({
toolbar,
mustDisableButtons,
formRef,
onRefreshParentValues: handleRefresh,
});

const handleRemove = useCallback(async () => {
try {
setRemovingItem?.(true);
Expand Down Expand Up @@ -148,17 +159,53 @@ function FormActionBar({ toolbar }: { toolbar: any }) {
}
}, [currentId, currentModel, formRef, goToResourceId, setDuplicatingItem]);

const runAction = useCallback(
(actionData: any) => {
processAction?.({
actionData,
values: (formRef.current as any).getValues(),
fields: (formRef.current as any).getFields(),
context: (formRef.current as any).getContext(),
onRefreshParentValues: () => (formRef.current as any).fetchValues(),
const handleChangeView = useCallback(
(view: any) => {
setPreviousView?.(currentView);
setFormHasChanges?.(false);
setCurrentView?.(view);
},
[currentView, setPreviousView, setFormHasChanges, setCurrentView],
);

const handleAddNewAttachment = useCallback(async () => {
const result = await saveDocument({ onFormSave });
if (result.succeed) {
openDefaultActionForModel?.({
...getAttachmentActionPayload(
currentModel as string,
result.currentId as number,
),
initialViewType: "form",
});
}
}, [currentModel, onFormSave, openDefaultActionForModel]);

const handleListAllAttachments = useCallback(async () => {
const result = await saveDocument({ onFormSave });
if (result.succeed) {
openDefaultActionForModel?.({
...getAttachmentActionPayload(
currentModel as string,
result.currentId as number,
),
initialViewType: "tree",
});
}
}, [currentModel, onFormSave, openDefaultActionForModel]);

const handleViewAttachmentDetails = useCallback(
async (attachment: Attachment) => {
const result = await saveDocument({ onFormSave });
if (result.succeed) {
openDefaultActionForModel?.({
model: "ir.attachment",
res_id: attachment.id,
initialViewType: "form",
});
}
},
[formRef, processAction],
[onFormSave, openDefaultActionForModel],
);

useHotkeys(
Expand Down Expand Up @@ -267,151 +314,75 @@ function FormActionBar({ toolbar }: { toolbar: any }) {
icon={<ReloadOutlined />}
tooltip={t("refresh")}
disabled={mustDisableButtons || currentId === undefined}
onClick={() => tryAction(() => (formRef.current as any).fetchValues())}
onClick={handleRefresh}
/>
<ActionBarSeparator />
<ChangeViewButton
currentView={currentView}
previousView={previousView}
availableViews={availableViews}
onChangeView={(view: any) => {
setPreviousView?.(currentView);
setFormHasChanges?.(false);
setCurrentView?.(view);
}}
onChangeView={handleChangeView}
disabled={mustDisableButtons}
formHasChanges={formHasChanges}
/>
<ActionBarSeparator />
<Space>
<ActionButton
icon={<LeftOutlined />}
tooltip={t("previous")}
disabled={mustDisableButtons}
onClick={() => tryAction(onPreviousClick)}
/>
<ActionButton
icon={<RightOutlined />}
tooltip={t("next")}
disabled={mustDisableButtons}
onClick={() => tryAction(onNextClick)}
/>
</Space>
<ActionBarSeparator />
<DropdownButton
icon={<ThunderboltOutlined />}
placement="bottomRight"
disabled={mustDisableButtons}
onRetrieveData={async () => [
{ label: t("actions"), items: toolbar?.action },
]}
onItemClick={async (action: any) => {
if (action) {
const result = await saveDocument({ onFormSave });
if (result.succeed) runAction(action);
}
}}
/>
<DropdownButton
icon={<PrinterOutlined />}
disabled={mustDisableButtons}
placement="bottomRight"
onRetrieveData={async () => [
{ label: t("reports"), items: toolbar?.print },
]}
onItemClick={async (report: any) => {
if (report) {
const result = await saveDocument({ onFormSave });
if (result.succeed) {
runAction({
...report,
datas: {
...(report.datas || {}),
ids: [result.currentId as number],
},
});
}
}
}}
/>
<DropdownButton
icon={<EnterOutlined />}
disabled={mustDisableButtons}
placement="bottomRight"
onRetrieveData={async () => [
{ label: t("related"), items: toolbar?.relate },
]}
onItemClick={async (relate: any) => {
if (relate) {
const result = await saveDocument({ onFormSave });
if (result.succeed) {
openRelate({
relateData: relate,
values: (formRef.current as any).getValues(),
fields: (formRef.current as any).getFields(),
action_id: relate.id,
action_type: relate.type,
});
}
}
}}
<NavigationButtons
disabled={mustDisableButtons || false}
onPreviousClick={onPreviousClick}
onNextClick={onNextClick}
tryAction={tryAction}
/>
<ActionBarSeparator />
<DropdownButton icon={<ThunderboltOutlined />} {...actionButtonProps} />
<DropdownButton icon={<PrinterOutlined />} {...printButtonProps} />
<DropdownButton icon={<EnterOutlined />} {...relateButtonProps} />
<AttachmentsButton
disabled={mustDisableButtons}
attachments={attachments}
onAddNewAttachment={async () => {
const result = await saveDocument({ onFormSave });
if (result.succeed) {
openDefaultActionForModel({
...getAttachmentActionPayload(
currentModel as string,
result.currentId as number,
),
initialViewType: "form",
});
}
}}
onListAllAttachments={async () => {
const result = await saveDocument({ onFormSave });
if (result.succeed) {
openDefaultActionForModel({
...getAttachmentActionPayload(
currentModel as string,
result.currentId as number,
),
initialViewType: "tree",
});
}
}}
onViewAttachmentDetails={async (attachment: Attachment) => {
const result = await saveDocument({ onFormSave });
if (result.succeed) {
openDefaultActionForModel({
model: "ir.attachment",
res_id: attachment.id,
initialViewType: "form",
});
}
}}
onAddNewAttachment={handleAddNewAttachment}
onListAllAttachments={handleListAllAttachments}
onViewAttachmentDetails={handleViewAttachmentDetails}
/>
<ActionBarSeparator />
<ShareUrlButton res_id={currentId} />
</Space>
);
}

export const ActionBarSeparator = () => <div className="inline-block w-2" />;
const FormActionBar = memo(FormActionBarComponent);

const saveDocument = async ({
onFormSave,
}: {
onFormSave?: () => Promise<{ succeed: boolean; id: number }>;
}): Promise<{ succeed: boolean; currentId?: number }> => {
const result = await onFormSave?.();
return result?.succeed
? { succeed: true, currentId: result.id }
: { succeed: false, currentId: undefined };
};
const NavigationButtons = memo(
({
disabled,
onPreviousClick,
onNextClick,
tryAction,
}: {
disabled: boolean;
onPreviousClick: () => void;
onNextClick: () => void;
tryAction: (action: () => void) => void;
}) => {
const { t } = useLocale();
return (
<Space>
<ActionButton
icon={<LeftOutlined />}
tooltip={t("previous")}
disabled={disabled}
onClick={() => tryAction(onPreviousClick)}
/>
<ActionButton
icon={<RightOutlined />}
tooltip={t("next")}
disabled={disabled}
onClick={() => tryAction(onNextClick)}
/>
</Space>
);
},
);
NavigationButtons.displayName = "NavigationButtons";

const getAttachmentActionPayload = (res_model: string, res_id: number) => ({
model: "ir.attachment",
Expand Down
2 changes: 1 addition & 1 deletion src/actionbar/GraphActionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ButtonWithBadge from "./ButtonWithBadge";
import { ReloadOutlined, FilterOutlined } from "@ant-design/icons";
import { View } from "@/types";
import { ShareUrlButton } from "./ShareUrlButton";
import { ActionBarSeparator } from "./FormActionBar";
import { ActionBarSeparator } from "./ActionBarSeparator";

function GraphActionBar({ refreshGraph }: { refreshGraph: () => void }) {
const { t } = useLocale();
Expand Down
Loading