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/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/templates/gatewayDetailTemplate/GatewayDetailTemplate.tsx b/pwa/src/templates/gatewayDetailTemplate/GatewayDetailTemplate.tsx
index 88b79bde..43c6f468 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/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.tsx b/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.tsx
index 3fe5167e..af1d3315 100644
--- a/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.tsx
+++ b/pwa/src/templates/templateParts/actionsForm/ActionFormTemplate.tsx
@@ -275,46 +275,50 @@ export const ActionFormTemplate: React.FC = ({ 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")}
-
-
-
-
+ {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.tsx b/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.tsx
index 7164f965..5beb5569 100644
--- a/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.tsx
+++ b/pwa/src/templates/templateParts/logsTable/LogsTableTemplate.tsx
@@ -78,6 +78,7 @@ export const LogsTableTemplate: React.FC = ({ logs, pagi
{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")}}
@@ -144,6 +145,19 @@ export const LogsTableTemplate: React.FC = ({ logs, pagi
)}
+ {logColumns.source && (
+
+ handleResourceClick(e, "sources", log.context.source)}
+ />
+
+ )}
+
{logColumns.cronjob && (