mirror of
https://github.com/inventree/InvenTree.git
synced 2026-09-02 18:28:38 +00:00
edit / delete existing notes from the UI
This commit is contained in:
@@ -865,7 +865,8 @@ class NoteList(NoteMixin, ListCreateAPI):
|
|||||||
filter_backends = SEARCH_ORDER_FILTER
|
filter_backends = SEARCH_ORDER_FILTER
|
||||||
filterset_class = NoteFilter
|
filterset_class = NoteFilter
|
||||||
|
|
||||||
ordering_fields = ['model_id', 'model_type', 'user', 'creation']
|
ordering = '-primary'
|
||||||
|
ordering_fields = ['model_id', 'model_type', 'user', 'creation', 'primary']
|
||||||
search_fields = ['content', 'model_id', 'model_type', 'user__username']
|
search_fields = ['content', 'model_id', 'model_type', 'user__username']
|
||||||
unique_create_fields = ['model_type', 'model_id']
|
unique_create_fields = ['model_type', 'model_id']
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ import { useCreateBlockNote } from '@blocknote/react';
|
|||||||
import {
|
import {
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
Alert,
|
Alert,
|
||||||
|
Badge,
|
||||||
Box,
|
Box,
|
||||||
|
Button,
|
||||||
Flex,
|
Flex,
|
||||||
Group,
|
Group,
|
||||||
Paper,
|
Paper,
|
||||||
@@ -30,11 +32,21 @@ import {
|
|||||||
IconCirclePlus,
|
IconCirclePlus,
|
||||||
IconDeviceFloppy,
|
IconDeviceFloppy,
|
||||||
IconInfoCircle,
|
IconInfoCircle,
|
||||||
IconReload
|
IconReload,
|
||||||
|
IconStar
|
||||||
} from '@tabler/icons-react';
|
} from '@tabler/icons-react';
|
||||||
import { useNoteFields } from '../../forms/CommonForms';
|
import { useNoteFields } from '../../forms/CommonForms';
|
||||||
import { useCreateApiFormModal } from '../../hooks/UseForm';
|
import {
|
||||||
|
useCreateApiFormModal,
|
||||||
|
useDeleteApiFormModal,
|
||||||
|
useEditApiFormModal
|
||||||
|
} from '../../hooks/UseForm';
|
||||||
import { useUserState } from '../../states/UserState';
|
import { useUserState } from '../../states/UserState';
|
||||||
|
import {
|
||||||
|
DeleteItemAction,
|
||||||
|
EditItemAction,
|
||||||
|
OptionsActionDropdown
|
||||||
|
} from '../items/ActionDropdown';
|
||||||
|
|
||||||
export default function NotesEditor({
|
export default function NotesEditor({
|
||||||
modelType,
|
modelType,
|
||||||
@@ -91,10 +103,10 @@ export default function NotesEditor({
|
|||||||
|
|
||||||
if (blocks) {
|
if (blocks) {
|
||||||
editor.replaceBlocks(editor.document, blocks);
|
editor.replaceBlocks(editor.document, blocks);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
editor.replaceBlocks(editor.document, []);
|
editor.replaceBlocks(editor.document, []);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setIsDirty(false);
|
setIsDirty(false);
|
||||||
},
|
},
|
||||||
@@ -147,6 +159,29 @@ export default function NotesEditor({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const deleteNote = useDeleteApiFormModal({
|
||||||
|
title: t`Delete Note`,
|
||||||
|
url: apiUrl(ApiEndpoints.note_list),
|
||||||
|
pk: selectedNote,
|
||||||
|
onFormSuccess: () => {
|
||||||
|
setSelectedNote(undefined);
|
||||||
|
notesQuery.refetch();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const editNote = useEditApiFormModal({
|
||||||
|
title: t`Edit Note`,
|
||||||
|
fields: noteFields,
|
||||||
|
url: apiUrl(ApiEndpoints.note_list),
|
||||||
|
pk: selectedNote,
|
||||||
|
onFormSuccess: (response: any) => {
|
||||||
|
notesQuery.refetch().then(() => {
|
||||||
|
// Select the updated note
|
||||||
|
setSelectedNote(response.pk);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const reloadNote = useCallback(() => {
|
const reloadNote = useCallback(() => {
|
||||||
loadNote(selectedNote ?? -1);
|
loadNote(selectedNote ?? -1);
|
||||||
}, [selectedNote, loadNote]);
|
}, [selectedNote, loadNote]);
|
||||||
@@ -199,9 +234,74 @@ export default function NotesEditor({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{createNote.modal}
|
{createNote.modal}
|
||||||
|
{deleteNote.modal}
|
||||||
|
{editNote.modal}
|
||||||
<Flex align='left'>
|
<Flex align='left'>
|
||||||
<Box style={{ flex: 1 }}>
|
<Box style={{ flex: 1 }} p='sm'>
|
||||||
<Paper p='sm' shadow='sm' withBorder>
|
<Stack gap='xs'>
|
||||||
|
{selectedNote && (
|
||||||
|
<Paper p='xs' shadow='sm' withBorder>
|
||||||
|
<Group justify='space-between'>
|
||||||
|
<Group justify='left' gap='lg'>
|
||||||
|
<Text>Note Title Here</Text>
|
||||||
|
<Text size='sm'>Note description here</Text>
|
||||||
|
</Group>
|
||||||
|
{canEdit && (
|
||||||
|
<Group justify='right' gap='xs'>
|
||||||
|
{isDirty && (
|
||||||
|
<Badge color='yellow'>{t`Unsaved Changes`}</Badge>
|
||||||
|
)}
|
||||||
|
{isDirty && (
|
||||||
|
<Tooltip label={t`Save Notes (Ctrl+S)`}>
|
||||||
|
<ActionIcon
|
||||||
|
variant='transparent'
|
||||||
|
color={isDirty ? 'yellow' : undefined}
|
||||||
|
onClick={saveNote}
|
||||||
|
disabled={!canEdit || !isDirty}
|
||||||
|
>
|
||||||
|
<IconDeviceFloppy />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
{isDirty && (
|
||||||
|
<Tooltip label={t`Reset Notes`}>
|
||||||
|
<ActionIcon
|
||||||
|
variant='transparent'
|
||||||
|
color='red'
|
||||||
|
onClick={reloadNote}
|
||||||
|
disabled={!canEdit || !isDirty}
|
||||||
|
>
|
||||||
|
<IconReload />
|
||||||
|
</ActionIcon>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
<OptionsActionDropdown
|
||||||
|
tooltip={t`Note Actions`}
|
||||||
|
actions={[
|
||||||
|
EditItemAction({
|
||||||
|
hidden:
|
||||||
|
!selectedNote ||
|
||||||
|
!user.hasChangePermission(modelType),
|
||||||
|
onClick: () => {
|
||||||
|
editNote.open();
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
DeleteItemAction({
|
||||||
|
hidden:
|
||||||
|
!selectedNote ||
|
||||||
|
!user.hasDeletePermission(modelType),
|
||||||
|
onClick: () => {
|
||||||
|
deleteNote.open();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
)}
|
||||||
|
</Group>
|
||||||
|
</Paper>
|
||||||
|
)}
|
||||||
|
<Paper p='xs' shadow='sm' withBorder>
|
||||||
{hasNotes ? (
|
{hasNotes ? (
|
||||||
<Stack gap='xs'>
|
<Stack gap='xs'>
|
||||||
<BlockNoteView
|
<BlockNoteView
|
||||||
@@ -216,43 +316,19 @@ export default function NotesEditor({
|
|||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
</Paper>
|
</Paper>
|
||||||
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
<Paper p='sm' shadow='sm' withBorder ml='md' style={{ width: '200px' }}>
|
<Paper p='sm' shadow='sm' withBorder ml='md' style={{ width: '200px' }}>
|
||||||
<Stack gap='xs'>
|
<Stack gap='xs'>
|
||||||
{canEdit && (
|
<Button
|
||||||
<Group justify='space-apart' grow>
|
|
||||||
<Tooltip label={t`Save Notes (Ctrl+S)`}>
|
|
||||||
<ActionIcon
|
|
||||||
variant='transparent'
|
|
||||||
color={isDirty ? 'yellow' : undefined}
|
|
||||||
onClick={saveNote}
|
|
||||||
disabled={!canEdit || !isDirty}
|
|
||||||
>
|
|
||||||
<IconDeviceFloppy />
|
|
||||||
</ActionIcon>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip label={t`Reset Notes`}>
|
|
||||||
<ActionIcon
|
|
||||||
variant='transparent'
|
|
||||||
color='red'
|
|
||||||
onClick={reloadNote}
|
|
||||||
disabled={!canEdit || !isDirty}
|
|
||||||
>
|
|
||||||
<IconReload />
|
|
||||||
</ActionIcon>
|
|
||||||
</Tooltip>
|
|
||||||
<Tooltip label={t`New Note`}>
|
|
||||||
<ActionIcon
|
|
||||||
variant='transparent'
|
|
||||||
color='green'
|
color='green'
|
||||||
|
leftSection={<IconCirclePlus />}
|
||||||
onClick={createNote.open}
|
onClick={createNote.open}
|
||||||
disabled={!canEdit || isDirty}
|
disabled={!canEdit || isDirty}
|
||||||
>
|
>
|
||||||
<IconCirclePlus />
|
{t`Add Note`}
|
||||||
</ActionIcon>
|
</Button>
|
||||||
</Tooltip>
|
|
||||||
</Group>
|
|
||||||
)}
|
|
||||||
<Tabs
|
<Tabs
|
||||||
orientation='vertical'
|
orientation='vertical'
|
||||||
placement='right'
|
placement='right'
|
||||||
@@ -266,8 +342,17 @@ export default function NotesEditor({
|
|||||||
value={note.pk?.toString()}
|
value={note.pk?.toString()}
|
||||||
onClick={() => setSelectedNote(note.pk)}
|
onClick={() => setSelectedNote(note.pk)}
|
||||||
>
|
>
|
||||||
<Group gap='xs' wrap='nowrap'>
|
<Group gap='xs' wrap='nowrap' justify='space-between'>
|
||||||
<Text size='sm'>{note.title}</Text>
|
<Text size='sm'>{note.title}</Text>
|
||||||
|
{note.primary && (
|
||||||
|
<ActionIcon
|
||||||
|
size='xs'
|
||||||
|
color='yellow'
|
||||||
|
variant='transparent'
|
||||||
|
>
|
||||||
|
<IconStar />
|
||||||
|
</ActionIcon>
|
||||||
|
)}
|
||||||
</Group>
|
</Group>
|
||||||
</Tabs.Tab>
|
</Tabs.Tab>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -302,7 +302,8 @@ export function useNoteFields({
|
|||||||
value: modelId
|
value: modelId
|
||||||
},
|
},
|
||||||
title: {},
|
title: {},
|
||||||
description: {}
|
description: {},
|
||||||
|
primary: {}
|
||||||
};
|
};
|
||||||
}, [modelType, modelId]);
|
}, [modelType, modelId]);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user