diff --git a/pwa/src/apiService/apiService.ts b/pwa/src/apiService/apiService.ts
index b035aab1..3dde8d6b 100644
--- a/pwa/src/apiService/apiService.ts
+++ b/pwa/src/apiService/apiService.ts
@@ -32,6 +32,7 @@ import Upload from "./resources/upload";
interface PromiseMessage {
loading?: string;
success?: string;
+ error?: string;
}
export type TSendFunction = (
@@ -255,37 +256,35 @@ export default class APIService {
switch (action) {
case "GET":
const response = instance.get(endpoint);
-
- response.catch((err) => toast.error(err.message));
-
+ response.catch((err) => toast.error(promiseMessage?.error ?? err.message));
return response;
case "POST":
return toast.promise(instance.post(endpoint, _payload), {
loading: promiseMessage?.loading ?? "Creating item...",
success: promiseMessage?.success ?? "Succesfully created item",
- error: (err) => err.message,
+ error: (err) => promiseMessage?.error ?? err.message,
});
case "PUT":
return toast.promise(instance.put(endpoint, _payload), {
loading: promiseMessage?.loading ?? "Updating item...",
success: promiseMessage?.success ?? "Succesfully updated item",
- error: (err) => err.message,
+ error: (err) => promiseMessage?.error ?? err.message,
});
case "DELETE":
return toast.promise(instance.delete(endpoint), {
loading: promiseMessage?.loading ?? "Deleting item...",
success: promiseMessage?.success ?? "Succesfully deleted item",
- error: (err) => err.message,
+ error: (err) => promiseMessage?.error ?? err.message,
});
case "DOWNLOAD":
return toast.promise(instance.get(endpoint), {
loading: promiseMessage?.loading ?? "Downloading item...",
success: promiseMessage?.success ?? "Succesfully downloaded item",
- error: (err) => err.message,
+ error: (err) => promiseMessage?.error ?? err.message,
});
}
};
diff --git a/pwa/src/apiService/resources/dashboardCards.tsx b/pwa/src/apiService/resources/dashboardCards.tsx
index 7e3b866a..b9d4975e 100644
--- a/pwa/src/apiService/resources/dashboardCards.tsx
+++ b/pwa/src/apiService/resources/dashboardCards.tsx
@@ -25,7 +25,9 @@ export default class DashboardCards {
}
public getAll = async (): Promise => {
- const { data } = await this._send(this._instance, "GET", "/admin/dashboardCards");
+ const { data } = await this._send(this._instance, "GET", "/admin/dashboardCards", undefined, {
+ error: "Could not fetch Dashboardcards.",
+ });
return data;
};
diff --git a/pwa/src/apiService/resources/source.ts b/pwa/src/apiService/resources/source.ts
index dfdaadb0..82877ff0 100644
--- a/pwa/src/apiService/resources/source.ts
+++ b/pwa/src/apiService/resources/source.ts
@@ -16,6 +16,12 @@ export default class Source {
return data;
};
+ public getAllSelectOptions = async (): Promise => {
+ const { data } = await this._send(this._instance, "GET", "/admin/gateways?limit=200");
+
+ return data?.map((source: any) => ({ label: source.name, value: source.id }));
+ };
+
public getOne = async (id: string): Promise => {
const { data } = await this._send(this._instance, "GET", `/admin/gateways/${id}`);
diff --git a/pwa/src/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.module.css b/pwa/src/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.module.css
new file mode 100644
index 00000000..8b32a3d9
--- /dev/null
+++ b/pwa/src/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.module.css
@@ -0,0 +1,52 @@
+:root {
+ --conduction-horizontal-overflow-wrapper-background-color: unset;
+ --conduction-horizontal-overflow-wrapper-buttons-top: 12px;
+
+ --conduction-horizontal-overflow-wrapper-margin-inline-start: 8px;
+ --conduction-horizontal-overflow-wrapper-margin-inline-end: 8px;
+ --conduction-horizontal-overflow-wrapper-margin-block-start: 8px;
+ --conduction-horizontal-overflow-wrapper-margin-block-end: 8px;
+}
+
+.container {
+ position: relative;
+ background-color: var(
+ --conduction-horizontal-overflow-wrapper-background-color
+ );
+}
+
+.wrapper {
+ overflow-x: scroll;
+}
+
+.scrollButton {
+ position: sticky;
+ top: var(--conduction-horizontal-overflow-wrapper-buttons-top);
+
+ margin-inline-start: var(
+ --conduction-horizontal-overflow-wrapper-margin-inline-start
+ );
+ margin-inline-end: var(
+ --conduction-horizontal-overflow-wrapper-margin-inline-end
+ );
+ margin-block-start: var(
+ --conduction-horizontal-overflow-wrapper-margin-block-start
+ );
+ margin-block-end: var(
+ --conduction-horizontal-overflow-wrapper-margin-block-end
+ );
+ z-index: 10000;
+}
+
+.scrollButton.right {
+ left: 100%;
+}
+
+/* Hide scrollbar */
+.wrapper::-webkit-scrollbar {
+ display: none;
+}
+.wrapper {
+ -ms-overflow-style: none;
+ scrollbar-width: none;
+}
diff --git a/pwa/src/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.tsx b/pwa/src/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.tsx
new file mode 100644
index 00000000..c6385d7d
--- /dev/null
+++ b/pwa/src/components/horizontalOverflowWrapper/HorizontalOverflowWrapper.tsx
@@ -0,0 +1,84 @@
+/**
+ * IMPORTANT: This is a temporary component that will be removed if the @conduction/components package can be updated.
+ */
+
+import * as React from "react";
+import * as styles from "./HorizontalOverflowWrapper.module.css";
+import clsx from "clsx";
+import { Button } from "@utrecht/component-library-react/dist/css-module";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faChevronLeft, faChevronRight } from "@fortawesome/free-solid-svg-icons";
+
+interface HorizontalOverflowWrapperProps {
+ children: React.ReactNode;
+ ariaLabels: {
+ scrollRightButton: string;
+ scrollLeftButton: string;
+ };
+}
+
+export const HorizontalOverflowWrapper: React.FC = ({ children, ariaLabels }) => {
+ const [canScrollRight, setCanScrollRight] = React.useState(false);
+ const [canScrollLeft, setCanScrollLeft] = React.useState(false);
+
+ const wrapperRef = React.useRef(null);
+
+ const scrollRight = (): void => {
+ wrapperRef.current?.scrollTo({
+ left: wrapperRef.current.scrollLeft + wrapperRef.current.clientWidth * 0.9,
+ behavior: "smooth",
+ });
+ };
+
+ const scrollLeft = (): void => {
+ wrapperRef.current?.scrollTo({
+ left: wrapperRef.current.scrollLeft - wrapperRef.current.clientWidth * 0.9,
+ behavior: "smooth",
+ });
+ };
+
+ React.useEffect(() => {
+ checkScrollDirections(); // initiate available scroll directions
+
+ window.addEventListener("resize", checkScrollDirections);
+
+ return () => window.removeEventListener("resize", checkScrollDirections);
+ }, []);
+
+ const checkScrollDirections = (): void => {
+ if (!wrapperRef.current) return;
+
+ setCanScrollRight(wrapperRef.current.scrollLeft + wrapperRef.current.clientWidth < wrapperRef.current.scrollWidth);
+ setCanScrollLeft(wrapperRef.current.scrollLeft > 0);
+ };
+
+ return (
+
+ {canScrollLeft && (
+
+ )}
+
+ {canScrollRight && (
+
+ )}
+
+
+ {children}
+
+
+ );
+};
diff --git a/pwa/src/context/logs.ts b/pwa/src/context/logs.ts
index 74125129..f3f234b1 100644
--- a/pwa/src/context/logs.ts
+++ b/pwa/src/context/logs.ts
@@ -13,6 +13,7 @@ export interface ILogFiltersContext {
process?: string;
endpoint?: string;
schema?: string;
+ source?: string;
cronjob?: string;
action?: string;
user?: string;
diff --git a/pwa/src/context/tableColumns.ts b/pwa/src/context/tableColumns.ts
index 3d5361b7..e55b307a 100644
--- a/pwa/src/context/tableColumns.ts
+++ b/pwa/src/context/tableColumns.ts
@@ -21,6 +21,7 @@ const logColumns = {
created: true,
endpoint: true,
schema: true,
+ source: true,
cronjob: true,
action: true,
user: true,
diff --git a/pwa/src/hooks/dashboardCards.ts b/pwa/src/hooks/dashboardCards.ts
index 20f79d0e..9b321a5f 100644
--- a/pwa/src/hooks/dashboardCards.ts
+++ b/pwa/src/hooks/dashboardCards.ts
@@ -13,6 +13,7 @@ export const useDashboardCards = (queryClient: QueryClient) => {
onError: (error) => {
console.warn(error.message);
},
+ retry: 0,
});
const getOne = (dashboardCardsId: string) =>
diff --git a/pwa/src/hooks/source.ts b/pwa/src/hooks/source.ts
index f809615c..b0dfff2d 100644
--- a/pwa/src/hooks/source.ts
+++ b/pwa/src/hooks/source.ts
@@ -18,6 +18,13 @@ export const useSource = (queryClient: QueryClient) => {
},
});
+ const getAllSelectOptions = () =>
+ useQuery("source_select_options", API.Sources.getAllSelectOptions, {
+ onError: (error) => {
+ console.warn(error.message);
+ },
+ });
+
const getOne = (sourceId: string) =>
useQuery(["sources", sourceId], () => API?.Sources.getOne(sourceId), {
initialData: () => queryClient.getQueryData("sources")?.find((_sources) => _sources.id === sourceId),
@@ -78,5 +85,5 @@ export const useSource = (queryClient: QueryClient) => {
},
});
- return { getAll, getOne, remove, createOrEdit, getProxy };
+ return { getAll, getOne, remove, createOrEdit, getProxy, getAllSelectOptions };
};
diff --git a/pwa/src/services/removeTrailingSlash.ts b/pwa/src/services/removeTrailingSlash.ts
new file mode 100644
index 00000000..304ff730
--- /dev/null
+++ b/pwa/src/services/removeTrailingSlash.ts
@@ -0,0 +1,4 @@
+export const removeTrailingSlash = (str: string) => {
+ const newStr = str.endsWith("/") ? str.slice(0, -1) : str;
+ return newStr;
+};
diff --git a/pwa/src/templates/actionsTemplate/ActionsTemplate.tsx b/pwa/src/templates/actionsTemplate/ActionsTemplate.tsx
index ec84a986..e2503a3e 100644
--- a/pwa/src/templates/actionsTemplate/ActionsTemplate.tsx
+++ b/pwa/src/templates/actionsTemplate/ActionsTemplate.tsx
@@ -89,7 +89,7 @@ export const ActionsTemplate: React.FC = () => {
{action.lastRun ? dateTime(t(i18n.language), action.lastRun) : "-"}
- {`${action.lastRunTime}ms` ?? "-"}
+ {`${action.lastRunTime}s` ?? "-"}
{translateDate(i18n.language, action.dateCreated) ?? "-"}
diff --git a/pwa/src/templates/gatewayDetailTemplate/GatewayDetailTemplate.tsx b/pwa/src/templates/gatewayDetailTemplate/GatewayDetailTemplate.tsx
index 88b79bde..673b4690 100644
--- a/pwa/src/templates/gatewayDetailTemplate/GatewayDetailTemplate.tsx
+++ b/pwa/src/templates/gatewayDetailTemplate/GatewayDetailTemplate.tsx
@@ -70,7 +70,9 @@ export const GatewayDetailTemplate: React.FC = () => {
getPlugins.data.update ? getPlugins.data?.version : `Latest (${getPlugins.data?.version})`
} `}
)}
- {`last update time: ${new Date(getPlugins.data?.time).toLocaleString()}`}
+ {`last update time: ${new Date(
+ getPlugins.data?.versions[getPlugins.data?.version]?.time,
+ ).toLocaleString()}`}
diff --git a/pwa/src/templates/login/LoginTemplate.tsx b/pwa/src/templates/login/LoginTemplate.tsx
index 1d372f6d..7f33e33a 100644
--- a/pwa/src/templates/login/LoginTemplate.tsx
+++ b/pwa/src/templates/login/LoginTemplate.tsx
@@ -12,6 +12,7 @@ import { useAuthentication } from "../../hooks/useAuthentication";
import { useIsLoadingContext } from "../../context/isLoading";
import APIService from "../../apiService/apiService";
import APIContext from "../../apiService/apiContext";
+import { removeTrailingSlash } from "../../services/removeTrailingSlash";
export const LoginTemplate: React.FC = () => {
const { t } = useTranslation();
@@ -54,7 +55,9 @@ export const LoginTemplate: React.FC = () => {
React.useEffect(() => {
window.sessionStorage.getItem("GATSBY_BASE_URL") &&
- setDexRedirectURL(`${window.sessionStorage.getItem("GATSBY_BASE_URL")}/login/oidc/dex`);
+ setDexRedirectURL(
+ `${removeTrailingSlash(window.sessionStorage.getItem("GATSBY_BASE_URL") ?? "")}/login/oidc/dex`,
+ );
});
return (
diff --git a/pwa/src/templates/logsDetailTemplate/LogsDetailTemplate.module.css b/pwa/src/templates/logsDetailTemplate/LogsDetailTemplate.module.css
index f73f4b63..188a61ec 100644
--- a/pwa/src/templates/logsDetailTemplate/LogsDetailTemplate.module.css
+++ b/pwa/src/templates/logsDetailTemplate/LogsDetailTemplate.module.css
@@ -48,7 +48,7 @@
}
.warningLevel {
- --denhaag-alert-info-background-color: #var(
+ --denhaag-alert-info-background-color: var(
--gateway-ui-color-status-background-warning
);
--denhaag-alert-info-icon-color: var(--gateway-ui-color-status-warning);
diff --git a/pwa/src/templates/logsDetailTemplate/LogsDetailTemplate.tsx b/pwa/src/templates/logsDetailTemplate/LogsDetailTemplate.tsx
index 14feb4fb..2d7e6267 100644
--- a/pwa/src/templates/logsDetailTemplate/LogsDetailTemplate.tsx
+++ b/pwa/src/templates/logsDetailTemplate/LogsDetailTemplate.tsx
@@ -23,6 +23,8 @@ import { Button } from "../../components/button/Button";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useMapping } from "../../hooks/mapping";
import { useObject } from "../../hooks/object";
+import { CodeEditor } from "../../components/codeEditor/CodeEditor";
+import { useSource } from "../../hooks/source";
interface LogsDetailTemplateProps {
logId: string;
@@ -31,6 +33,10 @@ interface LogsDetailTemplateProps {
export const LogsDetailTemplate: React.FC
= ({ logId }) => {
const { t } = useTranslation();
const { setLogFilters } = useLogFiltersContext();
+ const [bodyData, setBodyData] = React.useState("");
+ const [exceptionData, setExceptionData] = React.useState("");
+ const [routeParametersData, setRouteParametersData] = React.useState("");
+ const [sourceCallData, setSourceCallData] = React.useState("");
const queryClient = useQueryClient();
@@ -44,6 +50,7 @@ export const LogsDetailTemplate: React.FC = ({ logId })
const getOrganization = useOrganization(queryClient).getOne(getLog.data?.context?.organization);
const getMapping = useMapping(queryClient).getOne(getLog.data?.context?.mapping);
const getObject = useObject().getOne(getLog.data?.context?.object);
+ const getSource = useSource(queryClient).getOne(getLog.data?.context?.source);
const handleSetContextFilter = (
context:
@@ -51,6 +58,7 @@ export const LogsDetailTemplate: React.FC = ({ logId })
| "process"
| "endpoint"
| "schema"
+ | "source"
| "cronjob"
| "action"
| "user"
@@ -70,6 +78,13 @@ export const LogsDetailTemplate: React.FC = ({ logId })
navigate("/logs");
};
+ React.useEffect(() => {
+ setBodyData(JSON.stringify(getLog.data?.context?.body, null, 2));
+ setExceptionData(JSON.stringify(getLog.data?.context?.exception, null, 2));
+ setRouteParametersData(JSON.stringify(getLog.data?.context?.route_parameters, null, 2));
+ setSourceCallData(JSON.stringify(getLog.data?.context?.sourceCall, null, 2));
+ }, [getLog]);
+
return (
{t("Logs detail page")}
@@ -99,22 +114,120 @@ export const LogsDetailTemplate: React.FC = ({ logId })
-
- Host
- {getLog.data.context?.host !== "" ? getLog.data.context?.host : "-"}
- -
- -
-
-
- IP
- {getLog.data.context?.ip !== "" ? getLog.data.context?.ip : "-"}
- -
- -
-
+ {getLog.data.context?.exception && (
+
+ Exception
+
+
+
+
+ )}
+ {getLog.data.context?.method && (
+
+ Method
+ {getLog.data.context?.method !== "" ? getLog.data.context?.method : "-"}
+ -
+ -
+
+ )}
+ {getLog.data.context?.querystring && (
+
+ Querystring
+
+ {getLog.data.context?.querystring !== "" ? getLog.data.context?.querystring : "-"}
+
+ -
+ -
+
+ )}
+ {getLog.data.context?.pathRaw && (
+
+ pathRaw
+ {getLog.data.context?.pathRaw !== "" ? getLog.data.context?.pathRaw : "-"}
+ -
+ -
+
+ )}
+ {getLog.data.context?.request_uri && (
+
+ Request URI
+
+ {getLog.data.context?.request_uri !== "" ? getLog.data.context?.request_uri : "-"}
+
+ -
+ -
+
+ )}
+ {getLog.data.context?.route && (
+
+ Route
+ {getLog.data.context?.route !== "" ? getLog.data.context?.route : "-"}
+ -
+ -
+
+ )}
+ {getLog.data.context?.route_parameters && (
+
+ Route Parameters
+
+
+
+
+ )}
+ {getLog.data.context?.contentType && (
+
+ Content Type
+
+ {getLog.data.context?.contentType !== "" ? getLog.data.context?.contentType : "-"}
+
+ -
+ -
+
+ )}
+ {getLog.data.context?.body && (
+
+ Body
+
+
+
+
+ )}
+ {getLog.data.context?.crude_body && (
+
+ Crude Body
+ {getLog.data.context?.crude_body}
+
+ )}
+ {getLog.data.context?.mongoDBFilter && (
+
+ MongoDB Filter
+ {getLog.data.context?.mongoDBFilter}
+
+ )}
+ {getLog.data.context?.plugin && (
+
+ Plugin
+ {getLog.data.context?.plugin !== "" ? getLog.data.context?.plugin : "-"}
+ -
+ -
+
+ )}
+ {getLog.data.context?.sourceCall && (
+
+ Source Call
+
+
+
+
+ )}
Session
{getLog.data.context?.session !== "" ? getLog.data.context?.session : "-"}
-
+
+ Host
+ {getLog.data.context?.host !== "" ? getLog.data.context?.host : "-"}
+ -
+ -
+
+
+ IP
+ {getLog.data.context?.ip !== "" ? getLog.data.context?.ip : "-"}
+ -
+ -
+
diff --git a/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.module.css b/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.module.css
index 3638d30c..9fe0e619 100644
--- a/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.module.css
+++ b/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.module.css
@@ -6,10 +6,6 @@
padding-block-end: var(--gateway-ui-size-md);
}
-.gridContainer > *:not(:first-child) {
- margin-block-start: var(--gateway-ui-size-sm);
-}
-
.grid {
display: grid;
grid-gap: var(--gateway-ui-size-lg);
diff --git a/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.tsx b/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.tsx
index ebde5e48..af1d3315 100644
--- a/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.tsx
+++ b/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.tsx
@@ -15,6 +15,9 @@ import { SchemaFormTemplate } from "../schemaForm/SchemaFormTemplate";
import { useIsLoadingContext } from "../../../context/isLoading";
import { enrichValidation } from "../../../services/enrichReactHookFormValidation";
import { CodeEditor } from "../../../components/codeEditor/CodeEditor";
+import { translateDate } from "../../../services/dateFormat";
+import { StatusTag } from "../../../components/statusTag/StatusTag";
+import { formatDateTime } from "../../../services/dateTime";
export const formId: string = "action-form";
@@ -23,7 +26,7 @@ interface ActionFormTemplateProps {
}
export const ActionFormTemplate: React.FC = ({ action }) => {
- const { t } = useTranslation();
+ const { t, i18n } = useTranslation();
const { setIsLoading, isLoading } = useIsLoadingContext();
const [listensAndThrows, setListensAndThrows] = React.useState([]);
@@ -149,7 +152,7 @@ export const ActionFormTemplate: React.FC = ({ action }
-
+
@@ -272,6 +275,50 @@ export const ActionFormTemplate: React.FC = ({ action }
+ {action && (
+ <>
+
+
+
+
+ {t("Date Created")}
+ {translateDate(i18n.language, action.dateCreated) ?? "-"}
+
+
+
+
+
+ {t("Date Modified")}
+ {translateDate(i18n.language, action.dateModified) ?? "-"}
+
+
+
+
+
+ {t("Last run")}
+ {action.lastRun ? formatDateTime(t(i18n.language), action.lastRun) : "-"}
+
+
+
+
+
+ {t("Last run time")}
+ {`${action.lastRunTime}s` ?? "-"}
+
+
+
+
+
+ {t("Status")}
+
+
+
+
+ >
+ )}
diff --git a/pwa/src/templates/templateParts/logFilters/LogFiltersTemplate.tsx b/pwa/src/templates/templateParts/logFilters/LogFiltersTemplate.tsx
index dcb4cdee..807dcb09 100644
--- a/pwa/src/templates/templateParts/logFilters/LogFiltersTemplate.tsx
+++ b/pwa/src/templates/templateParts/logFilters/LogFiltersTemplate.tsx
@@ -9,6 +9,7 @@ import { useUser } from "../../../hooks/user";
import { useSchema } from "../../../hooks/schema";
import { useAction } from "../../../hooks/action";
import { useObject } from "../../../hooks/object";
+import { useSource } from "../../../hooks/source";
import { useMapping } from "../../../hooks/mapping";
import { useCronjob } from "../../../hooks/cronjob";
import { useEndpoint } from "../../../hooks/endpoint";
@@ -33,6 +34,7 @@ export const LogFiltersTemplate: React.FC
= ({ layoutCl
const getEndpoints = useEndpoint(queryClient).getAllSelectOptions();
const getSchemas = useSchema(queryClient).getAllSelectOptions();
+ const getSources = useSource(queryClient).getAllSelectOptions();
const getCronjobs = useCronjob(queryClient).getAllSelectOptions();
const getActions = useAction(queryClient).getAllSelectOptions();
const getUsers = useUser(queryClient).getAllSelectOptions();
@@ -72,6 +74,7 @@ export const LogFiltersTemplate: React.FC = ({ layoutCl
process: formValues.process,
endpoint: formValues.endpoints?.value,
schema: formValues.schemas?.value,
+ source: formValues.sources?.value,
cronjob: formValues.cronjobs?.value,
action: formValues.actions?.value,
user: formValues.users?.value,
@@ -114,6 +117,11 @@ export const LogFiltersTemplate: React.FC = ({ layoutCl
getSchemas.data?.find((schema) => schema.value === logFilters.context?.schema),
);
+ setValue(
+ "sources",
+ getSources.data?.find((source) => source.value === logFilters.context?.source),
+ );
+
setValue(
"cronjobs",
getCronjobs.data?.find((cronjob) => cronjob.value === logFilters.context?.cronjob),
@@ -229,6 +237,18 @@ export const LogFiltersTemplate: React.FC = ({ layoutCl
+
+
+ Sources
+
+ {getSources.isSuccess && (
+
+ )}
+
+ {getSources.isLoading && }
+
+
+
Cronjobs
@@ -322,7 +342,6 @@ export const LogFiltersTemplate: React.FC = ({ layoutCl
{getMappings.isLoading && }
-
diff --git a/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.module.css b/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.module.css
index 2d46eeac..bc2070f9 100644
--- a/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.module.css
+++ b/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.module.css
@@ -17,10 +17,6 @@
justify-content: space-between;
}
-.tableContainer {
- max-width: 100%;
- overflow-x: scroll;
-}
.button > span > svg {
margin-inline-end: var(--gateway-ui-size-xs);
diff --git a/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.tsx b/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.tsx
index 7164f965..7a8b1691 100644
--- a/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.tsx
+++ b/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.tsx
@@ -16,6 +16,7 @@ import { Link } from "@gemeente-denhaag/components-react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { usePagination } from "../../../hooks/usePagination";
import clsx from "clsx";
+import { HorizontalOverflowWrapper } from "../../../components/horizontalOverflowWrapper/HorizontalOverflowWrapper";
interface LogsTableTemplateProps {
logs: any[];
@@ -69,192 +70,210 @@ export const LogsTableTemplate: React.FC = ({ logs, pagi
-
-
-
-
- {logColumns.level && {t("Level")}}
- {logColumns.message && {t("Message")}}
- {logColumns.created && {t("Created")}}
- {logColumns.endpoint && {t("Endpoint")}}
- {logColumns.schema && {t("Schema")}}
- {logColumns.cronjob && {t("Cronjob")}}
- {logColumns.action && {t("Action")}}
- {logColumns.user && {t("User")}}
- {logColumns.organization && {t("Organization")}}
- {logColumns.application && {t("Application")}}
- {logColumns.object && {t("Object")}}
- {logColumns.mapping && {t("Mapping")}}
-
-
-
-
- {logs.map((log: any) => (
-
- {logColumns.level && (
-
-
-
- )}
+
+
+
+
+
+ {logColumns.level && {t("Level")}}
+ {logColumns.message && {t("Message")}}
+ {logColumns.created && {t("Created")}}
+ {logColumns.endpoint && {t("Endpoint")}}
+ {logColumns.schema && {t("Schema")}}
+ {logColumns.source && {t("Source")}}
+ {logColumns.cronjob && {t("Cronjob")}}
+ {logColumns.action && {t("Action")}}
+ {logColumns.user && {t("User")}}
+ {logColumns.organization && {t("Organization")}}
+ {logColumns.application && {t("Application")}}
+ {logColumns.object && {t("Object")}}
+ {logColumns.mapping && {t("Mapping")}}
+
+
+
+
+ {logs.map((log: any) => (
+
+ {logColumns.level && (
+
+
+
+ )}
- {logColumns.message && (
-
-
- {log.message}
-
-
- )}
+ {logColumns.message && (
+
+
+ {log.message}
+
+
+ )}
- {logColumns.created && (
-
-
-
- {formatUnixDateTime(t(i18n.language), log.datetime.$date.$numberLong)}
-
-
-
- )}
+ {logColumns.created && (
+
+
+
+ {formatUnixDateTime(t(i18n.language), log.datetime.$date.$numberLong)}
+
+
+
+ )}
- {logColumns.endpoint && (
-
- handleResourceClick(e, "endpoints", log.context.endpoint)}
- />
-
- )}
+ {logColumns.endpoint && (
+
+ handleResourceClick(e, "endpoints", log.context.endpoint)}
+ />
+
+ )}
- {logColumns.schema && (
-
- handleResourceClick(e, "schemas", log.context.schema)}
- />
-
- )}
+ {logColumns.schema && (
+
+ handleResourceClick(e, "schemas", log.context.schema)}
+ />
+
+ )}
- {logColumns.cronjob && (
-
- handleResourceClick(e, "cronjobs", log.context.cronjob)}
- />
-
- )}
+ {logColumns.source && (
+
+ handleResourceClick(e, "sources", log.context.source)}
+ />
+
+ )}
- {logColumns.action && (
-
- handleResourceClick(e, "actions", log.context.action)}
- />
-
- )}
+ {logColumns.cronjob && (
+
+ handleResourceClick(e, "cronjobs", log.context.cronjob)}
+ />
+
+ )}
- {logColumns.user && (
-
- handleResourceClick(e, "settings/users", log.context.user)}
- />
-
- )}
+ {logColumns.action && (
+
+ handleResourceClick(e, "actions", log.context.action)}
+ />
+
+ )}
- {logColumns.organization && (
-
- handleResourceClick(e, "settings/organizations", log.context.organization)}
- />
-
- )}
+ {logColumns.user && (
+
+ handleResourceClick(e, "settings/users", log.context.user)}
+ />
+
+ )}
- {logColumns.application && (
-
- handleResourceClick(e, "settings/applications", log.context.application)}
- />
-
- )}
+ {logColumns.organization && (
+
+ handleResourceClick(e, "settings/organizations", log.context.organization)}
+ />
+
+ )}
- {logColumns.object && (
-
- handleResourceClick(e, "objects", log.context.object)}
- />
-
- )}
+ {logColumns.application && (
+
+ handleResourceClick(e, "settings/applications", log.context.application)}
+ />
+
+ )}
- {logColumns.mapping && (
-
- handleResourceClick(e, "mappings", log.context.mapping)}
- />
-
- )}
+ {logColumns.object && (
+
+ handleResourceClick(e, "objects", log.context.object)}
+ />
+
+ )}
- navigate(`/logs/${log._id.$oid}`)}>
- } iconAlign="start">
- {t("Details")}
-
-
-
- ))}
+ {logColumns.mapping && (
+
+ handleResourceClick(e, "mappings", log.context.mapping)}
+ />
+
+ )}
- {!logs.length && (
-
- {Object.values(logColumns)
- .filter((value) => value)
- .map((_, idx) => (
- {idx === 0 && <>No logs found>}
- ))}
-
- )}
-
-
-
+ navigate(`/logs/${log._id.$oid}`)}>
+ } iconAlign="start">
+ {t("Details")}
+
+
+
+ ))}
+
+ {!logs.length && (
+
+ {Object.values(logColumns)
+ .filter((value) => value)
+ .map((_, idx) => (
+ {idx === 0 && <>No logs found>}
+ ))}
+
+ )}
+
+
+
+