{
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id });
- const context = useFormManagerStore((state) => state.context);
+ const context = useFormManagerStore(state => state.context);
return (
= ({
editComponent={
}
>
) : (
-
-
-
+
+
+
)}
>
);
diff --git a/packages/design/src/FormManager/index.tsx b/packages/design/src/FormManager/index.tsx
index db0fc78ac..4145535a4 100644
--- a/packages/design/src/FormManager/index.tsx
+++ b/packages/design/src/FormManager/index.tsx
@@ -7,7 +7,12 @@ import {
useSearchParams,
} from 'react-router-dom';
-import { type FormConfig, createFormSession, nullSession } from '@atj/forms';
+import {
+ type FormConfig,
+ createFormSession,
+ nullSession,
+ defaultFormConfig,
+} from '@atj/forms';
import { service } from '@atj/forms';
import { type ComponentForPattern } from '../Form';
@@ -28,22 +33,37 @@ import AvailableFormList, {
} from '../AvailableFormList';
import styles from './FormEdit/formEditStyles.module.css';
-export type FormManagerContext = {
+import { defaultPatternComponents, defaultPatternEditComponents } from '..';
+
+export type PatternLessFormManagerContext = {
baseUrl: `${string}/`;
- components: ComponentForPattern;
- config: FormConfig;
- editComponents: EditComponentForPattern;
formService: service.FormService;
uswdsRoot: `${string}/`;
urlForForm: UrlForForm;
urlForFormManager: UrlForFormManager;
};
+export type FormManagerContext = PatternLessFormManagerContext & {
+ config: FormConfig;
+ components: ComponentForPattern;
+ editComponents: EditComponentForPattern;
+};
+
type FormManagerProps = {
- context: FormManagerContext;
+ //context: FormManagerContext;
+ context: PatternLessFormManagerContext;
};
-export default function FormManager({ context }: FormManagerProps) {
+export default function FormManager(props: FormManagerProps) {
+ // For now, hardcode the pattern React components.
+ // If these are user-configurable, we'll likely need to, in some manner,
+ // inject a compiled bundle into the application.
+ const context: FormManagerContext = {
+ ...props.context,
+ components: defaultPatternComponents,
+ config: defaultFormConfig,
+ editComponents: defaultPatternEditComponents,
+ };
return (
diff --git a/packages/design/src/FormRouter/index.tsx b/packages/design/src/FormRouter/index.tsx
index ca50c04df..1ece77e0c 100644
--- a/packages/design/src/FormRouter/index.tsx
+++ b/packages/design/src/FormRouter/index.tsx
@@ -1,20 +1,29 @@
import React from 'react';
import { useParams, HashRouter, Route, Routes } from 'react-router-dom';
-import { service } from '@atj/forms';
+import { defaultFormConfig, service } from '@atj/forms';
import { createFormSession } from '@atj/forms';
-import Form, { type FormUIContext } from '../Form';
import { useQueryString } from './hooks';
+import { defaultPatternComponents } from '..';
+import Form, { FormUIContext } from '../Form';
// Wrapper around Form that includes a client-side router for loading forms.
export default function FormRouter({
- context,
+ uswdsRoot,
formService,
}: {
- context: FormUIContext;
+ uswdsRoot: `${string}/`;
formService: service.FormService;
}) {
+ // For now, hardcode the pattern configuration.
+ // If these are user-configurable, we'll likely need to, in some manner,
+ // inject a compiled bundle into the application.
+ const context: FormUIContext = {
+ config: defaultFormConfig,
+ components: defaultPatternComponents,
+ uswdsRoot,
+ };
return (
diff --git a/packages/design/src/index.ts b/packages/design/src/index.ts
index c0eb5ede1..fd9ebfcdd 100644
--- a/packages/design/src/index.ts
+++ b/packages/design/src/index.ts
@@ -1,8 +1,8 @@
-import '@uswds/uswds';
+//import '@uswds/uswds';
export { default as AvailableFormList } from './AvailableFormList';
export { default as Form } from './Form';
export { defaultPatternComponents } from './Form/components';
-export { default as FormManager } from './FormManager';
+export { default as FormManager, type FormManagerContext } from './FormManager';
export { defaultPatternEditComponents } from './FormManager/FormEdit/components';
export { default as FormRouter } from './FormRouter';
diff --git a/apps/doj-demo/.gitignore b/packages/server/.gitignore
similarity index 100%
rename from apps/doj-demo/.gitignore
rename to packages/server/.gitignore
diff --git a/apps/doj-demo/.nvmrc b/packages/server/.nvmrc
similarity index 100%
rename from apps/doj-demo/.nvmrc
rename to packages/server/.nvmrc
diff --git a/packages/server/README.md b/packages/server/README.md
new file mode 100644
index 000000000..640bfb6de
--- /dev/null
+++ b/packages/server/README.md
@@ -0,0 +1,35 @@
+# @atj/server
+
+The form platform's web server.
+
+## Build
+
+The build consists of Astro's node.js adapter's output, as well as a constructor for running the web server with user-provided configuration. The build target produces both:
+
+```bash
+pnpm build
+```
+
+## Development
+
+```bash
+pnpm dev
+```
+
+## Usage example
+
+To start the provided Express server:
+
+```typescript
+import { createServer } from '@atj/server/dist/index.js';
+
+const port = process.env.PORT || 4321;
+
+const app = createServer({
+ title: 'Example Form Service',
+});
+
+app.listen(port, () => {
+ console.log(`Server running on http://localhost:${port}`);
+});
+```
diff --git a/apps/doj-demo/astro.config.mjs b/packages/server/astro.config.mjs
similarity index 97%
rename from apps/doj-demo/astro.config.mjs
rename to packages/server/astro.config.mjs
index 662ad374a..ca1aac85a 100644
--- a/apps/doj-demo/astro.config.mjs
+++ b/packages/server/astro.config.mjs
@@ -12,7 +12,7 @@ export default defineConfig({
trailingSlash: 'never',
base: addTrailingSlash(process.env.BASEURL || ''),
adapter: node({
- mode: 'standalone',
+ mode: 'middleware',
}),
integrations: [
react({
diff --git a/apps/doj-demo/package.json b/packages/server/package.json
similarity index 69%
rename from apps/doj-demo/package.json
rename to packages/server/package.json
index 06e607c06..1bb32792c 100644
--- a/apps/doj-demo/package.json
+++ b/packages/server/package.json
@@ -1,11 +1,13 @@
{
- "name": "doj-demo",
+ "name": "@atj/server",
"type": "module",
"version": "0.0.1",
+ "main": "dist/server/index.js",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
- "build": "astro check && astro build",
+ "build": "astro check && astro build && pnpm build:entry",
+ "build:entry": "tsup --dts --format esm src/index.ts",
"preview": "astro preview",
"astro": "astro"
},
@@ -16,12 +18,14 @@
"@atj/design": "workspace:*",
"@atj/forms": "workspace:*",
"astro": "^4.10.3",
+ "express": "^4.19.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.12",
"typescript": "^5.3.3"
},
"devDependencies": {
+ "@types/express": "^4.17.21",
"@types/react": "^18.2.62"
}
}
diff --git a/packages/server/public/design b/packages/server/public/design
new file mode 120000
index 000000000..32b8ef7c5
--- /dev/null
+++ b/packages/server/public/design
@@ -0,0 +1 @@
+../../../packages/design/storybook-static
\ No newline at end of file
diff --git a/apps/doj-demo/public/favicon.ico b/packages/server/public/favicon.ico
similarity index 100%
rename from apps/doj-demo/public/favicon.ico
rename to packages/server/public/favicon.ico
diff --git a/apps/doj-demo/public/favicon/android-chrome-192x192.png b/packages/server/public/favicon/android-chrome-192x192.png
similarity index 100%
rename from apps/doj-demo/public/favicon/android-chrome-192x192.png
rename to packages/server/public/favicon/android-chrome-192x192.png
diff --git a/apps/doj-demo/public/favicon/android-chrome-384x384.png b/packages/server/public/favicon/android-chrome-384x384.png
similarity index 100%
rename from apps/doj-demo/public/favicon/android-chrome-384x384.png
rename to packages/server/public/favicon/android-chrome-384x384.png
diff --git a/apps/doj-demo/public/favicon/android-chrome-512x512.png b/packages/server/public/favicon/android-chrome-512x512.png
similarity index 100%
rename from apps/doj-demo/public/favicon/android-chrome-512x512.png
rename to packages/server/public/favicon/android-chrome-512x512.png
diff --git a/apps/doj-demo/public/favicon/apple-touch-icon.png b/packages/server/public/favicon/apple-touch-icon.png
similarity index 100%
rename from apps/doj-demo/public/favicon/apple-touch-icon.png
rename to packages/server/public/favicon/apple-touch-icon.png
diff --git a/apps/doj-demo/public/favicon/favicon-16x16.png b/packages/server/public/favicon/favicon-16x16.png
similarity index 100%
rename from apps/doj-demo/public/favicon/favicon-16x16.png
rename to packages/server/public/favicon/favicon-16x16.png
diff --git a/apps/doj-demo/public/favicon/favicon-32x32.png b/packages/server/public/favicon/favicon-32x32.png
similarity index 100%
rename from apps/doj-demo/public/favicon/favicon-32x32.png
rename to packages/server/public/favicon/favicon-32x32.png
diff --git a/apps/doj-demo/public/favicon/favicon.ico b/packages/server/public/favicon/favicon.ico
similarity index 100%
rename from apps/doj-demo/public/favicon/favicon.ico
rename to packages/server/public/favicon/favicon.ico
diff --git a/packages/server/public/sample-documents b/packages/server/public/sample-documents
new file mode 120000
index 000000000..edc7ca954
--- /dev/null
+++ b/packages/server/public/sample-documents
@@ -0,0 +1 @@
+../../../packages/forms/sample-documents
\ No newline at end of file
diff --git a/apps/doj-demo/public/uswds b/packages/server/public/uswds
similarity index 100%
rename from apps/doj-demo/public/uswds
rename to packages/server/public/uswds
diff --git a/packages/server/src/components/AppAvailableFormList.tsx b/packages/server/src/components/AppAvailableFormList.tsx
new file mode 100644
index 000000000..90ab59322
--- /dev/null
+++ b/packages/server/src/components/AppAvailableFormList.tsx
@@ -0,0 +1,29 @@
+import React from 'react';
+import { ErrorBoundary } from 'react-error-boundary';
+
+import { AvailableFormList } from '@atj/design';
+import { service } from '@atj/forms';
+
+import { type AppContext } from '../context';
+import { getFormManagerUrlById, getFormUrl } from '../routes';
+import DebugTools from './DebugTools';
+
+export default ({ ctx }: { ctx: AppContext }) => {
+ const formService = service.createBrowserFormService();
+ return (
+
+ There was an unexpected error rendering the form list.
+
+