Skip to content

Commit

Permalink
oh, yeah; it works!
Browse files Browse the repository at this point in the history
  • Loading branch information
ciur committed Oct 15, 2024
1 parent d20dc64 commit b8a1041
Show file tree
Hide file tree
Showing 11 changed files with 215 additions and 23 deletions.
6 changes: 3 additions & 3 deletions papermerge/core/cli/docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from rich.table import Table

from papermerge.core import db, schemas
from papermerge.core.db.doc import get_documents_by_type
from papermerge.core.db.doc import get_docs_by_type
from papermerge.core.db.document_types import get_document_types

app = typer.Typer(help="List various entities")
Expand All @@ -22,8 +22,8 @@ def document_types():
@app.command(name="list-by-type")
def list_documents_by_type(type_id: uuid.UUID, parent_id: uuid.UUID):
"""List all documents by specific document type"""
docs = get_documents_by_type(
session, type_id=type_id, user_id=uuid.uuid4(), parent_id=parent_id
docs = get_docs_by_type(
session, type_id=type_id, user_id=uuid.uuid4(), ancestor_id=parent_id
)
print_docs(docs)

Expand Down
2 changes: 1 addition & 1 deletion papermerge/core/db/doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ def get_docs_by_type(
type_id: UUID,
ancestor_id: UUID,
user_id: UUID,
):
) -> list[schemas.DocumentCFV]:
"""
Returns list of documents + doc CFv for all documents with of given type
Expand Down
9 changes: 6 additions & 3 deletions papermerge/core/routers/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,22 @@
@router.get("/type/{document_type_id}")
@utils.docstring_parameter(scope=scopes.NODE_VIEW)
def get_documents_by_type(
document_type_id: uuid.UUID,
user: Annotated[
schemas.User, Security(get_current_user, scopes=[scopes.NODE_VIEW])
],
type_id: uuid.UUID,
ancestor_id: uuid.UUID,
db_session: db.Session = Depends(db.get_session),
):
) -> list[schemas.DocumentCFV]:
"""
Get all documents of specific type with all custom field values
Required scope: `{scope}`
"""

docs = db.get_documents_by_type(db_session, type_id=type_id, user_id=user.id)
docs = db.get_docs_by_type(
db_session, type_id=document_type_id, ancestor_id=ancestor_id, user_id=user.id
)

return docs

Expand Down
3 changes: 2 additions & 1 deletion ui2/src/features/api/slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ export const apiSlice = createApi({
"Document",
"CustomField", // CRUD custom field
"DocumentType",
"DocumentCustomField" // custom fields associated to specific document (via document type)
"DocumentCustomField", // custom fields associated to specific document (via document type)
"DocumentCFV"
],
endpoints: _ => ({})
})
17 changes: 16 additions & 1 deletion ui2/src/features/document/apiSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {ONE_DAY_IN_SECONDS} from "@/cconstants"
import {apiSlice} from "@/features/api/slice"
import type {
AddCustomFieldValueType,
DocumentCFV,
DocumentCustomFieldValue,
UpdateCustomFieldValueType
} from "@/types"
Expand Down Expand Up @@ -62,6 +63,11 @@ type AddDocumentCustomFields = {
}
}

type GetDocsByTypeArgs = {
document_type_id: string
ancestor_id: string
}

export const apiSliceWithDocuments = apiSlice.injectEndpoints({
endpoints: builder => ({
getDocument: builder.query<DocumentType, string>({
Expand Down Expand Up @@ -187,6 +193,14 @@ export const apiSliceWithDocuments = apiSlice.injectEndpoints({
providesTags: (_result, _error, arg) => [
{type: "DocumentCustomField", id: arg}
]
}),
getDocsByType: builder.query<DocumentCFV[], GetDocsByTypeArgs>({
query: args => ({
url: `/documents/type/${args.document_type_id}?ancestor_id=${args.ancestor_id}`
}),
providesTags: (_result, _error, arg) => [
{type: "DocumentCFV", id: arg.document_type_id}
]
})
})
})
Expand All @@ -199,5 +213,6 @@ export const {
useExtractPagesMutation,
useUpdateDocumentCustomFieldsMutation,
useAddDocumentCustomFieldsMutation,
useGetDocumentCustomFieldsQuery
useGetDocumentCustomFieldsQuery,
useGetDocsByTypeQuery
} = apiSliceWithDocuments
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import ToggleSecondaryPanel from "@/components/DualPanel/ToggleSecondaryPanel"
import {Group} from "@mantine/core"
import ViewOptionsMenu from "../ViewOptionsMenu"
import DocumentTypeFilter from "./DocumentTypeFilter"

export default function ActionButtons() {
return (
<Group>
<ViewOptionsMenu />
<Group justify="space-between">
<DocumentTypeFilter />
<Group>
<ViewOptionsMenu />
<ToggleSecondaryPanel />
</Group>
</Group>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {Checkbox, Table} from "@mantine/core"
import {useDispatch, useSelector} from "react-redux"
import {Link} from "react-router-dom"

import {selectSelectedIds} from "@/features/users/usersSlice"

import type {DocumentCFV} from "@/types"

type Args = {
doc: DocumentCFV
}

export default function DocumentRow({doc}: Args) {
const selectedIds = useSelector(selectSelectedIds)
const dispatch = useDispatch()
const customFieldsDataColumns = doc.custom_fields.map(cf => (
<Table.Td key={cf[0]}>{cf[1]}</Table.Td>
))

const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {}

return (
<Table.Tr>
<Table.Td>
<Checkbox checked={selectedIds.includes(doc.id)} onChange={onChange} />
</Table.Td>
<Table.Td>
<Link to={`/document/${doc.id}`}>{doc.title}</Link>
</Table.Td>
{customFieldsDataColumns}
</Table.Tr>
)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,47 @@
import {useAppDispatch} from "@/app/hooks"
import PanelContext from "@/contexts/PanelContext"
import {useGetDocumentTypesQuery} from "@/features/document-types/apiSlice"
import {commanderDocumentTypeIDUpdated} from "@/features/ui/uiSlice"
import {Select} from "@mantine/core"
import {useContext, useState} from "react"

import type {PanelMode} from "@/types"

export default function DocumentTypeFilter() {
const mode: PanelMode = useContext(PanelContext)
const dispatch = useAppDispatch()
const {data: allDocumentTypes = []} = useGetDocumentTypesQuery()
const [currentDocumentTypeID, setCurrentDocumentTypeID] = useState<
string | undefined
>("")
const onDocumentTypeChanged = (value: string | null) => {
let newValue

if (!value) {
newValue = undefined
} else {
newValue = value
}

setCurrentDocumentTypeID(newValue)

dispatch(
commanderDocumentTypeIDUpdated({
mode,
documentTypeID: newValue
})
)
}

return (
<Select
searchable
placeholder="Pick Document Type"
data={["React", "Angular", "Vue", "Svelte"]}
onChange={onDocumentTypeChanged}
data={allDocumentTypes.map(i => {
return {value: i.id, label: i.name}
})}
value={currentDocumentTypeID}
/>
)
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,79 @@
import ToggleSecondaryPanel from "@/components/DualPanel/ToggleSecondaryPanel"
import {Box, Group, Stack} from "@mantine/core"
import {useAppSelector} from "@/app/hooks"
import Breadcrumbs from "@/components/Breadcrumbs"
import PanelContext from "@/contexts/PanelContext"
import {useGetDocsByTypeQuery} from "@/features/document/apiSlice"
import {useGetFolderQuery} from "@/features/nodes/apiSlice"
import {
selectCommanderDocumentTypeID,
selectCurrentNodeID
} from "@/features/ui/uiSlice"
import type {NType, PanelMode} from "@/types"
import {Box, Checkbox, Stack, Table} from "@mantine/core"
import {skipToken} from "@reduxjs/toolkit/query"
import {useContext} from "react"
import ActionButtons from "./ActionButtons"
import DocumentTypeFilter from "./DocumentTypeFilter"
import DocumentRow from "./DocumentRow"

export default function DocumentsByCategoryCommander() {
const mode: PanelMode = useContext(PanelContext)
const currentNodeID = useAppSelector(s => selectCurrentNodeID(s, mode))
const currentDocumentTypeID = useAppSelector(s =>
selectCommanderDocumentTypeID(s, mode)
)
const {data: currentFolder} = useGetFolderQuery(currentNodeID ?? skipToken)
const {data: nodes} = useGetDocsByTypeQuery(
currentNodeID && currentDocumentTypeID
? {document_type_id: currentDocumentTypeID, ancestor_id: currentNodeID}
: skipToken
)

const onClick = (node: NType) => {}

if (!nodes || (nodes && nodes.length == 0)) {
return (
<Box>
<Stack>
<ActionButtons />
<Breadcrumbs
breadcrumb={currentFolder?.breadcrumb}
onClick={onClick}
isFetching={false}
/>
</Stack>
<Stack>Empty</Stack>
</Box>
)
}

const rows = nodes.map(n => <DocumentRow key={n.id} doc={n} />)
const customFieldsHeaderColumns = nodes[0].custom_fields.map(cf => (
<Table.Th key={cf[0]}>{cf[0]}</Table.Th>
))

return (
<Box>
<Group justify="space-between">
<DocumentTypeFilter />
<Group>
<ActionButtons />
<ToggleSecondaryPanel />
</Group>
</Group>
<Stack>Empty</Stack>
<Stack>
<ActionButtons />
<Breadcrumbs
breadcrumb={currentFolder?.breadcrumb}
onClick={onClick}
isFetching={false}
/>
</Stack>
<Stack>
<Table>
<Table.Thead>
<Table.Tr>
<Table.Th>
<Checkbox />
</Table.Th>
<Table.Th>Title</Table.Th>
{customFieldsHeaderColumns}
</Table.Tr>
</Table.Thead>
<Table.Tbody>{rows}</Table.Tbody>
</Table>
</Stack>
</Box>
)
}
30 changes: 30 additions & 0 deletions ui2/src/features/ui/uiSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ type ViewOptionArgs = {
viewOption: ViewOption
}

type DocumentTypeIDArgs = {
mode: PanelMode
documentTypeID?: string
}

export interface UploaderFileItemArgs {
item: {
source: NodeType | null
Expand Down Expand Up @@ -195,12 +200,14 @@ interface UIState {
mainCommanderSortMenuColumn?: SortMenuColumn
mainCommanderSortMenuDir?: SortMenuDirection
mainCommanderViewOption?: ViewOption
mainCommanderDocumentTypeID?: string
secondaryCommanderSelectedIDs?: Array<String>
secondaryCommanderFilter?: string
secondaryCommanderLastPageSize?: number
secondaryCommanderSortMenuColumn?: SortMenuColumn
secondaryCommanderSortMenuDir?: SortMenuDirection
secondaryCommanderViewOption?: ViewOption
secondaryCommanderDocumentTypeID?: string
/* Which component should main panel display:
commander, viewer or search results? */
mainPanelComponent?: PanelComponent
Expand Down Expand Up @@ -528,6 +535,17 @@ const uiSlice = createSlice({
state.secondaryCommanderViewOption = viewOption
}
},
commanderDocumentTypeIDUpdated(
state,
action: PayloadAction<DocumentTypeIDArgs>
) {
const {mode, documentTypeID} = action.payload
if (mode == "main") {
state.mainCommanderDocumentTypeID = documentTypeID
} else {
state.secondaryCommanderDocumentTypeID = documentTypeID
}
},
viewerThumbnailsPanelToggled(state, action: PayloadAction<PanelMode>) {
const mode = action.payload

Expand Down Expand Up @@ -744,6 +762,7 @@ export const {
commanderSortMenuColumnUpdated,
commanderSortMenuDirectionUpdated,
commanderViewOptionUpdated,
commanderDocumentTypeIDUpdated,
viewerThumbnailsPanelToggled,
viewerDocumentDetailsPanelToggled,
zoomFactorIncremented,
Expand Down Expand Up @@ -942,6 +961,17 @@ export const selectCommanderViewOption = (
return state.ui.secondaryCommanderViewOption || "tile"
}

export const selectCommanderDocumentTypeID = (
state: RootState,
mode: PanelMode
): string | undefined => {
if (mode == "main") {
return state.ui.mainCommanderDocumentTypeID
}

return state.ui.secondaryCommanderDocumentTypeID
}

export const selectZoomFactor = (state: RootState, mode: PanelMode) => {
if (mode == "main") {
return state.ui.mainViewerZoomFactor || ZOOM_FACTOR_INIT
Expand Down
8 changes: 8 additions & 0 deletions ui2/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,14 @@ export type DocumentCustomFieldValue = {
field_id?: string
}

export type DocumentCFV = {
id: string
title: string
document_type_id: string
thumbnail_url: string
custom_fields: Array<[string, string]>
}

export type CurrencyType =
| "CHF"
| "CZK"
Expand Down

0 comments on commit b8a1041

Please sign in to comment.