Skip to content

Commit ac693c6

Browse files
committed
Create a document as a glose of multiple documents (see#404): dev main fonctionnalities
1 parent 6dbd3de commit ac693c6

2 files changed

Lines changed: 89 additions & 11 deletions

File tree

frontend/src/components/DocumentsCards.jsx

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
11
import Card from 'react-bootstrap/Card';
22
import Col from 'react-bootstrap/Col';
33
import Row from 'react-bootstrap/Row';
4+
import Form from 'react-bootstrap/Form';
45
import Metadata from './Metadata';
56
import BrowseTools from './BrowseTools';
67
import FutureDocument from './FutureDocument';
78
import { TypeBadge } from './Type';
89

9-
function DocumentsCards({docs, expandable, byRow, createOn, setLastUpdate, backend, user}) {
10+
function DocumentsCards({docs, expandable, byRow, createOn, setLastUpdate, backend, user, selectedDocs, setSelectedDocs}) {
1011
return (
1112
<Row className="gy-4">
1213
{docs.map(x => x?._id && x?.dc_title &&
1314
<Col key={x._id} md={ byRow && (12 / byRow) }>
14-
<DocumentCard doc={x} expandable={expandable} />
15+
<DocumentCard
16+
doc={x}
17+
expandable={expandable}
18+
selectedDocs={selectedDocs}
19+
setSelectedDocs={setSelectedDocs}
20+
/>
1521
</Col>
1622
)}
1723
{createOn &&
@@ -27,16 +33,36 @@ function DocumentsCards({docs, expandable, byRow, createOn, setLastUpdate, backe
2733
);
2834
}
2935

30-
function DocumentCard({doc, expandable}) {
36+
function DocumentCard({doc, expandable, selectedDocs, setSelectedDocs}) {
37+
const handleCheck = (e) => {
38+
if (e.target.checked) {
39+
setSelectedDocs(prev => [...prev, doc._id]);
40+
} else {
41+
setSelectedDocs(prev => prev.filter(id => id !== doc._id));
42+
}
43+
};
44+
3145
return (
32-
<Card className="h-100">
46+
<Card className="h-100 position-relative">
3347
<Card.Body>
34-
<BrowseTools id={doc._id} openable={expandable} />
48+
<div className="d-flex align-items-start gap-2 mb-2">
49+
<Form.Check
50+
type="checkbox"
51+
id={`check-${doc._id}`}
52+
className="me-1"
53+
style={{ cursor: 'pointer' }}
54+
checked={selectedDocs?.includes(doc._id) || false}
55+
onChange={handleCheck}
56+
/>
57+
<div className="flex-grow-1">
58+
<BrowseTools id={doc._id} openable={expandable} />
59+
</div>
60+
</div>
3561
<Metadata metadata={doc} />
3662
<TypeBadge type={doc?.type}/>
3763
</Card.Body>
3864
</Card>
3965
);
4066
}
4167

42-
export default DocumentsCards;
68+
export default DocumentsCards;

frontend/src/routes/Bookshelf.jsx

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
11
import '../styles/Bookshelf.css';
22
import { useState, useEffect } from 'react';
3+
import { useNavigate } from 'react-router';
34
import Container from 'react-bootstrap/Container';
45
import ButtonGroup from 'react-bootstrap/ButtonGroup';
56
import ToggleButton from 'react-bootstrap/ToggleButton';
7+
import Button from 'react-bootstrap/Button';
68
import FutureDocument from '../components/FutureDocument.jsx';
79
import DocumentsCards from '../components/DocumentsCards.jsx';
810
import Graph from '../components/Graph.jsx';
911
import Col from 'react-bootstrap/Col';
1012
import Row from 'react-bootstrap/Row';
13+
import { v4 as uuid } from 'uuid';
1114

1215
function Bookshelf({ backend, user }) {
1316
const [documents, setDocuments] = useState([]);
1417
const [lastUpdate, setLastUpdate] = useState();
1518
const [displayMode, setDisplayMode] = useState(localStorage.getItem('displayMode') || 'graph');
19+
const [selectedDocs, setSelectedDocs] = useState([]);
1620

21+
const navigate = useNavigate();
1722
const displayModesList = ['graph', 'list'];
1823

1924
useEffect(() => {
2025
backend.getAllDocuments(user)
2126
.then(setDocuments);
2227
}, [lastUpdate, user, backend]);
28+
2329
const docs = [
2430
...new Map(
2531
documents?.filter(x => !!x)
@@ -28,6 +34,34 @@ function Bookshelf({ backend, user }) {
2834
];
2935
const displayedDocs = docs?.flatMap(d => d[0]);
3036

37+
const handleCreateQuotation = async () => {
38+
const _id = uuid().replace(/-/g, '');
39+
const doc = {
40+
_id,
41+
editors: [user],
42+
dc_creator: '…',
43+
dc_title: '…',
44+
dc_issued: new Date(),
45+
dc_isPartOf: null,
46+
dc_license: null,
47+
dc_translator: null,
48+
dc_language: null,
49+
dc_publisher: null,
50+
dc_spatial: null,
51+
text: '…',
52+
links: selectedDocs.map((object) => ({ verb: 'includes', object }))
53+
};
54+
55+
try {
56+
await backend.putDocument(doc);
57+
setLastUpdate(_id);
58+
setSelectedDocs([]);
59+
navigate(`/${_id}#${_id}`);
60+
} catch (error) {
61+
console.error(error);
62+
}
63+
};
64+
3165
function DisplayDocuments() {
3266
switch (displayMode) {
3367
case 'graph':
@@ -42,9 +76,28 @@ function Bookshelf({ backend, user }) {
4276
</Row>
4377
);
4478
case 'list':
45-
return <DocumentsCards docs={documents} byRow={4} createOn={[]}
46-
{...{setLastUpdate, backend, user}}
47-
/>;
79+
return (
80+
<>
81+
{selectedDocs.length > 0 && (
82+
<div className="card p-3 mb-4 justify-content-between align-items-center flex-direction-row">
83+
<div>Create a new quotation with the <strong>{selectedDocs.length}</strong> selected document(s)</div>
84+
<Button variant="danger" onClick={handleCreateQuotation}>
85+
Create Quotation
86+
</Button>
87+
</div>
88+
)}
89+
<DocumentsCards
90+
docs={documents}
91+
byRow={4}
92+
createOn={[]}
93+
selectedDocs={selectedDocs}
94+
setSelectedDocs={setSelectedDocs}
95+
{...{setLastUpdate, backend, user}}
96+
/>
97+
</>
98+
);
99+
default:
100+
return null;
48101
}
49102
}
50103

@@ -75,5 +128,4 @@ function Bookshelf({ backend, user }) {
75128
);
76129
}
77130

78-
export default Bookshelf;
79-
131+
export default Bookshelf;

0 commit comments

Comments
 (0)