From 6efb319c634b89c159af1598da9427489072326a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20G=C3=BCell=20Segarra?= Date: Fri, 24 Jan 2025 11:40:06 +0100 Subject: [PATCH 1/4] fix: bug where domain was null in handle open action url (#841) [skip ci] --- src/views/RootView.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/views/RootView.tsx b/src/views/RootView.tsx index d996d8b60..1fe824187 100644 --- a/src/views/RootView.tsx +++ b/src/views/RootView.tsx @@ -84,7 +84,7 @@ function RootView(props: RootViewProps, ref: any) { actionRawData.context !== null ) { parsedContext = actionRawData; - } else { + } else if (actionRawData && actionRawData.context) { parsedContext = actionRawData && parseContext({ @@ -92,6 +92,8 @@ function RootView(props: RootViewProps, ref: any) { fields: actionRawData.fields || {}, values: { ...globalValues, ...(actionRawData.values || {}) }, }); + } else { + parsedContext = {}; } const parsedDomain = await (async () => { @@ -102,7 +104,11 @@ function RootView(props: RootViewProps, ref: any) { actionRawData.domain.length > 0 ) { return actionRawData.domain; - } else if (actionRawData && !Array.isArray(actionRawData.domain)) { + } else if ( + actionRawData && + actionRawData.domain && + !Array.isArray(actionRawData.domain) + ) { return await ConnectionProvider.getHandler().evalDomain({ domain: actionRawData.domain, values: actionRawData.fields From 0c233d5c4ca05f4fb6999f62b2ec86be3447c813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20G=C3=BCell=20Segarra?= Date: Fri, 24 Jan 2025 15:45:17 +0100 Subject: [PATCH 2/4] fix: clear title when no tabs are open (#843) [skip ci] --- src/context/TabManagerContext.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/context/TabManagerContext.tsx b/src/context/TabManagerContext.tsx index c68a679e9..8a9564653 100644 --- a/src/context/TabManagerContext.tsx +++ b/src/context/TabManagerContext.tsx @@ -1,6 +1,7 @@ import { ActionInfo, Tab, View, ViewType } from "@/types"; import { ShortcutApi } from "@/ui/FavouriteButton"; -import React, { useState, useContext, useMemo } from "react"; +import React, { useState, useContext, useMemo, useEffect } from "react"; +import { useConfigContext } from "./ConfigContext"; export type TabManagerContextType = { openAction: (action: ActionInfo) => void; @@ -69,6 +70,17 @@ const TabManagerProvider = (props: TabManagerProviderProps): any => { const currentTab = useMemo(() => { return tabs.find((t) => t.key === activeKey); }, [tabs, activeKey]); + const { title } = useConfigContext(); + + const noTabs = useMemo(() => { + return !(tabs?.length > 0); + }, [tabs]); + + useEffect(() => { + if (noTabs) { + document.title = title; + } + }, [noTabs, title]); return ( Date: Fri, 24 Jan 2025 15:46:51 +0100 Subject: [PATCH 3/4] fix: improve url actions in order to ditch fields and re get them on resume (#844) * fix: bug where domain was null in handle open action url * fix: form rendering issue * fix: pass plain values to actions * fix: improve url actions in order to ditch fields and re get them on resume * fix: only pass certain values and reread register on resume --- src/actionbar/FormActionBar.tsx | 4 +-- src/helpers/shareUrlHelper.ts | 35 +++++++++++++++------------ src/types/index.ts | 2 +- src/views/RootView.tsx | 43 ++++++++++++++++++++++++--------- src/widgets/views/Form.tsx | 11 ++++++--- 5 files changed, 61 insertions(+), 34 deletions(-) diff --git a/src/actionbar/FormActionBar.tsx b/src/actionbar/FormActionBar.tsx index da972a663..48097b16d 100644 --- a/src/actionbar/FormActionBar.tsx +++ b/src/actionbar/FormActionBar.tsx @@ -152,7 +152,7 @@ function FormActionBar({ toolbar }: { toolbar: any }) { (actionData: any) => { processAction?.({ actionData, - values: (formRef.current as any).getValues(), + values: (formRef.current as any).getPlainValues(), fields: (formRef.current as any).getFields(), context: (formRef.current as any).getContext(), onRefreshParentValues: () => (formRef.current as any).fetchValues(), @@ -329,7 +329,7 @@ function FormActionBar({ toolbar }: { toolbar: any }) { if (result.succeed) { openRelate({ relateData: relate, - values: (formRef.current as any).getValues(), + values: (formRef.current as any).getPlainValues(), fields: (formRef.current as any).getFields(), action_id: relate.id, action_type: relate.type, diff --git a/src/helpers/shareUrlHelper.ts b/src/helpers/shareUrlHelper.ts index 7158ae687..80d88ed95 100644 --- a/src/helpers/shareUrlHelper.ts +++ b/src/helpers/shareUrlHelper.ts @@ -1,14 +1,14 @@ import { ActionInfo, ActionRawData } from "@/types"; const OPEN_ACTION_PATH = "action"; +// Parameters to exclude from the URL +const ALLOWED_VALUES_KEYS = ["active_id", "active_ids", "id"]; +const IGNORED_PARAMS = ["target", "context", "domain", "fields"]; export const createShareOpenUrl = (action: ActionInfo) => { const url = new URL(window.location.origin); url.pathname = OPEN_ACTION_PATH; - // Parameters to exclude from the URL - const ignoredParams = ["target", "context", "domain"]; - const finalAction = { ...action, actionRawData: @@ -18,7 +18,7 @@ export const createShareOpenUrl = (action: ActionInfo) => { // Add all non-null properties from action to URL Object.entries(finalAction).forEach(([key, value]) => { if ( - !ignoredParams.includes(key) && + !IGNORED_PARAMS.includes(key) && value && (!Array.isArray(value) || value.length > 0) ) { @@ -37,7 +37,7 @@ const convertToString = (value: any): string => { }; const filterActionRawData = (actionRawData: ActionRawData) => { - const { context, domain, values, fields } = actionRawData; + const { context, domain, values } = actionRawData; const filteredData: Partial = {}; @@ -67,25 +67,28 @@ const filterActionRawData = (actionRawData: ActionRawData) => { } } - // Include values and fields only if they are non-empty objects + // Include values only if they are non-empty objects if ( (filteredData.domain || filteredData.context) && values && typeof values === "object" && Object.keys(values).length > 0 ) { - const { arch, ...restValues } = values; // ignore arch if exists - filteredData.values = restValues; - } - if ( - (filteredData.domain || filteredData.context) && - fields && - typeof fields === "object" && - Object.keys(fields).length > 0 - ) { - filteredData.fields = fields; + // Only include allowed keys from values + const filteredValues = filterAllowedValues(values); + filteredData.values = + Object.keys(filteredValues).length > 0 ? filteredValues : undefined; } // Return undefined if no properties were added to filteredData return Object.keys(filteredData).length > 0 ? filteredData : undefined; }; + +export const filterAllowedValues = (values: any) => { + if (!values || typeof values !== "object") { + return {}; + } + return Object.fromEntries( + Object.entries(values).filter(([key]) => ALLOWED_VALUES_KEYS.includes(key)), + ); +}; diff --git a/src/types/index.ts b/src/types/index.ts index 3ad2ac114..f014e23f2 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -220,7 +220,7 @@ type GetViewRequest = { type GetFieldsRequest = { model: string; - fields: string[]; + fields?: string[]; context?: any; }; diff --git a/src/views/RootView.tsx b/src/views/RootView.tsx index 1fe824187..45f556350 100644 --- a/src/views/RootView.tsx +++ b/src/views/RootView.tsx @@ -18,6 +18,7 @@ import { nanoid } from "nanoid"; import { useLocale } from "@gisce/react-formiga-components"; import { useConfigContext } from "@/context/ConfigContext"; import { DEFAULT_SEARCH_LIMIT } from "@/models/constants"; +import { filterAllowedValues } from "@/helpers/shareUrlHelper"; type RootViewProps = { children: ReactNode; @@ -75,7 +76,28 @@ function RootView(props: RootViewProps, ref: any) { } async function handleOpenActionUrl(action: ActionInfo) { - const { actionRawData } = action; + const { actionRawData, res_id, initialView } = action; + + const fields = await ConnectionProvider.getHandler().getFields({ + model: action.model, + context: rootContext, + }); + + let values: Record = filterAllowedValues( + actionRawData?.values, + ); + + const finalIdToRead: number | undefined = + res_id || values.active_id || values.id; + + if (finalIdToRead) { + const readObjects = await ConnectionProvider.getHandler().readObjects({ + model: action.model, + context: rootContext, + ids: [finalIdToRead], + }); + values = { ...values, ...readObjects[0] }; + } let parsedContext; if ( @@ -89,8 +111,8 @@ function RootView(props: RootViewProps, ref: any) { actionRawData && parseContext({ context: actionRawData.context, - fields: actionRawData.fields || {}, - values: { ...globalValues, ...(actionRawData.values || {}) }, + fields, + values: { ...globalValues, ...(values || {}) }, }); } else { parsedContext = {}; @@ -111,14 +133,9 @@ function RootView(props: RootViewProps, ref: any) { ) { return await ConnectionProvider.getHandler().evalDomain({ domain: actionRawData.domain, - values: actionRawData.fields - ? transformPlainMany2Ones({ - fields: actionRawData.fields, - values: { ...(actionRawData.values || {}), ...globalValues }, - }) - : {}, + values: { ...(values || {}), ...globalValues }, context: { ...rootContext, ...parsedContext }, - fields: actionRawData.fields, + fields, }); } return []; @@ -132,7 +149,11 @@ function RootView(props: RootViewProps, ref: any) { ...action, context: { ...rootContext, ...parsedContext }, domain: parsedDomain, - actionRawData, + actionRawData: { + ...actionRawData, + values, + fields, + }, }); } diff --git a/src/widgets/views/Form.tsx b/src/widgets/views/Form.tsx index b569038b8..705802729 100644 --- a/src/widgets/views/Form.tsx +++ b/src/widgets/views/Form.tsx @@ -378,10 +378,13 @@ function Form(props: FormProps, ref: any) { ); }; - const getCurrentValues = (fields: any) => { - const currentValues = antForm.getFieldsValue(true); - return processValues(currentValues, fields); - }; + const getCurrentValues = useCallback( + (fields: any) => { + const currentValues = antForm.getFieldsValue(true); + return processValues(currentValues, fields); + }, + [antForm], + ); const setFieldValue = (field: string, value?: string) => { assignNewValuesToForm({ From 0ff681f8719cecb8ca59c9beef1ce26ee906854d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 24 Jan 2025 14:48:23 +0000 Subject: [PATCH 4/4] chore(release): 2.57.4 [skip ci] ## [2.57.4](https://github.com/gisce/react-ooui/compare/v2.57.3...v2.57.4) (2025-01-24) ### Bug Fixes * bug where domain was null in handle open action url ([#841](https://github.com/gisce/react-ooui/issues/841)) [skip ci] ([6efb319](https://github.com/gisce/react-ooui/commit/6efb319c634b89c159af1598da9427489072326a)) * clear title when no tabs are open ([#843](https://github.com/gisce/react-ooui/issues/843)) [skip ci] ([0c233d5](https://github.com/gisce/react-ooui/commit/0c233d5c4ca05f4fb6999f62b2ec86be3447c813)) * improve url actions in order to ditch fields and re get them on resume ([#844](https://github.com/gisce/react-ooui/issues/844)) ([e56f6c3](https://github.com/gisce/react-ooui/commit/e56f6c3f488c14f6d232352aef39c376705cc92b)) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 63b0bfeed..f2dfdb9a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@gisce/react-ooui", - "version": "2.57.3", + "version": "2.57.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@gisce/react-ooui", - "version": "2.57.3", + "version": "2.57.4", "dependencies": { "@ant-design/colors": "^7.2.0", "@ant-design/plots": "^1.0.9", diff --git a/package.json b/package.json index f414cc12c..49aa265e2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@gisce/react-ooui", - "version": "2.57.3", + "version": "2.57.4", "engines": { "node": "20.5.0" },