feat(dashboard): Setup workflows in V2 routes (#6939)
This commit is contained in:
1 parent
20e8df914e
commit
849010d875
33 files changed
+187
-132
No files matched your search
@@ -860,8 +860,8 @@
|
|||||||
"tokenExpiresIn": "Token expires in <0>{{time}}</0> minutes",
|
"tokenExpiresIn": "Token expires in <0>{{time}}</0> minutes",
|
||||||
"successfulRequest": "We have sent you an email with instructions on how to reset your password. If you don't receive an email, please check your spam folder or try again."
|
"successfulRequest": "We have sent you an email with instructions on how to reset your password. If you don't receive an email, please check your spam folder or try again."
|
||||||
},
|
},
|
||||||
"executions": {
|
"workflowExecutions": {
|
||||||
"domain": "Executions",
|
"domain": "Workflows",
|
||||||
"transactionIdLabel": "Transaction ID",
|
"transactionIdLabel": "Transaction ID",
|
||||||
"workflowIdLabel": "Workflow ID",
|
"workflowIdLabel": "Workflow ID",
|
||||||
"progressLabel": "Progress",
|
"progressLabel": "Progress",
|
||||||
|
|||||||
+2
-2
@@ -68,8 +68,8 @@ const useDeveloperRoutes = (): NavItemProps[] => {
|
|||||||
to: "/settings/api-key-management",
|
to: "/settings/api-key-management",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t("executions.domain"),
|
label: t("workflowExecutions.domain"),
|
||||||
to: "/settings/executions",
|
to: "/settings/workflows",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[t]
|
[t]
|
||||||
|
|||||||
@@ -820,23 +820,6 @@ export const v1Routes: RouteObject[] = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
path: "executions",
|
|
||||||
element: <Outlet />,
|
|
||||||
handle: {
|
|
||||||
crumb: () => "Executions",
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: "",
|
|
||||||
lazy: () => import("../../routes/executions/execution-list"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: ":id",
|
|
||||||
lazy: () => import("../../routes/executions/execution-detail"),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
...settingsExtensions,
|
...settingsExtensions,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -300,6 +300,38 @@ export const v2Routes: RouteObject[] = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "workflows",
|
||||||
|
element: <Outlet />,
|
||||||
|
handle: {
|
||||||
|
crumb: () => "Workflows",
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "",
|
||||||
|
lazy: () =>
|
||||||
|
import(
|
||||||
|
"../../v2-routes/workflow-executions/workflow-execution-list"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: ":id",
|
||||||
|
lazy: () =>
|
||||||
|
import(
|
||||||
|
"../../v2-routes/workflow-executions/workflow-execution-detail"
|
||||||
|
),
|
||||||
|
handle: {
|
||||||
|
crumb: (data: { workflow: any }) => {
|
||||||
|
if (!data) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return data.workflow.name
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
-1
@@ -1 +0,0 @@
|
|||||||
export * from "./execution-general-section"
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
export * from "./execution-history-section"
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
export * from "./execution-payload-section"
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
export * from "./execution-timeline-section"
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
import { useAdminCustomQuery } from "medusa-react"
|
|
||||||
import { useParams } from "react-router-dom"
|
|
||||||
import { JsonViewSection } from "../../../components/common/json-view-section"
|
|
||||||
import { adminExecutionKey } from "../utils"
|
|
||||||
import { ExecutionGeneralSection } from "./components/execution-general-section"
|
|
||||||
import { ExecutionHistorySection } from "./components/execution-history-section"
|
|
||||||
import { ExecutionPayloadSection } from "./components/execution-payload-section"
|
|
||||||
import { ExecutionTimelineSection } from "./components/execution-timeline-section"
|
|
||||||
|
|
||||||
export const ExecutionDetail = () => {
|
|
||||||
const { id } = useParams()
|
|
||||||
|
|
||||||
const { data, isLoading, isError, error } = useAdminCustomQuery(
|
|
||||||
`/workflows-executions/${id}`,
|
|
||||||
adminExecutionKey.detail(id!)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (isLoading || !data) {
|
|
||||||
return <div>Loading...</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isError) {
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col gap-y-2">
|
|
||||||
<ExecutionGeneralSection execution={data.workflow_execution} />
|
|
||||||
<ExecutionPayloadSection execution={data.workflow_execution} />
|
|
||||||
<ExecutionTimelineSection execution={data.workflow_execution} />
|
|
||||||
<ExecutionHistorySection execution={data.workflow_execution} />
|
|
||||||
<JsonViewSection data={data.workflow_execution} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { ExecutionDetail as Component } from "./execution-detail"
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
export * from "./executions-list-table"
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import { ExecutionsListTable } from "./components/executions-list-table"
|
|
||||||
|
|
||||||
export const ExcecutionList = () => {
|
|
||||||
return (
|
|
||||||
<div className="flex flex-col gap-y-2">
|
|
||||||
<ExecutionsListTable />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { ExcecutionList as Component } from "./execution-list"
|
|
||||||
File renamed without changes.
File renamed without changes.
+16
-16
@@ -40,19 +40,19 @@ export const getTransactionState = (
|
|||||||
) => {
|
) => {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case TransactionState.DONE:
|
case TransactionState.DONE:
|
||||||
return t("executions.state.done")
|
return t("workflowExecutions.state.done")
|
||||||
case TransactionState.FAILED:
|
case TransactionState.FAILED:
|
||||||
return t("executions.state.failed")
|
return t("workflowExecutions.state.failed")
|
||||||
case TransactionState.REVERTED:
|
case TransactionState.REVERTED:
|
||||||
return t("executions.state.reverted")
|
return t("workflowExecutions.state.reverted")
|
||||||
case TransactionState.INVOKING:
|
case TransactionState.INVOKING:
|
||||||
return t("executions.state.invoking")
|
return t("workflowExecutions.state.invoking")
|
||||||
case TransactionState.WAITING_TO_COMPENSATE:
|
case TransactionState.WAITING_TO_COMPENSATE:
|
||||||
return t("executions.transaction.state.waitingToCompensate")
|
return t("workflowExecutions.transaction.state.waitingToCompensate")
|
||||||
case TransactionState.COMPENSATING:
|
case TransactionState.COMPENSATING:
|
||||||
return t("executions.state.compensating")
|
return t("workflowExecutions.state.compensating")
|
||||||
case TransactionState.NOT_STARTED:
|
case TransactionState.NOT_STARTED:
|
||||||
return t("executions.state.notStarted")
|
return t("workflowExecutions.state.notStarted")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,22 +80,22 @@ export const getStepState = (
|
|||||||
) => {
|
) => {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case TransactionStepState.DONE:
|
case TransactionStepState.DONE:
|
||||||
return t("executions.state.done")
|
return t("workflowExecutions.state.done")
|
||||||
case TransactionStepState.FAILED:
|
case TransactionStepState.FAILED:
|
||||||
return t("executions.state.failed")
|
return t("workflowExecutions.state.failed")
|
||||||
case TransactionStepState.REVERTED:
|
case TransactionStepState.REVERTED:
|
||||||
return t("executions.state.reverted")
|
return t("workflowExecutions.state.reverted")
|
||||||
case TransactionStepState.INVOKING:
|
case TransactionStepState.INVOKING:
|
||||||
return t("executions.state.invoking")
|
return t("workflowExecutions.state.invoking")
|
||||||
case TransactionStepState.COMPENSATING:
|
case TransactionStepState.COMPENSATING:
|
||||||
return t("executions.state.compensating")
|
return t("workflowExecutions.state.compensating")
|
||||||
case TransactionStepState.NOT_STARTED:
|
case TransactionStepState.NOT_STARTED:
|
||||||
return t("executions.state.notStarted")
|
return t("workflowExecutions.state.notStarted")
|
||||||
case TransactionStepState.SKIPPED:
|
case TransactionStepState.SKIPPED:
|
||||||
return t("executions.step.state.skipped")
|
return t("workflowExecutions.step.state.skipped")
|
||||||
case TransactionStepState.DORMANT:
|
case TransactionStepState.DORMANT:
|
||||||
return t("executions.step.state.dormant")
|
return t("workflowExecutions.step.state.dormant")
|
||||||
case TransactionStepState.TIMEOUT:
|
case TransactionStepState.TIMEOUT:
|
||||||
return t("executions.step.state.timeout")
|
return t("workflowExecutions.step.state.timeout")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
export * from "./workflow-execution-general-section"
|
||||||
+8
-8
@@ -15,13 +15,13 @@ import {
|
|||||||
} from "../../../types"
|
} from "../../../types"
|
||||||
import { getTransactionState, getTransactionStateColor } from "../../../utils"
|
import { getTransactionState, getTransactionStateColor } from "../../../utils"
|
||||||
|
|
||||||
type ExecutionGeneralSectionProps = {
|
type WorkflowExecutionGeneralSectionProps = {
|
||||||
execution: WorkflowExecutionDTO
|
execution: WorkflowExecutionDTO
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ExecutionGeneralSection = ({
|
export const WorkflowExecutionGeneralSection = ({
|
||||||
execution,
|
execution,
|
||||||
}: ExecutionGeneralSectionProps) => {
|
}: WorkflowExecutionGeneralSectionProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const cleanId = execution.id.replace("wf_exec_", "")
|
const cleanId = execution.id.replace("wf_exec_", "")
|
||||||
@@ -39,7 +39,7 @@ export const ExecutionGeneralSection = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="text-ui-fg-subtle grid grid-cols-2 px-6 py-4">
|
<div className="text-ui-fg-subtle grid grid-cols-2 px-6 py-4">
|
||||||
<Text size="small" leading="compact" weight="plus">
|
<Text size="small" leading="compact" weight="plus">
|
||||||
{t("executions.workflowIdLabel")}
|
{t("workflowExecutions.workflowIdLabel")}
|
||||||
</Text>
|
</Text>
|
||||||
<Badge size="2xsmall" className="w-fit">
|
<Badge size="2xsmall" className="w-fit">
|
||||||
{execution.workflow_id}
|
{execution.workflow_id}
|
||||||
@@ -47,7 +47,7 @@ export const ExecutionGeneralSection = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="text-ui-fg-subtle grid grid-cols-2 px-6 py-4">
|
<div className="text-ui-fg-subtle grid grid-cols-2 px-6 py-4">
|
||||||
<Text size="small" leading="compact" weight="plus">
|
<Text size="small" leading="compact" weight="plus">
|
||||||
{t("executions.transactionIdLabel")}
|
{t("workflowExecutions.transactionIdLabel")}
|
||||||
</Text>
|
</Text>
|
||||||
<Badge size="2xsmall" className="w-fit">
|
<Badge size="2xsmall" className="w-fit">
|
||||||
{execution.transaction_id}
|
{execution.transaction_id}
|
||||||
@@ -55,7 +55,7 @@ export const ExecutionGeneralSection = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="text-ui-fg-subtle grid grid-cols-2 px-6 py-4">
|
<div className="text-ui-fg-subtle grid grid-cols-2 px-6 py-4">
|
||||||
<Text size="small" leading="compact" weight="plus">
|
<Text size="small" leading="compact" weight="plus">
|
||||||
{t("executions.progressLabel")}
|
{t("workflowExecutions.progressLabel")}
|
||||||
</Text>
|
</Text>
|
||||||
<Progress steps={execution.execution?.steps} />
|
<Progress steps={execution.execution?.steps} />
|
||||||
</div>
|
</div>
|
||||||
@@ -75,7 +75,7 @@ const Progress = ({
|
|||||||
if (!steps) {
|
if (!steps) {
|
||||||
return (
|
return (
|
||||||
<Text size="small" leading="compact" className="text-ui-fg-subtle">
|
<Text size="small" leading="compact" className="text-ui-fg-subtle">
|
||||||
{t("executions.stepsCompletedLabel", {
|
{t("workflowExecutions.stepsCompletedLabel", {
|
||||||
completed: 0,
|
completed: 0,
|
||||||
total: 0,
|
total: 0,
|
||||||
})}
|
})}
|
||||||
@@ -108,7 +108,7 @@ const Progress = ({
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<Text size="small" leading="compact" className="text-ui-fg-subtle">
|
<Text size="small" leading="compact" className="text-ui-fg-subtle">
|
||||||
{t("executions.stepsCompletedLabel", {
|
{t("workflowExecutions.stepsCompletedLabel", {
|
||||||
completed: completedSteps.length,
|
completed: completedSteps.length,
|
||||||
count: actionableSteps.length,
|
count: actionableSteps.length,
|
||||||
})}
|
})}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
export * from "./workflow-execution-history-section"
|
||||||
+18
-14
@@ -27,13 +27,13 @@ import {
|
|||||||
WorkflowExecutionStep,
|
WorkflowExecutionStep,
|
||||||
} from "../../../types"
|
} from "../../../types"
|
||||||
|
|
||||||
type ExecutionHistorySectionProps = {
|
type WorkflowExecutionHistorySectionProps = {
|
||||||
execution: WorkflowExecutionDTO
|
execution: WorkflowExecutionDTO
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ExecutionHistorySection = ({
|
export const WorkflowExecutionHistorySection = ({
|
||||||
execution,
|
execution,
|
||||||
}: ExecutionHistorySectionProps) => {
|
}: WorkflowExecutionHistorySectionProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const map = Object.values(execution.execution?.steps || {})
|
const map = Object.values(execution.execution?.steps || {})
|
||||||
@@ -57,7 +57,9 @@ export const ExecutionHistorySection = ({
|
|||||||
return (
|
return (
|
||||||
<Container className="divide-y p-0">
|
<Container className="divide-y p-0">
|
||||||
<div className="flex items-center justify-between px-6 py-4">
|
<div className="flex items-center justify-between px-6 py-4">
|
||||||
<Heading level="h2">{t("executions.history.sectionTitle")}</Heading>
|
<Heading level="h2">
|
||||||
|
{t("workflowExecutions.history.sectionTitle")}
|
||||||
|
</Heading>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-y-0.5 px-6 py-4">
|
<div className="flex flex-col gap-y-0.5 px-6 py-4">
|
||||||
{steps.map((step, index) => {
|
{steps.map((step, index) => {
|
||||||
@@ -178,13 +180,13 @@ const Event = ({
|
|||||||
<div className="flex flex-col gap-y-2 pb-4 pt-2">
|
<div className="flex flex-col gap-y-2 pb-4 pt-2">
|
||||||
<div className="text-ui-fg-subtle flex flex-col gap-y-2">
|
<div className="text-ui-fg-subtle flex flex-col gap-y-2">
|
||||||
<Text size="small" leading="compact">
|
<Text size="small" leading="compact">
|
||||||
{t("executions.history.definitionLabel")}
|
{t("workflowExecutions.history.definitionLabel")}
|
||||||
</Text>
|
</Text>
|
||||||
<CodeBlock
|
<CodeBlock
|
||||||
snippets={[
|
snippets={[
|
||||||
{
|
{
|
||||||
code: JSON.stringify(step.definition, null, 2),
|
code: JSON.stringify(step.definition, null, 2),
|
||||||
label: t("executions.history.definitionLabel"),
|
label: t("workflowExecutions.history.definitionLabel"),
|
||||||
language: "json",
|
language: "json",
|
||||||
hideLineNumbers: true,
|
hideLineNumbers: true,
|
||||||
},
|
},
|
||||||
@@ -196,7 +198,7 @@ const Event = ({
|
|||||||
{stepInvokeContext && (
|
{stepInvokeContext && (
|
||||||
<div className="text-ui-fg-subtle flex flex-col gap-y-2">
|
<div className="text-ui-fg-subtle flex flex-col gap-y-2">
|
||||||
<Text size="small" leading="compact">
|
<Text size="small" leading="compact">
|
||||||
{t("executions.history.outputLabel")}
|
{t("workflowExecutions.history.outputLabel")}
|
||||||
</Text>
|
</Text>
|
||||||
<CodeBlock
|
<CodeBlock
|
||||||
snippets={[
|
snippets={[
|
||||||
@@ -206,7 +208,7 @@ const Event = ({
|
|||||||
null,
|
null,
|
||||||
2
|
2
|
||||||
),
|
),
|
||||||
label: t("executions.history.outputLabel"),
|
label: t("workflowExecutions.history.outputLabel"),
|
||||||
language: "json",
|
language: "json",
|
||||||
hideLineNumbers: true,
|
hideLineNumbers: true,
|
||||||
},
|
},
|
||||||
@@ -220,7 +222,7 @@ const Event = ({
|
|||||||
step.compensate.state === TransactionStepState.REVERTED && (
|
step.compensate.state === TransactionStepState.REVERTED && (
|
||||||
<div className="text-ui-fg-subtle flex flex-col gap-y-2">
|
<div className="text-ui-fg-subtle flex flex-col gap-y-2">
|
||||||
<Text size="small" leading="compact">
|
<Text size="small" leading="compact">
|
||||||
{t("executions.history.compensateInputLabel")}
|
{t("workflowExecutions.history.compensateInputLabel")}
|
||||||
</Text>
|
</Text>
|
||||||
<CodeBlock
|
<CodeBlock
|
||||||
snippets={[
|
snippets={[
|
||||||
@@ -230,7 +232,9 @@ const Event = ({
|
|||||||
null,
|
null,
|
||||||
2
|
2
|
||||||
),
|
),
|
||||||
label: t("executions.history.compensateInputLabel"),
|
label: t(
|
||||||
|
"workflowExecutions.history.compensateInputLabel"
|
||||||
|
),
|
||||||
language: "json",
|
language: "json",
|
||||||
hideLineNumbers: true,
|
hideLineNumbers: true,
|
||||||
},
|
},
|
||||||
@@ -243,7 +247,7 @@ const Event = ({
|
|||||||
{stepError && (
|
{stepError && (
|
||||||
<div className="text-ui-fg-subtle flex flex-col gap-y-2">
|
<div className="text-ui-fg-subtle flex flex-col gap-y-2">
|
||||||
<Text size="small" leading="compact">
|
<Text size="small" leading="compact">
|
||||||
{t("executions.history.errorLabel")}
|
{t("workflowExecutions.history.errorLabel")}
|
||||||
</Text>
|
</Text>
|
||||||
<CodeBlock
|
<CodeBlock
|
||||||
snippets={[
|
snippets={[
|
||||||
@@ -256,7 +260,7 @@ const Event = ({
|
|||||||
null,
|
null,
|
||||||
2
|
2
|
||||||
),
|
),
|
||||||
label: t("executions.history.errorLabel"),
|
label: t("workflowExecutions.history.errorLabel"),
|
||||||
language: "json",
|
language: "json",
|
||||||
hideLineNumbers: true,
|
hideLineNumbers: true,
|
||||||
},
|
},
|
||||||
@@ -295,7 +299,7 @@ const StepState = ({
|
|||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-x-1">
|
<div className="flex items-center gap-x-1">
|
||||||
<Text size="small" leading="compact" className="text-ui-fg-subtle">
|
<Text size="small" leading="compact" className="text-ui-fg-subtle">
|
||||||
{t("executions.history.runningState")}
|
{t("workflowExecutions.history.runningState")}
|
||||||
</Text>
|
</Text>
|
||||||
<Spinner className="text-ui-fg-interactive animate-spin" />
|
<Spinner className="text-ui-fg-interactive animate-spin" />
|
||||||
</div>
|
</div>
|
||||||
@@ -305,7 +309,7 @@ const StepState = ({
|
|||||||
if (isFailed) {
|
if (isFailed) {
|
||||||
return (
|
return (
|
||||||
<Text size="small" leading="compact" className="text-ui-fg-subtle">
|
<Text size="small" leading="compact" className="text-ui-fg-subtle">
|
||||||
{t("executions.history.failedState")}
|
{t("workflowExecutions.history.failedState")}
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
export * from "./workflow-execution-payload-section"
|
||||||
+5
-5
@@ -1,21 +1,21 @@
|
|||||||
import { JsonViewSection } from "../../../../../components/common/json-view-section"
|
import { JsonViewSection } from "../../../../../components/common/json-view-section"
|
||||||
import { WorkflowExecutionDTO } from "../../../types"
|
import { WorkflowExecutionDTO } from "../../../types"
|
||||||
|
|
||||||
type ExecutionPayloadSectionProps = {
|
type WorkflowExecutionPayloadSectionProps = {
|
||||||
execution: WorkflowExecutionDTO
|
execution: WorkflowExecutionDTO
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ExecutionPayloadSection = ({
|
export const WorkflowExecutionPayloadSection = ({
|
||||||
execution,
|
execution,
|
||||||
}: ExecutionPayloadSectionProps) => {
|
}: WorkflowExecutionPayloadSectionProps) => {
|
||||||
let payload = execution.context?.data?.payload
|
let payload = execution.context?.data?.payload
|
||||||
|
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// payloads may be simple primitives, so we need to wrap them in an object
|
// payloads may be a primitive, so we need to wrap them in an object
|
||||||
// to ensure the JsonViewSection component can render them
|
// to ensure the JsonViewSection component can render them.
|
||||||
if (typeof payload !== "object") {
|
if (typeof payload !== "object") {
|
||||||
payload = { input: payload }
|
payload = { input: payload }
|
||||||
}
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
export * from "./workflow-execution-timeline-section"
|
||||||
+42
-6
@@ -1,5 +1,5 @@
|
|||||||
import { ArrowPathMini, MinusMini, PlusMini } from "@medusajs/icons"
|
import { ArrowPathMini, MinusMini, PlusMini } from "@medusajs/icons"
|
||||||
import { Container, Heading, Text, clx } from "@medusajs/ui"
|
import { Container, DropdownMenu, Heading, Text, clx } from "@medusajs/ui"
|
||||||
import {
|
import {
|
||||||
motion,
|
motion,
|
||||||
useAnimationControls,
|
useAnimationControls,
|
||||||
@@ -18,13 +18,13 @@ import {
|
|||||||
} from "../../../constants"
|
} from "../../../constants"
|
||||||
import { WorkflowExecutionDTO, WorkflowExecutionStep } from "../../../types"
|
import { WorkflowExecutionDTO, WorkflowExecutionStep } from "../../../types"
|
||||||
|
|
||||||
type ExecutionTimelineSectionProps = {
|
type WorkflowExecutionTimelineSectionProps = {
|
||||||
execution: WorkflowExecutionDTO
|
execution: WorkflowExecutionDTO
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ExecutionTimelineSection = ({
|
export const WorkflowExecutionTimelineSection = ({
|
||||||
execution,
|
execution,
|
||||||
}: ExecutionTimelineSectionProps) => {
|
}: WorkflowExecutionTimelineSectionProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -79,6 +79,7 @@ const ZOOM_STEP = 0.25
|
|||||||
|
|
||||||
const Canvas = ({ execution }: { execution: WorkflowExecutionDTO }) => {
|
const Canvas = ({ execution }: { execution: WorkflowExecutionDTO }) => {
|
||||||
const [zoom, setZoom] = useState<number>(1)
|
const [zoom, setZoom] = useState<number>(1)
|
||||||
|
const [isDragging, setIsDragging] = useState(false)
|
||||||
|
|
||||||
const scale = useMotionValue(defaultState.scale)
|
const scale = useMotionValue(defaultState.scale)
|
||||||
const x = useMotionValue(defaultState.x)
|
const x = useMotionValue(defaultState.x)
|
||||||
@@ -152,6 +153,8 @@ const Canvas = ({ execution }: { execution: WorkflowExecutionDTO }) => {
|
|||||||
<div className="relative size-full overflow-hidden object-contain">
|
<div className="relative size-full overflow-hidden object-contain">
|
||||||
<div>
|
<div>
|
||||||
<motion.div
|
<motion.div
|
||||||
|
onMouseDown={() => setIsDragging(true)}
|
||||||
|
onMouseUp={() => setIsDragging(false)}
|
||||||
drag
|
drag
|
||||||
dragConstraints={dragConstraints}
|
dragConstraints={dragConstraints}
|
||||||
dragElastic={0}
|
dragElastic={0}
|
||||||
@@ -165,7 +168,14 @@ const Canvas = ({ execution }: { execution: WorkflowExecutionDTO }) => {
|
|||||||
y,
|
y,
|
||||||
scale,
|
scale,
|
||||||
}}
|
}}
|
||||||
className="bg-ui-bg-subtle relative size-[500rem] origin-top-left items-start justify-start overflow-hidden bg-[radial-gradient(var(--border-base)_1.5px,transparent_0)] bg-[length:20px_20px] bg-repeat"
|
className={clx(
|
||||||
|
"bg-ui-bg-subtle relative size-[500rem] origin-top-left items-start justify-start overflow-hidden",
|
||||||
|
"bg-[radial-gradient(var(--border-base)_1.5px,transparent_0)] bg-[length:20px_20px] bg-repeat",
|
||||||
|
{
|
||||||
|
"cursor-grab": !isDragging,
|
||||||
|
"cursor-grabbing": isDragging,
|
||||||
|
}
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<main className="size-full">
|
<main className="size-full">
|
||||||
<div className="absolute left-[1100px] top-[1100px] flex select-none items-start">
|
<div className="absolute left-[1100px] top-[1100px] flex select-none items-start">
|
||||||
@@ -188,7 +198,8 @@ const Canvas = ({ execution }: { execution: WorkflowExecutionDTO }) => {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-ui-bg-base shadow-borders-base text-ui-fg-subtle absolute bottom-4 left-6 h-7 overflow-hidden rounded-md">
|
<div className="bg-ui-bg-base shadow-borders-base text-ui-fg-subtle absolute bottom-4 left-6 flex h-7 items-center overflow-hidden rounded-md">
|
||||||
|
<div className="flex items-center">
|
||||||
<button
|
<button
|
||||||
onClick={zoomIn}
|
onClick={zoomIn}
|
||||||
type="button"
|
type="button"
|
||||||
@@ -198,6 +209,30 @@ const Canvas = ({ execution }: { execution: WorkflowExecutionDTO }) => {
|
|||||||
>
|
>
|
||||||
<PlusMini />
|
<PlusMini />
|
||||||
</button>
|
</button>
|
||||||
|
<div>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenu.Trigger className="disabled:text-ui-fg-disabled transition-fg hover:bg-ui-bg-base-hover active:bg-ui-bg-base-pressed focus-visible:bg-ui-bg-base-pressed flex w-[50px] items-center justify-center border-r p-1 outline-none">
|
||||||
|
<Text
|
||||||
|
as="span"
|
||||||
|
size="xsmall"
|
||||||
|
leading="compact"
|
||||||
|
className="select-none tabular-nums"
|
||||||
|
>
|
||||||
|
{Math.round(zoom * 100)}%
|
||||||
|
</Text>
|
||||||
|
</DropdownMenu.Trigger>
|
||||||
|
<DropdownMenu.Content>
|
||||||
|
{[50, 75, 100, 125, 150].map((value) => (
|
||||||
|
<DropdownMenu.Item
|
||||||
|
key={value}
|
||||||
|
onClick={() => changeZoom(value / 100)}
|
||||||
|
>
|
||||||
|
{value}%
|
||||||
|
</DropdownMenu.Item>
|
||||||
|
))}
|
||||||
|
</DropdownMenu.Content>
|
||||||
|
</DropdownMenu>
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={zoomOut}
|
onClick={zoomOut}
|
||||||
type="button"
|
type="button"
|
||||||
@@ -207,6 +242,7 @@ const Canvas = ({ execution }: { execution: WorkflowExecutionDTO }) => {
|
|||||||
>
|
>
|
||||||
<MinusMini />
|
<MinusMini />
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={resetCanvas}
|
onClick={resetCanvas}
|
||||||
type="button"
|
type="button"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
export { ExecutionDetail as Component } from "./workflow-detail"
|
||||||
File renamed without changes.
+35
@@ -0,0 +1,35 @@
|
|||||||
|
import { useAdminCustomQuery } from "medusa-react"
|
||||||
|
import { useParams } from "react-router-dom"
|
||||||
|
import { JsonViewSection } from "../../../components/common/json-view-section"
|
||||||
|
import { adminExecutionKey } from "../utils"
|
||||||
|
import { WorkflowExecutionGeneralSection } from "./components/workflow-execution-general-section"
|
||||||
|
import { WorkflowExecutionHistorySection } from "./components/workflow-execution-history-section"
|
||||||
|
import { WorkflowExecutionPayloadSection } from "./components/workflow-execution-payload-section"
|
||||||
|
import { WorkflowExecutionTimelineSection } from "./components/workflow-execution-timeline-section"
|
||||||
|
|
||||||
|
export const ExecutionDetail = () => {
|
||||||
|
const { id } = useParams()
|
||||||
|
|
||||||
|
const { data, isLoading, isError, error } = useAdminCustomQuery(
|
||||||
|
`/workflows-executions/${id}`,
|
||||||
|
adminExecutionKey.detail(id!)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isLoading || !data) {
|
||||||
|
return <div>Loading...</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isError) {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-y-2">
|
||||||
|
<WorkflowExecutionGeneralSection execution={data.workflow_execution} />
|
||||||
|
<WorkflowExecutionTimelineSection execution={data.workflow_execution} />
|
||||||
|
<WorkflowExecutionPayloadSection execution={data.workflow_execution} />
|
||||||
|
<WorkflowExecutionHistorySection execution={data.workflow_execution} />
|
||||||
|
<JsonViewSection data={data.workflow_execution} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
export * from "./workflow-execution-list-table"
|
||||||
+4
-4
@@ -12,7 +12,7 @@ import { getTransactionState, getTransactionStateColor } from "../../../utils"
|
|||||||
|
|
||||||
const columnHelper = createColumnHelper<WorkflowExecutionDTO>()
|
const columnHelper = createColumnHelper<WorkflowExecutionDTO>()
|
||||||
|
|
||||||
export const useExecutionTableColumns = (): ColumnDef<
|
export const useWorkflowExecutionTableColumns = (): ColumnDef<
|
||||||
WorkflowExecutionDTO,
|
WorkflowExecutionDTO,
|
||||||
any
|
any
|
||||||
>[] => {
|
>[] => {
|
||||||
@@ -21,7 +21,7 @@ export const useExecutionTableColumns = (): ColumnDef<
|
|||||||
return useMemo(
|
return useMemo(
|
||||||
() => [
|
() => [
|
||||||
columnHelper.accessor("transaction_id", {
|
columnHelper.accessor("transaction_id", {
|
||||||
header: t("executions.transactionIdLabel"),
|
header: t("workflowExecutions.transactionIdLabel"),
|
||||||
cell: ({ getValue }) => <Badge size="2xsmall">{getValue()}</Badge>,
|
cell: ({ getValue }) => <Badge size="2xsmall">{getValue()}</Badge>,
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor("state", {
|
columnHelper.accessor("state", {
|
||||||
@@ -40,7 +40,7 @@ export const useExecutionTableColumns = (): ColumnDef<
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
columnHelper.accessor("execution", {
|
columnHelper.accessor("execution", {
|
||||||
header: t("executions.progressLabel"),
|
header: t("workflowExecutions.progressLabel"),
|
||||||
cell: ({ getValue }) => {
|
cell: ({ getValue }) => {
|
||||||
const steps = getValue()?.steps as
|
const steps = getValue()?.steps as
|
||||||
| Record<string, WorkflowExecutionStep>
|
| Record<string, WorkflowExecutionStep>
|
||||||
@@ -58,7 +58,7 @@ export const useExecutionTableColumns = (): ColumnDef<
|
|||||||
(step) => step.invoke.state === TransactionStepState.DONE
|
(step) => step.invoke.state === TransactionStepState.DONE
|
||||||
)
|
)
|
||||||
|
|
||||||
return t("executions.stepsCompletedLabel", {
|
return t("workflowExecutions.stepsCompletedLabel", {
|
||||||
completed: completedSteps.length,
|
completed: completedSteps.length,
|
||||||
count: actionableSteps.length,
|
count: actionableSteps.length,
|
||||||
})
|
})
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import { AdminGetWorkflowExecutionsParams } from "@medusajs/medusa"
|
import { AdminGetWorkflowExecutionsParams } from "@medusajs/medusa"
|
||||||
import { useQueryParams } from "../../../../../hooks/use-query-params"
|
import { useQueryParams } from "../../../../../hooks/use-query-params"
|
||||||
|
|
||||||
export const useExecutionTableQuery = ({
|
export const useWorkflowExecutionTableQuery = ({
|
||||||
pageSize = 20,
|
pageSize = 20,
|
||||||
prefix,
|
prefix,
|
||||||
}: {
|
}: {
|
||||||
+6
-6
@@ -6,8 +6,8 @@ import { DataTable } from "../../../../../components/table/data-table"
|
|||||||
import { useDataTable } from "../../../../../hooks/use-data-table"
|
import { useDataTable } from "../../../../../hooks/use-data-table"
|
||||||
import { WorkflowExecutionDTO } from "../../../types"
|
import { WorkflowExecutionDTO } from "../../../types"
|
||||||
import { adminExecutionKey } from "../../../utils"
|
import { adminExecutionKey } from "../../../utils"
|
||||||
import { useExecutionTableColumns } from "./use-execution-table-columns"
|
import { useWorkflowExecutionTableColumns } from "./use-workflow-execution-table-columns"
|
||||||
import { useExecutionTableQuery } from "./use-execution-table-query"
|
import { useWorkflowExecutionTableQuery } from "./use-workflow-execution-table-query"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type isn't exported from the package
|
* Type isn't exported from the package
|
||||||
@@ -21,10 +21,10 @@ type WorkflowExecutionsRes = {
|
|||||||
|
|
||||||
const PAGE_SIZE = 20
|
const PAGE_SIZE = 20
|
||||||
|
|
||||||
export const ExecutionsListTable = () => {
|
export const WorkflowExecutionListTable = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const { searchParams, raw } = useExecutionTableQuery({
|
const { searchParams, raw } = useWorkflowExecutionTableQuery({
|
||||||
pageSize: PAGE_SIZE,
|
pageSize: PAGE_SIZE,
|
||||||
})
|
})
|
||||||
const { data, isLoading, isError, error } = useAdminCustomQuery<
|
const { data, isLoading, isError, error } = useAdminCustomQuery<
|
||||||
@@ -42,7 +42,7 @@ export const ExecutionsListTable = () => {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
const columns = useExecutionTableColumns()
|
const columns = useWorkflowExecutionTableColumns()
|
||||||
|
|
||||||
const { table } = useDataTable({
|
const { table } = useDataTable({
|
||||||
data: data?.workflow_executions || [],
|
data: data?.workflow_executions || [],
|
||||||
@@ -60,7 +60,7 @@ export const ExecutionsListTable = () => {
|
|||||||
return (
|
return (
|
||||||
<Container className="divide-y p-0">
|
<Container className="divide-y p-0">
|
||||||
<div className="flex items-center justify-between px-6 py-4">
|
<div className="flex items-center justify-between px-6 py-4">
|
||||||
<Heading>{t("executions.domain")}</Heading>
|
<Heading>{t("workflowExecutions.domain")}</Heading>
|
||||||
</div>
|
</div>
|
||||||
<DataTable
|
<DataTable
|
||||||
table={table}
|
table={table}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
export { WorkflowExcecutionList as Component } from "./workflow-execution-list"
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
import { WorkflowExecutionListTable } from "./components/workflow-execution-list-table"
|
||||||
|
|
||||||
|
export const WorkflowExcecutionList = () => {
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-y-2">
|
||||||
|
<WorkflowExecutionListTable />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in new issue
Block a user