Skip to content

Commit

Permalink
WIP: page reorder with toasts notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
ciur committed Sep 28, 2023
1 parent 24f0b05 commit e21ee68
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 41 deletions.
30 changes: 14 additions & 16 deletions papermerge/core/page_operations.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import io
import os
from pathlib import Path
from typing import List

Expand All @@ -8,10 +7,10 @@
from papermerge.core.models import Page
from papermerge.core.schemas import DocumentVersion as PyDocVer
from papermerge.core.schemas.pages import PageAndRotOp
from papermerge.core.storage import abs_path, get_storage_instance
from papermerge.core.storage import get_storage_instance


def apply_pages_op(items: List[PageAndRotOp]):
def apply_pages_op(items: List[PageAndRotOp]) -> List[PyDocVer]:
pages = Page.objects.filter(
pk__in=[item.page.id for item in items]
)
Expand All @@ -23,30 +22,29 @@ def apply_pages_op(items: List[PageAndRotOp]):
)

reorder_pdf_pages(
old_version=old_version,
new_version=new_version,
src=old_version.file_path,
dst=new_version.file_path,
items=items
)

return doc.versions.all()


def reorder_pdf_pages(
old_version: PyDocVer,
new_version: PyDocVer,
src: Path,
dst: Path,
items: List[PageAndRotOp]
):
src = Pdf.open(abs_path(old_version.document_path.url))
src_pdf = Pdf.open(src)

dst = Pdf.new()
dst_pdf = Pdf.new()

for item in items:
page = src.pages.p(item.page.number)
dst.pages.append(page)
page = src_pdf.pages.p(item.page.number)
dst_pdf.pages.append(page)

dirname = os.path.dirname(
abs_path(new_version.document_path.url)
)
os.makedirs(dirname, exist_ok=True)
dst.save(abs_path(new_version.document_path.url))
dst.parent.mkdir(parents=True, exist_ok=True)
dst_pdf.save(dst)


def reuse_ocr_data(uuid_map) -> None:
Expand Down
2 changes: 1 addition & 1 deletion papermerge/core/routers/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,4 @@ def upload_file(
)
doc.generate_thumbnail()

return PyDocument.from_orm(doc)
return PyDocument.model_validate(doc)
6 changes: 2 additions & 4 deletions papermerge/core/routers/folders.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from fastapi import APIRouter, Depends

from papermerge.core.models import User

from papermerge.core.models import Folder, User
from papermerge.core.schemas.folders import Folder as PyFolder
from papermerge.core.models import Folder

from .auth import get_current_user as current_user

Expand All @@ -20,4 +18,4 @@ def get_node(
) -> PyFolder:

