[fix] Users with readOnly permissions should not be able to edit richtext fields (#10959)
Before <img width="1024" alt="Screenshot 2025-03-17 at 17 46 34" src="https://github.com/user-attachments/assets/c754adfb-4197-4be8-95dc-2f2024ed8a5c" /> After <img width="954" alt="Screenshot 2025-03-17 at 17 46 20" src="https://github.com/user-attachments/assets/e6063990-5d30-416f-9d16-2974d8d1d831" />
This commit is contained in:
@ -8,14 +8,18 @@ import { useUploadAttachmentFile } from '@/activities/files/hooks/useUploadAttac
|
|||||||
import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity';
|
import { useUpsertActivity } from '@/activities/hooks/useUpsertActivity';
|
||||||
import { canCreateActivityState } from '@/activities/states/canCreateActivityState';
|
import { canCreateActivityState } from '@/activities/states/canCreateActivityState';
|
||||||
import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope';
|
import { ActivityEditorHotkeyScope } from '@/activities/types/ActivityEditorHotkeyScope';
|
||||||
|
import { contextStoreCurrentViewTypeComponentState } from '@/context-store/states/contextStoreCurrentViewTypeComponentState';
|
||||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { modifyRecordFromCache } from '@/object-record/cache/utils/modifyRecordFromCache';
|
import { modifyRecordFromCache } from '@/object-record/cache/utils/modifyRecordFromCache';
|
||||||
|
import { isFieldValueReadOnly } from '@/object-record/record-field/utils/isFieldValueReadOnly';
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
|
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
|
||||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
||||||
import { isNonTextWritingKey } from '@/ui/utilities/hotkey/utils/isNonTextWritingKey';
|
import { isNonTextWritingKey } from '@/ui/utilities/hotkey/utils/isNonTextWritingKey';
|
||||||
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
import { useDebouncedCallback } from 'use-debounce';
|
import { useDebouncedCallback } from 'use-debounce';
|
||||||
@ -52,6 +56,19 @@ export const ActivityRichTextEditor = ({
|
|||||||
objectNameSingular: activityObjectNameSingular,
|
objectNameSingular: activityObjectNameSingular,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const contextStoreCurrentViewType = useRecoilComponentValueV2(
|
||||||
|
contextStoreCurrentViewTypeComponentState,
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasObjectReadOnlyPermission = useHasObjectReadOnlyPermission();
|
||||||
|
|
||||||
|
const isReadOnly = isFieldValueReadOnly({
|
||||||
|
objectNameSingular: activityObjectNameSingular,
|
||||||
|
hasObjectReadOnlyPermission,
|
||||||
|
contextStoreCurrentViewType,
|
||||||
|
isRecordDeleted: activityInStore?.deletedAt !== null,
|
||||||
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
goBackToPreviousHotkeyScope,
|
goBackToPreviousHotkeyScope,
|
||||||
setHotkeyScopeAndMemorizePreviousScope,
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
@ -62,6 +79,8 @@ export const ActivityRichTextEditor = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const persistBodyDebounced = useDebouncedCallback((blocknote: string) => {
|
const persistBodyDebounced = useDebouncedCallback((blocknote: string) => {
|
||||||
|
if (isReadOnly) return;
|
||||||
|
|
||||||
const input = {
|
const input = {
|
||||||
bodyV2: {
|
bodyV2: {
|
||||||
blocknote,
|
blocknote,
|
||||||
@ -301,6 +320,7 @@ export const ActivityRichTextEditor = ({
|
|||||||
onBlur={handlerBlockEditorBlur}
|
onBlur={handlerBlockEditorBlur}
|
||||||
onChange={handleEditorChange}
|
onChange={handleEditorChange}
|
||||||
editor={editor}
|
editor={editor}
|
||||||
|
readonly={isReadOnly}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -51,6 +51,11 @@ export const ShowPageActivityContainer = ({
|
|||||||
isNewViewableRecordLoadingState,
|
isNewViewableRecordLoadingState,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const activityObjectNameSingular =
|
||||||
|
targetableObject.targetObjectNameSingular as
|
||||||
|
| CoreObjectNameSingular.Note
|
||||||
|
| CoreObjectNameSingular.Task;
|
||||||
|
|
||||||
return !isNewViewableRecordLoading ? (
|
return !isNewViewableRecordLoading ? (
|
||||||
<ScrollWrapper
|
<ScrollWrapper
|
||||||
contextProviderName="showPageActivityContainer"
|
contextProviderName="showPageActivityContainer"
|
||||||
@ -60,11 +65,7 @@ export const ShowPageActivityContainer = ({
|
|||||||
<Suspense fallback={<LoadingSkeleton />}>
|
<Suspense fallback={<LoadingSkeleton />}>
|
||||||
<ActivityRichTextEditor
|
<ActivityRichTextEditor
|
||||||
activityId={targetableObject.id}
|
activityId={targetableObject.id}
|
||||||
activityObjectNameSingular={
|
activityObjectNameSingular={activityObjectNameSingular}
|
||||||
targetableObject.targetObjectNameSingular as
|
|
||||||
| CoreObjectNameSingular.Note
|
|
||||||
| CoreObjectNameSingular.Task
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</StyledShowPageActivityContainer>
|
</StyledShowPageActivityContainer>
|
||||||
|
|||||||
Reference in New Issue
Block a user