From d2a700390499d2934659b24c5ea9ee8992717d34 Mon Sep 17 00:00:00 2001 From: ferishili Date: Mon, 19 May 2025 13:52:02 +0200 Subject: [PATCH 1/3] make sure the overwriting events perms is offered by the configs with optional modal button --- .../ModalTabsAndPages/SeriesDetailsAccessTab.tsx | 9 ++++++++- src/components/shared/SaveEditFooter.tsx | 8 ++++++-- .../shared/modals/ResourceDetailsAccessPolicyTab.tsx | 1 + .../opencastproject/adminui/languages/lang-en_US.json | 5 +++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx b/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx index 0f3e5b4297..cd40bc3c18 100644 --- a/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx +++ b/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx @@ -8,6 +8,9 @@ import { import { removeNotificationWizardForm } from "../../../../slices/notificationSlice"; import { useAppDispatch, useAppSelector } from "../../../../store"; import { ParseKeys } from "i18next"; +import { + getOrgProperties, +} from "../../../../selectors/userInfoSelectors"; /** * This component manages the access policy tab of the series details modal @@ -28,6 +31,10 @@ const SeriesDetailsAccessTab = ({ const policies = useAppSelector(state => getSeriesDetailsAcl(state)); const policyTemplateId = useAppSelector(state => getPolicyTemplateId(state)); + const orgProperties = useAppSelector(state => getOrgProperties(state)); + + const overrideEnabled = (orgProperties['admin.series.acl.event.update.mode'] || 'optional').toLowerCase() === 'optional'; + useEffect(() => { dispatch(removeNotificationWizardForm()); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -54,7 +61,7 @@ const SeriesDetailsAccessTab = ({ viewNonUsersAccessRole={"ROLE_UI_SERIES_DETAILS_ACL_NONUSER_ROLES_VIEW"} policyChanged={policyChanged} setPolicyChanged={setPolicyChanged} - withOverrideButton={true} + withOverrideButton={overrideEnabled} /> ); }; diff --git a/src/components/shared/SaveEditFooter.tsx b/src/components/shared/SaveEditFooter.tsx index c648f86a51..61b845d9d7 100644 --- a/src/components/shared/SaveEditFooter.tsx +++ b/src/components/shared/SaveEditFooter.tsx @@ -7,6 +7,7 @@ type SaveEditFooterProps = { reset: () => void; submit: () => void; isValid?: boolean; + customSaveButtonText?: ParseKeys; additionalButton?: { label: ParseKeys, hint: ParseKeys, @@ -19,10 +20,13 @@ export const SaveEditFooter: React.FC = ({ reset, submit, isValid, - additionalButton + customSaveButtonText, + additionalButton, }) => { const { t } = useTranslation(); + const saveButtonText = customSaveButtonText || "SAVE"; + return
{active && isValid && (
@@ -53,7 +57,7 @@ export const SaveEditFooter: React.FC = ({ className={`save green ${ !isValid || !active ? "disabled" : "" }`} - >{t("SAVE")} + >{t(saveButtonText)}
; } diff --git a/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx b/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx index 3c28a3af88..fec65706a1 100644 --- a/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx +++ b/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx @@ -378,6 +378,7 @@ const ResourceDetailsAccessPolicyTab = ({ hint: "EVENTS.SERIES.DETAILS.ACCESS.ACCESS_POLICY.REPLACE_EVENT_ACLS_HINT", onClick: () => saveAccess(formik.values, true) } : undefined} + customSaveButtonText={withOverrideButton ? "EVENTS.SERIES.DETAILS.ACCESS.ACCESS_POLICY.SAVE_SERIES_ACL_ONLY" : undefined} />} )} diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json b/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json index a6c6ea7c46..90642952c4 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json @@ -1215,8 +1215,9 @@ "USER": "User", "USERS": "Users who are authorized for the series", "NEW_USER": "New user", - "REPLACE_EVENT_ACLS": "Update series permissions", - "REPLACE_EVENT_ACLS_HINT": "Ensure all events of this series have these permissions in effect", + "REPLACE_EVENT_ACLS": "Save series and overwrite event permissions", + "REPLACE_EVENT_ACLS_HINT": "Save the series permissions and overwrite the permissions for all events in this series.", + "SAVE_SERIES_ACL_ONLY": "Save series permission", "LOAD_MORE_LIMIT": "policies shown.", "LOAD_MORE_LINK": "Load more" }, From 934cc9f6b57ec8cbbb0990e8a0f4b57c2e76db57 Mon Sep 17 00:00:00 2001 From: ferishili Date: Mon, 19 May 2025 13:52:02 +0200 Subject: [PATCH 2/3] make sure the overwriting events perms is offered by the configs with optional modal button --- .../ModalTabsAndPages/SeriesDetailsAccessTab.tsx | 9 ++++++++- src/components/shared/SaveEditFooter.tsx | 8 ++++++-- .../shared/modals/ResourceDetailsAccessPolicyTab.tsx | 1 + .../opencastproject/adminui/languages/lang-en_US.json | 5 +++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx b/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx index f4e5702e61..3612f043c2 100644 --- a/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx +++ b/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx @@ -9,6 +9,9 @@ import { import { removeNotificationWizardForm } from "../../../../slices/notificationSlice"; import { useAppDispatch, useAppSelector } from "../../../../store"; import { ParseKeys } from "i18next"; +import { + getOrgProperties, +} from "../../../../selectors/userInfoSelectors"; /** * This component manages the access policy tab of the series details modal @@ -29,6 +32,10 @@ const SeriesDetailsAccessTab = ({ const policies = useAppSelector(state => getSeriesDetailsAcl(state)); + const orgProperties = useAppSelector(state => getOrgProperties(state)); + + const overrideEnabled = (orgProperties['admin.series.acl.event.update.mode'] || 'optional').toLowerCase() === 'optional'; + useEffect(() => { dispatch(removeNotificationWizardForm()); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -46,7 +53,7 @@ const SeriesDetailsAccessTab = ({ editAccessRole={"ROLE_UI_SERIES_DETAILS_ACL_EDIT"} policyChanged={policyChanged} setPolicyChanged={setPolicyChanged} - withOverrideButton={true} + withOverrideButton={overrideEnabled} /> ); }; diff --git a/src/components/shared/SaveEditFooter.tsx b/src/components/shared/SaveEditFooter.tsx index 929bde5559..dbcf02c6e3 100644 --- a/src/components/shared/SaveEditFooter.tsx +++ b/src/components/shared/SaveEditFooter.tsx @@ -8,6 +8,7 @@ type SaveEditFooterProps = { reset: () => void; submit: () => void; isValid?: boolean; + customSaveButtonText?: ParseKeys; additionalButton?: { label: ParseKeys, hint: ParseKeys, @@ -20,10 +21,13 @@ export const SaveEditFooter: React.FC = ({ reset, submit, isValid, - additionalButton + customSaveButtonText, + additionalButton, }) => { const { t } = useTranslation(); + const saveButtonText = customSaveButtonText || "SAVE"; + return ; } diff --git a/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx b/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx index ab94b06df1..c22bdaacaf 100644 --- a/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx +++ b/src/components/shared/modals/ResourceDetailsAccessPolicyTab.tsx @@ -658,6 +658,7 @@ const ResourceDetailsAccessPolicyTab = ({ hint: "EVENTS.SERIES.DETAILS.ACCESS.ACCESS_POLICY.REPLACE_EVENT_ACLS_HINT", onClick: () => saveAccess(formik.values, true) } : undefined} + customSaveButtonText={withOverrideButton ? "EVENTS.SERIES.DETAILS.ACCESS.ACCESS_POLICY.SAVE_SERIES_ACL_ONLY" : undefined} />} )} diff --git a/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json b/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json index e33f8e9db3..4398bf0782 100644 --- a/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json +++ b/src/i18n/org/opencastproject/adminui/languages/lang-en_US.json @@ -1212,8 +1212,9 @@ "ACTION": "Actions", "NEW": "New policy", "DETAILS": "Details", - "REPLACE_EVENT_ACLS": "Update series permissions", - "REPLACE_EVENT_ACLS_HINT": "Ensure all events of this series have these permissions in effect", + "REPLACE_EVENT_ACLS": "Save series and overwrite event permissions", + "REPLACE_EVENT_ACLS_HINT": "Save the series permissions and overwrite the permissions for all events in this series.", + "SAVE_SERIES_ACL_ONLY": "Save series permission", "LOAD_MORE_LIMIT": "policies shown.", "LOAD_MORE_LINK": "Load more" }, From 38745825134170cde7f549cb542c05ba46142dbb Mon Sep 17 00:00:00 2001 From: FarbodZamani <53179227+ferishili@users.noreply.github.com> Date: Mon, 19 Jan 2026 17:11:50 +0100 Subject: [PATCH 3/3] apply always mode --- .../ModalTabsAndPages/SeriesDetailsAccessTab.tsx | 7 +------ src/slices/seriesDetailsSlice.ts | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx b/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx index 8d92d6ad2b..b39f8c68e0 100644 --- a/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx +++ b/src/components/events/partials/ModalTabsAndPages/SeriesDetailsAccessTab.tsx @@ -32,12 +32,7 @@ const SeriesDetailsAccessTab = ({ const policyTemplateId = useAppSelector(state => getPolicyTemplateId(state)); const orgProperties = useAppSelector(state => getOrgProperties(state)); - - const overrideEnabled = (orgProperties['admin.series.acl.event.update.mode'] || 'optional').toLowerCase() === 'optional'; - - const orgProperties = useAppSelector(state => getOrgProperties(state)); - - const overrideEnabled = (orgProperties['admin.series.acl.event.update.mode'] || 'optional').toLowerCase() === 'optional'; + const overrideEnabled = (orgProperties["admin.series.acl.event.update.mode"] || "optional").toLowerCase() === "optional"; useEffect(() => { dispatch(removeNotificationWizardForm()); diff --git a/src/slices/seriesDetailsSlice.ts b/src/slices/seriesDetailsSlice.ts index 39fd0fb791..249d6a7af5 100644 --- a/src/slices/seriesDetailsSlice.ts +++ b/src/slices/seriesDetailsSlice.ts @@ -5,6 +5,9 @@ import { getSeriesDetailsExtendedMetadata, getStatistics, } from "../selectors/seriesDetailsSelectors"; +import { + getOrgProperties, +} from "../selectors/userInfoSelectors"; import { addNotification } from "./notificationSlice"; import { transformMetadataCollection, @@ -258,12 +261,19 @@ export const updateSeriesAccess = createAppAsyncThunk("seriesDetails/updateSerie id: Series["id"], policies: { acl: Acl }, override?: boolean - }, { dispatch }) => { + }, { dispatch, getState }) => { const { id, policies, override } = params; const data = new URLSearchParams(); - const overrideString = override ? String(true) : String(false); + // Here we should check for the "always" option as well, so that we can force override! + const orgProperties = getOrgProperties(getState()); + const alwaysOverride = (orgProperties["admin.series.acl.event.update.mode"] || "optional").toLowerCase() === "always"; + + let overrideString = override ? String(true) : String(false); + if (alwaysOverride) { + overrideString = String(true); + } data.append("acl", JSON.stringify(policies)); data.append("override", overrideString);