Skip to content

Commit

Permalink
update document type (#489)
Browse files Browse the repository at this point in the history
  • Loading branch information
ciur authored Oct 16, 2024
1 parent db38866 commit f33e63b
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 62 deletions.
62 changes: 30 additions & 32 deletions papermerge/core/routers/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from celery.app import default_app as celery_app
from fastapi import APIRouter, Depends, HTTPException, Security, UploadFile
from pydantic import BaseModel
from sqlalchemy.exc import NoResultFound

from papermerge.conf import settings
Expand All @@ -18,6 +19,10 @@
)


class DocumentTypeArg(BaseModel):
document_type_id: uuid.UUID | None = None


@router.get("/type/{document_type_id}")
@utils.docstring_parameter(scope=scopes.NODE_VIEW)
def get_documents_by_type(
Expand Down Expand Up @@ -62,38 +67,6 @@ def get_document_details(
return doc


@router.post("/{document_id}/custom-fields")
@utils.docstring_parameter(scope=scopes.NODE_UPDATE)
def add_document_custom_field_values(
document_id: uuid.UUID,
custom_fields_add: schemas.DocumentCustomFieldsAdd,
user: Annotated[
schemas.User, Security(get_current_user, scopes=[scopes.NODE_UPDATE])
],
db_session: db.Session = Depends(db.get_session),
) -> list[schemas.CustomFieldValue]:
"""
Associates document type to specified `document_type_id` and set it custom field
value(s). This API will create a NEW custom field value
All custom fields must be part of `DocumentType` specified by `document_type_id`,
otherwise response will return error 400 - invalid request.
Required scope: `{scope}`
"""
try:
added_entries = db.add_document_custom_field_values(
db_session,
id=document_id,
custom_fields_add=custom_fields_add,
user_id=user.id,
)
except NoResultFound:
raise HTTPException(status_code=404, detail="Document not found")

return added_entries


@router.patch("/{document_id}/custom-fields")
@utils.docstring_parameter(scope=scopes.NODE_UPDATE)
def update_document_custom_field_values(
Expand Down Expand Up @@ -150,6 +123,31 @@ def get_document_custom_field_values(
return doc


@router.patch("/{document_id}/type")
@utils.docstring_parameter(scope=scopes.NODE_UPDATE)
def update_document_type(
document_id: uuid.UUID,
document_type: DocumentTypeArg,
user: Annotated[
schemas.User, Security(get_current_user, scopes=[scopes.NODE_VIEW])
],
db_session: db.Session = Depends(db.get_session),
):
"""
Updates document type
Required scope: `{scope}`
"""
try:
db.update_doc_type(
db_session,
document_id=document_id,
document_type_id=document_type.document_type_id,
)
except NoResultFound:
raise HTTPException(status_code=404, detail="Document not found")


@router.post("/{document_id}/upload")
@utils.docstring_parameter(scope=scopes.DOCUMENT_UPLOAD)
def upload_file(
Expand Down
2 changes: 1 addition & 1 deletion papermerge/core/schemas/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,6 @@ class DocumentCustomFieldsUpdateValue(BaseModel):


class DocumentCustomFieldsUpdate(BaseModel):
custom_field_value_id: UUID | None
custom_field_value_id: UUID | None = None
key: CFNameType
value: CFValueType
24 changes: 24 additions & 0 deletions ui2/src/features/document/apiSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ type GetDocsByTypeArgs = {
ancestor_id: string
}

type UpdateDocumentTypeArgs = {
document_id?: string
invalidatesTags: {
documentTypeID?: string
}
body: {
document_type_id: string | null
}
}

export const apiSliceWithDocuments = apiSlice.injectEndpoints({
endpoints: builder => ({
getDocument: builder.query<DocumentType, string>({
Expand Down Expand Up @@ -168,6 +178,19 @@ export const apiSliceWithDocuments = apiSlice.injectEndpoints({
]
}
}),
updateDocumentType: builder.mutation<void, UpdateDocumentTypeArgs>({
query: data => ({
url: `/documents/${data.document_id}/type`,
method: "PATCH",
body: data.body
}),
invalidatesTags: (_result, _error, arg) => {
return [
{type: "Document", id: arg.document_id},
{type: "DocumentCFV", id: arg.invalidatesTags.documentTypeID}
]
}
}),
getDocumentCustomFields: builder.query<CFV[], string>({
query: documentID => ({
url: `/documents/${documentID}/custom-fields`
Expand All @@ -194,6 +217,7 @@ export const {
useMovePagesMutation,
useExtractPagesMutation,
useUpdateDocumentCustomFieldsMutation,
useUpdateDocumentTypeMutation,
useGetDocumentCustomFieldsQuery,
useGetDocsByTypeQuery
} = apiSliceWithDocuments
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,32 @@ import {
} from "@/features/document-types/apiSlice"
import {
useGetDocumentCustomFieldsQuery,
useUpdateDocumentCustomFieldsMutation
useUpdateDocumentCustomFieldsMutation,
useUpdateDocumentTypeMutation
} from "@/features/document/apiSlice"
import {selectCurrentNodeID} from "@/features/ui/uiSlice"
import type {CFV, PanelMode} from "@/types"
import {Button, ComboboxItem, Select, Skeleton, TextInput} from "@mantine/core"

export default function CustomFields() {
const [showSaveButton, setShowSaveButton] = useState<boolean>(false)
const {data: allDocumentTypes = [], isSuccess: isSuccessAllDocumentTypes} =
useGetDocumentTypesQuery()
const mode: PanelMode = useContext(PanelContext)
const docID = useAppSelector(s => selectCurrentNodeID(s, mode))
const {currentData: doc, isLoading} = useGetDocumentQuery(docID ?? skipToken)
const [showSaveButton, setShowSaveButton] = useState<boolean>(false)
const [customFieldValues, setCustomFieldValues] = useState<CFV[]>([])
const [documentTypeID, setDocumentTypeID] = useState<ComboboxItem | null>(
null
)

const docID = useAppSelector(s => selectCurrentNodeID(s, mode))

const {data: allDocumentTypes = [], isSuccess: isSuccessAllDocumentTypes} =
useGetDocumentTypesQuery()
const {currentData: doc, isLoading} = useGetDocumentQuery(docID ?? skipToken)
const {currentData: documentType} = useGetDocumentTypeQuery(
documentTypeID?.value ?? skipToken
)
const [customFieldValues, setCustomFieldValues] = useState<CFV[]>([])
const [updateDocumentCustomFields, {error}] =
useUpdateDocumentCustomFieldsMutation()

const [updateDocumentType] = useUpdateDocumentTypeMutation()
const {data: documentCustomFields, isSuccess: isSuccessDocumentCustomFields} =
useGetDocumentCustomFieldsQuery(docID ?? skipToken)

Expand Down Expand Up @@ -124,35 +127,34 @@ export default function CustomFields() {
/>
))

const onDocumentTypeChange = (_: any, option: ComboboxItem) => {
setDocumentTypeID(option)
if (option && option.value != doc?.document_type_id) {
setShowSaveButton(true)
} else {
setShowSaveButton(false)
}
if (
documentTypeID &&
documentTypeID.value == doc?.document_type_id &&
isSuccessDocumentCustomFields &&
documentCustomFields &&
documentCustomFields.length > 0
) {
const initialCustFieldValues = documentCustomFields.map(i => {
return {...i, value: i.value}
})
setCustomFieldValues(initialCustFieldValues)
const onDocumentTypeChange = async (_: any, option: ComboboxItem) => {
const documentTypeIDToInvalidate =
doc?.document_type_id || (option ? option.value : undefined)

const data = {
document_id: docID!,
invalidatesTags: {
documentTypeID: documentTypeIDToInvalidate
},
body: {
document_type_id: option ? option.value : null
}
}
await updateDocumentType(data)

setDocumentTypeID(option)
setCustomFieldValues([])
setShowSaveButton(false)
}

const onClear = () => {
const onClearDocumentType = () => {
setDocumentTypeID(null)
setShowSaveButton(true)
setCustomFieldValues([])
}

const onSave = async () => {
if (documentCustomFields && documentCustomFields.length > 0) {
if (customFieldValues && customFieldValues.length > 0) {
// document already has custom fields associated
// we need to update existing custom field value
const content = customFieldValues.map(i => {
Expand Down Expand Up @@ -188,7 +190,7 @@ export default function CustomFields() {
value={documentTypeID ? documentTypeID.value : null}
placeholder="Pick Value"
onChange={onDocumentTypeChange}
onClear={onClear}
onClear={onClearDocumentType}
clearable
/>
{genericCustomFieldsComponents}
Expand Down
2 changes: 2 additions & 0 deletions ui2/src/features/document/components/customFields/Date.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export default function CustomFieldDate({
const DATE_FORMAT = "YYYY-MM-DD"
const strValue = d.format(DATE_FORMAT)
onChange({customField, value: strValue})
} else {
onChange({customField, value: ""})
}
setValue(value)
}
Expand Down

0 comments on commit f33e63b

Please sign in to comment.