diff --git a/apps/rda/package.json b/apps/rda/package.json
index 4c6ae472..dd77bbea 100644
--- a/apps/rda/package.json
+++ b/apps/rda/package.json
@@ -18,7 +18,9 @@
"@dans-framework/theme": "workspace:*",
"@dans-framework/rdt-search-ui": "workspace:*",
"@fontsource/roboto": "^5.0.7",
+ "@mui/icons-material": "^5.14.3",
"@mui/material": "^5.14.3",
+ "html-react-parser": "^4.2.2",
"i18next": "^23.4.1",
"i18next-browser-languagedetector": "^7.1.0",
"i18next-resources-to-backend": "^1.1.4",
diff --git a/apps/rda/src/pages/record/index.tsx b/apps/rda/src/pages/record/index.tsx
index 0b159c7d..acd1b076 100644
--- a/apps/rda/src/pages/record/index.tsx
+++ b/apps/rda/src/pages/record/index.tsx
@@ -2,8 +2,9 @@ import { Chip, Container } from "@mui/material";
import type { Result } from "@dans-framework/rdt-search-ui";
import React from "react";
import { useParams } from "react-router-dom";
-
-import styles from "../search/index.module.css";
+import Button from "@mui/material/Button";
+import Typography from "@mui/material/Typography";
+import Grid from "@mui/material/Unstable_Grid2";
interface RdaRecord {
card_url: string;
@@ -47,36 +48,51 @@ export function RdaRecord() {
return (
-
-
{record.title || empty}
-
{record.dc_description || ""}
-
-
- {record.page_url && (
-
-
-
- )}
- {record.uri && (
-
-
-
- )}
- {record.pid_lod && (
-
-
-
- )}
-
-
-
+
+
+
+ {record.title || Untitled}
+
+ {record.dc_description || ""}
+
+
+
+
+ {record.page_url && (
+
+
+
+ )}
+ {record.uri && (
+
+
+
+ )}
+ {record.pid_lod && (
+
+
+
+ )}
+
+
+
+
);
}
const style = {
display: "grid",
- gridTemplateColumns: "200px 1fr",
+ gridTemplateColumns: "1fr 4fr",
+ marginBottom: "0.25rem",
};
function Metadata({ name, value }: { name: string; value: string | string[] }) {
@@ -85,23 +101,36 @@ function Metadata({ name, value }: { name: string; value: string | string[] }) {
const _value = Array.isArray(value) ? value.join(" / ") : value;
return (
-
- {name}
- {_value}
-
+
+
+ {name}
+
+
+ {_value}
+
+
);
}
export function MetadataList({ record }: { record: RdaRecord | Result }) {
return (
-
+ {JSON.stringify(record, undefined, 3)}
+
+ )}
+ >
);
}
diff --git a/apps/rda/src/pages/search/index.module.css b/apps/rda/src/pages/search/index.module.css
index 8885862d..2391027e 100644
--- a/apps/rda/src/pages/search/index.module.css
+++ b/apps/rda/src/pages/search/index.module.css
@@ -1,53 +1,3 @@
.wrapper {
- margin: auto;
- max-width: 1400px;
- padding-top: 4rem;
+ padding-top: 2rem;
}
-
-.result {
- background: white;
- box-shadow: 0 0px 20px #DDD;
- margin: 0 0 2rem 0;
- padding: 1rem;
-}
-
-.result em {
- background: yellow;
-}
-
-.header {
- display: grid;
- grid-template-columns: 1fr fit-content(0);
- grid-gap: 1rem;
-}
-
-.header h3 {
- margin-top: 0;
-}
-
-.header div {
- color: gray;
- white-space: nowrap;
-}
-
-.description {
- margin-bottom: 1rem;
-}
-
-.showjson pre {
- background: rgba(0, 0, 255, .05);
- border: 1px solid darkblue;
- border-radius: .25rem;
- overflow: hidden;
- padding: 1rem;
-}
-
-.showjson button,
-.description button {
- background: none;
- border: none;
- color: #007bff;
- cursor: pointer;
- font-size: 0.8rem;
- padding: 0;
-}
\ No newline at end of file
diff --git a/apps/rda/src/pages/search/index.tsx b/apps/rda/src/pages/search/index.tsx
index 611c9a69..c1b2d7b4 100644
--- a/apps/rda/src/pages/search/index.tsx
+++ b/apps/rda/src/pages/search/index.tsx
@@ -12,10 +12,6 @@ import { useNavigate } from "react-router-dom";
import styles from "./index.module.css";
const config: Partial = {
- style: {
- background: "#F6F6F6",
- buttonBackground: "#ececec",
- },
fullTextFields: ["title^2", "dc_description"],
fullTextHighlight: {
fields: {
@@ -42,7 +38,6 @@ export function RdaSearch({
url={`${
import.meta.env.VITE_ELASTICSEARCH_API_ENDPOINT
}/dans-rda2/_search`}
- style={config.style}
>
empty";
return (
-
-
- {/*
*/}
+ <>
+
{parse(title)}
+ {item.dc_date && (
+
+ {new Date(item.dc_date).toDateString()}
+
+ )}
-
+ >
);
}
function ReadMore({ item }: { item: ResultBodyProps["result"] }) {
- const [active, setActive] = React.useState(false);
-
- const hasHighlight = item.highlight?.dc_description?.[0] != null;
+ const [active, setActive] = useState(false);
// No description, return nothing
- if (item.dc_description == null) return null;
-
- // Highlighted description, return it
- if (hasHighlight) {
- return (
-
- );
- }
+ if (item.dc_description === null) return null;
- const [visibleText, hiddenText] = item.dc_description.split(/\. (.*)/);
+ const [visibleText, hiddenText] = [
+ item.dc_description.substring(0, 180),
+ item.dc_description.substring(180),
+ ];
// There is only one sentence, return it
if (hiddenText == null || hiddenText.trim().length === 0) {
- return {visibleText}
;
+ return {visibleText};
}
return (
-
- {visibleText}.{active && ` ${hiddenText}`}
-
-
-
+ <>
+
+ {`${visibleText}${
+ visibleText.length < item.dc_description.length && !active
+ ? "..."
+ : hiddenText
+ }`}
+
+
+ >
);
}
diff --git a/packages/deposit/src/features/metadata/fields/AutocompleteAPIField.tsx b/packages/deposit/src/features/metadata/fields/AutocompleteAPIField.tsx
index b7b059aa..2809edcf 100644
--- a/packages/deposit/src/features/metadata/fields/AutocompleteAPIField.tsx
+++ b/packages/deposit/src/features/metadata/fields/AutocompleteAPIField.tsx
@@ -699,7 +699,7 @@ const AutocompleteAPIField = ({
// only for freesolo, add input directly as option
if (
field.allowFreeText &&
- !isLoading &&
+ !isLoading &&
!isFetching &&
debouncedInputValue === inputValue
) {
diff --git a/packages/rdt-search-ui b/packages/rdt-search-ui
index 7ea361e0..dce9778b 160000
--- a/packages/rdt-search-ui
+++ b/packages/rdt-search-ui
@@ -1 +1 @@
-Subproject commit 7ea361e08424b23bc03c0db2472e36d8cf26a3ca
+Subproject commit dce9778b2e63f276b8a8e639329e7a649076ecda
diff --git a/packages/user-auth/src/languages/locales/en/user.json b/packages/user-auth/src/languages/locales/en/user.json
index 0e92b58b..40853806 100644
--- a/packages/user-auth/src/languages/locales/en/user.json
+++ b/packages/user-auth/src/languages/locales/en/user.json
@@ -35,6 +35,10 @@
"submittedTo": "Submitted to",
"submissionStatus": "Status",
"processing": "Processing your submission",
- "error": "Error with your submission",
- "success": "Succesfully submitted"
+ "error": "Error with your submission, click to see details",
+ "success": "Succesfully submitted",
+ "moreInfo": "Error",
+ "errorExplanation": "This is the error we got back from the server",
+ "retryItem": "Correct the error and try again",
+ "copyItem": "Copy this dataset for a new submission"
}
\ No newline at end of file
diff --git a/packages/user-auth/src/languages/locales/nl/user.json b/packages/user-auth/src/languages/locales/nl/user.json
index a3993714..3c2859f7 100644
--- a/packages/user-auth/src/languages/locales/nl/user.json
+++ b/packages/user-auth/src/languages/locales/nl/user.json
@@ -35,6 +35,10 @@
"submittedTo": "Gesubmit naar",
"submissionStatus": "Status",
"processing": "Bezig met verwerken",
- "error": "Fout bij het verwerken van je data",
- "success": "Succesvol gesubmit"
+ "error": "Fout bij het verwerken van je data, click om details te zien",
+ "success": "Succesvol gesubmit",
+ "moreInfo": "Fout",
+ "errorExplanation": "Dit is de foutmelding die we van de server terugkregen",
+ "retryItem": "Verbeter de foutmelding en probeer opnieuw",
+ "copyItem": "Kopiƫer deze dataset voor een nieuwe submissie"
}
\ No newline at end of file
diff --git a/packages/user-auth/src/types/index.ts b/packages/user-auth/src/types/index.ts
index 334ceada..0f741372 100644
--- a/packages/user-auth/src/types/index.ts
+++ b/packages/user-auth/src/types/index.ts
@@ -29,17 +29,16 @@ export interface ValidateTarget {
export type ReleaseVersion = "DRAFT" | "PUBLISH";
-type IngestStatus =
- | "initial"
- | "processing"
- | "finish"
- | "error"
- | "rejected"
- | "failed";
+type ActiveStatus = "initial" | "processing" | "submitted" | "finalizing";
+type ErrorStatus = "rejected" | "failed" | "error";
+type SuccessStatus = "finish" | "accepted" | "success";
+export type IngestStatus = ActiveStatus | ErrorStatus | SuccessStatus;
+type IngestStatusKeys = "processing" | "error" | "success";
+export type DepositStatus = { [key in IngestStatusKeys]: IngestStatus[] };
export interface TargetOutput {
"ingest-status": IngestStatus;
- "target-output": string;
+ "target-output": any;
"target-repo-name": string;
"target-repo-display-name": string;
"target-url": string;
diff --git a/packages/user-auth/src/user/UserSubmissions.tsx b/packages/user-auth/src/user/UserSubmissions.tsx
index 2eacdabd..e239b29d 100644
--- a/packages/user-auth/src/user/UserSubmissions.tsx
+++ b/packages/user-auth/src/user/UserSubmissions.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useMemo, useState } from "react";
+import { useEffect, useMemo, useState, MouseEvent } from "react";
import { useNavigate } from "react-router-dom";
import Container from "@mui/material/Container";
import Typography from "@mui/material/Typography";
@@ -19,15 +19,18 @@ import moment from "moment";
import { useSiteTitle, setSiteTitle } from "@dans-framework/utils";
import { useFetchUserSubmissionsQuery } from "./userApi";
import { useAuth } from "react-oidc-context";
-import type { SubmissionResponse, TargetOutput } from "../types";
+import type { SubmissionResponse, TargetOutput, DepositStatus } from "../types";
import CircularProgress from "@mui/material/CircularProgress";
import LinearProgress from "@mui/material/LinearProgress";
import PendingIcon from "@mui/icons-material/Pending";
import ErrorIcon from "@mui/icons-material/Error";
+import ReplayIcon from "@mui/icons-material/Replay";
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import Tooltip from "@mui/material/Tooltip";
+import Popover from "@mui/material/Popover";
+import Button from "@mui/material/Button";
-const depositStatus = {
+const depositStatus: DepositStatus = {
processing: ["initial", "processing", "submitted", "finalizing"],
error: ["rejected", "failed", "error"],
success: ["finish", "accepted", "success"],
@@ -118,13 +121,13 @@ const SubmissionList = ({
// useMemo to make sure columns don't change
const columns = useMemo(
() => [
- ...(type === "draft"
- ? [
- {
- field: "viewLink",
- headerName: "",
- width: 30,
- getActions: (params: any) => [
+ {
+ field: "viewLink",
+ headerName: "",
+ width: 30,
+ getActions: (params: any) => {
+ return type === "draft"
+ ? [
}
label={t("editItem")}
@@ -132,11 +135,26 @@ const SubmissionList = ({
navigate(`/${depositSlug}?id=${params.row.id}`)
}
/>,
- ],
- type: "actions",
- },
- ]
- : []),
+ ]
+ : // for submitted forms, either edit in case of error, or load with existing data for new submission
+ // params.value is true for an error, false for success
+ !params.row.processing && params.row.error
+ ? [
+
+ }
+ label={t("retryItem")}
+ onClick={() =>
+ // todo: need to work on this, how are we going to reload submitted form data for resubmission
+ navigate(`/${depositSlug}?id=${params.row.id}`)
+ }
+ />
+ ,
+ ]
+ : [];
+ },
+ type: "actions",
+ },
{
field: "title",
headerName: t("title"),
@@ -160,46 +178,11 @@ const SubmissionList = ({
renderCell: (params: any) => (
{params.value.map((v: TargetOutput, i: number) => (
-
-
- {depositStatus.processing.indexOf(
- v["ingest-status"],
- ) !== -1 ? (
-
- ) : depositStatus.error.indexOf(v["ingest-status"]) !==
- -1 ? (
-
- ) : depositStatus.success.indexOf(
- v["ingest-status"],
- ) !== -1 ? (
-
- ) : (
-
- )}
-
-
- {v["target-repo-display-name"]}
-
-
+ />
))}
),
@@ -214,6 +197,12 @@ const SubmissionList = ({
data &&
data.map((d) => ({
// Todo: API needs work and standardisation, also see types.
+ error: d["targets"].some(
+ (t) => depositStatus.error.indexOf(t["ingest-status"]) !== -1,
+ ),
+ processing: d["targets"].some(
+ (t) => depositStatus.processing.indexOf(t["ingest-status"]) !== -1,
+ ),
id: d["metadata-id"],
// viewLink: '',
created: type === "draft" ? d["created-date"] : d["submitted-date"],
@@ -273,6 +262,92 @@ const SubmissionList = ({
);
};
+// A separate component for a target, needs to have it's own state to display popover
+const SingleTargetStatus = ({
+ depositStatus,
+ target,
+}: {
+ depositStatus: DepositStatus;
+ target: TargetOutput;
+}) => {
+ const { t } = useTranslation("user");
+ const [anchorEl, setAnchorEl] = useState(null);
+ const handleClick = (event: MouseEvent) => {
+ setAnchorEl(event.currentTarget);
+ };
+ const handleClose = () => {
+ setAnchorEl(null);
+ };
+ const open = Boolean(anchorEl);
+ const id = open ? "popover" : undefined;
+
+ return (
+ <>
+
+
+ {depositStatus.processing.indexOf(target["ingest-status"]) !== -1 ? (
+
+ ) : depositStatus.error.indexOf(target["ingest-status"]) !== -1 ? (
+ }
+ size="small"
+ onClick={handleClick}
+ sx={{ fontSize: 10 }}
+ >
+ {t("moreInfo")}
+
+ ) : depositStatus.success.indexOf(target["ingest-status"]) !== -1 ? (
+
+ ) : (
+
+ )}
+
+
+ {target["target-repo-display-name"]}
+
+
+
+
+ {t("errorExplanation")}
+
+ {JSON.stringify(target["target-output"], null, 2)}
+
+
+
+ >
+ );
+};
+
const CustomColumnMenu = (props: GridColumnMenuProps) => {
return (