diff --git a/src/components/FormComponents/Lineage.jsx b/src/components/FormComponents/Lineage.jsx
new file mode 100644
index 00000000..430d093d
--- /dev/null
+++ b/src/components/FormComponents/Lineage.jsx
@@ -0,0 +1,210 @@
+import React, { useState } from "react";
+import { Add, Delete } from "@material-ui/icons";
+import {
+ TextField,
+ Grid,
+ Typography,
+ Button,
+ Paper,
+ List,
+ ListItem,
+ ListItemText,
+} from "@material-ui/core";
+import { En, Fr, I18n } from "../I18n";
+import { deepCopy } from "../../utils/misc";
+import { metadataScopeCodes } from "../../isoCodeLists";
+import RequiredMark from "./RequiredMark";
+import AdditionalDocumentation from "./LineageAdditionalDocumentation"
+import LineageSource from "./LineageSource";
+import SelectInput from "./SelectInput";
+
+const emptyLineage = {
+ statment: "",
+ scope: "",
+ additionalDocumentation: [],
+ source: [],
+};
+
+const Lineage = ({
+ updateLineage,
+ history = [],
+ disabled,
+ paperClass,
+ language,
+}) => {
+
+ const [activeLineage, setActiveLineage] = useState(0);
+
+ function addLineage() {
+ updateLineage(history.concat(deepCopy(emptyLineage)));
+ setActiveLineage(history.length);
+ }
+ function updateLineageField(key) {
+ return (e) => {
+
+ const lineageCopy = [...history];
+ lineageCopy[activeLineage][key] = e.target.value;
+ updateLineage(lineageCopy);
+ };
+ }
+ function updateLineageSubField(key) {
+ return (e) => {
+ const lineageCopy = [...history];
+ lineageCopy[activeLineage][key] = e;
+ updateLineage(lineageCopy);
+ };
+ }
+ function removeLineage() {
+ updateLineage(
+ history.filter((e, index) => index !== activeLineage)
+ );
+ if (history.length) setActiveLineage(history.length - 2);
+ }
+
+ if (typeof history === "string") {
+ const item = deepCopy(emptyLineage)
+ item['statment'] = history
+ history = [deepCopy(item)];
+ }
+
+ // const manufacturerLabel = ;
+ // const versionLabel = ;
+ // const typeLabel = ;
+ // const descriptionLabel = ;
+ const lineageStep = history.length > 0 && history[activeLineage];
+
+
+
+
+
+ return (
+
+
+
+
+
+
+
+ Lineage:
+ Lignée:
+
+
+ {history.map((lineageItem, i) => {
+ return (
+ setActiveLineage(i)}
+ >
+
+ {i + 1}. {
+ lineageItem.statment.length <= 50 ?
+ lineageItem.statment : lineageItem.statment.substring(0, 50) + '...'
+ }
+
+ }
+ />
+
+ );
+ })}
+
+
+
+
+ }
+ onClick={addLineage}
+ style={{ height: "56px", marginLeft: "10px" }}
+ >
+
+ Add Lineage
+ Ajouter une lignée
+
+
+
+
+
+
+
+ {lineageStep && (
+
+
+
+
+ Lineage Statment
+ Déclaration de lignée
+
+
+
+
+
+
+
+ Scope
+ Portée
+
+ title[language]
+ )}
+ disabled={disabled}
+ fullWidth
+ label={}
+ />
+
+
+
+
+
+
+
+
+ }
+ disabled={disabled}
+ onClick={removeLineage}
+ >
+
+ Remove item
+ Supprimer l'instrument
+
+
+
+
+
+ )}
+
+
+
+
+
+
+ );
+};
+export default Lineage;
diff --git a/src/components/FormComponents/LineageAdditionalDocumentation.jsx b/src/components/FormComponents/LineageAdditionalDocumentation.jsx
new file mode 100644
index 00000000..a70db7f6
--- /dev/null
+++ b/src/components/FormComponents/LineageAdditionalDocumentation.jsx
@@ -0,0 +1,163 @@
+import React, { useState } from "react";
+import { Add, Delete } from "@material-ui/icons";
+import {
+ TextField,
+ Grid,
+ Typography,
+ Button,
+ Paper,
+ List,
+ ListItem,
+ ListItemText,
+} from "@material-ui/core";
+import { En, Fr, I18n } from "../I18n";
+import { deepCopy } from "../../utils/misc";
+import RequiredMark from "./RequiredMark";
+
+const emptyDocumentation = {
+ title: "",
+ authority: "",
+ code: "",
+};
+
+const LineageAdditionalDocumentation = ({
+ updateDocumentations,
+ documentations = [],
+ disabled,
+ paperClass,
+}) => {
+ const [activeDocumentation, setActiveDocumentation] = useState(0);
+
+ function addDocumentation() {
+ updateDocumentations(documentations.concat(deepCopy(emptyDocumentation)));
+ setActiveDocumentation(documentations.length);
+ }
+ function updateDocumentationField(key) {
+ return (e) => {
+ const documentationsCopy = [...documentations];
+ documentationsCopy[activeDocumentation][key] = e.target.value;
+ updateDocumentations(documentationsCopy);
+ };
+ }
+ function removeDocumentation() {
+ updateDocumentations(
+ documentations.filter((e, index) => index !== activeDocumentation)
+ );
+ if (documentations.length) setActiveDocumentation(documentations.length - 2);
+ }
+
+
+
+ const documentation = documentations.length > 0 && documentations[activeDocumentation];
+
+ return (
+
+
+
+
+
+ Additional Documentation:
+ Documentation Supplémentaire:
+
+
+ {documentations.map((documentationItem, i) => {
+ return (
+ setActiveDocumentation(i)}
+ >
+
+ {i + 1}. {
+ documentationItem.title.length <= 50 ?
+ documentationItem.title : documentationItem.title.substring(0, 50) + '...'
+ }
+
+ }
+ />
+
+ );
+ })}
+
+
+
+
+ }
+ onClick={addDocumentation}
+ style={{ height: "56px", marginLeft: "10px" }}
+ >
+
+ Add documentation
+ Ajouter un documentation
+
+
+
+
+
+
+
+ {documentation && (
+
+
+
+
+ Title
+ Titre
+
+
+ }
+ value={documentation.title}
+ onChange={updateDocumentationField("title")}
+ fullWidth
+ disabled={disabled}
+ />
+
+
+ }
+ name="authority"
+ value={documentation.authority}
+ onChange={updateDocumentationField("authority")}
+ fullWidth
+ disabled={disabled}
+ />{" "}
+
+
+
+
+
+ }
+ disabled={disabled}
+ onClick={removeDocumentation}
+ >
+
+ Remove item
+ Supprimer l'documentation
+
+
+
+
+
+ )}
+
+
+
+ );
+};
+export default LineageAdditionalDocumentation;
diff --git a/src/components/FormComponents/LineageSource.jsx b/src/components/FormComponents/LineageSource.jsx
new file mode 100644
index 00000000..ebc04d0e
--- /dev/null
+++ b/src/components/FormComponents/LineageSource.jsx
@@ -0,0 +1,171 @@
+import React, { useState } from "react";
+import { Add, Delete } from "@material-ui/icons";
+import {
+ TextField,
+ Grid,
+ Typography,
+ Button,
+ Paper,
+ List,
+ ListItem,
+ ListItemText,
+} from "@material-ui/core";
+import { En, Fr, I18n } from "../I18n";
+import { deepCopy } from "../../utils/misc";
+import RequiredMark from "./RequiredMark";
+
+const emptySource = {
+ description: "",
+ title: "",
+ authority: "",
+ code: "",
+};
+
+const LineageSource = ({
+ updateSources,
+ sources = [],
+ disabled,
+ paperClass,
+}) => {
+ const [activeSource, setActiveSource] = useState(0);
+
+ function addSource() {
+ updateSources(sources.concat(deepCopy(emptySource)));
+ setActiveSource(sources.length);
+ }
+ function updateSourceField(key) {
+ return (e) => {
+ const sourcesCopy = [...sources];
+ sourcesCopy[activeSource][key] = e.target.value;
+ updateSources(sourcesCopy);
+ };
+ }
+ function removeSource() {
+ updateSources(
+ sources.filter((e, index) => index !== activeSource)
+ );
+ if (sources.length) setActiveSource(sources.length - 2);
+ }
+
+
+
+ const source = sources.length > 0 && sources[activeSource];
+
+ return (
+
+
+
+
+ Source:
+
+ {sources.map((sourceItem, i) => {
+ return (
+ setActiveSource(i)}
+ >
+
+ {i + 1}. {
+ sourceItem.description.length <= 50 ?
+ sourceItem.description : sourceItem.description.substring(0, 50) + '...'
+ }
+
+ }
+ />
+
+ );
+ })}
+
+
+
+
+ }
+ onClick={addSource}
+ style={{ height: "56px", marginLeft: "10px" }}
+ >
+
+ Add source
+ Ajouter un source
+
+
+
+
+
+
+
+ {source && (
+
+
+
+
+ Description
+ Description
+
+
+
+
+
+
+ }
+ value={source.title}
+ onChange={updateSourceField("title")}
+ fullWidth
+ disabled={disabled}
+ />
+
+
+ }
+ name="authority"
+ value={source.authority}
+ onChange={updateSourceField("authority")}
+ fullWidth
+ disabled={disabled}
+ />{" "}
+
+
+
+
+
+ }
+ disabled={disabled}
+ onClick={removeSource}
+ >
+
+ Remove item
+ Supprimer l'source
+
+
+
+
+
+ )}
+
+
+
+ );
+};
+export default LineageSource;
diff --git a/src/components/Pages/MetadataForm.jsx b/src/components/Pages/MetadataForm.jsx
index 8f1e19a2..81f8a778 100644
--- a/src/components/Pages/MetadataForm.jsx
+++ b/src/components/Pages/MetadataForm.jsx
@@ -26,6 +26,7 @@ import ContactTab from "../Tabs/ContactTab";
import ResourcesTab from "../Tabs/ResourcesTab";
import IdentificationTab from "../Tabs/IdentificationTab";
import PlatformTab from "../Tabs/PlatformTab";
+import LineageTab from "../Tabs/LineageTab";
import SpatialTab from "../Tabs/SpatialTab";
import SubmitTab from "../Tabs/SubmitTab";
@@ -472,6 +473,12 @@ class MetadataForm extends FormClassTemplate {
value="platform"
/>
)}
+
{loggedInUserCanEditRecord && (
-
+
+
+
{
+
+ const { language } = useParams()
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+};
+export default LineageTab;
diff --git a/src/utils/blankRecord.js b/src/utils/blankRecord.js
index 8e0753e1..5acf12da 100644
--- a/src/utils/blankRecord.js
+++ b/src/utils/blankRecord.js
@@ -37,6 +37,7 @@ const blankRecord = {
filename: "",
organization: "",
timeFirstPublished: "",
+ history: [],
};
function getBlankRecord() {
diff --git a/src/utils/tabs.js b/src/utils/tabs.js
index 666bc85d..d6ffc72e 100644
--- a/src/utils/tabs.js
+++ b/src/utils/tabs.js
@@ -10,5 +10,6 @@ const tabs = {
en: "Platform - instruments",
fr: "Plateforme - instruments",
},
+ lineage: { en: "Lineage", fr: "lignée" },
};
export default tabs;