| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- import type React from 'react';
- import { useCallback } from 'react';
- import { Collapse } from 'reactstrap';
- import type AdminGeneralSecurityContainer from '~/client/services/AdminGeneralSecurityContainer';
- import {
- type IPageDeleteConfigValue,
- type IPageDeleteConfigValueToProcessValidation,
- PageDeleteConfigValue,
- } from '~/interfaces/page-delete-config';
- import {
- prepareDeleteConfigValuesForCalc,
- validateDeleteConfigs,
- } from '~/utils/page-delete-config';
- import {
- DeletionType,
- type DeletionTypeValue,
- getDeleteConfigValueForT,
- getDeletionTypeForT,
- isRecursiveDeletion,
- isTypeDeletion,
- } from './types';
- type Props = {
- adminGeneralSecurityContainer: AdminGeneralSecurityContainer;
- t: (key: string) => string;
- };
- export const PageDeleteRightsSettings: React.FC<Props> = ({
- adminGeneralSecurityContainer,
- t,
- }) => {
- const {
- currentPageDeletionAuthority,
- currentPageCompleteDeletionAuthority,
- currentPageRecursiveDeletionAuthority,
- currentPageRecursiveCompleteDeletionAuthority,
- } = adminGeneralSecurityContainer.state;
- const getRecursiveDeletionConfigState = useCallback(
- (deletionType: DeletionTypeValue) => {
- if (isTypeDeletion(deletionType)) {
- return [
- adminGeneralSecurityContainer.state
- .currentPageRecursiveDeletionAuthority,
- adminGeneralSecurityContainer.changePageRecursiveDeletionAuthority,
- ] as const;
- }
- return [
- adminGeneralSecurityContainer.state
- .currentPageRecursiveCompleteDeletionAuthority,
- adminGeneralSecurityContainer.changePageRecursiveCompleteDeletionAuthority,
- ] as const;
- },
- [adminGeneralSecurityContainer],
- );
- const previousPageRecursiveAuthorityState = useCallback(
- (deletionType: DeletionTypeValue) => {
- return isTypeDeletion(deletionType)
- ? adminGeneralSecurityContainer.state
- .previousPageRecursiveDeletionAuthority
- : adminGeneralSecurityContainer.state
- .previousPageRecursiveCompleteDeletionAuthority;
- },
- [adminGeneralSecurityContainer],
- );
- const setPagePreviousRecursiveAuthorityState = useCallback(
- (
- deletionType: DeletionTypeValue,
- previousState: IPageDeleteConfigValue | null,
- ) => {
- if (isTypeDeletion(deletionType)) {
- adminGeneralSecurityContainer.changePreviousPageRecursiveDeletionAuthority(
- previousState,
- );
- return;
- }
- adminGeneralSecurityContainer.changePreviousPageRecursiveCompleteDeletionAuthority(
- previousState,
- );
- },
- [adminGeneralSecurityContainer],
- );
- const expandDeleteOptionsState = useCallback(
- (deletionType: DeletionTypeValue) => {
- return isTypeDeletion(deletionType)
- ? adminGeneralSecurityContainer.state.expandOtherOptionsForDeletion
- : adminGeneralSecurityContainer.state
- .expandOtherOptionsForCompleteDeletion;
- },
- [adminGeneralSecurityContainer],
- );
- const setExpandOtherDeleteOptionsState = useCallback(
- (deletionType: DeletionTypeValue, bool: boolean) => {
- if (isTypeDeletion(deletionType)) {
- adminGeneralSecurityContainer.switchExpandOtherOptionsForDeletion(bool);
- return;
- }
- adminGeneralSecurityContainer.switchExpandOtherOptionsForCompleteDeletion(
- bool,
- );
- },
- [adminGeneralSecurityContainer],
- );
- const setDeletionConfigState = useCallback(
- (
- newState: IPageDeleteConfigValue,
- setState: (value: IPageDeleteConfigValue) => void,
- deletionType: DeletionTypeValue,
- ) => {
- setState(newState);
- if (previousPageRecursiveAuthorityState(deletionType) !== null) {
- setPagePreviousRecursiveAuthorityState(deletionType, null);
- }
- if (isRecursiveDeletion(deletionType)) {
- return;
- }
- const [recursiveState, setRecursiveState] =
- getRecursiveDeletionConfigState(deletionType);
- const calculableValue = prepareDeleteConfigValuesForCalc(
- newState as IPageDeleteConfigValueToProcessValidation,
- recursiveState as IPageDeleteConfigValueToProcessValidation,
- );
- const shouldForceUpdate = !validateDeleteConfigs(
- calculableValue[0],
- calculableValue[1],
- );
- if (shouldForceUpdate) {
- setRecursiveState(newState);
- setPagePreviousRecursiveAuthorityState(deletionType, recursiveState);
- setExpandOtherDeleteOptionsState(deletionType, true);
- }
- },
- [
- getRecursiveDeletionConfigState,
- previousPageRecursiveAuthorityState,
- setPagePreviousRecursiveAuthorityState,
- setExpandOtherDeleteOptionsState,
- ],
- );
- const renderPageDeletePermissionDropdown = useCallback(
- (
- currentState: IPageDeleteConfigValue,
- setState: (value: IPageDeleteConfigValue) => void,
- deletionType: DeletionTypeValue,
- isButtonDisabled: boolean,
- ) => {
- return (
- <div className="dropdown">
- <button
- className="btn btn-outline-secondary dropdown-toggle text-end"
- type="button"
- id="dropdownMenuButton"
- data-bs-toggle="dropdown"
- aria-haspopup="true"
- aria-expanded="true"
- >
- <span className="float-start">
- {t(getDeleteConfigValueForT(currentState))}
- </span>
- </button>
- <div className="dropdown-menu">
- {isRecursiveDeletion(deletionType) ? (
- <button
- className="dropdown-item"
- type="button"
- onClick={() => {
- setDeletionConfigState(
- PageDeleteConfigValue.Inherit,
- setState,
- deletionType,
- );
- }}
- >
- {t('security_settings.inherit')}
- </button>
- ) : (
- <button
- className="dropdown-item"
- type="button"
- onClick={() => {
- setDeletionConfigState(
- PageDeleteConfigValue.Anyone,
- setState,
- deletionType,
- );
- }}
- >
- {t('security_settings.anyone')}
- </button>
- )}
- <button
- className={`dropdown-item ${isButtonDisabled ? 'disabled' : ''}`}
- type="button"
- onClick={() => {
- setDeletionConfigState(
- PageDeleteConfigValue.AdminAndAuthor,
- setState,
- deletionType,
- );
- }}
- >
- {t('security_settings.admin_and_author')}
- </button>
- <button
- className="dropdown-item"
- type="button"
- onClick={() => {
- setDeletionConfigState(
- PageDeleteConfigValue.AdminOnly,
- setState,
- deletionType,
- );
- }}
- >
- {t('security_settings.admin_only')}
- </button>
- </div>
- <p className="form-text text-muted small">
- {t(
- `security_settings.${getDeletionTypeForT(deletionType)}_explanation`,
- )}
- </p>
- </div>
- );
- },
- [t, setDeletionConfigState],
- );
- const renderPageDeletePermission = useCallback(
- (
- currentState: IPageDeleteConfigValue,
- setState: (value: IPageDeleteConfigValue) => void,
- deletionType: DeletionTypeValue,
- isButtonDisabled: boolean,
- ) => {
- const expandDeleteOptions = expandDeleteOptionsState(deletionType);
- return (
- <div
- key={`page-delete-permission-dropdown-${deletionType}`}
- className="row"
- >
- <div className="col-md-4 text-md-end">
- {!isRecursiveDeletion(deletionType) &&
- isTypeDeletion(deletionType) && (
- <strong>{t('security_settings.page_delete')}</strong>
- )}
- {!isRecursiveDeletion(deletionType) &&
- !isTypeDeletion(deletionType) && (
- <strong>{t('security_settings.page_delete_completely')}</strong>
- )}
- </div>
- <div className="col-md-8">
- {!isRecursiveDeletion(deletionType) ? (
- <>
- {renderPageDeletePermissionDropdown(
- currentState,
- setState,
- deletionType,
- isButtonDisabled,
- )}
- {currentState === PageDeleteConfigValue.Anyone &&
- deletionType === DeletionType.CompleteDeletion && (
- <>
- <input
- id="isAllGroupMembershipRequiredForPageCompleteDeletionCheckbox"
- className="form-check-input"
- type="checkbox"
- checked={
- adminGeneralSecurityContainer.state
- .isAllGroupMembershipRequiredForPageCompleteDeletion
- }
- onChange={() => {
- adminGeneralSecurityContainer.switchIsAllGroupMembershipRequiredForPageCompleteDeletion();
- }}
- />
- <label
- className="form-check-label"
- htmlFor="isAllGroupMembershipRequiredForPageCompleteDeletionCheckbox"
- >
- {t(
- 'security_settings.is_all_group_membership_required_for_page_complete_deletion',
- )}
- </label>
- <p className="form-text text-muted small mt-2">
- {t(
- 'security_settings.is_all_group_membership_required_for_page_complete_deletion_explanation',
- )}
- </p>
- </>
- )}
- </>
- ) : (
- <>
- <button
- type="button"
- className="btn btn-link p-0 mb-4"
- aria-expanded="false"
- onClick={() =>
- setExpandOtherDeleteOptionsState(
- deletionType,
- !expandDeleteOptions,
- )
- }
- >
- <span
- className={`material-symbols-outlined me-1 ${expandDeleteOptions ? 'rotate-90' : ''}`}
- >
- navigate_next
- </span>
- {t('security_settings.other_options')}
- </button>
- <Collapse isOpen={expandDeleteOptions}>
- <div className="pb-4">
- <p className="card custom-card bg-warning-sublte">
- <span className="text-warning">
- <span className="material-symbols-outlined">info</span>
- <span
- // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
- dangerouslySetInnerHTML={{
- __html: t(
- 'security_settings.page_delete_rights_caution',
- ),
- }}
- />
- </span>
- </p>
- {previousPageRecursiveAuthorityState(deletionType) !==
- null && (
- <div className="mb-3">
- <strong>
- {t('security_settings.forced_update_desc')}
- </strong>
- <code>
- {t(
- getDeleteConfigValueForT(
- previousPageRecursiveAuthorityState(deletionType),
- ),
- )}
- </code>
- </div>
- )}
- {renderPageDeletePermissionDropdown(
- currentState,
- setState,
- deletionType,
- isButtonDisabled,
- )}
- </div>
- </Collapse>
- </>
- )}
- </div>
- </div>
- );
- },
- [
- adminGeneralSecurityContainer,
- expandDeleteOptionsState,
- previousPageRecursiveAuthorityState,
- renderPageDeletePermissionDropdown,
- setExpandOtherDeleteOptionsState,
- t,
- ],
- );
- const isButtonDisabledForDeletion = !validateDeleteConfigs(
- currentPageDeletionAuthority,
- PageDeleteConfigValue.AdminAndAuthor,
- );
- const isButtonDisabledForCompleteDeletion = !validateDeleteConfigs(
- currentPageCompleteDeletionAuthority,
- PageDeleteConfigValue.AdminAndAuthor,
- );
- return (
- <>
- <h4 className="mb-3">{t('security_settings.page_delete_rights')}</h4>
- {[
- [
- currentPageDeletionAuthority,
- adminGeneralSecurityContainer.changePageDeletionAuthority,
- DeletionType.Deletion,
- false,
- ],
- [
- currentPageRecursiveDeletionAuthority,
- adminGeneralSecurityContainer.changePageRecursiveDeletionAuthority,
- DeletionType.RecursiveDeletion,
- isButtonDisabledForDeletion,
- ],
- ].map((arr) =>
- renderPageDeletePermission(
- arr[0] as IPageDeleteConfigValue,
- arr[1] as (value: IPageDeleteConfigValue) => void,
- arr[2] as DeletionTypeValue,
- arr[3] as boolean,
- ),
- )}
- {[
- [
- currentPageCompleteDeletionAuthority,
- adminGeneralSecurityContainer.changePageCompleteDeletionAuthority,
- DeletionType.CompleteDeletion,
- false,
- ],
- [
- currentPageRecursiveCompleteDeletionAuthority,
- adminGeneralSecurityContainer.changePageRecursiveCompleteDeletionAuthority,
- DeletionType.RecursiveCompleteDeletion,
- isButtonDisabledForCompleteDeletion,
- ],
- ].map((arr) =>
- renderPageDeletePermission(
- arr[0] as IPageDeleteConfigValue,
- arr[1] as (value: IPageDeleteConfigValue) => void,
- arr[2] as DeletionTypeValue,
- arr[3] as boolean,
- ),
- )}
- </>
- );
- };
|