folder = Folder.objects.get(id=folder_id, user_id=user.id)
return PyFolder.from_orm(folder)
return PyFolder.model_validate(folder)
4 changes: 3 additions & 1 deletion papermerge/core/routers/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,6 @@ def apply_page_operations(
Order in which input pages are provided is very important because
new document version will add pages in exact same order.
"""
apply_pages_op(items)
new_versions = apply_pages_op(items)

return [PyDocVer.model_validate(version) for version in new_versions]
2 changes: 2 additions & 0 deletions ui/src/components/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CentralBar from './central_bar';
import styles from './layout.module.css';
import Sidebar from './sidebar/sidebar';
import type { AppContentBlockEnum, State, User } from 'types';
import Notifications from 'components/notifications/Notifications';


const fetcher = (url:string) => {
Expand Down Expand Up @@ -80,6 +81,7 @@ function Layout({ children, onContentBlockChange, onSearchSubmit }: Args) {

return (
<main className={styles.main}>
<Notifications />
<Sidebar folded={sidebarFolded} onSidebarItemChange={onContentBlockChange} />
<CentralBar
username={data?.username}
Expand Down
12 changes: 7 additions & 5 deletions ui/src/components/loading_button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,30 @@ type Args = {
title?: string;
onClick: () => void;
className?: string;
variant?: string;
}


function SubmitButton({
function LoadingButton({
in_progress,
title,
onClick,
className
className,
variant
}: Args) {

if (!title) {
title = "Submit";
}

if (in_progress) {
return <Button onClick={onClick} disabled={true} className={className}>
return <Button variant={variant} onClick={onClick} disabled={true} className={className}>
<Spinner size="sm" />
</Button>;
}

return <Button onClick={onClick} className={className}>{title}</Button>;
return <Button variant={variant} onClick={onClick} className={className}>{title}</Button>;
}


export default SubmitButton;
export default LoadingButton;
20 changes: 20 additions & 0 deletions ui/src/components/notifications/Message.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Toast from 'react-bootstrap/Toast';

type Args = {
text: string;
}

function Message({text}: Args) {
return (
<Toast>
<div className='d-flex'>
<div className='toast-body'>
{text}
</div>
<button type="button" className="btn-close me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</Toast>
);
}

export default Message;
15 changes: 15 additions & 0 deletions ui/src/components/notifications/Notifications.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import ToastContainer from 'react-bootstrap/ToastContainer';
import Message from './Message';


function NotificationsContainer() {
return (
<ToastContainer position='bottom-end'>
<Message text={"Message 1"} />
<Message text={"Message 2"} />
<Message text={"Message 3"} />
</ToastContainer>
);
}

export default NotificationsContainer;
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import LoadingButton from "components/loading_button";
import { useState } from "react";
import { Button, Spinner } from "react-bootstrap"


type Args = {
Expand All @@ -9,19 +9,20 @@ type Args = {
export default function UnappliedPageOpChanges({onClick}: Args) {
const [inProgress, setInProgress] = useState(false);

const onLocalClick = () => {
const onLocalClick = async () => {
setInProgress(true);
onClick();
setInProgress(false);
}

return (
<span className="unapplied-page-op-changes">
Unapplied pages operations detected
<Button disabled={inProgress}
className="rounded-0 m-1" variant="success"
onClick={onLocalClick}>
{inProgress && <Spinner />} Apply
</Button>
<LoadingButton in_progress={inProgress}
variant={"success"}
title={"Apply"}
className="rounded-0 m-1"
onClick={onLocalClick} />
</span>
);
}
25 changes: 23 additions & 2 deletions ui/src/components/viewer/viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,38 @@ import { useViewerContentHeight } from 'hooks/viewer_content_height';

import ActionPanel from "components/viewer/action_panel/action_panel";
import { NodeClickArgsType, DocumentType, DocumentVersion } from "types";
import type { PageAndRotOp } from 'types';
import type { PageAndRotOp, PageType } from 'types';
import type { State, ThumbnailPageDroppedArgs } from 'types';
import ErrorMessage from 'components/error_message';
import { reorder_pages } from 'utils/misc';

import { apply_page_op_changes } from 'requests/viewer';


type ShortPageType = {
number: number;
id: string;
}


type ApplyPagesType = {
ccw: number;
page: ShortPageType;
}


type Args = {
node_id: string;
onNodeClick: ({node_id, node_type}: NodeClickArgsType) => void;
}

function apply_page_type(item: PageAndRotOp): ApplyPagesType {
return {
ccw: item.ccw,
page: {id: item.page.id, number: item.page.number}
}
}

export default function Viewer(
{node_id, onNodeClick}: Args
) {
Expand Down Expand Up @@ -115,7 +134,9 @@ export default function Viewer(
}

const onApplyPageOpChanges = async () => {
let response = await apply_page_op_changes(curPages)
let pages = curPages.map(item => apply_page_type(item));
let response = await apply_page_op_changes<ApplyPagesType[], PageType[]>(pages);
setUnappliedPagesOpChanges(false);
}

if (error) {
Expand Down
9 changes: 4 additions & 5 deletions ui/src/requests/viewer.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import type { PageAndRotOp, PageType } from "types";
import { fetcher_post } from "utils/fetcher";


export async function apply_page_op_changes(
pages: PageAndRotOp[]
): Promise<PageType[]> {
return fetcher_post<PageAndRotOp[], PageType[]>('/pages/reorder', pages);
export async function apply_page_op_changes<In, Out>(
pages: In
): Promise<Out> {
return fetcher_post<In, Out>('/api/pages/', pages);
}

0 comments on commit e21ee68

Please sign in to comment.