diff --git a/components/Digitization/DigitizationContainerList.js b/components/Digitization/DigitizationContainerList.js
new file mode 100644
index 0000000..836df55
--- /dev/null
+++ b/components/Digitization/DigitizationContainerList.js
@@ -0,0 +1,82 @@
+import React from 'react'
+import PopupTable from "../../components/Tables/PopupTable";
+import {renderDigitalVersion} from "../../utils/renders/renderDigitalVersion";
+import {renderDigitalVersionResearchCloud} from "../../utils/renders/renderDigitalVersionResearchCloud";
+import {renderLevel} from "../../utils/renders/renderLevel"
+import style from "./DigitizationContainerList.module.scss"
+
+export default function DigitizationContainerList() {
+ const renderContainerNo = (data, record) => {
+ return {data}
+ }
+
+ const columns = [
+ {
+ title: 'Container No.',
+ dataIndex: 'container_no',
+ key: 'container_no',
+ sorter: true,
+ width: 200,
+ render: renderContainerNo,
+ }, {
+ title: 'Barcode',
+ dataIndex: 'barcode',
+ key: 'barcode',
+ width: 140,
+ sorter: true
+ }, {
+ title: 'Research Cloud',
+ key: 'available_research_cloud',
+ width: 120,
+ className: 'centerColumn',
+ sorter: true,
+ render: renderDigitalVersionResearchCloud
+ }, {
+ title: 'Online',
+ dataIndex: 'available_online',
+ key: 'available_online',
+ width: 120,
+ className: 'centerColumn',
+ sorter: true,
+ render: renderDigitalVersion
+ }, {
+ title: 'Creation Date (Digital)',
+ dataIndex: 'creation_date',
+ key: 'creation_date',
+ className: 'centerColumn',
+ width: 150,
+ sorter: true
+ }, {
+ title: 'Level',
+ dataIndex: 'level',
+ key: 'level',
+ className: 'centerColumn',
+ width: 80,
+ render: renderLevel
+ }, {
+ title: 'Duration',
+ dataIndex: 'duration',
+ key: 'duration',
+ width: 100,
+ className: 'centerColumn',
+ }, {
+ title: 'Carrier Type',
+ dataIndex: 'carrier_type',
+ key: 'carrier_type',
+ className: 'centerColumn',
+ sorter: true
+ },
+ ];
+
+ return (
+
+ )
+}
diff --git a/components/Digitization/DigitizationContainerList.module.scss b/components/Digitization/DigitizationContainerList.module.scss
new file mode 100644
index 0000000..2285282
--- /dev/null
+++ b/components/Digitization/DigitizationContainerList.module.scss
@@ -0,0 +1,9 @@
+.ContainerNo {
+ text-decoration: none;
+ color: inherit;
+ border-bottom: 1px dotted gray;
+
+ &:hover {
+ color: #000;
+ }
+}
\ No newline at end of file
diff --git a/components/Digitization/DigitizationFindingAidsList.js b/components/Digitization/DigitizationFindingAidsList.js
new file mode 100644
index 0000000..8836fc2
--- /dev/null
+++ b/components/Digitization/DigitizationFindingAidsList.js
@@ -0,0 +1,65 @@
+import React from 'react'
+import {Card} from "antd";
+import PopupTable from "../../components/Tables/PopupTable";
+import {renderDigitalVersion} from "../../utils/renders/renderDigitalVersion";
+import {renderDigitalVersionResearchCloud} from "../../utils/renders/renderDigitalVersionResearchCloud";
+
+export default function DigitizationFindingAidsList() {
+ const columns = [
+ {
+ title: 'Reference No.',
+ dataIndex: 'archival_reference_code',
+ key: 'archival_reference_code',
+ sorter: true,
+ width: 200
+ }, {
+ title: 'Digital Version',
+ dataIndex: 'digital_version_exists',
+ key: 'digital_version_exists',
+ width: 150,
+ className: 'centerColumn',
+ sorter: true,
+ render: renderDigitalVersion
+ }, {
+ title: 'Research Cloud',
+ key: 'digital_version_research_cloud',
+ width: 150,
+ className: 'centerColumn',
+ sorter: true,
+ render: renderDigitalVersionResearchCloud
+ }, {
+ title: 'Online',
+ dataIndex: 'digital_version_online',
+ key: 'digital_version_online',
+ width: 150,
+ className: 'centerColumn',
+ sorter: true,
+ render: renderDigitalVersion
+ }, {
+ title: 'Creation Date',
+ dataIndex: 'digital_version_creation_date',
+ key: 'digital_version_creation_date',
+ className: 'centerColumn',
+ width: 150,
+ sorter: true
+ }, {
+ title: 'Primary Type',
+ dataIndex: 'primary_type',
+ key: 'primary_type',
+ className: 'centerColumn',
+ sorter: true
+ },
+ ];
+
+ return (
+
+ )
+}
diff --git a/components/Digitization/DigitizationLogView.js b/components/Digitization/DigitizationLogView.js
new file mode 100644
index 0000000..b9db11b
--- /dev/null
+++ b/components/Digitization/DigitizationLogView.js
@@ -0,0 +1,50 @@
+import React, {useState} from "react";
+import {Radio, Card} from "antd";
+import DigitizationContainerList from "./DigitizationContainerList";
+import DigitizationFindingAidsList from "./DigitizationFindingAidsList";
+
+
+const DigitazationLogView = () => {
+ const [view, setView] = useState('container');
+
+ const getTitle = () => {
+ switch (view) {
+ case 'container':
+ return 'Digitized Containers';
+ case 'finding_aids':
+ return 'Digitized Finding Aids (Folders / Items)';
+ default:
+ break;
+ }
+ };
+
+ const getView = () => {
+ switch (view) {
+ case 'container':
+ return ();
+ case 'finding_aids':
+ return ();
+ default:
+ break;
+ }
+ };
+
+ const onChange = (e) => {
+ setView(e.target.value);
+ };
+
+ const viewChange = () => (
+
+ Containers
+ Finding Aids (Folders / Items)
+
+ );
+
+ return (
+
+ {getView()}
+
+ )
+};
+
+export default DigitazationLogView;
diff --git a/components/Forms/ArchivalUnitSelectForm.js b/components/Forms/ArchivalUnitSelectForm.js
index 9adc901..626d845 100644
--- a/components/Forms/ArchivalUnitSelectForm.js
+++ b/components/Forms/ArchivalUnitSelectForm.js
@@ -1,36 +1,44 @@
-import React, {useState} from 'react';
+import React, {useEffect, useState} from 'react';
import {Button, Card, Col, Form, Row} from "antd";
import style from "./Forms.module.css";
import FormRemoteSelect from "./components/FormRemoteSelect";
import { ContainerOutlined } from '@ant-design/icons';
import Link from "next/link";
import {renderArchivalUnitDropdown} from "../../utils/renders/renderArchivalUnitDropdown";
+import useStickyState from "../../utils/hooks/useStickyState";
export const ArchivalUnitSelectForm = () => {
const [form] = Form.useForm();
- const [fonds, setFonds] = useState(undefined);
- const [subfonds, setSubfonds] = useState(undefined);
- const [series, setSeries] = useState(undefined);
+ const [ archivalUnitFormState, setArchivalUnitFormState ] = useStickyState({
+ fonds: undefined,
+ subfonds: undefined,
+ series: undefined
+ }, 'ams-select-archival-unit-form')
+
const onValuesChange = (values) => {
if (values.hasOwnProperty('fonds')) {
form.setFieldsValue({subfonds: undefined});
form.setFieldsValue({series: undefined});
- setFonds(values['fonds']);
- setSubfonds(undefined);
- setSeries(undefined);
+ setArchivalUnitFormState({
+ fonds: values['fonds'], subfonds: undefined, series: undefined
+ })
}
if (values.hasOwnProperty('subfonds')) {
form.setFieldsValue({series: undefined});
- setSubfonds(values['subfonds']);
- setSeries(undefined);
+
+ setArchivalUnitFormState({
+ fonds: archivalUnitFormState['fonds'], subfonds: values['subfonds'], series: undefined
+ })
}
if (values.hasOwnProperty('series')) {
- setSeries(values['series']);
+ setArchivalUnitFormState({
+ fonds: archivalUnitFormState['fonds'], subfonds: archivalUnitFormState['subfonds'], series: values['series']
+ })
}
};
@@ -40,6 +48,7 @@ export const ArchivalUnitSelectForm = () => {
scrollToFirstError={true}
form={form}
onValuesChange={onValuesChange}
+ initialValues={archivalUnitFormState}
layout={'vertical'}
className={style.Form}
>
@@ -53,6 +62,7 @@ export const ArchivalUnitSelectForm = () => {
selectAPI={'/v1/archival_unit/select/'}
selectAPIParams={{level: 'F'}}
placeholder={'- Select Fonds -'}
+ searchMinLength={0}
/>
@@ -62,8 +72,9 @@ export const ArchivalUnitSelectForm = () => {
valueField={'id'}
labelField={'title_full'}
renderFunction={renderArchivalUnitDropdown}
- selectAPI={fonds ? `/v1/archival_unit/select/${fonds}/` : undefined}
+ selectAPI={archivalUnitFormState['fonds'] ? `/v1/archival_unit/select/${archivalUnitFormState['fonds']}/` : undefined}
placeholder={'- Select Subfonds -'}
+ searchMinLength={0}
/>
@@ -73,8 +84,9 @@ export const ArchivalUnitSelectForm = () => {
valueField={'id'}
labelField={'title_full'}
renderFunction={renderArchivalUnitDropdown}
- selectAPI={subfonds ? `/v1/archival_unit/select/${subfonds}/` : undefined}
+ selectAPI={archivalUnitFormState['subfonds'] ? `/v1/archival_unit/select/${archivalUnitFormState['subfonds']}/` : undefined}
placeholder={'- Select Series -'}
+ searchMinLength={0}
/>
@@ -82,10 +94,10 @@ export const ArchivalUnitSelectForm = () => {
-
+
diff --git a/components/Forms/ContainerCreateForm.js b/components/Forms/ContainerCreateForm.js
index 952ad27..65aa9a1 100644
--- a/components/Forms/ContainerCreateForm.js
+++ b/components/Forms/ContainerCreateForm.js
@@ -1,16 +1,25 @@
-import {Button, Card, Col, Form, Input, notification, Row} from "antd";
+import {Button, Col, Form, Input, Row} from "antd";
import style from "./Forms.module.css";
import React, {useState} from "react";
import FormRemoteSelect from "./components/FormRemoteSelect";
import {useData} from "../../utils/hooks/useData";
import {post} from "../../utils/api";
+import {useUpdateEffect} from "react-use";
-export const ContainerCreateForm = ({seriesID, containerListRefresh}) => {
+export const ContainerCreateForm = ({seriesID, containerListRefresh, deletedContainer}) => {
const [loading, setLoading] = useState(false);
const [form] = Form.useForm();
const {data, refresh} = useData(seriesID ? `/v1/container/precreate/${seriesID}/` : undefined);
+ useUpdateEffect(() => {
+ form.setFieldValue('container_no', data['container_no'])
+ }, [data])
+
+ useUpdateEffect(() => {
+ refresh()
+ }, [deletedContainer])
+
const validateMessages = {
required: 'This field is required!'
};
diff --git a/components/Forms/FindingAidsForm.js b/components/Forms/FindingAidsForm.js
index def21bd..861e5df 100644
--- a/components/Forms/FindingAidsForm.js
+++ b/components/Forms/FindingAidsForm.js
@@ -7,7 +7,7 @@ import {SimpleFormFooter} from "./SimpleFormFooter";
import {FindingAidsEntityForm} from "./fields/FindingAidsEntityForm";
import {useData} from "../../utils/hooks/useData";
-export const FindingAidsForm = ({type, recordID, containerID, seriesID, initialValues}) => {
+export const FindingAidsForm = ({type, recordID, containerID, seriesID, onActiveTabChange, initialValues}) => {
const [params, setParams] = useState({});
const router = useRouter();
@@ -83,6 +83,7 @@ export const FindingAidsForm = ({type, recordID, containerID, seriesID, initialV
form={form}
locale={locale}
type={type}
+ onActiveTabChange={onActiveTabChange}
/>
diff --git a/components/Forms/FindingAidsTemplateForm.js b/components/Forms/FindingAidsTemplateForm.js
index 6bb0227..a5ff331 100644
--- a/components/Forms/FindingAidsTemplateForm.js
+++ b/components/Forms/FindingAidsTemplateForm.js
@@ -9,6 +9,12 @@ import {useRouter} from "next/router";
export const FindingAidsTemplateForm = ({type, recordID, seriesID, initialValues}) => {
const router = useRouter();
+ const [activeTabKey, setActiveTabKey] = useState('')
+
+ const onActiveTabChange = (activeKey) => {
+ setActiveTabKey(activeKey)
+ }
+
const getAPI = () => {
switch (type) {
case 'create':
@@ -52,6 +58,7 @@ export const FindingAidsTemplateForm = ({type, recordID, seriesID, initialValues
form={form}
locale={locale}
type={type}
+ onActiveTabChange={onActiveTabChange}
/>
diff --git a/components/Forms/Forms.module.css b/components/Forms/Forms.module.css
index 42d46d2..72e5651 100644
--- a/components/Forms/Forms.module.css
+++ b/components/Forms/Forms.module.css
@@ -31,6 +31,7 @@
.FooterInfo {
border-top: 0;
+ margin-top: 20px;
margin-bottom: 0;
}
diff --git a/components/Forms/PopupForm.js b/components/Forms/PopupForm.js
index f3df24d..c77a31a 100644
--- a/components/Forms/PopupForm.js
+++ b/components/Forms/PopupForm.js
@@ -1,5 +1,5 @@
import React, {useEffect} from "react";
-import {Form, Row, Col, Button, Input} from 'antd';
+import {Form, Row, Col, Button, Input, Divider} from 'antd';
import style from './Forms.module.css';
import {CarrierTypeForm} from "./fields/CarrierTypeForm";
import {CorporationForm} from "./fields/CorporationForm";
@@ -16,8 +16,8 @@ import {DonorForm} from "./fields/DonorForm";
import {useData} from "../../utils/hooks/useData";
import {fillManyFields} from "../../utils/functions/fillManyFields";
import {IsaarForm} from "./fields/IsaarForm";
-import {BarcodeForm} from "./fields/BarcodeForm";
-import {ContainerForm} from "./fields/ContainerForm";
+import {BarcodeForm} from "./fields/containers/BarcodeForm";
+import {ContainerForm} from "./fields/containers/ContainerForm";
import {ExtentUnitForm} from "./fields/ExtentUnitForm";
import {RoleForm} from "./fields/RoleForm";
import {useForm} from "../../utils/hooks/useForm";
@@ -27,10 +27,13 @@ import {MLRForm} from "./fields/MLRForm";
import {DigitizationForm} from "./fields/DigitizationForm";
import {RequestsForm} from "./fields/RequestsForm";
import {RequestItemForm} from "./fields/RequestsItemForm";
+import {NationalityForm} from "./fields/NationalityForm";
+import AuditLog from "./auditLog/AuditLog";
+import DigitalVersionsTable from "./fields/containers/DigitalVersionsTable";
-export const PopupForm = ({api, preCreateAPI, selectedRecord, module, type, field, label, onClose}) => {
- const afterFinish = () => {
- onClose();
+export const PopupForm = ({api, preCreateAPI, selectedRecord, module, type, field, label, hasMerge=true, onClose}) => {
+ const afterFinish = (data) => {
+ onClose(data);
};
const {form, formLoading, errors, onFinish, renderErrors, onValuesChange} =
@@ -38,7 +41,7 @@ export const PopupForm = ({api, preCreateAPI, selectedRecord, module, type, fiel
const readOnly = type === 'view';
- const {data, loading} = useData(selectedRecord ? `${preCreateAPI ? preCreateAPI : api}${selectedRecord}/` : undefined);
+ const {data} = useData(selectedRecord ? `${preCreateAPI ? preCreateAPI : api}${selectedRecord}/` : undefined);
useEffect(() => {
form.setFieldsValue(data)
@@ -59,7 +62,7 @@ export const PopupForm = ({api, preCreateAPI, selectedRecord, module, type, fiel
case 'languages':
return ;
case 'people':
- return ;
+ return ;
case 'places':
return ;
case 'subjects':
@@ -77,7 +80,7 @@ export const PopupForm = ({api, preCreateAPI, selectedRecord, module, type, fiel
case 'donors':
return ;
case 'isaar':
- return ;
+ return {}} />;
case 'barcode':
return ;
case 'container':
@@ -88,6 +91,8 @@ export const PopupForm = ({api, preCreateAPI, selectedRecord, module, type, fiel
return ;
case 'corporation_role':
return ;
+ case 'nationality':
+ return ;
case 'geo_role':
return ;
case 'finding-aids-quick-edit':
@@ -100,6 +105,8 @@ export const PopupForm = ({api, preCreateAPI, selectedRecord, module, type, fiel
return ;
case 'request_item':
return ;
+ case 'digital-versions':
+ return '';
default:
return (
@@ -164,40 +171,72 @@ export const PopupForm = ({api, preCreateAPI, selectedRecord, module, type, fiel
}
};
- return (
-
- { errors && renderErrors() }
-
-
- )
+ if (module === 'digital-versions') {
+ if (data && data.digital_versions && data.digital_versions.length > 0) {
+ return (
+ <>
+
+ >
+ )
+ } else {
+ return null;
+ }
+ } else {
+ return (
+
+ { errors && renderErrors() }
+
+
+ )
+ }
+
};
diff --git a/components/Forms/SimpleForm.js b/components/Forms/SimpleForm.js
index 02900a2..08b34d2 100644
--- a/components/Forms/SimpleForm.js
+++ b/components/Forms/SimpleForm.js
@@ -18,10 +18,10 @@ const MODULES = {
'isaar': 'ISAAR-CPF',
'isad': 'ISAD(G)',
'researchers-db/researchers': 'Researcher',
- 'researchers-db/requests': 'Request'
+ 'requests/list': 'Request'
};
-export const SimpleForm = ({api, module, type, initialValues}) => {
+export const SimpleForm = ({api, module, type, initialValues, onActiveTabChange}) => {
const router = useRouter();
const afterFinish = () => {
@@ -43,14 +43,14 @@ export const SimpleForm = ({api, module, type, initialValues}) => {
case 'donors':
return ;
case 'isaar':
- return ;
+ return ;
case 'isad':
- return ;
+ return ;
case 'finding-aids':
- return ;
+ return ;
case 'researchers-db/researchers':
return ;
- case 'researchers-db/requests':
+ case 'requests/list':
return ;
default:
break;
diff --git a/components/Forms/SimpleFormFooter.js b/components/Forms/SimpleFormFooter.js
index 0eab350..bfd9261 100644
--- a/components/Forms/SimpleFormFooter.js
+++ b/components/Forms/SimpleFormFooter.js
@@ -3,6 +3,7 @@ import style from "./Forms.module.css";
import React, {useState} from "react";
import {useRouter} from "next/router";
import Collapse from "@kunukn/react-collapse";
+import AuditLog from "./auditLog/AuditLog";
export const SimpleFormFooter = ({form, type, loading, module}) => {
const router = useRouter();
@@ -53,6 +54,7 @@ export const SimpleFormFooter = ({form, type, loading, module}) => {
{form.getFieldValue('date_updated')}
{form.getFieldValue('user_updated') ? ` by '${form.getFieldValue('user_updated')}'` : ''}
+
diff --git a/components/Forms/auditLog/AuditLog.js b/components/Forms/auditLog/AuditLog.js
new file mode 100644
index 0000000..82d0d4d
--- /dev/null
+++ b/components/Forms/auditLog/AuditLog.js
@@ -0,0 +1,68 @@
+import React from "react";
+import {useData} from "../../../utils/hooks/useData";
+import moment from "moment";
+
+const AuditLog = ({module, object_id}) => {
+ const getParams = () => {
+ let model = ''
+
+ if (module.includes('finding-aids/container')) {
+ model ='FindingAidsEntity'
+ } else {
+ switch(module) {
+ case 'accessions':
+ model = 'Accession'
+ break;
+ case 'donor':
+ model = 'Donor'
+ break;
+ case 'isad':
+ model = 'Isad'
+ break;
+ case 'isaar':
+ model = 'Isaar'
+ break;
+ case 'container':
+ model = 'Container'
+ break;
+ }
+ }
+
+ return {
+ model_name: model,
+ object_id: object_id
+ }
+ }
+ const { data, error } = useData(`/v1/audit_log/`, getParams());
+
+ const renderLogs = () => {
+ if (data.length > 0) {
+ return (
+
+ {
+ data.map(d => {
+ return -
+ {moment(d.timestamp).format('YYYY-MM-DD HH:mm:ss')} | [{d.action}] by {d.user}{d.changed_fields && <> | Fields: {d.changed_fields.join(', ')}>}
+
+ })
+ }
+
+ )
+ }
+ }
+
+ if (data && data.length > 0) {
+ return (
+ <>
+
+ {`Audit Log (from 2024. November 18th):`}
+ {renderLogs()}
+ >
+ )
+ } else {
+ return ''
+ }
+
+}
+
+export default AuditLog;
\ No newline at end of file
diff --git a/components/Forms/auditLog/AuditLog.module.scss b/components/Forms/auditLog/AuditLog.module.scss
new file mode 100644
index 0000000..e69de29
diff --git a/components/Forms/components/FormAuthoritySelect.js b/components/Forms/components/FormAuthoritySelect.js
index 450574b..b3acf08 100644
--- a/components/Forms/components/FormAuthoritySelect.js
+++ b/components/Forms/components/FormAuthoritySelect.js
@@ -1,10 +1,11 @@
import {Button, Col, Form, Input, Tooltip, Row, Table} from "antd";
import React, {useState} from "react";
import { SelectOutlined } from '@ant-design/icons';
-import style from "./FormAuthoritySelect.module.css";
+import style from "./FormAuthoritySelect.module.scss";
import {useData} from "../../../utils/hooks/useData";
+import ReactHtmlParser from 'react-html-parser';
-const AuthoritySelectTable = ({tableColumnTitle, tableColumnField, dataSource, ...props}) => {
+const AuthoritySelectTable = ({tableColumnTitle, tableColumnField, urlField, dataSource, ...props}) => {
const renderSelectButton = (data) => {
return(
@@ -17,14 +18,19 @@ const AuthoritySelectTable = ({tableColumnTitle, tableColumnField, dataSource, .
const renderTitle = (data) => {
return(
- {data}
+
+ {data[tableColumnField]}
+
)
};
+ const renderName = (data) => {
+ return (ReactHtmlParser(data))
+ }
+
const columns = [
{
title: tableColumnTitle,
- dataIndex: tableColumnField,
key: tableColumnField,
width: 400,
sorter: false,
@@ -34,6 +40,7 @@ const AuthoritySelectTable = ({tableColumnTitle, tableColumnField, dataSource, .
dataIndex: 'name',
key: 'name',
sorter: false,
+ render: renderName
}, {
title: 'Actions',
width: 150,
@@ -54,13 +61,15 @@ const AuthoritySelectTable = ({tableColumnTitle, tableColumnField, dataSource, .
)
};
-export const FormAuthoritySelect = ({api, type, nameField='name', field, form, columnTitle, columnField}) => {
+export const FormAuthoritySelect = ({api, type, nameField='name', field, form, columnTitle, columnField,
+ isWikidata=false, urlField}) => {
const [searchValue, setSearchValue] = useState('');
- const {data, loading} = useData(api, {query: searchValue, type: type});
+ const {data, loading} = useData(api, {query: searchValue, type: isWikidata ? undefined : type});
const onSearch = () => {
const search = form.getFieldValue(nameField);
+
if (search !== '') {
setSearchValue(search);
}
@@ -91,6 +100,7 @@ export const FormAuthoritySelect = ({api, type, nameField='name', field, form, c
onSelect={(val) => form.setFieldsValue({[field]: val})}
tableColumnTitle={columnTitle}
tableColumnField={columnField}
+ urlField={urlField}
/>
diff --git a/components/Forms/components/FormAuthoritySelect.module.css b/components/Forms/components/FormAuthoritySelect.module.scss
similarity index 74%
rename from components/Forms/components/FormAuthoritySelect.module.css
rename to components/Forms/components/FormAuthoritySelect.module.scss
index 23740ed..0c26ab7 100644
--- a/components/Forms/components/FormAuthoritySelect.module.css
+++ b/components/Forms/components/FormAuthoritySelect.module.scss
@@ -1,5 +1,9 @@
.AuthorityTable {
margin-top: 15px;
+
+ :global .searchmatch {
+ background-color: yellow;
+ }
}
.SearchButton {
diff --git a/components/Forms/components/FormDatePicker.js b/components/Forms/components/FormDatePicker.js
new file mode 100644
index 0000000..7d89a8d
--- /dev/null
+++ b/components/Forms/components/FormDatePicker.js
@@ -0,0 +1,28 @@
+import React from 'react';
+import {DatePicker} from "antd";
+import dayjs from "dayjs";
+
+
+const FormDatePicker = ({ format, disabled=false, value, onChange, ...props }) => {
+
+ const handleChange = (dateObj, dateString) => {
+ if (dateString === '') {
+ onChange(null)
+ } else {
+ onChange(dateString)
+ }
+ }
+
+ return (
+
+ )
+};
+
+export default FormDatePicker;
diff --git a/components/Forms/components/FormDuplications.js b/components/Forms/components/FormDuplications.js
new file mode 100644
index 0000000..24e626a
--- /dev/null
+++ b/components/Forms/components/FormDuplications.js
@@ -0,0 +1,142 @@
+import React, {useEffect, useState} from "react";
+import {get, post, remove} from "../../../utils/api";
+import style from "./FormDuplications.module.scss";
+import {LoadingOutlined, SaveOutlined, MergeOutlined } from "@ant-design/icons";
+import {Button, Modal, notification, Table, Tooltip} from "antd";
+import {renderURL} from "../../../utils/renders/renderURL";
+import {renderWikidataURL} from "../../../utils/renders/renderWikidataURL";
+import {renderSimilarity} from "../../../utils/renders/renderSimilarity";
+import {deleteAlert} from "../../Tables/functions/deleteAlert";
+
+
+const FormDuplications = ({api, selectedRecord, afterMergeFinish}) => {
+ const [loading, setLoading] = useState(true);
+ const [data, setData] = useState([]);
+
+ const onMergeClick = (record) => {
+ const keep_id = selectedRecord;
+ const merge_id = record.id;
+
+ const { confirm } = Modal;
+
+ confirm({
+ title: 'Are you sure you would merge the Person record into this one?',
+ okText: 'Yes',
+ okType: 'danger',
+ cancelText: 'No',
+ onOk() {
+ merge(keep_id, merge_id)
+ }
+ });
+ }
+
+ const onKeepClick = (record) => {
+ const keep_id = record.id;
+ const merge_id = selectedRecord;
+
+ const { confirm } = Modal;
+
+ confirm({
+ title: 'Are you sure you would merge (and after that, delete) this record with the selected one?',
+ okText: 'Yes',
+ okType: 'danger',
+ cancelText: 'No',
+ onOk() {
+ merge(keep_id, merge_id)
+ afterMergeFinish()
+ }
+ });
+ }
+
+ const merge = (keep_id, merge_id) => {
+ post(`/v1/authority_list/people/merge/`, {
+ keep_id: keep_id,
+ merge_id: merge_id}
+ ).then(response => {
+ getDuplicationData()
+ notification.success({
+ duration: 3,
+ message: 'Success!',
+ description: `Person records were merged, subject and contributor references were updated!`,
+ });
+ })
+ }
+
+ const renderActionButtons = (record) => {
+ return (
+
+
+ } onClick={() => onMergeClick(record)}/>
+
+
+ } onClick={() => onKeepClick(record)}/>
+
+
+ )
+ };
+
+ const columns = [
+ {
+ title: 'Name',
+ dataIndex: 'name',
+ key: 'name',
+ sorter: false,
+ }, {
+ title: 'Similarity',
+ width: 150,
+ dataIndex: 'similarity_percent',
+ key: 'similarity_percent',
+ sorter: false,
+ render: renderSimilarity
+ }, {
+ title: 'Authority URL',
+ dataIndex: 'authority_url',
+ key: 'authority_url',
+ sorter: false,
+ render: renderURL
+ }, {
+ title: 'Wikidata',
+ dataIndex: 'wikidata_id',
+ key: 'wikidata_id',
+ sorter: false,
+ render: renderWikidataURL
+ }, {
+ key: 'actions',
+ title: 'Actions',
+ width: 150,
+ className: style.ActionColumn,
+ render: (record) => renderActionButtons(record)
+ },
+ ];
+
+ const getDuplicationData = () => {
+ get(api).then(response => {
+ setLoading(false);
+ setData(response.data)
+ }).catch(error => {
+ setData(undefined);
+ setLoading(false);
+ })
+ }
+
+ useEffect(() => {
+ getDuplicationData()
+ }, [])
+
+ return (
+ record.id}
+ dataSource={data ? data : []}
+ columns={columns}
+ size={'small'}
+ loading={{
+ spinning: loading,
+ indicator: ,
+ }}
+ />
+ )
+}
+
+export default FormDuplications;
\ No newline at end of file
diff --git a/components/Forms/components/FormDuplications.module.scss b/components/Forms/components/FormDuplications.module.scss
new file mode 100644
index 0000000..5f264e7
--- /dev/null
+++ b/components/Forms/components/FormDuplications.module.scss
@@ -0,0 +1,7 @@
+.Table {
+ margin: 16px 0;
+}
+
+.ActionColumn {
+ text-align: center;
+}
\ No newline at end of file
diff --git a/components/Forms/components/FormFormattedText.js b/components/Forms/components/FormFormattedText.js
index 8c9f0ca..1def748 100644
--- a/components/Forms/components/FormFormattedText.js
+++ b/components/Forms/components/FormFormattedText.js
@@ -1,7 +1,11 @@
-import SunEditor from "suneditor-react";
import 'suneditor/dist/css/suneditor.min.css';
import React from "react";
import style from "./FormFormattedText.module.css";
+import dynamic from "next/dynamic";
+
+const SunEditor = dynamic(() => import("suneditor-react"), {
+ ssr: false,
+});
export const FormFormattedText = ({value, disabled=false, initialValue, ...props}) => {
const options = {
@@ -9,17 +13,18 @@ export const FormFormattedText = ({value, disabled=false, initialValue, ...props
['bold', 'underline', 'italic'],
['list', 'link'],
['outdent', 'indent'],
- ['undo', 'redo']
+ ['undo', 'redo'],
+ ['removeFormat']
],
defaultStyle: 'font-family: -apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif; ' +
'font-size: 14px; color: #5c6873;',
- resizingBar : false
+ resizingBar : true
};
return (
import("@uiw/react-md-editor/nohighlight").then((mod) => mod.default),
+ { ssr: false }
+)
+
+export const FormFormattedTextV3 = ({value, disabled=false, initialValue, ...props}) => {
+ return (
+
+
+
+ )
+};
diff --git a/components/Forms/components/FormFormattedTextV3.module.scss b/components/Forms/components/FormFormattedTextV3.module.scss
new file mode 100644
index 0000000..92c0ae8
--- /dev/null
+++ b/components/Forms/components/FormFormattedTextV3.module.scss
@@ -0,0 +1,21 @@
+.FormattedTextArea {
+ :global .w-md-editor-toolbar {
+ border-radius: 1px;
+ height: 40px;
+ }
+
+ :global .w-md-editor {
+ border-radius: 1px;
+ }
+
+ :global .w-md-editor-preview {
+ background-color: #F7F7F7;
+
+ :global .wmde-markdown {
+ background-color: #F7F7F7;
+ font-size: 14px !important;
+ line-height: 21px !important;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/components/Forms/components/FormRadioGroup.js b/components/Forms/components/FormRadioGroup.js
index b2a6790..2b08d37 100644
--- a/components/Forms/components/FormRadioGroup.js
+++ b/components/Forms/components/FormRadioGroup.js
@@ -1,17 +1,19 @@
import React, {useState, useEffect} from 'react';
import {Radio} from "antd";
-const FormRadioGroup = ({ value, options, onChange, valueField, labelField, disabled=false, ...props }) => {
+const FormRadioGroup = ({ value, options, defaultValue = undefined, optionType='radio', onChange, valueField, labelField, disabled=false, ...props }) => {
const radioOptions = options.map((d, idx) => (
{d[labelField]}
));
return (
onChange(e.target.value)}
disabled={disabled}
+ optionType={optionType}
+ buttonStyle="solid"
>
{radioOptions}
diff --git a/components/Forms/components/FormRemoteSelect.js b/components/Forms/components/FormRemoteSelect.js
index a34e5d1..cd29d3e 100644
--- a/components/Forms/components/FormRemoteSelect.js
+++ b/components/Forms/components/FormRemoteSelect.js
@@ -18,7 +18,7 @@ const FormRemoteSelect = ({ selectAPI, selectAPIParams={}, valueField, labelFiel
}, [data]);
const handleSearch = (value) => {
- if (value.length > 2 || value.length === 0) {
+ if (value.length > searchMinLength || value.length === 0) {
setParams(prevParams => ({
...prevParams,
search: value
diff --git a/components/Forms/components/FormRemoteSelectInfiniteScroll.js b/components/Forms/components/FormRemoteSelectInfiniteScroll.js
new file mode 100644
index 0000000..803895f
--- /dev/null
+++ b/components/Forms/components/FormRemoteSelectInfiniteScroll.js
@@ -0,0 +1,138 @@
+import React, {useState, useEffect} from 'react';
+import {Select, Spin} from "antd";
+import {useData} from "../../../utils/hooks/useData";
+import {useList, useUpdateEffect} from "react-use";
+import {get} from "../../../utils/api";
+
+const {Option} = Select;
+
+const FormRemoteSelectInfiniteScroll = ({ selectAPI, selectAPIParams={}, valueField, labelField,
+ onChange, placeholder, mode='default',
+ disabled=false, renderFunction, searchMinLength=2, ...props }) => {
+
+ const [data, setData] = useState(undefined);
+ const [params, setParams] = useState(selectAPIParams);
+
+ const [loading, setLoading] = useState(false);
+
+ const [selectAPIurl, setSelectAPIurl] = useState(undefined);
+ const [selectAPINextURL, setSelectAPINextURL] = useState(undefined)
+
+ const [selectData, { set, push }] = useList(undefined);
+ const [isDataLast, setIsDataLast] = useState(false)
+
+ useEffect(() => {
+ if (selectAPI) {
+ if (selectAPIurl) {
+ onChange(undefined)
+ }
+ setSelectAPIurl(selectAPI)
+ } else {
+ resetSelectOptions()
+ }
+ }, [selectAPI])
+
+ useUpdateEffect(() => {
+ fetchData()
+ }, [params])
+
+ useUpdateEffect(() => {
+ resetSelectOptions()
+ }, [selectAPIurl])
+
+ useUpdateEffect(() => {
+ data && push(...data['results']);
+ if (data) {
+ if (data['next']) {
+ setSelectAPINextURL(data['next'])
+ setIsDataLast(false)
+ } else {
+ setIsDataLast(true)
+ }
+ }
+ }, [data]);
+
+ const fetchData = () => {
+ get(selectAPIurl, params).then(response => {
+ setLoading(false);
+ setData(response.data)
+ }).catch(error => {
+ setData(undefined);
+ setLoading(false);
+ })
+ }
+
+ const createParams = () => {
+ const url = new URL(selectAPINextURL);
+ const URLParams = new URLSearchParams(url.search);
+
+ setParams(prevParams => ({
+ ...prevParams,
+ page: URLParams.get('page')
+ }))
+ }
+
+ const handleSearch = (value) => {
+ if (value.length > searchMinLength || value.length === 0) {
+ setParams({search: value})
+ set([])
+ }
+ };
+
+ const resetSelectOptions = () => {
+ setParams({});
+ set([])
+ }
+
+ const handleSelect = (value) => {
+ onChange(value)
+ resetSelectOptions()
+ };
+
+ const handleClear = () => {
+ resetSelectOptions()
+ onChange(undefined);
+ };
+
+ const onScroll = async (event) => {
+ if (!isDataLast) {
+ const target = event.target;
+ if (!loading && target.scrollTop + target.offsetHeight === target.scrollHeight) {
+ target.scrollTo(0, target.scrollHeight);
+ createParams()
+ }
+ }
+ }
+
+ const selectOptions = selectData.map(d => (
+
+ )
+ )
+
+
+ return (
+
+ )
+};
+
+export default FormRemoteSelectInfiniteScroll;
diff --git a/components/Forms/components/FormRemoteSelectWithEdit.js b/components/Forms/components/FormRemoteSelectWithEdit.js
index 2c34f18..a3e530c 100644
--- a/components/Forms/components/FormRemoteSelectWithEdit.js
+++ b/components/Forms/components/FormRemoteSelectWithEdit.js
@@ -1,122 +1,184 @@
import React, {useEffect, useState} from "react";
-import { EditOutlined, PlusOutlined } from '@ant-design/icons';
-import {Button, Drawer, Input, Select} from 'antd';
+import {EditOutlined, PlusOutlined} from "@ant-design/icons";
+import {Button, Drawer, Input, Select} from "antd";
import _ from "lodash";
import {PopupForm} from "../PopupForm";
import {useData} from "../../../utils/hooks/useData";
const {Option} = Select;
-export const FormRemoteSelectWithEdit = (
- { api, fieldName, module, selectAPI, selectAPIParams={}, valueField, labelField, onChange, placeholder,
- disabled=false, form, mode='default', ...props }) => {
- const [params, setParams] = useState(selectAPIParams);
- const [selectData, setSelectData] = useState([]);
- const [drawerShown, setDrawerShown] = useState(false);
- const [action, setAction] = useState('create');
- const [selectedRecord, setSelectedRecord] = useState({});
-
- const {data, loading, refresh} = useData(selectAPI, params);
-
- useEffect(() => {
- data && setSelectData(data)
- }, [data]);
-
- const handleSearch = (value) => {
- if (value.length > 2 || value.length === 0) {
- setParams(prevParams => ({
- ...prevParams,
- search: value
- }))
- }
- };
-
- const handleSelect = (value) => {
- if (params.hasOwnProperty('search') && params['search'] !== "") {
- setParams(prevParams => ({
- ...prevParams,
- search: ''
- }));
- }
- onChange(value)
- };
-
- const handleClear = () => {
- onChange(undefined);
- };
-
- const selectOptions = selectData.map(d => (
-
- ));
-
- const openForm = (action) => {
- setAction(action);
- setSelectedRecord(action === 'edit' ? props.value : undefined);
- setDrawerShown(true);
- };
-
- const onClose = (id) => {
- refresh();
- if (id) {
- form.setFieldsValue({[fieldName]: id})
- }
- setDrawerShown(false);
- };
-
- return (
-
-
-
- {
- mode !== 'multiple' &&
-
+export const FormRemoteSelectWithEdit = ({
+ api,
+ fieldName,
+ module,
+ selectAPI,
+ selectAPIParams = {},
+ valueField,
+ labelField,
+ onChange,
+ placeholder,
+ disabled = false,
+ form,
+ mode = "default",
+ ...props
+ }) => {
+ const [params, setParams] = useState(selectAPIParams);
+ const [selectData, setSelectData] = useState([]);
+ const [drawerShown, setDrawerShown] = useState(false);
+ const [action, setAction] = useState("create");
+ const [selectedRecord, setSelectedRecord] = useState(null);
+
+ const {data, loading, refresh} = useData(selectAPI, params);
+
+ // Load initial data
+ useEffect(() => {
+ if (data) setSelectData(data);
+ }, [data]);
+
+ const handleSearch = (value) => {
+ setParams((prev) => ({
+ ...prev,
+ search: value.length > 2 ? value : ""
+ }));
+ };
+
+ const handleSelect = (value) => {
+ // Clear search after selecting
+ if (params.search) {
+ setParams((p) => ({...p, search: ""}));
+ }
+ onChange(value);
+ };
+
+ const handleClear = () => onChange(undefined);
+
+ const openForm = (type) => {
+ setAction(type);
+ setSelectedRecord(type === "edit" ? props.value : null);
+ setDrawerShown(true);
+ };
+
+ /**
+ * onClose(record)
+ * record = newly created or edited record object
+ */
+ const onClose = (record) => {
+ setDrawerShown(false);
+
+ if (record) {
+ const newOption = {
+ [valueField]: record[valueField],
+ [labelField]: record[labelField],
+ };
+
+ // Add or update option optimistically
+ setSelectData((prev) =>
+ _.uniqBy([newOption, ...prev], valueField)
+ );
+
+ if (mode === "multiple") {
+ // CURRENT values may come from props or the form
+ const currentValues =
+ props.value ??
+ form.getFieldValue(fieldName) ??
+ [];
+
+ const updatedValues = _.uniq([
+ ...currentValues,
+ record[valueField]
+ ]);
+
+ form.setFieldsValue({[fieldName]: updatedValues});
+ onChange && onChange(updatedValues);
+ } else {
+ // SINGLE SELECT
+ form.setFieldsValue({[fieldName]: record[valueField]});
+ onChange && onChange(record[valueField]);
+ }
+ }
+
+ // Sync with the server in the background
+ refresh();
+ };
+
+ const getMessageText = () => {
+ switch (module) {
+ case 'places':
+ return 'Place';
+ case 'people':
+ return 'Person';
+ case 'corporations':
+ return 'Corporation';
+ case 'keywords':
+ return 'Keyword';
+ default:
+ return 'The';
}
-
-
- onClose()}
- open={drawerShown}
- destroyOnClose={true}
- >
-
-
-
- )
+ }
+
+ return (
+ <>
+
+
+
+ {/* EDIT BUTTON */}
+ {mode !== "multiple" && (
+
+ )}
+
+ {/* CREATE BUTTON */}
+
+
+
+ onClose()}
+ open={drawerShown}
+ destroyOnClose
+ >
+
+
+ >
+ );
};
diff --git a/components/Forms/components/FormTranslateButton.js b/components/Forms/components/FormTranslateButton.js
new file mode 100644
index 0000000..f19c406
--- /dev/null
+++ b/components/Forms/components/FormTranslateButton.js
@@ -0,0 +1,91 @@
+import style from "./FormTranslateButton.module.scss"
+import {Form, Modal, notification} from "antd";
+import {post} from "../../../utils/api";
+import {useState} from "react";
+
+const FormTranslateButton = ({form, mode, fieldName, toField}) => {
+ const value = Form.useWatch(fieldName, form);
+ const toFieldValue = Form.useWatch(toField, form);
+ const locale = Form.useWatch('original_locale', form);
+
+ const [loading, setLoading] = useState(false);
+
+ const { confirm } = Modal;
+
+ const translateText = () => {
+ let api;
+ let params = {};
+
+ if (mode === 'toOriginal') {
+ api = '/v1/workflow/translate_to_original/'
+ params = {
+ english_text: value,
+ original_locale: locale
+ }
+ } else {
+ api = '/v1/workflow/translate_to_english/'
+ params = {
+ original_text: value,
+ original_locale: locale
+ }
+ }
+
+ confirm({
+ title: 'Are you sure you would like to translate this field?',
+ okText: 'Yes',
+ okType: 'danger',
+ cancelText: 'No',
+ onOk() {
+ setLoading(true)
+ post(api, params).then(response => {
+ form.setFieldValue(toField, response.data['text'])
+ setLoading(false)
+ }).catch(error => {
+ notification.error({
+ duration: 3,
+ message: 'Error!',
+ description: `There is something wrong with the translation engine!`,
+ });
+ setLoading(false)
+ })
+ }
+ });
+
+ }
+
+ const getLabel = () => {
+ return mode === 'toOriginal' ? 'Translate to Original Language' : 'Translate to English'
+ }
+
+ const detectValue = (v) => {
+ if (!v) {
+ return false
+ }
+
+ if (v === null || v === '' || v === '
' || v === '' ) {
+ return false
+ }
+
+ return true
+ }
+
+ if (detectValue(value) && locale && !detectValue(toFieldValue)) {
+ if (loading) {
+ return (
+
+ Loading...
+
+ )
+ } else {
+ return (
+
+ )
+ }
+ } else {
+ return
+ }
+}
+
+export default FormTranslateButton;
\ No newline at end of file
diff --git a/components/Forms/components/FormTranslateButton.module.scss b/components/Forms/components/FormTranslateButton.module.scss
new file mode 100644
index 0000000..c33d186
--- /dev/null
+++ b/components/Forms/components/FormTranslateButton.module.scss
@@ -0,0 +1,8 @@
+.TranslateLink {
+ font-size: 10px;
+ margin-bottom: 12px;
+
+ a {
+ border-bottom: 1px dotted;
+ }
+}
\ No newline at end of file
diff --git a/components/Forms/fields/ArchivalUnitsSeriesForm.js b/components/Forms/fields/ArchivalUnitsSeriesForm.js
index 916f755..72cfbae 100644
--- a/components/Forms/fields/ArchivalUnitsSeriesForm.js
+++ b/components/Forms/fields/ArchivalUnitsSeriesForm.js
@@ -1,5 +1,5 @@
import React from 'react';
-import {Form, Col, Input, Row} from "antd";
+import {Form, Col, Input, Row, InputNumber} from "antd";
import FormRemoteSelect from "../components/FormRemoteSelect";
@@ -42,7 +42,7 @@ export const ArchivalUnitsSeriesForm = ({type, readOnly}) => {
name="series"
rules={[{ required: true, type: 'number', min: 1 }]}
>
-
+
diff --git a/components/Forms/fields/ArchivalUnitsSubFondsForm.js b/components/Forms/fields/ArchivalUnitsSubFondsForm.js
index 505b821..d4f6da3 100644
--- a/components/Forms/fields/ArchivalUnitsSubFondsForm.js
+++ b/components/Forms/fields/ArchivalUnitsSubFondsForm.js
@@ -1,9 +1,11 @@
import React from 'react';
-import {Form, Col, Input, Row} from "antd";
+import {Form, Col, Input, Row, InputNumber} from "antd";
import FormRemoteSelect from "../components/FormRemoteSelect";
-export const ArchivalUnitsSubFondsForm = ({type, readOnly}) => {
+export const ArchivalUnitsSubFondsForm = ({form, type, readOnly}) => {
+ const subfonds = Form.useWatch('subfonds', form)
+
return (
@@ -26,13 +28,24 @@ export const ArchivalUnitsSubFondsForm = ({type, readOnly}) => {
label="Subfonds"
name="subfonds"
required
- rules={[{ required: true, type: 'number', min: 1 }]}
+ rules={[{ required: true, type: 'number', min: 0 }]}
>
-
+
-
+ {
+ if (subfonds !== 0) {
+ if (value.length === 0) {
+ return Promise.reject(
+ new Error("Empty title is only allowed for 0 subfonds!"),
+ );
+ }
+ }
+ return Promise.resolve();
+ }
+ }]}>
diff --git a/components/Forms/fields/CarrierTypeForm.js b/components/Forms/fields/CarrierTypeForm.js
index 89a59f4..70c5789 100644
--- a/components/Forms/fields/CarrierTypeForm.js
+++ b/components/Forms/fields/CarrierTypeForm.js
@@ -15,17 +15,17 @@ export const CarrierTypeForm = ({readOnly}) => {
-
+
-
+
-
+
diff --git a/components/Forms/fields/CorporationForm.js b/components/Forms/fields/CorporationForm.js
index edfae5f..9cf071f 100644
--- a/components/Forms/fields/CorporationForm.js
+++ b/components/Forms/fields/CorporationForm.js
@@ -34,6 +34,18 @@ export const CorporationForm = ({form, readOnly}) => {
type={'corporation'}
/>
+
+
+
{
type={'country'}
/>
+
+
+
{
- console.log(value);
-
return (
value ?
{
return (
-
+
diff --git a/components/Forms/fields/DonorForm.js b/components/Forms/fields/DonorForm.js
index 744cec3..a8b6dbe 100644
--- a/components/Forms/fields/DonorForm.js
+++ b/components/Forms/fields/DonorForm.js
@@ -41,7 +41,7 @@ export const DonorForm = ({readOnly}) => {
-
+
@@ -66,7 +66,7 @@ export const DonorForm = ({readOnly}) => {
-
+
diff --git a/components/Forms/fields/FindingAidsEntityForm.js b/components/Forms/fields/FindingAidsEntityForm.js
index 4639f93..e2f58b6 100644
--- a/components/Forms/fields/FindingAidsEntityForm.js
+++ b/components/Forms/fields/FindingAidsEntityForm.js
@@ -1,9 +1,8 @@
-import React from "react";
-import {Checkbox, Col, Form, Input, Row, Tabs} from "antd";
+import React, {useEffect, useState} from "react";
+import {Badge, Button, Checkbox, Col, DatePicker, Form, Input, Row, Space, Tabs} from "antd";
import FormSelect from "../components/FormSelect";
import FormRemoteSelect from "../components/FormRemoteSelect";
import {renderLabelFlag} from "../../../utils/functions/renderLabelFlag";
-import {FormFormattedText} from "../components/FormFormattedText";
import {Dates} from "./finding_aids/Dates";
import {Languages} from "./finding_aids/Languages";
import {Extents} from "./finding_aids/Extents";
@@ -12,8 +11,12 @@ import {ContributorsCorporations} from "./finding_aids/ContributorsCorporations"
import {AdditionalCountries} from "./finding_aids/AdditionalCountries";
import {AdditionalPlaces} from "./finding_aids/AdditionalPlaces";
import {FormRemoteSelectWithEdit} from "../components/FormRemoteSelectWithEdit";
-
-const {TabPane} = Tabs;
+import FormTranslateButton from "../components/FormTranslateButton";
+import DigitalVersionTab from "./finding_aids/DigitalVersionTab";
+import FormDatePicker from "../components/FormDatePicker";
+import dayjs from "dayjs";
+import {Identifiers} from "./finding_aids/Identifiers";
+import {FormFormattedTextV3} from "../components/FormFormattedTextV3";
const L1_LEVELS = [
{ id: 'F', level: 'Folders'},
@@ -29,6 +32,11 @@ const DESCRIPTION_LEVELS = [
{ id: 'L2', level: 'Level 2'},
];
+const ACCESS_RIGHTS = [
+ { id: 1, right: 'Not Restricted'},
+ { id: 3, right: 'Restricted'},
+];
+
const createData = (maxValue) => {
const data = [...Array(maxValue+1).keys()].map(value => {return {id: value, number: value}});
data.shift();
@@ -102,99 +110,173 @@ const Identifier = ({initialValues, type}) => (
);
-const Tab01 = ({locale, readOnly, type}) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-);
+const Tab01 = ({form, locale, readOnly}) => {
+ const accessRights = Form.useWatch('access_rights', form)
+ const dateFrom = Form.useWatch('date_from', form)
+ const restrictionDate = Form.useWatch('access_rights_restriction_date', form)
+
+ const setRestrictionDate = (number) => {
+ let dObj;
+ if (restrictionDate) {
+ dObj = dayjs(restrictionDate)
+ } else {
+ if (dateFrom) {
+ try {
+ dObj = dayjs(`${dateFrom.slice(0, 4)}-12-31`)
+ } catch (error) {
+ // Invalid date
+ }
+ }
+ }
+ if (dObj.isValid()) {
+ form.setFieldValue('access_rights_restriction_date', dObj.add(number, 'year').format('YYYY-MM-DD'))
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
const IdentifierTemplate = ({initialValues, type}) => (
(
);
-const Tab01Template = ({locale, readOnly, type}) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-);
+const Tab01Template = ({form, locale, readOnly, type}) => {
+ const accessRights = Form.useWatch('access_rights', form)
+ const dateFrom = Form.useWatch('date_from', form)
+ const restrictionDate = Form.useWatch('access_rights_restriction_date', form)
-const Tab02 = ({form, locale, readOnly}) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-);
+ const setRestrictionDate = (number) => {
+ let dObj;
+ if (restrictionDate) {
+ dObj = dayjs(restrictionDate)
+ } else {
+ if (dateFrom) {
+ try {
+ dObj = dayjs(`${dateFrom.slice(0, 4)}-12-31`)
+ } catch (error) {
+ // Invalid date
+ }
+ }
+ }
+ if (dObj.isValid()) {
+ form.setFieldValue('access_rights_restriction_date', dObj.add(number, 'year').format('YYYY-MM-DD'))
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+const Tab02 = ({form, locale, readOnly}) => {
+ const timeStart = Form.useWatch('time_start', form)
+ const timeEnd = Form.useWatch('time_end', form)
+
+ useEffect(() => {
+ const ts = dayjs(timeStart, 'HH:mm:ss')
+ const te = dayjs(timeEnd, 'HH:mm:ss')
+
+ if (timeStart) {
+ if (timeEnd) {
+ if (ts.isValid() && te.isValid()) {
+ if (ts.isBefore(te)) {
+ const duration = te.diff(ts)
+ form.setFieldValue('duration', dayjs(duration).subtract(1, 'hour').format('HH:mm:ss'))
+ } else {
+ form.setFieldValue('duration', '')
+ }
+ } else {
+ form.setFieldValue('duration', '')
+ }
+ } else {
+ if (ts.isValid()) {
+ form.setFieldValue('duration', timeStart)
+ } else {
+ form.setFieldValue('duration', '')
+ }
+ }
+ } else {
+ form.setFieldValue('duration', '')
+ }
+
+ }, [timeStart, timeEnd])
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+};
const Tab03 = ({form, readOnly}) => (
@@ -454,9 +660,9 @@ const Tab04 = ({form, readOnly}) => (
-
+
(
);
-const Tab05 = ({locale, readOnly}) => (
+const Tab05 = ({form, locale, readOnly}) => (
-
+
+
-
+ name="note_original"
+ style={{marginBottom: 0}}>
+
+
-
+
);
-export const FindingAidsEntityForm = ({form, locale, type, initialValues, isTemplate=false}) => {
+export const FindingAidsEntityForm = ({form, locale, type, initialValues, onActiveTabChange, isTemplate=false}) => {
const readOnly = type === 'view';
+ useEffect(() => {
+ onActiveTabChange('basic')
+ }, [])
+
+ const onChange = (activeKey) => {
+ onActiveTabChange(activeKey)
+ }
+
+ let items = [
+ {
+ key: 'basic',
+ label: 'Basic Metadata',
+ forceRender: true,
+ children: isTemplate ?
+ :
+
+ }, {
+ key: 'extra',
+ label: 'Extra Metadata',
+ forceRender: true,
+ children:
+ }, {
+ key: 'contributors',
+ label: 'Contributors',
+ forceRender: true,
+ children:
+ }, {
+ key: 'subjects',
+ label: 'Subjects',
+ forceRender: true,
+ children:
+ }, {
+ key: 'notes',
+ label: 'Notes',
+ forceRender: true,
+ children:
+ }
+ ]
+
return (
@@ -539,27 +797,7 @@ export const FindingAidsEntityForm = ({form, locale, type, initialValues, isTemp
}
-
-
- {
- isTemplate ?
- :
-
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
)
diff --git a/components/Forms/fields/FindingAidsEntityQuickForm.js b/components/Forms/fields/FindingAidsEntityQuickForm.js
index e181cf9..38c1c62 100644
--- a/components/Forms/fields/FindingAidsEntityQuickForm.js
+++ b/components/Forms/fields/FindingAidsEntityQuickForm.js
@@ -1,9 +1,12 @@
import React from "react";
-import { Col, Form, Input, Row } from "antd";
+import {Button, Col, Form, Input, Row, Space} from "antd";
import FormSelect from "../components/FormSelect";
import FormRemoteSelect from "../components/FormRemoteSelect";
import {renderLabelFlag} from "../../../utils/functions/renderLabelFlag";
-import {FormFormattedText} from "../components/FormFormattedText";
+import {FormFormattedTextV3} from "../components/FormFormattedTextV3";
+import FormTranslateButton from "../components/FormTranslateButton";
+import FormDatePicker from "../components/FormDatePicker";
+import dayjs from "dayjs";
const L1_LEVELS = [
@@ -20,6 +23,11 @@ const DESCRIPTION_LEVELS = [
{ id: 'L2', level: 'Level 2'},
];
+const ACCESS_RIGHTS = [
+ { id: 1, right: 'Not Restricted'},
+ { id: 3, right: 'Restricted'},
+];
+
const Identifier = ({initialValues, type}) => (
(
export const FindingAidsEntityQuickForm = ({form, locale, type}) => {
const readOnly = type === 'view';
+ const accessRights = Form.useWatch('access_rights', form)
+ const dateFrom = Form.useWatch('date_from', form)
+ const restrictionDate = Form.useWatch('access_rights_restriction_date', form)
+
+ const setRestrictionDate = (number) => {
+ let dObj;
+ if (restrictionDate) {
+ dObj = dayjs(restrictionDate)
+ } else {
+ if (dateFrom) {
+ try {
+ dObj = dayjs(`${dateFrom.slice(0, 4)}-12-31`)
+ } catch (error) {
+ // Invalid date
+ }
+ }
+ }
+ if (dObj.isValid()) {
+ form.setFieldValue('access_rights_restriction_date', dObj.add(number, 'year').format('YYYY-MM-DD'))
+ }
+ }
+
return (
@@ -97,16 +127,29 @@ export const FindingAidsEntityQuickForm = ({form, locale, type}) => {
-
+
+
+ name="title_original"
+ style={{marginBottom: 0}}>
+
@@ -123,17 +166,59 @@ export const FindingAidsEntityQuickForm = ({form, locale, type}) => {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
-
+ name="contents_summary_original"
+ style={{marginBottom: 0}}>
+
+
diff --git a/components/Forms/fields/GenreForm.js b/components/Forms/fields/GenreForm.js
index b7d394b..d4d35aa 100644
--- a/components/Forms/fields/GenreForm.js
+++ b/components/Forms/fields/GenreForm.js
@@ -30,6 +30,19 @@ export const GenreForm = ({form, readOnly}) => {
type={'genre'}
/>
+
+
+
(
);
-export const IsaarForm = ({form, readOnly}) => {
+export const IsaarForm = ({form, readOnly, onActiveTabChange}) => {
+ useEffect(() => {
+ onActiveTabChange('required_values')
+ }, [])
+
+ const onChange = (activeKey) => {
+ onActiveTabChange(activeKey)
+ }
+
+ const items = [
+ {
+ key: 'required_values',
+ label: renderTabTitle(form, FIELD_NAMES['tab01'], "Required Values"),
+ children:
+ }, {
+ key: 'identity',
+ label: renderTabTitle(form, FIELD_NAMES['tab02'], "Identity"),
+ children:
+ }, {
+ key: 'description',
+ label: renderTabTitle(form, FIELD_NAMES['tab03'], "Description"),
+ children:
+ }, {
+ key: 'control',
+ label: 'Control',
+ children:
+ }
+ ]
+
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
)
diff --git a/components/Forms/fields/IsadForm.js b/components/Forms/fields/IsadForm.js
index 74319c6..cdc0f24 100644
--- a/components/Forms/fields/IsadForm.js
+++ b/components/Forms/fields/IsadForm.js
@@ -1,4 +1,4 @@
-import React from "react";
+import React, {useEffect, useState} from "react";
import {Col, Form, Input, Row, Tabs} from "antd";
import FormSelect from "../components/FormSelect";
import FormRemoteSelect from "../components/FormRemoteSelect";
@@ -6,12 +6,11 @@ import {Creators} from "./isad/Creators";
import {FormRemoteSelectWithEdit} from "../components/FormRemoteSelectWithEdit";
import {renderLabelFlag} from "../../../utils/functions/renderLabelFlag";
import {Extents} from "./isad/Extents";
-import {FormFormattedText} from "../components/FormFormattedText";
import {RelatedFindingAids} from "./isad/RelatedFindingAids";
import {LocationOfOriginals} from "./isad/LocationOfOriginals";
import {LocationOfCopies} from "./isad/LocationOfCopies";
-
-const {TabPane} = Tabs;
+import FormTranslateButton from "../components/FormTranslateButton";
+import {FormFormattedTextV3} from "../components/FormFormattedTextV3";
const ACCRUALS = [
{ id: true, accrual: 'Expected'},
@@ -30,18 +29,18 @@ const Tab01 = ({form, readOnly}) => (
-
+
-
+
(
@@ -60,7 +59,7 @@ const Tab01 = ({form, readOnly}) => (
-
+
(
-
+
(
disabled={readOnly}
/>
-
+
(
-
+
-
+
(
-
+
(
);
-const Tab02 = ({locale, readOnly}) => {
+const Tab02 = ({form, locale, readOnly}) => {
return (
-
+
@@ -172,108 +171,199 @@ const Tab02 = ({locale, readOnly}) => {
-
-
+
+
+
-
+ label={renderLabelFlag(locale, 'Estimated amount of carriers - Original language')}
+ name="carrier_estimated_original"
+ style={{marginBottom: 0}}>
+
+
)
};
-const Tab03 = ({locale, readOnly}) => {
+const Tab03 = ({form, locale, readOnly}) => {
return (
-
-
+
+
+
-
+ label={renderLabelFlag(locale, '3.2.2 Administrative history - Original language')}
+ name="administrative_history_original"
+ style={{marginBottom: 0}}>
+
+
-
-
+
+
+
-
+ label={renderLabelFlag(locale, '3.2.3 Archival history - Original language')}
+ name="archival_history_original"
+ style={{marginBottom: 0}}>
+
+
)
};
-const Tab04 = ({locale, readOnly}) => {
+const Tab04 = ({form, locale, readOnly}) => {
return (
-
-
+
+
+
-
+ label={renderLabelFlag(locale, '3.3.1 Scope and content (abstract) - Original Language')}
+ name="scope_and_content_abstract_original"
+ style={{marginBottom: 0}}>
+
+
-
-
+
+
+
-
+ label={renderLabelFlag(locale, '3.3.1 Scope and content (narrative) - Original Language')}
+ name="scope_and_content_narrative_original"
+ style={{marginBottom: 0}}>
+
+
-
-
+
+
+
-
+ label={renderLabelFlag(locale, '3.3.2 Appraisal - Original language')}
+ name="appraisal_original"
+ style={{marginBottom: 0}}>
+
+
-
-
+
+
+
-
+ label={renderLabelFlag(locale, '3.3.4 System of arrangement information - Original language')}
+ name="system_of_arrangement_information_original"
+ style={{marginBottom: 0}}>
+
+
)
};
-const Tab05 = ({locale, readOnly}) => {
+const Tab05 = ({form, locale, readOnly}) => {
return (
@@ -282,16 +372,29 @@ const Tab05 = ({locale, readOnly}) => {
-
-
+
+
+
-
+ label={renderLabelFlag(locale, '3.4.4 Physical characteristics and technical requirements - Original language')}
+ name="physical_characteristics_original"
+ style={{marginBottom: 0}}>
+
+
@@ -300,7 +403,7 @@ const Tab05 = ({locale, readOnly}) => {
)
};
-const Tab06 = ({locale, readOnly}) => {
+const Tab06 = ({form, locale, readOnly}) => {
return (
@@ -310,62 +413,114 @@ const Tab06 = ({locale, readOnly}) => {
-
-
+
+
+
-
+ label={renderLabelFlag(locale, '3.5.4 Publication note - Original Language')}
+ name="publication_note_original"
+ style={{marginBottom: 0}}>
+
+
)
};
-const Tab07 = ({locale, readOnly}) => {
+const Tab07 = ({form, locale, readOnly}) => {
return (
-
-
+
+
+
-
+ label={renderLabelFlag(locale, '3.6.1 Note - Original language')}
+ name="note_original"
+ style={{marginBottom: 0}}>
+
+
-
+
+
+ label={renderLabelFlag(locale, 'Internal note - Original language')}
+ name="internal_note_original"
+ style={{marginBottom: 0}}>
+
-
+
+
+ label={renderLabelFlag(locale, '3.7.1 Archivists note - Original language')}
+ name="archivists_note_original"
+ style={{marginBottom: 0}}>
+
-
+
@@ -373,33 +528,52 @@ const Tab07 = ({locale, readOnly}) => {
)
};
-export const IsadForm = ({form, locale, readOnly}) => {
+export const IsadForm = ({form, readOnly, onActiveTabChange}) => {
+
+ useEffect(() => {
+ onActiveTabChange('required_values')
+ }, [])
+
+ const onChange = (activeKey) => {
+ onActiveTabChange(activeKey)
+ }
+
+ const items = [
+ {
+ key: 'required_values',
+ label: 'Required Values',
+ children:
+ }, {
+ key: 'identity',
+ label: 'Identity',
+ children:
+ }, {
+ key: 'context',
+ label: 'Context',
+ children:
+ }, {
+ key: 'content',
+ label: 'Content',
+ children:
+ }, {
+ key: 'access_and_use',
+ label: 'Access & Use',
+ children:
+ }, {
+ key: 'allied_materials',
+ label: 'Allied Materials',
+ children:
+ }, {
+ key: 'notes',
+ label: 'Notes',
+ children:
+ },
+ ]
+
return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
)
diff --git a/components/Forms/fields/LanguageForm.js b/components/Forms/fields/LanguageForm.js
index 9b19ade..219ff31 100644
--- a/components/Forms/fields/LanguageForm.js
+++ b/components/Forms/fields/LanguageForm.js
@@ -1,21 +1,27 @@
import React from 'react';
import {Form, Col, Input} from "antd";
+import {FormAuthoritySelect} from "../components/FormAuthoritySelect";
-export const LanguageForm = ({readOnly}) => {
+export const LanguageForm = ({form, readOnly}) => {
return (
-
+
+
+
+
+
+
-
+
@@ -29,6 +35,19 @@ export const LanguageForm = ({readOnly}) => {
+
+
+
)
};
diff --git a/components/Forms/fields/NationalityForm.js b/components/Forms/fields/NationalityForm.js
new file mode 100644
index 0000000..7575b5e
--- /dev/null
+++ b/components/Forms/fields/NationalityForm.js
@@ -0,0 +1,15 @@
+import React from 'react';
+import {Form, Col, Input} from "antd";
+
+export const NationalityForm = ({readOnly}) => {
+ return (
+
+
+
+
+
+
+
+ )
+};
+
diff --git a/components/Forms/fields/PersonForm.js b/components/Forms/fields/PersonForm.js
index 2ea48ee..8556504 100644
--- a/components/Forms/fields/PersonForm.js
+++ b/components/Forms/fields/PersonForm.js
@@ -2,10 +2,11 @@ import React from 'react';
import {Form, Col, Input, Tabs} from "antd";
import {FormAuthoritySelect} from "../components/FormAuthoritySelect";
import {PersonOtherNames} from "./authority_lists/PersonOtherNames";
+import FormDuplications from "../components/FormDuplications";
const { TabPane } = Tabs;
-export const PersonForm = ({form, readOnly}) => {
+export const PersonForm = ({form, selectedRecord, readOnly, afterMergeFinish, hasMerge}) => {
return (
@@ -38,6 +39,18 @@ export const PersonForm = ({form, readOnly}) => {
type={'person'}
/>
+
+
+
{
type={'person'}
/>
+ { selectedRecord && hasMerge &&
+
+
+
+ }
diff --git a/components/Forms/fields/PlaceForm.js b/components/Forms/fields/PlaceForm.js
index 7e7b140..84d7461 100644
--- a/components/Forms/fields/PlaceForm.js
+++ b/components/Forms/fields/PlaceForm.js
@@ -31,6 +31,19 @@ export const PlaceForm = ({form, readOnly}) => {
type={'place'}
/>
+
+
+
{
return item_type === 'FA'
case 'title':
return item_type === 'FA'
+ case 'quantity':
+ return item_type === 'FA'
default:
return true
}
}
+ const getSeriesID = () => {
+ if (archival_unit) {
+ if (archival_unit.hasOwnProperty('value')) {
+ return archival_unit['value']
+ } else {
+ return undefined
+ }
+ } else {
+ return undefined
+ }
+ }
+
return (
{
name={'archival_unit'}
rules={[(form) => checkRequiredIfArchival(form, 'item_origin')]}
>
- {
name={'container'}
rules={[(form) => checkRequiredIfArchival(form, 'item_origin')]}
>
-
-
+
{
/>
-
+
{
/>
+
+ checkRequiredIfLibrary(form, 'item_origin')]}
+ >
+
+
+
)
diff --git a/components/Forms/fields/ResearcherForm.js b/components/Forms/fields/ResearcherForm.js
index 5984b08..9071e64 100644
--- a/components/Forms/fields/ResearcherForm.js
+++ b/components/Forms/fields/ResearcherForm.js
@@ -6,6 +6,8 @@ import FormRadioGroup from "../components/FormRadioGroup";
import style from "../Forms.module.css";
const OCCUPATION = [
+ { id: 'ceu_student', occupation: 'CEU Student'},
+ { id: 'ceu_faculty', occupation: 'CEU Faculty'},
{ id: 'ceu', occupation: 'CEU'},
{ id: 'other', occupation: 'Other'},
];
@@ -21,8 +23,21 @@ const YES_NO = [
{ value: 'no', label: 'No' }
]
+const HOW_DO_YOU_KNOW_CHOICES = [
+ { value: 'web', label: 'OSA web page'},
+ { value: 'event', label: 'Event at OSA'},
+ { value: 'verzio', label: 'Verzio'},
+ { value: 'ceu', label: 'CEU'},
+ { value: 'contacts', label: 'Personal contacts'},
+ { value: 'media', label: 'Media'},
+ { value: 'other', label: 'Other'}
+]
+
export const ResearcherForm = ({form, readOnly}) => {
const cardNumber = form.getFieldValue('card_number')
+ const howDoYouKnowOSA = Form.useWatch('how_do_you_know_osa')
+
+ console.log(howDoYouKnowOSA)
return (
@@ -36,42 +51,36 @@ export const ResearcherForm = ({form, readOnly}) => {
-
-
+
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
{
options={OCCUPATION_TYPE}
valueField={'value'}
labelField={'label'}
- disabled={readOnly}
+ disabled={true}
/>
-
+
-
+
{
+
+
+
+ {
+ howDoYouKnowOSA === 'other' &&
+
+
+
+ }
diff --git a/components/Forms/fields/SubjectForm.js b/components/Forms/fields/SubjectForm.js
index 81ce548..38b6032 100644
--- a/components/Forms/fields/SubjectForm.js
+++ b/components/Forms/fields/SubjectForm.js
@@ -30,6 +30,19 @@ export const SubjectForm = ({form, readOnly}) => {
type={'subject'}
/>
+
+
+
(
/>
-
+
-
+
+
+
+
+
+
diff --git a/components/Forms/fields/BarcodeForm.js b/components/Forms/fields/containers/BarcodeForm.js
similarity index 100%
rename from components/Forms/fields/BarcodeForm.js
rename to components/Forms/fields/containers/BarcodeForm.js
diff --git a/components/Forms/fields/ContainerForm.js b/components/Forms/fields/containers/ContainerForm.js
similarity index 63%
rename from components/Forms/fields/ContainerForm.js
rename to components/Forms/fields/containers/ContainerForm.js
index 2eb6975..03940dc 100644
--- a/components/Forms/fields/ContainerForm.js
+++ b/components/Forms/fields/containers/ContainerForm.js
@@ -1,6 +1,8 @@
-import React from 'react';
-import {Form, Col, Input, Checkbox} from "antd";
-import FormRemoteSelect from "../components/FormRemoteSelect";
+import React, {useEffect} from 'react';
+import {Form, Col, Input, Checkbox, Divider, Switch, Button} from "antd";
+import FormRemoteSelect from "../../components/FormRemoteSelect";
+import ResearchCloudLink from "../finding_aids/ResearchCloudLink";
+import {FormFormattedText} from "../../components/FormFormattedText";
export const ContainerForm = ({form, readOnly}) => {
return (
@@ -30,8 +32,13 @@ export const ContainerForm = ({form, readOnly}) => {
-
- Digital version exists
+
+
+
+
+
+
+
diff --git a/components/Forms/fields/containers/DigitalVersionsTable.js b/components/Forms/fields/containers/DigitalVersionsTable.js
new file mode 100644
index 0000000..2c921c0
--- /dev/null
+++ b/components/Forms/fields/containers/DigitalVersionsTable.js
@@ -0,0 +1,99 @@
+import {Button, Table} from "antd";
+import ResearchCloudLink from "../finding_aids/ResearchCloudLink";
+import style from "./DigitalVersionsTable.module.scss";
+import CatalogLink from "../finding_aids/CatalogLink";
+
+const DigitalVersionsTable = ({digitalVersions, catalogID}) => {
+ const renderLevel = (text, record) => {
+ switch (text) {
+ case 'A':
+ return 'Access Copy';
+ case 'M':
+ return 'Master';
+ }
+ }
+
+ const renderAvailability = (text, record) => {
+ switch (record['level']) {
+ case 'A':
+ if (record['available_research_cloud']) {
+ return (
+
+
+
+ )
+ }
+
+ if (record['available_online']) {
+ return (
+
+
+
+ )
+ }
+
+ return (
+
+
+
+ )
+ case 'M':
+ const physical_copies = record['physical_copies'];
+
+ return (
+
+ { physical_copies.map((physical_copy, index) => (
+
+
+ {physical_copy['storage_unit']}
+
+
+ {physical_copy['storage_unit_label']}
+
+
+ ))}
+
+ )
+
+
+ }
+ }
+
+ const columns = [
+ {
+ title: 'Level',
+ dataIndex: 'level',
+ key: 'level',
+ render: renderLevel,
+ filters: [
+ { text: 'Master', value: 'M' },
+ { text: 'Access Copy', value: 'A' }
+ ],
+ onFilter: (value, record) => record.level.indexOf(value) === 0,
+ width: 150,
+ }, {
+ title: 'Filename',
+ dataIndex: 'filename',
+ key: 'filename',
+ width: 250,
+ }, {
+ title: 'Available',
+ dataIndex: 'available',
+ key: 'available',
+ render: renderAvailability,
+ }
+ ]
+
+ return (
+ record.id}
+ dataSource={digitalVersions}
+ columns={columns}
+ size={'small'}
+ pagination={false}
+ />
+ )
+}
+
+export default DigitalVersionsTable;
\ No newline at end of file
diff --git a/components/Forms/fields/containers/DigitalVersionsTable.module.scss b/components/Forms/fields/containers/DigitalVersionsTable.module.scss
new file mode 100644
index 0000000..7d7011e
--- /dev/null
+++ b/components/Forms/fields/containers/DigitalVersionsTable.module.scss
@@ -0,0 +1,19 @@
+.Availability {
+ text-align: center;
+}
+
+.AvailabilityRow {
+ font-size: 12px;
+ display: flex;
+ align-items: center;
+
+ .StorageUnit {
+ width: 50px;
+ text-align: left;
+ }
+
+ .StorageLabel {
+ flex: 1;
+ text-align: left;
+ }
+}
\ No newline at end of file
diff --git a/components/Forms/fields/finding_aids/CatalogLink.js b/components/Forms/fields/finding_aids/CatalogLink.js
new file mode 100644
index 0000000..15fa06d
--- /dev/null
+++ b/components/Forms/fields/finding_aids/CatalogLink.js
@@ -0,0 +1,24 @@
+import {Badge, Button} from "antd";
+
+const CatalogLink = ({catalogID, buttonText='Open', isBadge=false}) => {
+ const getLink = () => {
+ return encodeURI(`https://catalog.archivum.org/catalog/${catalogID}`);
+ }
+
+ if (isBadge) {
+ return (
+
+
+
+ )
+ } else {
+ return (
+
+
+
+ )
+ }
+
+}
+
+export default CatalogLink;
\ No newline at end of file
diff --git a/components/Forms/fields/finding_aids/DigitalVersionTab.js b/components/Forms/fields/finding_aids/DigitalVersionTab.js
new file mode 100644
index 0000000..74e750f
--- /dev/null
+++ b/components/Forms/fields/finding_aids/DigitalVersionTab.js
@@ -0,0 +1,159 @@
+import {Badge, Checkbox, Col, Divider, Form, Input, Row, Switch} from "antd";
+import React, {useEffect} from "react";
+import ResearchCloudLink from "./ResearchCloudLink";
+
+const DigitalVersionTab = ({form, initialValues, locale, readOnly}) => {
+ const digitalVersionExists = Form.useWatch('digital_version_exists', form);
+ const archivalReferenceCode = Form.useWatch('archival_reference_code', form);
+
+ const {digital_version_exists_container} = initialValues
+
+ useEffect(() => {
+ if (digitalVersionExists && !digitalVersionExists) {
+ form.setFieldValue("digital_version_research_cloud", false)
+ form.setFieldValue("digital_version_online", false)
+ }
+ }, [digitalVersionExists])
+
+ const getDisabled = () => {
+ if (readOnly) {
+ return true
+ } else {
+ return !digitalVersionExists
+ }
+ }
+
+ const renderContainerDigitalVersion = () => {
+ const {digital_version} = digital_version_exists_container
+
+ if (digital_version) {
+ if (digital_version_exists_container['digital_version_online']) {
+ return (
+
+
+
+ )
+ }
+
+ if (digital_version_exists_container['digital_version_research_cloud']) {
+ return (
+
+
+
+ )
+ }
+
+ return (
+
+
+
+ )
+
+ } else {
+ return (
+
+
+
+ )
+ }
+ }
+
+ const renderDigitalVersionIdentifier = () => {
+ const {digital_version} = digital_version_exists_container
+ const {digital_version_barcode} = digital_version_exists_container
+
+ const renderContainerLevelIdentifier = () => {
+ if (archivalReferenceCode) {
+ let unit = archivalReferenceCode.split(':')[0]
+ let container = archivalReferenceCode.replaceAll(unit, '').split('/')[0]
+ container = container.replaceAll(":", "").padStart(4, "0")
+
+ return `${unit.replaceAll(" ", "_").replaceAll("-", "_")}_${container}`;
+ } else {
+ return ''
+ }
+ }
+
+ const renderFolderItemLevelIdentifier = () => {
+ let unit = archivalReferenceCode.split(':')[0]
+ let container = archivalReferenceCode.replaceAll(unit, '').split('/')[0]
+ let folder = archivalReferenceCode.replaceAll(unit, '').split('/')[1]
+
+ container = container.replaceAll(":", "").padStart(4, "0")
+ folder = folder.padStart(4, "0")
+
+ return `${unit.replaceAll(" ", "_").replaceAll("-", "_")}_${container}_${folder}`;
+ }
+
+ if (digitalVersionExists) {
+ return renderFolderItemLevelIdentifier()
+ } else {
+ if (digital_version) {
+ if (digital_version_barcode) {
+ return digital_version_barcode
+ } else {
+ return renderContainerLevelIdentifier()
+ }
+ } else {
+ return 'N/A'
+ }
+ }
+ }
+
+ return (
+
+
+
+
+
+
+
+
+ {renderContainerDigitalVersion()}
+
+ {
+ digital_version_exists_container['digital_version_research_cloud'] &&
+
+
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default DigitalVersionTab
\ No newline at end of file
diff --git a/components/Forms/fields/finding_aids/Extents.js b/components/Forms/fields/finding_aids/Extents.js
index 7b6b8c4..fe1bf38 100644
--- a/components/Forms/fields/finding_aids/Extents.js
+++ b/components/Forms/fields/finding_aids/Extents.js
@@ -5,7 +5,7 @@ import {FormRemoteSelectWithEdit} from "../../components/FormRemoteSelectWithEdi
export const Extents = ({form, disabled}) => (
- Creators
+ Extent
{(fields, { add, remove }) => {
return (
diff --git a/components/Forms/fields/finding_aids/Identifiers.js b/components/Forms/fields/finding_aids/Identifiers.js
new file mode 100644
index 0000000..cbeab76
--- /dev/null
+++ b/components/Forms/fields/finding_aids/Identifiers.js
@@ -0,0 +1,63 @@
+import React from "react";
+import {Button, Checkbox, Col, Form, Input, Row} from "antd";
+import {CloseOutlined, PlusOutlined} from '@ant-design/icons';
+import FormRemoteSelect from "../../components/FormRemoteSelect";
+
+export const Identifiers = ({disabled}) => (
+
+ Identifiers
+
+ {(fields, { add, remove }) => {
+ return (
+ <>
+ {fields.map((field, idx) => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+ {!disabled &&
+
+
+
+ }
+ >
+ )
+ }}
+
+
+);
diff --git a/components/Forms/fields/finding_aids/ResearchCloudLink.js b/components/Forms/fields/finding_aids/ResearchCloudLink.js
new file mode 100644
index 0000000..fd3e41d
--- /dev/null
+++ b/components/Forms/fields/finding_aids/ResearchCloudLink.js
@@ -0,0 +1,35 @@
+import {Badge, Button} from "antd";
+
+const ResearchCloudLink = ({path, buttonText='Open', isBadge=false}) => {
+ const getLink = () => {
+ const getParentPath = () => {
+ if (path) {
+ return path.slice(0, path.lastIndexOf("/"))
+ } else {
+ return ''
+ }
+ }
+
+ const basePath = 'sites/osa-researchcloud/Shared Documents'
+ const url = `https://ceuedu.sharepoint.com/${basePath}/Forms/AllItems.aspx?id=/${basePath}/${path}&parent=${basePath}/${getParentPath()}`
+
+ return encodeURI(url)
+ }
+
+ if (isBadge) {
+ return (
+
+
+
+ )
+ } else {
+ return (
+
+
+
+ )
+ }
+
+}
+
+export default ResearchCloudLink;
\ No newline at end of file
diff --git a/components/Forms/fields/isad/Creators.js b/components/Forms/fields/isad/Creators.js
index dfed621..82b682b 100644
--- a/components/Forms/fields/isad/Creators.js
+++ b/components/Forms/fields/isad/Creators.js
@@ -4,7 +4,7 @@ import {CloseOutlined, PlusOutlined} from '@ant-design/icons';
export const Creators = ({disabled}) => (
- Creators
+ 3.2.1 Creators
{(fields, { add, remove }) => {
return (
diff --git a/components/Forms/fields/isad/Extents.js b/components/Forms/fields/isad/Extents.js
index 0d23e9c..7952bb7 100644
--- a/components/Forms/fields/isad/Extents.js
+++ b/components/Forms/fields/isad/Extents.js
@@ -5,7 +5,7 @@ import FormRemoteSelect from "../../components/FormRemoteSelect";
export const Extents = ({disabled}) => (
- Creators
+ 3.1.5 Extent of the unit of description
{(fields, { add, remove }) => {
return (
diff --git a/components/Forms/fields/isad/LocationOfCopies.js b/components/Forms/fields/isad/LocationOfCopies.js
index 548e496..95c7201 100644
--- a/components/Forms/fields/isad/LocationOfCopies.js
+++ b/components/Forms/fields/isad/LocationOfCopies.js
@@ -4,7 +4,7 @@ import {CloseOutlined, PlusOutlined} from '@ant-design/icons';
export const LocationOfCopies = ({disabled}) => (
- Location of Copies
+ 3.5.2 Location of copies
{(fields, { add, remove }) => {
return (
diff --git a/components/Forms/fields/isad/LocationOfOriginals.js b/components/Forms/fields/isad/LocationOfOriginals.js
index 968d44f..2ba1633 100644
--- a/components/Forms/fields/isad/LocationOfOriginals.js
+++ b/components/Forms/fields/isad/LocationOfOriginals.js
@@ -4,7 +4,7 @@ import {CloseOutlined, PlusOutlined} from '@ant-design/icons';
export const LocationOfOriginals = ({disabled}) => (
- Location of Originals
+ 3.5.1 Location of originals
{(fields, { add, remove }) => {
return (
diff --git a/components/Forms/fields/isad/RelatedFindingAids.js b/components/Forms/fields/isad/RelatedFindingAids.js
index c3cb22c..bbb8ea4 100644
--- a/components/Forms/fields/isad/RelatedFindingAids.js
+++ b/components/Forms/fields/isad/RelatedFindingAids.js
@@ -4,7 +4,7 @@ import {CloseOutlined, PlusOutlined} from '@ant-design/icons';
export const RelatedFindingAids = ({disabled}) => (
- Related Finding Aids
+ 3.5.3 Related finding aids
{(fields, { add, remove }) => {
return (
diff --git a/components/Forms/fields/requests/RequestItems.js b/components/Forms/fields/requests/RequestItems.js
index 9aaa1c0..03e0dda 100644
--- a/components/Forms/fields/requests/RequestItems.js
+++ b/components/Forms/fields/requests/RequestItems.js
@@ -1,9 +1,10 @@
-import React, {useState} from "react";
+import React, {useEffect, useState} from "react";
import {Button, Col, Form, Input, Row, Select} from "antd";
-import { PlusOutlined, CloseOutlined } from '@ant-design/icons';
-import FormRemoteSelect from "../../components/FormRemoteSelect";
+import {PlusOutlined, CloseOutlined, CopyOutlined} from '@ant-design/icons';
import FormSelect from "../../components/FormSelect";
import {checkRequiredIfArchival, checkRequiredIfLibrary} from "../../validations/requestItemFormValidation";
+import FormRemoteSelectInfiniteScroll from "../../components/FormRemoteSelectInfiniteScroll";
+import {useDeepCompareEffect, usePrevious} from "react-use";
const ITEM_ORIGINS = [
{ value: 'FA', label: 'Archival'},
@@ -19,15 +20,23 @@ export const RequestItems = ({form}) => {
if (request_items[row]) {
const item_type = request_items[row]['item_origin']
- switch (field) {
- case 'archival_unit':
- return item_type !== 'FA'
- case 'container':
- return item_type !== 'FA'
- case 'identifier':
- return item_type === 'FA'
- case 'title':
- return item_type === 'FA'
+ if (item_type) {
+ switch (field) {
+ case 'archival_unit':
+ return item_type !== 'FA'
+ case 'container':
+ return item_type !== 'FA'
+ case 'identifier':
+ return item_type === 'FA'
+ case 'quantity':
+ return item_type === 'FA'
+ case 'title':
+ return item_type === 'FA'
+ default:
+ return true
+ }
+ } else {
+ return true
}
}
}
@@ -38,7 +47,17 @@ export const RequestItems = ({form}) => {
const getSeriesID = (row) => {
if (request_items) {
if (request_items[row]) {
- return request_items[row]['archival_unit']
+ if (request_items[row]['archival_unit']) {
+ return request_items[row]['archival_unit']['value']
+ }
+ }
+ }
+ }
+
+ const clone = (add, row) => {
+ if (request_items) {
+ if (request_items[row]) {
+ add(request_items[row])
}
}
}
@@ -70,7 +89,7 @@ export const RequestItems = ({form}) => {
name={[field.name, 'archival_unit']}
rules={[(form) => checkRequiredIfArchival(form, [field.name, 'item_type'], true)]}
>
- {
name={[field.name, 'container']}
rules={[(form) => checkRequiredIfArchival(form, [field.name, 'item_type'], true)]}
>
-
-
+
{
/>
-
+
{
/>
+
+ checkRequiredIfLibrary(form, [field.name, 'quantity'], true)]}
+ >
+
+
+
+