diff --git a/postcss.config.js b/postcss.config.js deleted file mode 100644 index 2e7af2b..0000000 --- a/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} diff --git a/src/App.tsx b/src/App.tsx deleted file mode 100644 index 176813c..0000000 --- a/src/App.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export default function App() { - return ( -
-

Asset Management

-
- ) -} diff --git a/src/index.css b/src/index.css deleted file mode 100644 index b5c61c9..0000000 --- a/src/index.css +++ /dev/null @@ -1,3 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; diff --git a/src/main.tsx b/src/main.tsx deleted file mode 100644 index 51dc01d..0000000 --- a/src/main.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import { BrowserRouter } from 'react-router-dom' -import { ZinoProvider } from './zino-sdk' -import { requireConfigValue, basePath } from './runtimeConfig' -import './index.css' -import App from './App' - -createRoot(document.getElementById('root')!).render( - - - - - - - , -) diff --git a/src/runtimeConfig.ts b/src/runtimeConfig.ts deleted file mode 100644 index df0b705..0000000 --- a/src/runtimeConfig.ts +++ /dev/null @@ -1,35 +0,0 @@ -declare global { - interface Window { - __RUNTIME_CONFIG__?: Record - } -} - -// SAME_ORIGIN resolves to the serving origin, for a frontend mounted on a custom -// domain where the platform is proxied under the same host. It exists because an -// empty string is falsy and so can never survive the || chain below, which is -// exactly what a "use the current origin" value has to do. -export function resolveConfigValue(key: string, fallback = ''): string { - const runtime = (window.__RUNTIME_CONFIG__ || {})[key] - const devFallback = import.meta.env.DEV ? (import.meta.env[key] as string) : '' - const value = runtime || devFallback || fallback - return value === 'SAME_ORIGIN' ? window.location.origin.replace(/\/$/, '') : value -} - -// Throws rather than silently running against the wrong backend. -export function requireConfigValue(key: string): string { - const value = resolveConfigValue(key) - if (!value) { - throw new Error( - 'Missing runtime config "' + key + '". The server writes config.js when it ' + - 'places the build; for local dev set ' + key + ' in .env.', - ) - } - return value -} - -// The mount path this app is served under, taken from the the server -// writes into index.html. Drives the router basename, so one build serves any -// mount without being rebuilt. -export function basePath(): string { - return new URL(document.baseURI).pathname -} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts deleted file mode 100644 index 11f02fe..0000000 --- a/src/vite-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/src/zino-sdk/DynamicForm.tsx b/src/zino-sdk/DynamicForm.tsx deleted file mode 100644 index 9ef2870..0000000 --- a/src/zino-sdk/DynamicForm.tsx +++ /dev/null @@ -1,175 +0,0 @@ -import React, { useState } from "react"; -import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; -import { useZino } from "./provider"; -import type { FormField } from "./types"; - -export interface DynamicFormProps { - /** Workflow definition ID. */ - workflowId: string; - /** Activity UID — the form schema is fetched for this activity. */ - activityId: string; - /** Instance ID — omit for INIT activities (start workflow). */ - instanceId?: string; - /** Called after successful submission with the result. */ - onSuccess?: (result: unknown) => void; - /** Called on submission error. */ - onError?: (error: unknown) => void; - /** Optional CSS class for the form wrapper. */ - className?: string; -} - -/** - * Renders a dynamic form based on the activity's form schema. - * - * Fetches the form config from the core-service, renders fields by type, - * and submits via performActivity or startWorkflow. - * - * ```tsx - * { closeModal(); }} - * /> - * ``` - */ -export function DynamicForm({ - workflowId, - activityId, - instanceId, - onSuccess, - onError, - className, -}: DynamicFormProps) { - const { workflows } = useZino(); - const queryClient = useQueryClient(); - const [formData, setFormData] = useState>({}); - - // Fetch form schema - const { data: form, isLoading: formLoading, error: formError } = useQuery({ - queryKey: ["form", workflowId, activityId, instanceId], - queryFn: () => workflows.getForm(workflowId, activityId, "desktop", instanceId), - }); - - // Submit mutation - const submit = useMutation({ - mutationFn: async (data: Record) => { - if (instanceId) { - return workflows.performActivity(workflowId, instanceId, activityId, data); - } else { - return workflows.startWorkflow(workflowId, activityId, data); - } - }, - onSuccess: (result) => { - queryClient.invalidateQueries({ queryKey: ["recordview"] }); - queryClient.invalidateQueries({ queryKey: ["instance"] }); - queryClient.invalidateQueries({ queryKey: ["detailview"] }); - queryClient.invalidateQueries({ queryKey: ["audit"] }); - onSuccess?.(result); - }, - onError: (err) => { - onError?.(err); - }, - }); - - const handleChange = (fieldId: string, value: string) => { - setFormData((prev) => ({ ...prev, [fieldId]: value })); - }; - - const handleSubmit = (e: React.FormEvent) => { - e.preventDefault(); - // Map form field IDs to their mapped_activity_field_id - const mapped: Record = {}; - for (const field of form?.form_json?.fields ?? []) { - const key = field.mapped_activity_field_id || field.id; - mapped[key] = formData[field.id] ?? ""; - } - submit.mutate(mapped); - }; - - if (formLoading) { - return
; - } - - if (formError) { - return
Failed to load form: {(formError as any)?.message ?? "Unknown error"}
; - } - - const fields: FormField[] = form?.form_json?.fields ?? []; - - return ( -
- {form?.form_json?.title && ( -

{form.form_json.title}

- )} - -
- {fields.map((field) => ( -
- - {renderField(field, formData[field.id] ?? "", (v) => handleChange(field.id, v))} -
- ))} -
- - {submit.error && ( -
- {(submit.error as any)?.message ?? "Submission failed"} -
- )} - - -
- ); -} - -function renderField( - field: FormField, - value: string, - onChange: (value: string) => void, -) { - const baseClass = - "w-full border border-gray-300 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"; - - switch (field.type) { - case "paragraph": - return ( -