mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-17 00:24:43 -04:00
feat(frontend): deactivate permissions buttons if user is not owner
These buttons and their functionality only work if the user is the owner, so it doesn't make sense to make it possible to press them otherwise… Signed-off-by: Philip Molares <philip.molares@udo.edu>
This commit is contained in:
parent
09e56a418e
commit
e7e81cf670
10 changed files with 107 additions and 28 deletions
|
@ -1,10 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { useOnInputChange } from '../../../../hooks/common/use-on-input-change'
|
import { useOnInputChange } from '../../../../hooks/common/use-on-input-change'
|
||||||
import { UiIcon } from '../../../common/icons/ui-icon'
|
import { UiIcon } from '../../../common/icons/ui-icon'
|
||||||
|
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import { Button, FormControl, InputGroup } from 'react-bootstrap'
|
import { Button, FormControl, InputGroup } from 'react-bootstrap'
|
||||||
import { Plus as IconPlus } from 'react-bootstrap-icons'
|
import { Plus as IconPlus } from 'react-bootstrap-icons'
|
||||||
|
@ -20,8 +21,13 @@ export interface PermissionAddEntryFieldProps {
|
||||||
*
|
*
|
||||||
* @param onAddEntry Callback that is fired with the entered username as identifier of the entry to add.
|
* @param onAddEntry Callback that is fired with the entered username as identifier of the entry to add.
|
||||||
* @param i18nKey The localization key for the submit button.
|
* @param i18nKey The localization key for the submit button.
|
||||||
|
* @param disabled If the user is not the owner, functionality is disabled.
|
||||||
*/
|
*/
|
||||||
export const PermissionAddEntryField: React.FC<PermissionAddEntryFieldProps> = ({ onAddEntry, i18nKey }) => {
|
export const PermissionAddEntryField: React.FC<PermissionAddEntryFieldProps & PermissionDisabledProps> = ({
|
||||||
|
onAddEntry,
|
||||||
|
i18nKey,
|
||||||
|
disabled
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const [newEntryIdentifier, setNewEntryIdentifier] = useState('')
|
const [newEntryIdentifier, setNewEntryIdentifier] = useState('')
|
||||||
|
@ -34,8 +40,18 @@ export const PermissionAddEntryField: React.FC<PermissionAddEntryFieldProps> = (
|
||||||
return (
|
return (
|
||||||
<li className={'list-group-item'}>
|
<li className={'list-group-item'}>
|
||||||
<InputGroup className={'me-1 mb-1'}>
|
<InputGroup className={'me-1 mb-1'}>
|
||||||
<FormControl value={newEntryIdentifier} placeholder={t(i18nKey) ?? undefined} onChange={onChange} />
|
<FormControl
|
||||||
<Button variant='light' className={'text-secondary ms-2'} title={t(i18nKey) ?? undefined} onClick={onSubmit}>
|
value={newEntryIdentifier}
|
||||||
|
placeholder={t(i18nKey) ?? undefined}
|
||||||
|
onChange={onChange}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
variant='light'
|
||||||
|
className={'text-secondary ms-2'}
|
||||||
|
title={t(i18nKey) ?? undefined}
|
||||||
|
onClick={onSubmit}
|
||||||
|
disabled={disabled}>
|
||||||
<UiIcon icon={IconPlus} />
|
<UiIcon icon={IconPlus} />
|
||||||
</Button>
|
</Button>
|
||||||
</InputGroup>
|
</InputGroup>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface PermissionDisabledProps {
|
||||||
|
disabled: boolean
|
||||||
|
}
|
|
@ -1,9 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { UiIcon } from '../../../common/icons/ui-icon'
|
import { UiIcon } from '../../../common/icons/ui-icon'
|
||||||
|
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||||
import { AccessLevel } from './types'
|
import { AccessLevel } from './types'
|
||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import { Button, ToggleButtonGroup } from 'react-bootstrap'
|
import { Button, ToggleButtonGroup } from 'react-bootstrap'
|
||||||
|
@ -41,14 +42,16 @@ export interface PermissionEntryButtonsProps {
|
||||||
* @param onSetReadOnly Callback that is fired when the entry is changed to read-only permission.
|
* @param onSetReadOnly Callback that is fired when the entry is changed to read-only permission.
|
||||||
* @param onSetWriteable Callback that is fired when the entry is changed to writeable permission.
|
* @param onSetWriteable Callback that is fired when the entry is changed to writeable permission.
|
||||||
* @param onRemove Callback that is fired when the entry is removed.
|
* @param onRemove Callback that is fired when the entry is removed.
|
||||||
|
* @param disabled If the user is not the owner, functionality is disabled.
|
||||||
*/
|
*/
|
||||||
export const PermissionEntryButtons: React.FC<PermissionEntryButtonsProps> = ({
|
export const PermissionEntryButtons: React.FC<PermissionEntryButtonsProps & PermissionDisabledProps> = ({
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
currentSetting,
|
currentSetting,
|
||||||
onSetReadOnly,
|
onSetReadOnly,
|
||||||
onSetWriteable,
|
onSetWriteable,
|
||||||
onRemove
|
onRemove,
|
||||||
|
disabled
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
@ -74,18 +77,21 @@ export const PermissionEntryButtons: React.FC<PermissionEntryButtonsProps> = ({
|
||||||
<Button
|
<Button
|
||||||
variant='light'
|
variant='light'
|
||||||
className={'text-danger me-2'}
|
className={'text-danger me-2'}
|
||||||
|
disabled={disabled}
|
||||||
title={t(i18nKeys.remove, { name }) ?? undefined}
|
title={t(i18nKeys.remove, { name }) ?? undefined}
|
||||||
onClick={onRemove}>
|
onClick={onRemove}>
|
||||||
<UiIcon icon={IconX} />
|
<UiIcon icon={IconX} />
|
||||||
</Button>
|
</Button>
|
||||||
<ToggleButtonGroup type='radio' name='edit-mode' value={currentSetting}>
|
<ToggleButtonGroup type='radio' name='edit-mode' value={currentSetting}>
|
||||||
<Button
|
<Button
|
||||||
|
disabled={disabled}
|
||||||
title={t(i18nKeys.setReadOnly, { name }) ?? undefined}
|
title={t(i18nKeys.setReadOnly, { name }) ?? undefined}
|
||||||
variant={currentSetting === AccessLevel.READ_ONLY ? 'secondary' : 'outline-secondary'}
|
variant={currentSetting === AccessLevel.READ_ONLY ? 'secondary' : 'outline-secondary'}
|
||||||
onClick={onSetReadOnly}>
|
onClick={onSetReadOnly}>
|
||||||
<UiIcon icon={IconEye} />
|
<UiIcon icon={IconEye} />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
disabled={disabled}
|
||||||
title={t(i18nKeys.setWriteable, { name }) ?? undefined}
|
title={t(i18nKeys.setWriteable, { name }) ?? undefined}
|
||||||
variant={currentSetting === AccessLevel.WRITEABLE ? 'secondary' : 'outline-secondary'}
|
variant={currentSetting === AccessLevel.WRITEABLE ? 'secondary' : 'outline-secondary'}
|
||||||
onClick={onSetWriteable}>
|
onClick={onSetWriteable}>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
@ -8,6 +8,7 @@ import { useApplicationState } from '../../../../hooks/common/use-application-st
|
||||||
import { setNotePermissionsFromServer } from '../../../../redux/note-details/methods'
|
import { setNotePermissionsFromServer } from '../../../../redux/note-details/methods'
|
||||||
import { IconButton } from '../../../common/icon-button/icon-button'
|
import { IconButton } from '../../../common/icon-button/icon-button'
|
||||||
import { useUiNotifications } from '../../../notifications/ui-notification-boundary'
|
import { useUiNotifications } from '../../../notifications/ui-notification-boundary'
|
||||||
|
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||||
import { AccessLevel, SpecialGroup } from './types'
|
import { AccessLevel, SpecialGroup } from './types'
|
||||||
import React, { useCallback, useMemo } from 'react'
|
import React, { useCallback, useMemo } from 'react'
|
||||||
import { ToggleButtonGroup } from 'react-bootstrap'
|
import { ToggleButtonGroup } from 'react-bootstrap'
|
||||||
|
@ -26,8 +27,13 @@ export interface PermissionEntrySpecialGroupProps {
|
||||||
*
|
*
|
||||||
* @param level The access level that is currently set for the group.
|
* @param level The access level that is currently set for the group.
|
||||||
* @param type The type of the special group. Must be either {@link SpecialGroup.EVERYONE} or {@link SpecialGroup.LOGGED_IN}.
|
* @param type The type of the special group. Must be either {@link SpecialGroup.EVERYONE} or {@link SpecialGroup.LOGGED_IN}.
|
||||||
|
* @param disabled If the user is not the owner, functionality is disabled.
|
||||||
*/
|
*/
|
||||||
export const PermissionEntrySpecialGroup: React.FC<PermissionEntrySpecialGroupProps> = ({ level, type }) => {
|
export const PermissionEntrySpecialGroup: React.FC<PermissionEntrySpecialGroupProps & PermissionDisabledProps> = ({
|
||||||
|
level,
|
||||||
|
type,
|
||||||
|
disabled
|
||||||
|
}) => {
|
||||||
const noteId = useApplicationState((state) => state.noteDetails.primaryAddress)
|
const noteId = useApplicationState((state) => state.noteDetails.primaryAddress)
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { showErrorNotification } = useUiNotifications()
|
const { showErrorNotification } = useUiNotifications()
|
||||||
|
@ -75,6 +81,7 @@ export const PermissionEntrySpecialGroup: React.FC<PermissionEntrySpecialGroupPr
|
||||||
title={t('editor.modal.permissions.denyGroup', { name }) ?? undefined}
|
title={t('editor.modal.permissions.denyGroup', { name }) ?? undefined}
|
||||||
variant={level === AccessLevel.NONE ? 'secondary' : 'outline-secondary'}
|
variant={level === AccessLevel.NONE ? 'secondary' : 'outline-secondary'}
|
||||||
onClick={onSetEntryDenied}
|
onClick={onSetEntryDenied}
|
||||||
|
disabled={disabled}
|
||||||
className={'p-1'}
|
className={'p-1'}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
@ -82,6 +89,7 @@ export const PermissionEntrySpecialGroup: React.FC<PermissionEntrySpecialGroupPr
|
||||||
title={t('editor.modal.permissions.viewOnlyGroup', { name }) ?? undefined}
|
title={t('editor.modal.permissions.viewOnlyGroup', { name }) ?? undefined}
|
||||||
variant={level === AccessLevel.READ_ONLY ? 'secondary' : 'outline-secondary'}
|
variant={level === AccessLevel.READ_ONLY ? 'secondary' : 'outline-secondary'}
|
||||||
onClick={onSetEntryReadOnly}
|
onClick={onSetEntryReadOnly}
|
||||||
|
disabled={disabled}
|
||||||
className={'p-1'}
|
className={'p-1'}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
@ -89,6 +97,7 @@ export const PermissionEntrySpecialGroup: React.FC<PermissionEntrySpecialGroupPr
|
||||||
title={t('editor.modal.permissions.editGroup', { name }) ?? undefined}
|
title={t('editor.modal.permissions.editGroup', { name }) ?? undefined}
|
||||||
variant={level === AccessLevel.WRITEABLE ? 'secondary' : 'outline-secondary'}
|
variant={level === AccessLevel.WRITEABLE ? 'secondary' : 'outline-secondary'}
|
||||||
onClick={onSetEntryWriteable}
|
onClick={onSetEntryWriteable}
|
||||||
|
disabled={disabled}
|
||||||
className={'p-1'}
|
className={'p-1'}
|
||||||
/>
|
/>
|
||||||
</ToggleButtonGroup>
|
</ToggleButtonGroup>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
@ -11,6 +11,7 @@ import { setNotePermissionsFromServer } from '../../../../redux/note-details/met
|
||||||
import { ShowIf } from '../../../common/show-if/show-if'
|
import { ShowIf } from '../../../common/show-if/show-if'
|
||||||
import { UserAvatarForUser } from '../../../common/user-avatar/user-avatar-for-user'
|
import { UserAvatarForUser } from '../../../common/user-avatar/user-avatar-for-user'
|
||||||
import { useUiNotifications } from '../../../notifications/ui-notification-boundary'
|
import { useUiNotifications } from '../../../notifications/ui-notification-boundary'
|
||||||
|
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||||
import { PermissionEntryButtons, PermissionType } from './permission-entry-buttons'
|
import { PermissionEntryButtons, PermissionType } from './permission-entry-buttons'
|
||||||
import { AccessLevel } from './types'
|
import { AccessLevel } from './types'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
@ -24,8 +25,12 @@ export interface PermissionEntryUserProps {
|
||||||
* Permission entry for a user that can be set to read-only or writeable and can be removed.
|
* Permission entry for a user that can be set to read-only or writeable and can be removed.
|
||||||
*
|
*
|
||||||
* @param entry The permission entry.
|
* @param entry The permission entry.
|
||||||
|
* @param disabled If the user is not the owner, functionality is disabled.
|
||||||
*/
|
*/
|
||||||
export const PermissionEntryUser: React.FC<PermissionEntryUserProps> = ({ entry }) => {
|
export const PermissionEntryUser: React.FC<PermissionEntryUserProps & PermissionDisabledProps> = ({
|
||||||
|
entry,
|
||||||
|
disabled
|
||||||
|
}) => {
|
||||||
const noteId = useApplicationState((state) => state.noteDetails.primaryAddress)
|
const noteId = useApplicationState((state) => state.noteDetails.primaryAddress)
|
||||||
const { showErrorNotification } = useUiNotifications()
|
const { showErrorNotification } = useUiNotifications()
|
||||||
|
|
||||||
|
@ -72,6 +77,7 @@ export const PermissionEntryUser: React.FC<PermissionEntryUserProps> = ({ entry
|
||||||
onSetReadOnly={onSetEntryReadOnly}
|
onSetReadOnly={onSetEntryReadOnly}
|
||||||
onSetWriteable={onSetEntryWriteable}
|
onSetWriteable={onSetEntryWriteable}
|
||||||
onRemove={onRemoveEntry}
|
onRemove={onRemoveEntry}
|
||||||
|
disabled={disabled}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
</ShowIf>
|
</ShowIf>
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
import { useIsOwner } from '../../../../hooks/common/use-is-owner'
|
||||||
import type { ModalVisibilityProps } from '../../../common/modals/common-modal'
|
import type { ModalVisibilityProps } from '../../../common/modals/common-modal'
|
||||||
import { CommonModal } from '../../../common/modals/common-modal'
|
import { CommonModal } from '../../../common/modals/common-modal'
|
||||||
import { PermissionSectionOwner } from './permission-section-owner'
|
import { PermissionSectionOwner } from './permission-section-owner'
|
||||||
|
@ -18,12 +19,13 @@ import { Modal } from 'react-bootstrap'
|
||||||
* @param onHide Callback that is fired when the modal is about to be closed.
|
* @param onHide Callback that is fired when the modal is about to be closed.
|
||||||
*/
|
*/
|
||||||
export const PermissionModal: React.FC<ModalVisibilityProps> = ({ show, onHide }) => {
|
export const PermissionModal: React.FC<ModalVisibilityProps> = ({ show, onHide }) => {
|
||||||
|
const isOwner = useIsOwner()
|
||||||
return (
|
return (
|
||||||
<CommonModal show={show} onHide={onHide} showCloseButton={true} titleI18nKey={'editor.modal.permissions.title'}>
|
<CommonModal show={show} onHide={onHide} showCloseButton={true} titleI18nKey={'editor.modal.permissions.title'}>
|
||||||
<Modal.Body>
|
<Modal.Body>
|
||||||
<PermissionSectionOwner />
|
<PermissionSectionOwner disabled={!isOwner} />
|
||||||
<PermissionSectionUsers />
|
<PermissionSectionUsers disabled={!isOwner} />
|
||||||
<PermissionSectionSpecialGroups />
|
<PermissionSectionSpecialGroups disabled={!isOwner} />
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
</CommonModal>
|
</CommonModal>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
||||||
import { UiIcon } from '../../../common/icons/ui-icon'
|
import { UiIcon } from '../../../common/icons/ui-icon'
|
||||||
import { UserAvatarForUsername } from '../../../common/user-avatar/user-avatar-for-username'
|
import { UserAvatarForUsername } from '../../../common/user-avatar/user-avatar-for-username'
|
||||||
|
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||||
import React, { Fragment } from 'react'
|
import React, { Fragment } from 'react'
|
||||||
import { Button } from 'react-bootstrap'
|
import { Button } from 'react-bootstrap'
|
||||||
import { Pencil as IconPencil } from 'react-bootstrap-icons'
|
import { Pencil as IconPencil } from 'react-bootstrap-icons'
|
||||||
|
@ -19,8 +20,12 @@ export interface PermissionOwnerInfoProps {
|
||||||
* Content for the owner section of the permission modal that shows the current note owner.
|
* Content for the owner section of the permission modal that shows the current note owner.
|
||||||
*
|
*
|
||||||
* @param onEditOwner Callback that is fired when the user chooses to change the note owner.
|
* @param onEditOwner Callback that is fired when the user chooses to change the note owner.
|
||||||
|
* @param disabled If the user is not the owner, functionality is disabled.
|
||||||
*/
|
*/
|
||||||
export const PermissionOwnerInfo: React.FC<PermissionOwnerInfoProps> = ({ onEditOwner }) => {
|
export const PermissionOwnerInfo: React.FC<PermissionOwnerInfoProps & PermissionDisabledProps> = ({
|
||||||
|
onEditOwner,
|
||||||
|
disabled
|
||||||
|
}) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const noteOwner = useApplicationState((state) => state.noteDetails.permissions.owner)
|
const noteOwner = useApplicationState((state) => state.noteDetails.permissions.owner)
|
||||||
|
|
||||||
|
@ -29,6 +34,7 @@ export const PermissionOwnerInfo: React.FC<PermissionOwnerInfoProps> = ({ onEdit
|
||||||
<UserAvatarForUsername username={noteOwner} />
|
<UserAvatarForUsername username={noteOwner} />
|
||||||
<Button
|
<Button
|
||||||
variant='light'
|
variant='light'
|
||||||
|
disabled={disabled}
|
||||||
title={t('editor.modal.permissions.ownerChange.button') ?? undefined}
|
title={t('editor.modal.permissions.ownerChange.button') ?? undefined}
|
||||||
onClick={onEditOwner}>
|
onClick={onEditOwner}>
|
||||||
<UiIcon icon={IconPencil} />
|
<UiIcon icon={IconPencil} />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
@ -7,6 +7,7 @@ import { setNoteOwner } from '../../../../api/permissions'
|
||||||
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
||||||
import { setNotePermissionsFromServer } from '../../../../redux/note-details/methods'
|
import { setNotePermissionsFromServer } from '../../../../redux/note-details/methods'
|
||||||
import { useUiNotifications } from '../../../notifications/ui-notification-boundary'
|
import { useUiNotifications } from '../../../notifications/ui-notification-boundary'
|
||||||
|
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||||
import { PermissionOwnerChange } from './permission-owner-change'
|
import { PermissionOwnerChange } from './permission-owner-change'
|
||||||
import { PermissionOwnerInfo } from './permission-owner-info'
|
import { PermissionOwnerInfo } from './permission-owner-info'
|
||||||
import React, { Fragment, useCallback, useState } from 'react'
|
import React, { Fragment, useCallback, useState } from 'react'
|
||||||
|
@ -14,8 +15,10 @@ import { Trans } from 'react-i18next'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Section in the permissions modal for managing the owner of a note.
|
* Section in the permissions modal for managing the owner of a note.
|
||||||
|
*
|
||||||
|
* @param disabled If the user is not the owner, functionality is disabled.
|
||||||
*/
|
*/
|
||||||
export const PermissionSectionOwner: React.FC = () => {
|
export const PermissionSectionOwner: React.FC<PermissionDisabledProps> = ({ disabled }) => {
|
||||||
const noteId = useApplicationState((state) => state.noteDetails.primaryAddress)
|
const noteId = useApplicationState((state) => state.noteDetails.primaryAddress)
|
||||||
const [changeOwner, setChangeOwner] = useState(false)
|
const [changeOwner, setChangeOwner] = useState(false)
|
||||||
const { showErrorNotification } = useUiNotifications()
|
const { showErrorNotification } = useUiNotifications()
|
||||||
|
@ -48,7 +51,7 @@ export const PermissionSectionOwner: React.FC = () => {
|
||||||
{changeOwner ? (
|
{changeOwner ? (
|
||||||
<PermissionOwnerChange onConfirmOwnerChange={onOwnerChange} />
|
<PermissionOwnerChange onConfirmOwnerChange={onOwnerChange} />
|
||||||
) : (
|
) : (
|
||||||
<PermissionOwnerInfo onEditOwner={onSetChangeOwner} />
|
<PermissionOwnerInfo onEditOwner={onSetChangeOwner} disabled={disabled} />
|
||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
import { useApplicationState } from '../../../../hooks/common/use-application-state'
|
||||||
|
import { useIsOwner } from '../../../../hooks/common/use-is-owner'
|
||||||
|
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||||
import { PermissionEntrySpecialGroup } from './permission-entry-special-group'
|
import { PermissionEntrySpecialGroup } from './permission-entry-special-group'
|
||||||
import { AccessLevel, SpecialGroup } from './types'
|
import { AccessLevel, SpecialGroup } from './types'
|
||||||
import React, { Fragment, useMemo } from 'react'
|
import React, { Fragment, useMemo } from 'react'
|
||||||
|
@ -11,10 +13,13 @@ import { Trans, useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Section of the permission modal for managing special group access to the note.
|
* Section of the permission modal for managing special group access to the note.
|
||||||
|
*
|
||||||
|
* @param disabled If the user is not the owner, functionality is disabled.
|
||||||
*/
|
*/
|
||||||
export const PermissionSectionSpecialGroups: React.FC = () => {
|
export const PermissionSectionSpecialGroups: React.FC<PermissionDisabledProps> = ({ disabled }) => {
|
||||||
useTranslation()
|
useTranslation()
|
||||||
const groupPermissions = useApplicationState((state) => state.noteDetails.permissions.sharedToGroups)
|
const groupPermissions = useApplicationState((state) => state.noteDetails.permissions.sharedToGroups)
|
||||||
|
const isOwner = useIsOwner()
|
||||||
|
|
||||||
const specialGroupEntries = useMemo(() => {
|
const specialGroupEntries = useMemo(() => {
|
||||||
const groupEveryone = groupPermissions.find((entry) => entry.groupName === SpecialGroup.EVERYONE)
|
const groupEveryone = groupPermissions.find((entry) => entry.groupName === SpecialGroup.EVERYONE)
|
||||||
|
@ -40,8 +45,16 @@ export const PermissionSectionSpecialGroups: React.FC = () => {
|
||||||
<Trans i18nKey={'editor.modal.permissions.sharedWithElse'} />
|
<Trans i18nKey={'editor.modal.permissions.sharedWithElse'} />
|
||||||
</h5>
|
</h5>
|
||||||
<ul className={'list-group'}>
|
<ul className={'list-group'}>
|
||||||
<PermissionEntrySpecialGroup level={specialGroupEntries.loggedIn} type={SpecialGroup.LOGGED_IN} />
|
<PermissionEntrySpecialGroup
|
||||||
<PermissionEntrySpecialGroup level={specialGroupEntries.everyone} type={SpecialGroup.EVERYONE} />
|
level={specialGroupEntries.loggedIn}
|
||||||
|
type={SpecialGroup.LOGGED_IN}
|
||||||
|
disabled={!isOwner}
|
||||||
|
/>
|
||||||
|
<PermissionEntrySpecialGroup
|
||||||
|
level={specialGroupEntries.everyone}
|
||||||
|
type={SpecialGroup.EVERYONE}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file)
|
* SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file)
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
@ -8,22 +8,27 @@ import { useApplicationState } from '../../../../hooks/common/use-application-st
|
||||||
import { setNotePermissionsFromServer } from '../../../../redux/note-details/methods'
|
import { setNotePermissionsFromServer } from '../../../../redux/note-details/methods'
|
||||||
import { useUiNotifications } from '../../../notifications/ui-notification-boundary'
|
import { useUiNotifications } from '../../../notifications/ui-notification-boundary'
|
||||||
import { PermissionAddEntryField } from './permission-add-entry-field'
|
import { PermissionAddEntryField } from './permission-add-entry-field'
|
||||||
|
import type { PermissionDisabledProps } from './permission-disabled.prop'
|
||||||
import { PermissionEntryUser } from './permission-entry-user'
|
import { PermissionEntryUser } from './permission-entry-user'
|
||||||
import React, { Fragment, useCallback, useMemo } from 'react'
|
import React, { Fragment, useCallback, useMemo } from 'react'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Section of the permission modal for managing user access to the note.
|
* Section of the permission modal for managing user access to the note.
|
||||||
|
*
|
||||||
|
* @param disabled If the user is not the owner, functionality is disabled.
|
||||||
*/
|
*/
|
||||||
export const PermissionSectionUsers: React.FC = () => {
|
export const PermissionSectionUsers: React.FC<PermissionDisabledProps> = ({ disabled }) => {
|
||||||
useTranslation()
|
useTranslation()
|
||||||
const userPermissions = useApplicationState((state) => state.noteDetails.permissions.sharedToUsers)
|
const userPermissions = useApplicationState((state) => state.noteDetails.permissions.sharedToUsers)
|
||||||
const noteId = useApplicationState((state) => state.noteDetails.primaryAddress)
|
const noteId = useApplicationState((state) => state.noteDetails.primaryAddress)
|
||||||
const { showErrorNotification } = useUiNotifications()
|
const { showErrorNotification } = useUiNotifications()
|
||||||
|
|
||||||
const userEntries = useMemo(() => {
|
const userEntries = useMemo(() => {
|
||||||
return userPermissions.map((entry) => <PermissionEntryUser key={entry.username} entry={entry} />)
|
return userPermissions.map((entry) => (
|
||||||
}, [userPermissions])
|
<PermissionEntryUser key={entry.username} entry={entry} disabled={disabled} />
|
||||||
|
))
|
||||||
|
}, [userPermissions, disabled])
|
||||||
|
|
||||||
const onAddEntry = useCallback(
|
const onAddEntry = useCallback(
|
||||||
(username: string) => {
|
(username: string) => {
|
||||||
|
@ -43,7 +48,11 @@ export const PermissionSectionUsers: React.FC = () => {
|
||||||
</h5>
|
</h5>
|
||||||
<ul className={'list-group'}>
|
<ul className={'list-group'}>
|
||||||
{userEntries}
|
{userEntries}
|
||||||
<PermissionAddEntryField onAddEntry={onAddEntry} i18nKey={'editor.modal.permissions.addUser'} />
|
<PermissionAddEntryField
|
||||||
|
onAddEntry={onAddEntry}
|
||||||
|
i18nKey={'editor.modal.permissions.addUser'}
|
||||||
|
disabled={disabled}
|
||||||
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue