wcz-layout 6.7.2 → 8.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Approval-BTJTexDo.js +143 -0
- package/dist/Approval-BTJTexDo.js.map +1 -0
- package/dist/DialogsContext-DLqA8RJ_.js +7 -0
- package/dist/DialogsContext-DLqA8RJ_.js.map +1 -0
- package/dist/Email-C9qwj7GD.js +20 -0
- package/dist/Email-C9qwj7GD.js.map +1 -0
- package/dist/FileMeta-DDqUju1Y.js +19 -0
- package/dist/FileMeta-DDqUju1Y.js.map +1 -0
- package/dist/FileMeta-ILLTOjaM.d.ts +20 -0
- package/dist/NotificationContext-CgwUOeW0.js +7 -0
- package/dist/NotificationContext-CgwUOeW0.js.map +1 -0
- package/dist/RouterListItemButton-owZVvuC_.js +78 -0
- package/dist/RouterListItemButton-owZVvuC_.js.map +1 -0
- package/dist/User-CT_IDGuG.d.ts +15 -0
- package/dist/apiMiddleware-CtY4rOFU.js +23 -0
- package/dist/apiMiddleware-CtY4rOFU.js.map +1 -0
- package/dist/components.d.ts +118 -0
- package/dist/components.js +1554 -0
- package/dist/components.js.map +1 -0
- package/dist/data/client.d.ts +3111 -0
- package/dist/data/client.js +188 -0
- package/dist/data/client.js.map +1 -0
- package/dist/data/server.d.ts +19 -0
- package/dist/data/server.js +16 -0
- package/dist/data/server.js.map +1 -0
- package/dist/data.d.ts +7 -0
- package/dist/data.js +2 -0
- package/dist/env-ON-cyE3N.js +31 -0
- package/dist/env-ON-cyE3N.js.map +1 -0
- package/dist/file-BUdLb7H1.js +148 -0
- package/dist/file-BUdLb7H1.js.map +1 -0
- package/dist/file-Dsht7yOP.js +100 -0
- package/dist/file-Dsht7yOP.js.map +1 -0
- package/dist/hooks.d.ts +226 -0
- package/dist/hooks.js +1180 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +2106 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware.d.ts +47 -0
- package/dist/middleware.js +80 -0
- package/dist/middleware.js.map +1 -0
- package/dist/models.d.ts +474 -0
- package/dist/models.js +74 -0
- package/dist/models.js.map +1 -0
- package/dist/msalClient-CYiQAFnY.d.ts +15 -0
- package/dist/msalServer-B9sVqpQ2.js +47 -0
- package/dist/msalServer-B9sVqpQ2.js.map +1 -0
- package/dist/peoplesoft-BCjRje6b.js +240 -0
- package/dist/peoplesoft-BCjRje6b.js.map +1 -0
- package/dist/peoplesoft-Cze2ngGd.d.ts +1150 -0
- package/dist/queryClient-D64McLhZ.js +7 -0
- package/dist/queryClient-D64McLhZ.js.map +1 -0
- package/dist/useDialogs-BJVhBr8S.js +248 -0
- package/dist/useDialogs-BJVhBr8S.js.map +1 -0
- package/dist/utils-BMUmv2ws.js +191 -0
- package/dist/utils-BMUmv2ws.js.map +1 -0
- package/dist/utils-CvvyM8Xw.d.ts +56 -0
- package/dist/utils.d.ts +21 -0
- package/dist/utils.js +6 -0
- package/dist/vite.d.ts +7 -0
- package/dist/vite.js +147 -0
- package/dist/vite.js.map +1 -0
- package/package.json +158 -62
- package/skills/client-db/SKILL.md +107 -0
- package/skills/data-grid/SKILL.md +147 -0
- package/skills/db-schema/SKILL.md +68 -0
- package/skills/dialogs/SKILL.md +79 -0
- package/skills/forms/SKILL.md +82 -0
- package/skills/general/SKILL.md +17 -0
- package/skills/notifications/SKILL.md +43 -0
- package/skills/routing/SKILL.md +123 -0
- package/skills/server-functions/SKILL.md +109 -0
- package/skills/services/SKILL.md +28 -0
- package/skills/services/docs/approval.md +204 -0
- package/skills/services/docs/email.md +32 -0
- package/skills/services/docs/file.md +85 -0
- package/skills/services/docs/peoplesoft.md +110 -0
- package/skills/start/SKILL.md +46 -0
- package/skills/start/steps/01-git-setup.md +10 -0
- package/skills/start/steps/02-project-name-setup.md +14 -0
- package/skills/start/steps/03-apm-setup.md +208 -0
- package/skills/start/steps/04-database-setup.md +37 -0
- package/skills/start/steps/05-entra-setup.md +59 -0
- package/skills/start/steps/06-vault-setup.md +53 -0
- package/skills/start/steps/07-generate-favicon.md +10 -0
- package/skills/start/steps/08-commit.md +15 -0
- package/dist/src/components/Layout.d.ts +0 -16
- package/dist/src/components/Layout.js +0 -122
- package/dist/src/components/Layout.js.map +0 -1
- package/dist/src/components/dataGrid/ChipInputCell.d.ts +0 -9
- package/dist/src/components/dataGrid/ChipInputCell.js +0 -17
- package/dist/src/components/dataGrid/ChipInputCell.js.map +0 -1
- package/dist/src/components/dataGrid/EditableColumnHeader.d.ts +0 -2
- package/dist/src/components/dataGrid/EditableColumnHeader.js +0 -7
- package/dist/src/components/dataGrid/EditableColumnHeader.js.map +0 -1
- package/dist/src/components/dataGrid/GridToolbar.d.ts +0 -8
- package/dist/src/components/dataGrid/GridToolbar.js +0 -40
- package/dist/src/components/dataGrid/GridToolbar.js.map +0 -1
- package/dist/src/components/dataGrid/TableContainer.d.ts +0 -3
- package/dist/src/components/dataGrid/TableContainer.js +0 -32
- package/dist/src/components/dataGrid/TableContainer.js.map +0 -1
- package/dist/src/components/form/FormAutocomplete.d.ts +0 -7
- package/dist/src/components/form/FormAutocomplete.js +0 -10
- package/dist/src/components/form/FormAutocomplete.js.map +0 -1
- package/dist/src/components/form/FormCheckbox.d.ts +0 -7
- package/dist/src/components/form/FormCheckbox.js +0 -11
- package/dist/src/components/form/FormCheckbox.js.map +0 -1
- package/dist/src/components/form/FormDatePicker.d.ts +0 -9
- package/dist/src/components/form/FormDatePicker.js +0 -19
- package/dist/src/components/form/FormDatePicker.js.map +0 -1
- package/dist/src/components/form/FormDateTimePicker.d.ts +0 -9
- package/dist/src/components/form/FormDateTimePicker.js +0 -19
- package/dist/src/components/form/FormDateTimePicker.js.map +0 -1
- package/dist/src/components/form/FormNumberField.d.ts +0 -12
- package/dist/src/components/form/FormNumberField.js +0 -12
- package/dist/src/components/form/FormNumberField.js.map +0 -1
- package/dist/src/components/form/FormRadioGroup.d.ts +0 -13
- package/dist/src/components/form/FormRadioGroup.js +0 -11
- package/dist/src/components/form/FormRadioGroup.js.map +0 -1
- package/dist/src/components/form/FormSlider.d.ts +0 -7
- package/dist/src/components/form/FormSlider.js +0 -11
- package/dist/src/components/form/FormSlider.js.map +0 -1
- package/dist/src/components/form/FormSubmitButton.d.ts +0 -5
- package/dist/src/components/form/FormSubmitButton.js +0 -13
- package/dist/src/components/form/FormSubmitButton.js.map +0 -1
- package/dist/src/components/form/FormSwitch.d.ts +0 -7
- package/dist/src/components/form/FormSwitch.js +0 -11
- package/dist/src/components/form/FormSwitch.js.map +0 -1
- package/dist/src/components/form/FormTextField.d.ts +0 -7
- package/dist/src/components/form/FormTextField.js +0 -11
- package/dist/src/components/form/FormTextField.js.map +0 -1
- package/dist/src/components/layout/AccountMenu.d.ts +0 -9
- package/dist/src/components/layout/AccountMenu.js +0 -44
- package/dist/src/components/layout/AccountMenu.js.map +0 -1
- package/dist/src/components/layout/DevelopmentBanner.d.ts +0 -7
- package/dist/src/components/layout/DevelopmentBanner.js +0 -29
- package/dist/src/components/layout/DevelopmentBanner.js.map +0 -1
- package/dist/src/components/layout/ErrorPage.d.ts +0 -2
- package/dist/src/components/layout/ErrorPage.js +0 -25
- package/dist/src/components/layout/ErrorPage.js.map +0 -1
- package/dist/src/components/layout/LayoutDialog.d.ts +0 -12
- package/dist/src/components/layout/LayoutDialog.js +0 -12
- package/dist/src/components/layout/LayoutDialog.js.map +0 -1
- package/dist/src/components/layout/LayoutSnackbar.d.ts +0 -8
- package/dist/src/components/layout/LayoutSnackbar.js +0 -25
- package/dist/src/components/layout/LayoutSnackbar.js.map +0 -1
- package/dist/src/components/layout/NavigationDrawer.d.ts +0 -11
- package/dist/src/components/layout/NavigationDrawer.js +0 -70
- package/dist/src/components/layout/NavigationDrawer.js.map +0 -1
- package/dist/src/components/layout/NotificationMenu.d.ts +0 -8
- package/dist/src/components/layout/NotificationMenu.js +0 -26
- package/dist/src/components/layout/NotificationMenu.js.map +0 -1
- package/dist/src/components/layout/TypographyWithIcon.d.ts +0 -7
- package/dist/src/components/layout/TypographyWithIcon.js +0 -22
- package/dist/src/components/layout/TypographyWithIcon.js.map +0 -1
- package/dist/src/components/layout/Unauthorized.d.ts +0 -2
- package/dist/src/components/layout/Unauthorized.js +0 -26
- package/dist/src/components/layout/Unauthorized.js.map +0 -1
- package/dist/src/contexts/LayoutContext.d.ts +0 -40
- package/dist/src/contexts/LayoutContext.js +0 -60
- package/dist/src/contexts/LayoutContext.js.map +0 -1
- package/dist/src/contexts/UserContext.d.ts +0 -24
- package/dist/src/contexts/UserContext.js +0 -55
- package/dist/src/contexts/UserContext.js.map +0 -1
- package/dist/src/hooks/FormHooks.d.ts +0 -46
- package/dist/src/hooks/FormHooks.js +0 -31
- package/dist/src/hooks/FormHooks.js.map +0 -1
- package/dist/src/hooks/UseSnackbar.d.ts +0 -10
- package/dist/src/hooks/UseSnackbar.js +0 -23
- package/dist/src/hooks/UseSnackbar.js.map +0 -1
- package/dist/src/hooks/UseUser.d.ts +0 -10
- package/dist/src/hooks/UseUser.js +0 -25
- package/dist/src/hooks/UseUser.js.map +0 -1
- package/dist/src/index.d.ts +0 -20
- package/dist/src/index.js +0 -15
- package/dist/src/index.js.map +0 -1
- package/dist/src/models/Error.d.ts +0 -6
- package/dist/src/models/Error.js +0 -2
- package/dist/src/models/Error.js.map +0 -1
- package/dist/src/models/KeycloakSettings.d.ts +0 -8
- package/dist/src/models/KeycloakSettings.js +0 -2
- package/dist/src/models/KeycloakSettings.js.map +0 -1
- package/dist/src/models/LayoutPaletteColorOptions.d.ts +0 -6
- package/dist/src/models/LayoutPaletteColorOptions.js +0 -2
- package/dist/src/models/LayoutPaletteColorOptions.js.map +0 -1
- package/dist/src/models/LayoutRoute.d.ts +0 -14
- package/dist/src/models/LayoutRoute.js +0 -2
- package/dist/src/models/LayoutRoute.js.map +0 -1
- package/dist/src/models/Notification.d.ts +0 -9
- package/dist/src/models/Notification.js +0 -2
- package/dist/src/models/Notification.js.map +0 -1
- package/dist/src/models/PeoplesoftDepartment.d.ts +0 -14
- package/dist/src/models/PeoplesoftDepartment.js +0 -2
- package/dist/src/models/PeoplesoftDepartment.js.map +0 -1
- package/dist/src/models/PeoplesoftEmployee.d.ts +0 -34
- package/dist/src/models/PeoplesoftEmployee.js +0 -2
- package/dist/src/models/PeoplesoftEmployee.js.map +0 -1
- package/dist/src/models/Snackbar.d.ts +0 -15
- package/dist/src/models/Snackbar.js +0 -2
- package/dist/src/models/Snackbar.js.map +0 -1
- package/dist/src/models/User.d.ts +0 -27
- package/dist/src/models/User.js +0 -11
- package/dist/src/models/User.js.map +0 -1
- package/dist/src/models/types/EmployeeCategoryGroup.d.ts +0 -1
- package/dist/src/models/types/EmployeeCategoryGroup.js +0 -2
- package/dist/src/models/types/EmployeeCategoryGroup.js.map +0 -1
- package/dist/src/models/types/EmployeeStatus.d.ts +0 -1
- package/dist/src/models/types/EmployeeStatus.js +0 -2
- package/dist/src/models/types/EmployeeStatus.js.map +0 -1
- package/dist/src/utils/Auth.d.ts +0 -12
- package/dist/src/utils/Auth.js +0 -49
- package/dist/src/utils/Auth.js.map +0 -1
- package/dist/src/utils/Fetches.d.ts +0 -5
- package/dist/src/utils/Fetches.js +0 -66
- package/dist/src/utils/Fetches.js.map +0 -1
- package/dist/src/utils/FormUtils.d.ts +0 -7
- package/dist/src/utils/FormUtils.js +0 -9
- package/dist/src/utils/FormUtils.js.map +0 -1
- package/dist/src/utils/Helpers.d.ts +0 -11
- package/dist/src/utils/Helpers.js +0 -26
- package/dist/src/utils/Helpers.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/components/Layout.tsx +0 -183
- package/src/components/dataGrid/ChipInputCell.tsx +0 -31
- package/src/components/dataGrid/EditableColumnHeader.tsx +0 -7
- package/src/components/dataGrid/GridToolbar.tsx +0 -63
- package/src/components/dataGrid/TableContainer.tsx +0 -39
- package/src/components/form/FormAutocomplete.tsx +0 -34
- package/src/components/form/FormCheckbox.tsx +0 -32
- package/src/components/form/FormDatePicker.tsx +0 -34
- package/src/components/form/FormDateTimePicker.tsx +0 -34
- package/src/components/form/FormNumberField.tsx +0 -33
- package/src/components/form/FormRadioGroup.tsx +0 -43
- package/src/components/form/FormSlider.tsx +0 -28
- package/src/components/form/FormSubmitButton.tsx +0 -29
- package/src/components/form/FormSwitch.tsx +0 -32
- package/src/components/form/FormTextField.tsx +0 -26
- package/src/components/layout/AccountMenu.tsx +0 -160
- package/src/components/layout/DevelopmentBanner.tsx +0 -54
- package/src/components/layout/ErrorPage.tsx +0 -34
- package/src/components/layout/LayoutDialog.tsx +0 -50
- package/src/components/layout/LayoutSnackbar.tsx +0 -44
- package/src/components/layout/NavigationDrawer.tsx +0 -131
- package/src/components/layout/NotificationMenu.tsx +0 -76
- package/src/components/layout/TypographyWithIcon.tsx +0 -35
- package/src/components/layout/Unauthorized.tsx +0 -37
- package/src/contexts/LayoutContext.tsx +0 -127
- package/src/contexts/UserContext.tsx +0 -88
- package/src/hooks/FormHooks.ts +0 -33
- package/src/hooks/UseSnackbar.tsx +0 -28
- package/src/hooks/UseUser.tsx +0 -29
- package/src/index.ts +0 -27
- package/src/models/Error.tsx +0 -6
- package/src/models/KeycloakSettings.ts +0 -8
- package/src/models/LayoutPaletteColorOptions.tsx +0 -7
- package/src/models/LayoutRoute.ts +0 -15
- package/src/models/Notification.ts +0 -10
- package/src/models/PeoplesoftDepartment.ts +0 -15
- package/src/models/PeoplesoftEmployee.ts +0 -35
- package/src/models/Snackbar.ts +0 -16
- package/src/models/User.ts +0 -13
- package/src/models/types/EmployeeCategoryGroup.ts +0 -1
- package/src/models/types/EmployeeStatus.ts +0 -1
- package/src/utils/Auth.ts +0 -58
- package/src/utils/Fetches.ts +0 -83
- package/src/utils/FormUtils.ts +0 -22
- package/src/utils/Helpers.ts +0 -27
- package/tsconfig.json +0 -29
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: db-schema
|
|
3
|
+
description: "Use when: defining or updating Drizzle ORM table schemas, relations, enums, migrations, or Zod schemas derived from database models."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Database Schema Patterns
|
|
7
|
+
|
|
8
|
+
## Rules
|
|
9
|
+
|
|
10
|
+
- Always use `uuid` for primary keys, and `snakeCase` for generating tables.
|
|
11
|
+
- Always add `withTimezone: true` to timestamp columns.
|
|
12
|
+
- Always add `onDelete: "cascade"` on foreign keys for child/dependent tables.
|
|
13
|
+
- Define relations in a central `relations.ts` file.
|
|
14
|
+
- Generate Zod schemas with `createSelectSchema`; override fields with stricter rules (trim, min/max) where needed.
|
|
15
|
+
- Use `.transform()` on all Zod schemas that include related data to assign parent IDs.
|
|
16
|
+
- Do not auto-generate migrations unless the user explicitly asks.
|
|
17
|
+
|
|
18
|
+
## File Placement
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
drizzle-orm/pg-core - table, column types, relations, and defineRelations utility
|
|
22
|
+
zod - Zod
|
|
23
|
+
src/server/db/schemas/ - Drizzle table schemas and relations
|
|
24
|
+
src/server/db/migrations/ - Drizzle migration files
|
|
25
|
+
src/lib/schemas/ - Zod schemas (shared between client and server)
|
|
26
|
+
wcz-layout/utils - `t` translation function
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Examples
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
// src/server/db/schemas/<feature>.ts
|
|
33
|
+
export const bookTable = snakeCase.table("books", {
|
|
34
|
+
id: uuid().primaryKey(),
|
|
35
|
+
title: text().notNull(),
|
|
36
|
+
libraryId: uuid()
|
|
37
|
+
.notNull()
|
|
38
|
+
.references(() => libraryTable.id, { onDelete: "cascade" }),
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// src/server/db/schemas/relations.ts
|
|
42
|
+
export const relations = defineRelations(
|
|
43
|
+
{ libraryTable, bookTable },
|
|
44
|
+
({ one, many, libraryTable: library, bookTable: book }) => ({
|
|
45
|
+
libraryTable: {
|
|
46
|
+
books: many.bookTable(),
|
|
47
|
+
},
|
|
48
|
+
bookTable: {
|
|
49
|
+
library: one.libraryTable({ from: book.libraryId, to: library.id }),
|
|
50
|
+
},
|
|
51
|
+
}),
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
// src/lib/schemas/<feature>.ts
|
|
55
|
+
export const BookSchema = createSelectSchema(bookTable, {
|
|
56
|
+
title: (schema) =>
|
|
57
|
+
schema
|
|
58
|
+
.trim()
|
|
59
|
+
.min(1, t("Validation.Required"))
|
|
60
|
+
.max(255, t("Validation.MaxLength", { length: 255 })),
|
|
61
|
+
pages: PageSchema.array().min(1, t("Validation.Required")),
|
|
62
|
+
}).transform((data) => ({
|
|
63
|
+
...data,
|
|
64
|
+
pages: data.pages.map((page) => ({ ...page, bookId: data.id })),
|
|
65
|
+
}));
|
|
66
|
+
|
|
67
|
+
export type Book = z.infer<typeof BookSchema>;
|
|
68
|
+
```
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dialogs
|
|
3
|
+
description: "Use when: creating or modifying alert dialogs, confirm dialogs, typed custom dialogs, or dialog-driven user flows."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Rules
|
|
7
|
+
|
|
8
|
+
- Always use `useDialogs()` for modal interactions.
|
|
9
|
+
- Use `confirm()` for destructive or user-confirmed actions.
|
|
10
|
+
- Use `alert()` for informational or error messages that require acknowledgement.
|
|
11
|
+
- Use `open()` for feature-specific custom dialogs with typed payloads.
|
|
12
|
+
- Custom dialogs must receive `DialogProps<T>`.
|
|
13
|
+
- Keep dialogs colocated inside `routes/feature/-components` when feature-specific.
|
|
14
|
+
- Always use translation; add new keys for feature-specific messages.
|
|
15
|
+
- Use notifications for lightweight feedback; dialogs when the user must decide or acknowledge.
|
|
16
|
+
|
|
17
|
+
## File Placement
|
|
18
|
+
|
|
19
|
+
```txt
|
|
20
|
+
src/components/dialogs/ — shared dialogs used across features
|
|
21
|
+
src/routes/<feature>s/-components/ — feature-scoped dialogs
|
|
22
|
+
wcz-layout/hooks — useDialogs hook, DialogProps type, useTranslation
|
|
23
|
+
src/lib/locales/ — translation keys
|
|
24
|
+
@mui/material — MUI Dialog components
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
// confirmation dialog
|
|
31
|
+
const { confirm } = useDialogs();
|
|
32
|
+
const { t } = useTranslation();
|
|
33
|
+
|
|
34
|
+
const confirmed = await confirm(t("DeleteConfirmation", { count: selectedIds.length }));
|
|
35
|
+
if (confirmed) await deleteFeature({ data: id });
|
|
36
|
+
|
|
37
|
+
// alert dialog
|
|
38
|
+
const { alert } = useDialogs();
|
|
39
|
+
const { t } = useTranslation();
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
await saveFeature(values);
|
|
43
|
+
await alert(t("FeatureSavedSuccessfully"));
|
|
44
|
+
} catch (error) {
|
|
45
|
+
await alert(error instanceof Error ? error.message : t("UnknownError"));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// custom dialog
|
|
49
|
+
const { open } = useDialogs();
|
|
50
|
+
|
|
51
|
+
await open(EditFeatureDialog, id);
|
|
52
|
+
|
|
53
|
+
// custom dialog component
|
|
54
|
+
interface Payload {
|
|
55
|
+
id: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const EditFeatureDialog = ({
|
|
59
|
+
payload,
|
|
60
|
+
open,
|
|
61
|
+
onClose,
|
|
62
|
+
}: DialogProps<Payload>) => {
|
|
63
|
+
const { t } = useTranslation();
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<Dialog fullWidth open={open} onClose={() => onClose()}>
|
|
67
|
+
<DialogTitle>{t("EditFeature")}</DialogTitle>
|
|
68
|
+
<DialogContent>
|
|
69
|
+
{payload.id}
|
|
70
|
+
</DialogContent>
|
|
71
|
+
<DialogActions>
|
|
72
|
+
<Button onClick={() => onClose()}>
|
|
73
|
+
Close
|
|
74
|
+
</Button>
|
|
75
|
+
</DialogActions>
|
|
76
|
+
</Dialog>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
```
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: forms
|
|
3
|
+
description: "Use when: creating or modifying TanStack Form components, field layouts, validation schemas, submit handling, or custom form controls."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Form Patterns
|
|
7
|
+
|
|
8
|
+
## Rules
|
|
9
|
+
|
|
10
|
+
- Always use `useLayoutForm` with pre-defined components.
|
|
11
|
+
- Define `width` for all form fields based on the expected content length.
|
|
12
|
+
- Reuse Zod schemas from `src/lib/schemas/` which are derived from Drizzle schemas with `createSelectSchema` from table schemas.
|
|
13
|
+
- Use translation for labels, helper text, validation messages and submit.
|
|
14
|
+
- Reset the form after successful create.
|
|
15
|
+
- Use one of the following field based on the use case: `Autocomplete`, `Checkbox`, `DatePicker`, `DateRangePicker`, `DateTimePicker`, `DateTimeRangePicker`, `NumberField`, `RadioGroup`, `Slider`, `SubmitButton`, `Switch`, `TextField`, `TimePicker`, or `TimeRangePicker`.
|
|
16
|
+
|
|
17
|
+
## File Placement
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
src/routes/<feature>s/-components/ - route-scoped forms
|
|
21
|
+
src/lib/schemas/ — Zod schemas (shared between client and server)
|
|
22
|
+
wcz-layout/hooks - useLayoutForm hook, useTranslation
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
// Form Component
|
|
29
|
+
interface FormProps {
|
|
30
|
+
defaultValues: Feature;
|
|
31
|
+
onSubmit: (value: Feature) => Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const Form: FC<FormProps> = ({ defaultValues, onSubmit }) => {
|
|
35
|
+
const { t } = useTranslation();
|
|
36
|
+
|
|
37
|
+
const form = useLayoutForm({
|
|
38
|
+
defaultValues,
|
|
39
|
+
validators: { onChange: FeatureSchema },
|
|
40
|
+
onSubmit: async ({ value, formApi }) => {
|
|
41
|
+
await onSubmit(value);
|
|
42
|
+
formApi.reset();
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<form
|
|
48
|
+
onSubmit={(event) => {
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
event.stopPropagation();
|
|
51
|
+
form.handleSubmit();
|
|
52
|
+
}}
|
|
53
|
+
>
|
|
54
|
+
{/* some styling */}
|
|
55
|
+
<form.AppField name="name">
|
|
56
|
+
{(field) => <field.TextField label={t("Feature.Name")} required sx={{ width: 420 }} />}
|
|
57
|
+
</form.AppField>
|
|
58
|
+
{/* some styling */}
|
|
59
|
+
<form.AppForm>
|
|
60
|
+
<form.SubmitButton variant="contained">{t("Submit")}</form.SubmitButton>
|
|
61
|
+
</form.AppForm>
|
|
62
|
+
</form>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Autocomplete
|
|
67
|
+
<field.Autocomplete
|
|
68
|
+
options={options}
|
|
69
|
+
sx={{ width: 250 }}
|
|
70
|
+
autoHighlight
|
|
71
|
+
autoSelect
|
|
72
|
+
autoComplete
|
|
73
|
+
loading={isLoading}
|
|
74
|
+
textFieldProps={{
|
|
75
|
+
label: t("Customer"),
|
|
76
|
+
required: true,
|
|
77
|
+
}}
|
|
78
|
+
/>
|
|
79
|
+
|
|
80
|
+
// Checkbox
|
|
81
|
+
<field.Checkbox label={t("IsThisTrue")} />
|
|
82
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: general
|
|
3
|
+
description: "Use ALWAYS for project-wide conventions and coding standards. It defines the default style, rules, and best practices that apply to every file and feature."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Rules
|
|
7
|
+
|
|
8
|
+
- Generate modern ES6+ TypeScript with explicit types and never use `any`.
|
|
9
|
+
- Stick to double quotes, semicolons, and the `~/` alias for `src/` imports.
|
|
10
|
+
- Avoid `useMemo` / `useCallback`; the React Compiler handles memoization.
|
|
11
|
+
- Keep code self-documenting; only add comments to clarify non-obvious intent.
|
|
12
|
+
- When building UI, always design for both light and dark mode; this app uses `colorSchemeSelector: "data-mui-color-scheme"`, so prefer `theme.applyStyles("dark", ...)` for mode-specific styling.
|
|
13
|
+
- Before implementing features of external libraries, search for the latest docs on Context7 MCP.
|
|
14
|
+
|
|
15
|
+
## When to Use This Skill
|
|
16
|
+
|
|
17
|
+
This is the default skill. Reference it in combination with more specific skills (e.g., `forms`, `tables`, `dialogs`) for targeted tasks.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: notifications
|
|
3
|
+
description: "Use when: displaying success, error, warning, or informational feedback with snackbars or async user actions."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Rules
|
|
7
|
+
|
|
8
|
+
- Use `useNotification()` for lightweight non-blocking user feedback.
|
|
9
|
+
- Always use translation; add new keys for feature-specific messages.
|
|
10
|
+
- Notifications are automatically queued and stacked by the provider.
|
|
11
|
+
- Always set `autoHideDuration` between 5000 and 10000 ms to prevent stale messages.
|
|
12
|
+
- Use `severity: "success" | "info" | "warning" | "error"` consistently with the outcome.
|
|
13
|
+
- Use notifications for lightweight feedback; dialogs when the user must decide or acknowledge.
|
|
14
|
+
|
|
15
|
+
## File Placement
|
|
16
|
+
|
|
17
|
+
```txt
|
|
18
|
+
wcz-layout/hooks — useNotification hook, useTranslation
|
|
19
|
+
src/lib/locales/ — translation keys
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Examples
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
// basic usage
|
|
26
|
+
const { notify } = useNotification();
|
|
27
|
+
const { t } = useTranslation();
|
|
28
|
+
|
|
29
|
+
notify(t("Feature.Created"), {
|
|
30
|
+
severity: "success",
|
|
31
|
+
autoHideDuration: 6000,
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// error handling
|
|
35
|
+
try {
|
|
36
|
+
await deleteFeature({ data: id });
|
|
37
|
+
} catch (error) {
|
|
38
|
+
notify(error instanceof Error ? error.message : t("DeleteFailed"), {
|
|
39
|
+
severity: "error",
|
|
40
|
+
autoHideDuration: 10000,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
```
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: routing
|
|
3
|
+
description: "Use when: creating or modifying TanStack Router routes, feature folders, navigation, permissions, loaders, suspense flows, or route-scoped components/hooks."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Rules
|
|
7
|
+
|
|
8
|
+
- Always include `requirePermission("all")` in the route's `beforeLoad` function to enforce access control unless the route is meant to be public.
|
|
9
|
+
- Use `Route.useRouteContext()` to access the authenticated user. User can be `null` if the route doesn't include `requirePermission`.
|
|
10
|
+
- Use the route `loader` option to preload db collections. Preload only root-level collections.
|
|
11
|
+
- Create a `pendingComponent` for routes that suspend or preload meaningful data.
|
|
12
|
+
- Route names must always be kebab-case. Entity route names must always be plural.
|
|
13
|
+
- If a feature contains only one route, create a single file route: `src/routes/libraries.tsx`
|
|
14
|
+
- If a feature contains multiple related routes, create a folder: `src/routes/libraries/index.tsx`
|
|
15
|
+
- Colocate route-specific components/hooks inside `routes/<feature>/-components` or `-hooks`.
|
|
16
|
+
- Root-level `components/` and `hooks/` are only for code shared across multiple routes.
|
|
17
|
+
- After creating a new route, add or ask for a navigation item with a unique icon from `@mui/icons-material` in `src/routes/__root.tsx`.
|
|
18
|
+
|
|
19
|
+
## Base Project Structure
|
|
20
|
+
|
|
21
|
+
```txt
|
|
22
|
+
src/ # client-first architecture
|
|
23
|
+
├── components/ # shared components across multiple routes
|
|
24
|
+
├── db-collections/ # tanstack-db collections
|
|
25
|
+
├── hooks/ # shared hooks across multiple routes
|
|
26
|
+
├── lib/ # contains isomorphic/shared logic usable by both client and server
|
|
27
|
+
│ ├── auth/
|
|
28
|
+
│ │ ├── permissions.ts
|
|
29
|
+
│ │ └── scopes.ts
|
|
30
|
+
│ ├── locales/
|
|
31
|
+
│ │ ├── cs.json
|
|
32
|
+
│ │ └── en.json
|
|
33
|
+
│ └── schemas/ # shared zod schemas
|
|
34
|
+
├── routes/ # TanStack Router file-based routing
|
|
35
|
+
│ ├── __root.tsx
|
|
36
|
+
│ ├── index.tsx
|
|
37
|
+
│ └── features/ # route group with multiple pages
|
|
38
|
+
│ ├── -components/ # components specific to feature routes
|
|
39
|
+
│ ├── -hooks/ # hooks specific to feature routes
|
|
40
|
+
│ ├── index.tsx
|
|
41
|
+
│ ├── create.tsx
|
|
42
|
+
│ ├── edit.$id.tsx
|
|
43
|
+
│ └── $id.tsx
|
|
44
|
+
├── server/ # server-only code
|
|
45
|
+
│ ├── db/
|
|
46
|
+
│ │ ├── migrations/
|
|
47
|
+
│ │ ├── schemas/ # drizzle database schemas
|
|
48
|
+
│ │ │ └── feature.ts
|
|
49
|
+
│ │ └── index.ts # drizzle db instance
|
|
50
|
+
│ ├── middleware/
|
|
51
|
+
│ │ └── databaseMiddleware.ts
|
|
52
|
+
│ └── feature.ts # server functions / api logic
|
|
53
|
+
└── types/
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Examples
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// imports
|
|
60
|
+
import { useDialogs, useTranslation } from "wcz-layout/hooks";
|
|
61
|
+
import { requirePermission, uuidv7 } from "wcz-layout/utils";
|
|
62
|
+
|
|
63
|
+
// src/routes/features/create.tsx
|
|
64
|
+
export const Route = createFileRoute("/features/create")({
|
|
65
|
+
component: RouteComponent,
|
|
66
|
+
beforeLoad: requirePermission("all"),
|
|
67
|
+
pendingComponent: FeatureSkeleton,
|
|
68
|
+
loader: () => {
|
|
69
|
+
featureCollection.preload();
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
function RouteComponent() {
|
|
74
|
+
const { t } = useTranslation();
|
|
75
|
+
const { alert, confirm } = useDialogs();
|
|
76
|
+
const { user } = Route.useRouteContext();
|
|
77
|
+
// route component code...
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// __root.tsx
|
|
81
|
+
const { user } = Route.useRouteContext();
|
|
82
|
+
|
|
83
|
+
const navigation: Navigation = [
|
|
84
|
+
{
|
|
85
|
+
kind: "item",
|
|
86
|
+
to: "/",
|
|
87
|
+
title: "Home",
|
|
88
|
+
icon: <Home />,
|
|
89
|
+
hidden: !user?.hasPermission("all"),
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
kind: "header",
|
|
93
|
+
title: "Documentation",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
kind: "group",
|
|
97
|
+
title: "Components",
|
|
98
|
+
icon: <Widgets />,
|
|
99
|
+
children: [
|
|
100
|
+
{
|
|
101
|
+
kind: "item",
|
|
102
|
+
to: "/components/navigation",
|
|
103
|
+
title: "Navigation",
|
|
104
|
+
icon: <AccountTree />,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
kind: "divider",
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
kind: "item",
|
|
111
|
+
to: "/components/forms",
|
|
112
|
+
title: "Forms",
|
|
113
|
+
icon: <Code />,
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
// __root.tsx how to add public route
|
|
120
|
+
<LayoutProvider {/* other props */} options={{
|
|
121
|
+
publicRoutes: ["/feature-name"]
|
|
122
|
+
}}>
|
|
123
|
+
```
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: server-functions
|
|
3
|
+
description: "Use when: creating or modifying TanStack Start server functions, REST routes, middleware, validation, database transactions, external service calls, or permission checks."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Rules
|
|
7
|
+
|
|
8
|
+
- Before generating code, clarify whether the feature should be exposed as public REST API routes or implemented as internal TanStack Start server functions (recommended), and what permission should be required for access.
|
|
9
|
+
- If permission is unknown, use `"all"`.
|
|
10
|
+
- Follow the chain order for server functions: `inputValidator` → `middleware` → `handler`.
|
|
11
|
+
- In middleware, always follow this order: `validationMiddleware` → `databaseMiddleware` → `authorizationMiddleware`.
|
|
12
|
+
- Use `validationMiddleware` only in REST API routes. Server functions use `.inputValidator()`.
|
|
13
|
+
- `databaseMiddleware` wraps the handler in a DB transaction.
|
|
14
|
+
- Reuse schemas from `src/lib/schemas/`.
|
|
15
|
+
|
|
16
|
+
## File Placement
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
src/server/actions/ — server functions
|
|
20
|
+
src/routes/api/ — REST API routes
|
|
21
|
+
src/server/middleware/ — databaseMiddleware
|
|
22
|
+
wcz-layout/middleware/ — authorizationMiddleware, validationMiddleware
|
|
23
|
+
src/server/db/schemas/ — tables, enums, relations
|
|
24
|
+
src/lib/schemas/ — Zod schemas (shared between client and server)
|
|
25
|
+
src/lib/auth/permissions.ts — permission keys
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Examples
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
// src/server/actions/<feature>.ts
|
|
32
|
+
export const selectFeatures = createServerFn()
|
|
33
|
+
.middleware([databaseMiddleware, authorizationMiddleware("all")])
|
|
34
|
+
.handler(async ({ context }) => {
|
|
35
|
+
return await context.db.select().from(featureTable);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const insertFeature = createServerFn({ method: "POST" })
|
|
39
|
+
.inputValidator(FeatureSchema)
|
|
40
|
+
.middleware([databaseMiddleware, authorizationMiddleware("admin")])
|
|
41
|
+
.handler(async ({ data, context }) => {
|
|
42
|
+
await context.db.insert(featureTable).values(data);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
export const updateFeature = createServerFn({ method: "POST" })
|
|
46
|
+
.inputValidator(FeatureSchema)
|
|
47
|
+
.middleware([databaseMiddleware, authorizationMiddleware("admin")])
|
|
48
|
+
.handler(async ({ data, context }) => {
|
|
49
|
+
await context.db.update(featureTable).set(data).where(eq(featureTable.id, data.id));
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
export const deleteFeature = createServerFn({ method: "POST" })
|
|
53
|
+
.inputValidator(FeatureSchema.pick({ id: true }))
|
|
54
|
+
.middleware([databaseMiddleware, authorizationMiddleware("admin")])
|
|
55
|
+
.handler(async ({ data, context }) => {
|
|
56
|
+
await context.db.delete(featureTable).where(eq(featureTable.id, data.id));
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// src/routes/api/<feature>s/index.ts
|
|
60
|
+
export const Route = createFileRoute("/api/features/")({
|
|
61
|
+
server: {
|
|
62
|
+
middleware: [databaseMiddleware],
|
|
63
|
+
handlers: ({ createHandlers }) =>
|
|
64
|
+
createHandlers({
|
|
65
|
+
GET: {
|
|
66
|
+
middleware: [authorizationMiddleware("all")],
|
|
67
|
+
handler: async ({ context }) => {
|
|
68
|
+
const items = await context.db.select().from(featureTable);
|
|
69
|
+
return Response.json(items);
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
POST: {
|
|
73
|
+
middleware: [validationMiddleware(FeatureSchema), authorizationMiddleware("admin")],
|
|
74
|
+
handler: async ({ context }) => {
|
|
75
|
+
const [response] = await context.db
|
|
76
|
+
.insert(featureTable)
|
|
77
|
+
.values(context.data)
|
|
78
|
+
.returning();
|
|
79
|
+
return Response.json(response, { status: 201 });
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
}),
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// src/routes/api/<feature>s/$id.ts
|
|
87
|
+
export const Route = createFileRoute("/api/features/$id")({
|
|
88
|
+
server: {
|
|
89
|
+
middleware: [databaseMiddleware, authorizationMiddleware("admin")],
|
|
90
|
+
handlers: ({ createHandlers }) =>
|
|
91
|
+
createHandlers({
|
|
92
|
+
PUT: {
|
|
93
|
+
middleware: [validationMiddleware(FeatureSchema)],
|
|
94
|
+
handler: async ({ params, context }) => {
|
|
95
|
+
await context.db
|
|
96
|
+
.update(featureTable)
|
|
97
|
+
.set(context.data)
|
|
98
|
+
.where(eq(featureTable.id, params.id));
|
|
99
|
+
return new Response(null, { status: 204 });
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
DELETE: async ({ params, context }) => {
|
|
103
|
+
await context.db.delete(featureTable).where(eq(featureTable.id, params.id));
|
|
104
|
+
return new Response(null, { status: 204 });
|
|
105
|
+
},
|
|
106
|
+
}),
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: services
|
|
3
|
+
description: "Use when: integrating file, approval, PeopleSoft, email, or attendance services into your workflow."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Info
|
|
7
|
+
|
|
8
|
+
You can read about each service in the links below. Services are categorized as either client or server exports, depending on their intended usage.
|
|
9
|
+
|
|
10
|
+
- **Client exports** — Contains `queryOptions` and `mutationOptions`; use for data fetching/mutations on the client with React Query.
|
|
11
|
+
- **Server exports** — Server functions; prefer calling mutations inside other server functions or database transactions.
|
|
12
|
+
- To read a step, open the linked file in the **File** column directly.
|
|
13
|
+
|
|
14
|
+
## Import Paths
|
|
15
|
+
|
|
16
|
+
- Client exports: `wcz-layout/data/client`
|
|
17
|
+
- Server exports: `wcz-layout/data/server`
|
|
18
|
+
- Schemas & Models: `wcz-layout/models`
|
|
19
|
+
|
|
20
|
+
## Services
|
|
21
|
+
|
|
22
|
+
| Service | File | Summary |
|
|
23
|
+
| ---------- | ----------------------------------- | ----------------------------------------------------------------------- |
|
|
24
|
+
| file | [file.md](docs/file.md) | File metadata, thumbnails, binary download/open, upload, update, delete |
|
|
25
|
+
| approval | [approval.md](docs/approval.md) | Approval request lifecycle, approvers, flows, statuses, step results |
|
|
26
|
+
| peoplesoft | [peoplesoft.md](docs/peoplesoft.md) | Employee, manager, department, and company general manager lookups |
|
|
27
|
+
| email | [email.md](docs/email.md) | Server-only email sending with optional file attachment references |
|
|
28
|
+
| attendance | [attendance.md](docs/attendance.md) | (Coming soon) |
|