diff --git a/i18n/en.pot b/i18n/en.pot index f63c84ea2..93644a8ee 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2025-06-25T11:55:58.705Z\n" -"PO-Revision-Date: 2025-06-25T11:55:58.705Z\n" +"POT-Creation-Date: 2025-07-29T11:53:44.041Z\n" +"PO-Revision-Date: 2025-07-29T11:53:44.041Z\n" msgid "" "THIS NEW RELEASE INCLUDES SHARING SETTINGS PER INSTANCES. FOR THIS VERSION " @@ -1467,12 +1467,18 @@ msgstr "" msgid "Exclude relationships" msgstr "" +msgid "Configure user dependencies" +msgstr "" + msgid "Include owner and sharing settings" msgstr "" msgid "Include users" msgstr "" +msgid "Configure organisation units dependencies" +msgstr "" + msgid "Include organisation units" msgstr "" @@ -1481,16 +1487,10 @@ msgid "" "categoryOptionCombos" msgstr "" -msgid "Remove lastUpdated, lastUpdatedBy, created and createdBys" -msgstr "" - -msgid "Exclude objects and references ->" -msgstr "" - -msgid "Include objects" +msgid "Exclude dependencies" msgstr "" -msgid "Include only references ->" +msgid "Include dependencies" msgstr "" msgid "Include references and objects" diff --git a/i18n/es.po b/i18n/es.po index 17640fd90..5517953cc 100644 --- a/i18n/es.po +++ b/i18n/es.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2025-06-25T11:55:58.705Z\n" +"POT-Creation-Date: 2025-07-23T12:43:24.019Z\n" "PO-Revision-Date: 2020-07-10T06:53:30.625Z\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1471,12 +1471,18 @@ msgstr "" msgid "Exclude relationships" msgstr "" +msgid "Configure user dependencies" +msgstr "" + msgid "Include owner and sharing settings" msgstr "" msgid "Include users" msgstr "" +msgid "Configure organisation units dependencies" +msgstr "" + msgid "Include organisation units" msgstr "" @@ -1485,16 +1491,10 @@ msgid "" "categoryOptionCombos" msgstr "" -msgid "Remove lastUpdated, lastUpdatedBy, created and createdBys" -msgstr "" - -msgid "Exclude objects and references ->" -msgstr "" - -msgid "Include objects" +msgid "Exclude dependencies" msgstr "" -msgid "Include only references ->" +msgid "Include dependencies" msgstr "" msgid "Include references and objects" diff --git a/i18n/fr.po b/i18n/fr.po index 89d517726..e1f7f4788 100644 --- a/i18n/fr.po +++ b/i18n/fr.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2025-06-25T11:55:58.705Z\n" +"POT-Creation-Date: 2025-07-23T12:43:24.019Z\n" "PO-Revision-Date: 2020-07-10T06:53:30.625Z\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1471,12 +1471,18 @@ msgstr "" msgid "Exclude relationships" msgstr "" +msgid "Configure user dependencies" +msgstr "" + msgid "Include owner and sharing settings" msgstr "" msgid "Include users" msgstr "" +msgid "Configure organisation units dependencies" +msgstr "" + msgid "Include organisation units" msgstr "" @@ -1485,16 +1491,10 @@ msgid "" "categoryOptionCombos" msgstr "" -msgid "Remove lastUpdated, lastUpdatedBy, created and createdBys" -msgstr "" - -msgid "Exclude objects and references ->" -msgstr "" - -msgid "Include objects" +msgid "Exclude dependencies" msgstr "" -msgid "Include only references ->" +msgid "Include dependencies" msgstr "" msgid "Include references and objects" diff --git a/i18n/pt.po b/i18n/pt.po index 89d517726..e1f7f4788 100644 --- a/i18n/pt.po +++ b/i18n/pt.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: i18next-conv\n" -"POT-Creation-Date: 2025-06-25T11:55:58.705Z\n" +"POT-Creation-Date: 2025-07-23T12:43:24.019Z\n" "PO-Revision-Date: 2020-07-10T06:53:30.625Z\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -1471,12 +1471,18 @@ msgstr "" msgid "Exclude relationships" msgstr "" +msgid "Configure user dependencies" +msgstr "" + msgid "Include owner and sharing settings" msgstr "" msgid "Include users" msgstr "" +msgid "Configure organisation units dependencies" +msgstr "" + msgid "Include organisation units" msgstr "" @@ -1485,16 +1491,10 @@ msgid "" "categoryOptionCombos" msgstr "" -msgid "Remove lastUpdated, lastUpdatedBy, created and createdBys" -msgstr "" - -msgid "Exclude objects and references ->" -msgstr "" - -msgid "Include objects" +msgid "Exclude dependencies" msgstr "" -msgid "Include only references ->" +msgid "Include dependencies" msgstr "" msgid "Include references and objects" diff --git a/src/domain/rules/entities/SynchronizationRule.ts b/src/domain/rules/entities/SynchronizationRule.ts index 04379dd63..7b7fdbe18 100644 --- a/src/domain/rules/entities/SynchronizationRule.ts +++ b/src/domain/rules/entities/SynchronizationRule.ts @@ -240,6 +240,21 @@ export class SynchronizationRule { public get syncParams(): MetadataSynchronizationParams { const params = this.syncRule.builder?.syncParams ?? {}; + return { + ...SynchronizationRule.syncParamsDefaults, + ...params, + }; + } + + public get dataParams(): DataSynchronizationParams { + return this.syncRule.builder?.dataParams ?? {}; + } + + public get ondemand(): boolean { + return this.syncRule.ondemand ?? false; + } + + public static get syncParamsDefaults(): MetadataSynchronizationParams { return { enableMapping: false, useDefaultIncludeExclude: true, @@ -252,18 +267,9 @@ export class SynchronizationRule { includeOnlyOrgUnitsReferences: false, removeDefaultCategoryObjects: false, removeUserNonEssentialObjects: false, - ...params, }; } - public get dataParams(): DataSynchronizationParams { - return this.syncRule.builder?.dataParams ?? {}; - } - - public get ondemand(): boolean { - return this.syncRule.ondemand ?? false; - } - public static create(type: SynchronizationType = "metadata"): SynchronizationRule { return new SynchronizationRule({ id: "", diff --git a/src/presentation/react/core/components/sync-wizard/metadata/MetadataIncludeExcludeStep.tsx b/src/presentation/react/core/components/sync-wizard/metadata/MetadataIncludeExcludeStep.tsx index 63e488a89..ffedc97f2 100644 --- a/src/presentation/react/core/components/sync-wizard/metadata/MetadataIncludeExcludeStep.tsx +++ b/src/presentation/react/core/components/sync-wizard/metadata/MetadataIncludeExcludeStep.tsx @@ -7,6 +7,7 @@ import { Toggle } from "../../toggle/Toggle"; import { SyncWizardStepProps } from "../Steps"; import { styled } from "styled-components"; import { IncludeObjectsAndReferences, useMetadataIncludeExcludeStep } from "./useMetadataIncludeExcludeStep"; +import { useConfigureDependencies } from "./useConfigureDependencies"; const useStyles = makeStyles({ includeExcludeContainer: { @@ -40,16 +41,12 @@ const MetadataIncludeExcludeStep: React.FC = ({ syncRule, o includeRuleOptions, includeReferencesAndObjectsRules, includeObjectsAndReferencesOptions, - changeSharingSettingsObjectsAndReferences, - changeUsersObjectsAndReferences, - changeOrgUnitsObjectsAndReferences, + changeObjectsAndReferences, sharingSettingsObjectsAndReferencesValue, usersObjectsAndReferencesValue, orgUnitsObjectsAndReferencesValue, removeDefaultCategoryObjects, changeRemoveDefaultCategoryObjects, - removeUserNonEssentialObjects, - changeRemoveNonEssentialUserObjects, } = useMetadataIncludeExcludeStep(syncRule, onChange); useEffect(() => { @@ -58,66 +55,84 @@ const MetadataIncludeExcludeStep: React.FC = ({ syncRule, o } }, [error, snackbar]); + const { + configureUserDependencies, + onChangeConfigureUserDependencies, + configureOrgUnitsDependencies, + onChangeConfigureOrgUnitsDependencies, + } = useConfigureDependencies({ + sharingSettingsObjectsAndReferencesValue, + usersObjectsAndReferencesValue, + orgUnitsObjectsAndReferencesValue, + changeObjectsAndReferences, + }); + console.debug("Rendering MetadataIncludeExcludeStep"); return modelSelectItems.length > 0 ? (
- - - value={sharingSettingsObjectsAndReferencesValue} - items={includeObjectsAndReferencesOptions} - label={i18n.t("Include owner and sharing settings")} - style={{ width: "100%", marginTop: 20, marginBottom: 20, marginLeft: -10 }} - onValueChange={changeSharingSettingsObjectsAndReferences} - hideEmpty - /> - - - - - value={usersObjectsAndReferencesValue} - items={includeObjectsAndReferencesOptions} - label={i18n.t("Include users")} - style={{ width: "100%", marginTop: 20, marginBottom: 20, marginLeft: -10 }} - onValueChange={changeUsersObjectsAndReferences} - hideEmpty - /> - - - - - value={orgUnitsObjectsAndReferencesValue} - items={includeObjectsAndReferencesOptions} - label={i18n.t("Include organisation units")} - style={{ width: "100%", marginTop: 20, marginBottom: 20, marginLeft: -10 }} - onValueChange={changeOrgUnitsObjectsAndReferences} - hideEmpty - /> - - - {syncRule.type === "metadata" && ( -
- -
+ + {configureUserDependencies && ( + + + + value={sharingSettingsObjectsAndReferencesValue} + items={includeObjectsAndReferencesOptions} + label={i18n.t("Include owner and sharing settings")} + style={{ width: "100%", marginTop: 20, marginBottom: 20, marginLeft: -10 }} + onValueChange={value => changeObjectsAndReferences({ sharingSettings: value })} + hideEmpty + /> + + + + value={usersObjectsAndReferencesValue} + items={includeObjectsAndReferencesOptions} + label={i18n.t("Include users")} + style={{ width: "100%", marginTop: 20, marginBottom: 20, marginLeft: -10 }} + onValueChange={value => changeObjectsAndReferences({ users: value })} + hideEmpty + /> + + )} - - {syncRule.type === "metadata" && ( -
- +
+ + {configureOrgUnitsDependencies && ( + + + value={orgUnitsObjectsAndReferencesValue} + items={includeObjectsAndReferencesOptions} + label={i18n.t("Include organisation units")} + style={{ width: "100%", marginTop: 20, marginBottom: 20, marginLeft: -10 }} + onValueChange={value => changeObjectsAndReferences({ orgUnits: value })} + hideEmpty /> -
+ )}
+ {syncRule.type === "metadata" && ( +
+ +
+ )} + = ({ syncRule, o {selectedType && ( <>
- - {i18n.t("Exclude objects and references ->")} - {i18n.t("Include objects")} - + = ({ syncRule, o />
- - {i18n.t("Include only references ->")} - {i18n.t("Include references and objects")} - + = ({ syncRule, o export default React.memo(MetadataIncludeExcludeStep); -const Row = styled.div` - display: flex; - flex-direction: row; - align-items: center; +/** + * Display a title above each select box in the MultiSelector. + * @todo `@eyeseetea/d2-ui-components/Multiselector` should implement this + */ +const MultiSelectorTitle: React.FC<{ left: string; right: string }> = ({ left, right }) => ( + + {left} +
+ {right} + +); + +const MultiSelectorTitleContainer = styled.div` + display: grid; + grid-template-columns: 1fr 120px 1fr 2.5rem; `; const LoadingContainer = styled.div` diff --git a/src/presentation/react/core/components/sync-wizard/metadata/useConfigureDependencies.ts b/src/presentation/react/core/components/sync-wizard/metadata/useConfigureDependencies.ts new file mode 100644 index 000000000..1286259ff --- /dev/null +++ b/src/presentation/react/core/components/sync-wizard/metadata/useConfigureDependencies.ts @@ -0,0 +1,94 @@ +import React from "react"; +import { SynchronizationRule } from "../../../../../../domain/rules/entities/SynchronizationRule"; +import { + getObjectsAndReferencesValue, + IncludeObjectsAndReferenceOptions, + IncludeObjectsAndReferences, +} from "./useMetadataIncludeExcludeStep"; + +const includeObjectsAndReferencesDefaults = { + sharingSettingsObjectsAndReferencesValue: getObjectsAndReferencesValue( + SynchronizationRule.syncParamsDefaults.includeSharingSettingsObjectsAndReferences, + SynchronizationRule.syncParamsDefaults.includeOnlySharingSettingsReferences + ), + usersObjectsAndReferencesValue: getObjectsAndReferencesValue( + SynchronizationRule.syncParamsDefaults.includeUsersObjectsAndReferences, + SynchronizationRule.syncParamsDefaults.includeOnlyUsersReferences + ), + orgUnitsObjectsAndReferencesValue: getObjectsAndReferencesValue( + SynchronizationRule.syncParamsDefaults.includeOrgUnitsObjectsAndReferences, + SynchronizationRule.syncParamsDefaults.includeOnlyOrgUnitsReferences + ), +}; + +export const isDefaultIncludeObjectsAndReferences = (param: { + sharingSettingsObjectsAndReferencesValue?: IncludeObjectsAndReferences; + usersObjectsAndReferencesValue?: IncludeObjectsAndReferences; + orgUnitsObjectsAndReferencesValue?: IncludeObjectsAndReferences; +}): boolean => { + return Object.entries(param).every( + ([key, value]) => + value === includeObjectsAndReferencesDefaults[key as keyof typeof includeObjectsAndReferencesDefaults] + ); +}; + +interface UseConfigureDependenciesParams { + sharingSettingsObjectsAndReferencesValue: IncludeObjectsAndReferences; + usersObjectsAndReferencesValue: IncludeObjectsAndReferences; + orgUnitsObjectsAndReferencesValue: IncludeObjectsAndReferences; + changeObjectsAndReferences: (updates: IncludeObjectsAndReferenceOptions) => void; +} + +export function useConfigureDependencies(params: UseConfigureDependenciesParams) { + const { + sharingSettingsObjectsAndReferencesValue, + usersObjectsAndReferencesValue, + orgUnitsObjectsAndReferencesValue, + changeObjectsAndReferences, + } = params; + + const [configureUserDependencies, setConfigureUserDependencies] = React.useState( + !isDefaultIncludeObjectsAndReferences({ + sharingSettingsObjectsAndReferencesValue, + usersObjectsAndReferencesValue, + }) + ); + + const [configureOrgUnitsDependencies, setConfigureOrgUnitsDependencies] = React.useState( + !isDefaultIncludeObjectsAndReferences({ + orgUnitsObjectsAndReferencesValue, + }) + ); + + const onChangeConfigureUserDependencies = React.useCallback( + (value: boolean) => { + setConfigureUserDependencies(value); + if (!value) { + changeObjectsAndReferences({ + sharingSettings: includeObjectsAndReferencesDefaults.sharingSettingsObjectsAndReferencesValue, + users: includeObjectsAndReferencesDefaults.usersObjectsAndReferencesValue, + }); + } + }, + [changeObjectsAndReferences] + ); + + const onChangeConfigureOrgUnitsDependencies = React.useCallback( + (value: boolean) => { + setConfigureOrgUnitsDependencies(value); + if (!value) { + changeObjectsAndReferences({ + orgUnits: includeObjectsAndReferencesDefaults.orgUnitsObjectsAndReferencesValue, + }); + } + }, + [changeObjectsAndReferences] + ); + + return { + configureUserDependencies, + configureOrgUnitsDependencies, + onChangeConfigureUserDependencies, + onChangeConfigureOrgUnitsDependencies, + }; +} diff --git a/src/presentation/react/core/components/sync-wizard/metadata/useMetadataIncludeExcludeStep.ts b/src/presentation/react/core/components/sync-wizard/metadata/useMetadataIncludeExcludeStep.ts index 716786236..7e0c4aaa0 100644 --- a/src/presentation/react/core/components/sync-wizard/metadata/useMetadataIncludeExcludeStep.ts +++ b/src/presentation/react/core/components/sync-wizard/metadata/useMetadataIncludeExcludeStep.ts @@ -26,6 +26,12 @@ export const includeObjectsAndReferencesOptions: { id: IncludeObjectsAndReferenc name, })); +export interface IncludeObjectsAndReferenceOptions { + sharingSettings?: IncludeObjectsAndReferences; + users?: IncludeObjectsAndReferences; + orgUnits?: IncludeObjectsAndReferences; +} + export function useMetadataIncludeExcludeStep( syncRule: SynchronizationRule, onChange: (syncRule: SynchronizationRule) => void @@ -205,39 +211,28 @@ export function useMetadataIncludeExcludeStep( ); }, [syncParams.includeOrgUnitsObjectsAndReferences, syncParams.includeOnlyOrgUnitsReferences]); - const changeSharingSettingsObjectsAndReferences = useCallback( - (value: IncludeObjectsAndReferences) => { - onChange( - syncRule.updateSyncParams({ - ...syncRule.syncParams, - includeSharingSettingsObjectsAndReferences: value === "includeObjectsAndReferences", - includeOnlySharingSettingsReferences: value === "includeOnlyReferences", - }) - ); - }, - [onChange, syncRule] - ); + const changeObjectsAndReferences = useCallback( + (updates: IncludeObjectsAndReferenceOptions) => { + const syncParamsUpdates = { + ...(updates.sharingSettings && { + includeSharingSettingsObjectsAndReferences: + updates.sharingSettings === "includeObjectsAndReferences", + includeOnlySharingSettingsReferences: updates.sharingSettings === "includeOnlyReferences", + }), + ...(updates.users && { + includeUsersObjectsAndReferences: updates.users === "includeObjectsAndReferences", + includeOnlyUsersReferences: updates.users === "includeOnlyReferences", + }), + ...(updates.orgUnits && { + includeOrgUnitsObjectsAndReferences: updates.orgUnits === "includeObjectsAndReferences", + includeOnlyOrgUnitsReferences: updates.orgUnits === "includeOnlyReferences", + }), + }; - const changeUsersObjectsAndReferences = useCallback( - (value: IncludeObjectsAndReferences) => { onChange( syncRule.updateSyncParams({ ...syncRule.syncParams, - includeUsersObjectsAndReferences: value === "includeObjectsAndReferences", - includeOnlyUsersReferences: value === "includeOnlyReferences", - }) - ); - }, - [onChange, syncRule] - ); - - const changeOrgUnitsObjectsAndReferences = useCallback( - (value: IncludeObjectsAndReferences) => { - onChange( - syncRule.updateSyncParams({ - ...syncRule.syncParams, - includeOrgUnitsObjectsAndReferences: value === "includeObjectsAndReferences", - includeOnlyOrgUnitsReferences: value === "includeOnlyReferences", + ...syncParamsUpdates, }) ); }, @@ -248,10 +243,6 @@ export function useMetadataIncludeExcludeStep( return syncParams.removeDefaultCategoryObjects; }, [syncParams.removeDefaultCategoryObjects]); - const removeUserNonEssentialObjects = useMemo(() => { - return syncParams.removeUserNonEssentialObjects; - }, [syncParams.removeUserNonEssentialObjects]); - const changeRemoveDefaultCategoryObjects = useCallback( (removeDefaultCategoryObjects: boolean) => { onChange( @@ -264,18 +255,6 @@ export function useMetadataIncludeExcludeStep( [syncParams, onChange, syncRule] ); - const changeRemoveNonEssentialUserObjects = useCallback( - (removeUserNonEssentialObjects: boolean) => { - onChange( - syncRule.updateSyncParams({ - ...syncParams, - removeUserNonEssentialObjects, - }) - ); - }, - [syncParams, onChange, syncRule] - ); - return { error, d2, @@ -290,17 +269,13 @@ export function useMetadataIncludeExcludeStep( changeIncludeReferencesAndObjectsRules, includeRuleOptions, includeReferencesAndObjectsRules, - changeSharingSettingsObjectsAndReferences, - changeUsersObjectsAndReferences, - changeOrgUnitsObjectsAndReferences, + changeObjectsAndReferences, includeObjectsAndReferencesOptions, sharingSettingsObjectsAndReferencesValue, usersObjectsAndReferencesValue, orgUnitsObjectsAndReferencesValue, removeDefaultCategoryObjects, - removeUserNonEssentialObjects, changeRemoveDefaultCategoryObjects, - changeRemoveNonEssentialUserObjects, }; } @@ -327,7 +302,7 @@ function getModels(metadata: MetadataPackage, metadataModelsSync .map(type => modelFactory(type)); } -function getObjectsAndReferencesValue( +export function getObjectsAndReferencesValue( includeObjectsAndReferences: boolean, includeOnlyReferences: boolean ): IncludeObjectsAndReferences {