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
package/dist/vite.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import z$1 from "zod";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import https from "node:https";
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { loadEnv } from "vite";
|
|
7
|
+
//#region src/models/VaultConfig.ts
|
|
8
|
+
const VaultConfigSchema = z$1.object({
|
|
9
|
+
VAULT_ADDRESS: z$1.url(),
|
|
10
|
+
VAULT_USERNAME: z$1.string().min(1),
|
|
11
|
+
VAULT_PASSWORD: z$1.string().min(1),
|
|
12
|
+
VAULT_SECRET_PATH: z$1.string().min(1),
|
|
13
|
+
VAULT_MOUNT_POINT: z$1.string().default("release")
|
|
14
|
+
});
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/lib/vite-plugin.ts
|
|
17
|
+
async function fetchVaultSecrets(env) {
|
|
18
|
+
const { VAULT_ADDRESS, VAULT_USERNAME, VAULT_PASSWORD, VAULT_SECRET_PATH, VAULT_MOUNT_POINT } = VaultConfigSchema.parse(env);
|
|
19
|
+
const client = axios.create({
|
|
20
|
+
baseURL: VAULT_ADDRESS,
|
|
21
|
+
httpsAgent: new https.Agent({ rejectUnauthorized: false })
|
|
22
|
+
});
|
|
23
|
+
const { data: loginData } = await client.post(`/v1/auth/userpass/login/${VAULT_USERNAME}`, { password: VAULT_PASSWORD });
|
|
24
|
+
const { data: secretData } = await client.get(`/v1/${VAULT_MOUNT_POINT}/data/${VAULT_SECRET_PATH}`, { headers: { "X-Vault-Token": loginData.auth.client_token } });
|
|
25
|
+
const secrets = secretData?.data?.data;
|
|
26
|
+
if (!secrets) throw new Error("No secrets found");
|
|
27
|
+
return Object.fromEntries(Object.entries(secrets).map(([key, value]) => [key, typeof value === "string" ? value : JSON.stringify(value)]));
|
|
28
|
+
}
|
|
29
|
+
async function loadVaultSecrets(command) {
|
|
30
|
+
if (command !== "serve") return;
|
|
31
|
+
const env = loadEnv("development", process.cwd(), "");
|
|
32
|
+
if (!env.VAULT_ADDRESS) return;
|
|
33
|
+
try {
|
|
34
|
+
const secrets = await fetchVaultSecrets(env);
|
|
35
|
+
Object.entries(secrets).forEach(([key, value]) => {
|
|
36
|
+
process.env[key] ??= value;
|
|
37
|
+
});
|
|
38
|
+
} catch (e) {
|
|
39
|
+
console.warn("[vite:wcz-layout] Vault failed:", e instanceof Error ? e.message : e);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function loadLocaleResources(localesPath, addWatchFile) {
|
|
43
|
+
if (!fs.existsSync(localesPath)) fs.mkdirSync(localesPath, { recursive: true });
|
|
44
|
+
const enPath = path.join(localesPath, "en.json");
|
|
45
|
+
if (!fs.existsSync(enPath)) fs.writeFileSync(enPath, JSON.stringify({}));
|
|
46
|
+
const files = fs.readdirSync(localesPath);
|
|
47
|
+
const resources = {};
|
|
48
|
+
for (const file of files.filter((f) => f.endsWith(".json"))) {
|
|
49
|
+
const lang = path.basename(file, ".json");
|
|
50
|
+
const filePath = path.join(localesPath, file);
|
|
51
|
+
try {
|
|
52
|
+
resources[lang] = { translation: JSON.parse(fs.readFileSync(filePath, "utf-8")) };
|
|
53
|
+
} catch {
|
|
54
|
+
resources[lang] = { translation: {} };
|
|
55
|
+
}
|
|
56
|
+
addWatchFile(filePath);
|
|
57
|
+
}
|
|
58
|
+
return resources;
|
|
59
|
+
}
|
|
60
|
+
function ensurePermissionsFile(permissionsPath, addWatchFile) {
|
|
61
|
+
const dir = path.dirname(permissionsPath);
|
|
62
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
63
|
+
if (!fs.existsSync(permissionsPath)) fs.writeFileSync(permissionsPath, "export const permissions = {\n admin: [\"wcz-developers\"]\n} as const;");
|
|
64
|
+
addWatchFile(permissionsPath);
|
|
65
|
+
}
|
|
66
|
+
function ensureScopesFile(scopesPath, addWatchFile) {
|
|
67
|
+
const dir = path.dirname(scopesPath);
|
|
68
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
69
|
+
if (!fs.existsSync(scopesPath)) fs.writeFileSync(scopesPath, "export const scopes = {\n} as const;");
|
|
70
|
+
addWatchFile(scopesPath);
|
|
71
|
+
}
|
|
72
|
+
function viteWczLayout() {
|
|
73
|
+
const virtualModuleId = "virtual:wcz-layout";
|
|
74
|
+
const resolvedVirtualModuleId = "\0virtual:wcz-layout";
|
|
75
|
+
let localesPath;
|
|
76
|
+
let permissionsPath;
|
|
77
|
+
let scopesPath;
|
|
78
|
+
let envPath;
|
|
79
|
+
return {
|
|
80
|
+
name: "vite:wcz-layout",
|
|
81
|
+
enforce: "pre",
|
|
82
|
+
configResolved(resolvedConfig) {
|
|
83
|
+
localesPath = path.resolve(resolvedConfig.root, "src/lib/locales");
|
|
84
|
+
permissionsPath = path.resolve(resolvedConfig.root, "src/lib/auth/permissions.ts");
|
|
85
|
+
scopesPath = path.resolve(resolvedConfig.root, "src/lib/auth/scopes.ts");
|
|
86
|
+
envPath = path.resolve(resolvedConfig.root, "src/env.ts");
|
|
87
|
+
},
|
|
88
|
+
async config(_, { command }) {
|
|
89
|
+
await loadVaultSecrets(command);
|
|
90
|
+
return { optimizeDeps: {
|
|
91
|
+
exclude: [virtualModuleId],
|
|
92
|
+
include: [
|
|
93
|
+
"prop-types",
|
|
94
|
+
"react-is",
|
|
95
|
+
"hoist-non-react-statics",
|
|
96
|
+
"url-parse",
|
|
97
|
+
"file-saver",
|
|
98
|
+
"attr-accept"
|
|
99
|
+
]
|
|
100
|
+
} };
|
|
101
|
+
},
|
|
102
|
+
configureServer(server) {
|
|
103
|
+
const refresh = (filePath) => {
|
|
104
|
+
if (filePath.includes(localesPath) || filePath === permissionsPath || filePath === scopesPath || filePath === envPath) {
|
|
105
|
+
const module = server.moduleGraph.getModuleById(resolvedVirtualModuleId);
|
|
106
|
+
if (module) server.moduleGraph.invalidateModule(module);
|
|
107
|
+
server.ws.send({
|
|
108
|
+
type: "full-reload",
|
|
109
|
+
path: "*"
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
server.watcher.add([
|
|
114
|
+
localesPath,
|
|
115
|
+
permissionsPath,
|
|
116
|
+
scopesPath,
|
|
117
|
+
envPath
|
|
118
|
+
]);
|
|
119
|
+
server.watcher.on("add", refresh);
|
|
120
|
+
server.watcher.on("change", refresh);
|
|
121
|
+
server.watcher.on("unlink", refresh);
|
|
122
|
+
},
|
|
123
|
+
resolveId(id) {
|
|
124
|
+
if (id === virtualModuleId) return resolvedVirtualModuleId;
|
|
125
|
+
return null;
|
|
126
|
+
},
|
|
127
|
+
load(id) {
|
|
128
|
+
if (id !== resolvedVirtualModuleId) return null;
|
|
129
|
+
const resources = loadLocaleResources(localesPath, this.addWatchFile.bind(this));
|
|
130
|
+
ensurePermissionsFile(permissionsPath, this.addWatchFile.bind(this));
|
|
131
|
+
ensureScopesFile(scopesPath, this.addWatchFile.bind(this));
|
|
132
|
+
const normalizedPermissionsPath = permissionsPath.split(path.sep).join(path.posix.sep);
|
|
133
|
+
const normalizedScopesPath = scopesPath.split(path.sep).join(path.posix.sep);
|
|
134
|
+
const normalizedEnvPath = envPath.split(path.sep).join(path.posix.sep);
|
|
135
|
+
return `
|
|
136
|
+
export const resources = ${JSON.stringify(resources)};
|
|
137
|
+
export { permissions } from "${normalizedPermissionsPath}";
|
|
138
|
+
export { scopes } from "${normalizedScopesPath}";
|
|
139
|
+
export { serverEnv } from "${normalizedEnvPath}";
|
|
140
|
+
`;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
145
|
+
export { viteWczLayout };
|
|
146
|
+
|
|
147
|
+
//# sourceMappingURL=vite.js.map
|
package/dist/vite.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite.js","names":["z","VaultConfigSchema","object","VAULT_ADDRESS","url","VAULT_USERNAME","string","min","VAULT_PASSWORD","VAULT_SECRET_PATH","VAULT_MOUNT_POINT","default","VaultConfig","infer","fs","https","path","axios","loadEnv","VaultConfigSchema","Resource","Plugin","fetchVaultSecrets","env","Record","Promise","config","parse","VAULT_ADDRESS","VAULT_USERNAME","VAULT_PASSWORD","VAULT_SECRET_PATH","VAULT_MOUNT_POINT","client","create","baseURL","httpsAgent","Agent","rejectUnauthorized","data","loginData","post","password","secretData","get","headers","auth","client_token","secrets","Error","Object","fromEntries","entries","map","key","value","JSON","stringify","loadVaultSecrets","command","process","cwd","forEach","e","console","warn","message","loadLocaleResources","localesPath","addWatchFile","existsSync","mkdirSync","recursive","enPath","join","writeFileSync","files","readdirSync","resources","file","filter","f","endsWith","lang","basename","filePath","translation","readFileSync","ensurePermissionsFile","permissionsPath","dir","dirname","ensureScopesFile","scopesPath","viteWczLayout","virtualModuleId","resolvedVirtualModuleId","envPath","name","enforce","configResolved","resolvedConfig","resolve","root","_","optimizeDeps","exclude","include","configureServer","server","refresh","includes","module","moduleGraph","getModuleById","invalidateModule","ws","send","type","watcher","add","on","resolveId","id","load","bind","normalizedPermissionsPath","split","sep","posix","normalizedScopesPath","normalizedEnvPath"],"sources":["../src/models/VaultConfig.ts","../src/lib/vite-plugin.ts"],"sourcesContent":["import z from \"zod\";\n\nexport const VaultConfigSchema = z.object({\n VAULT_ADDRESS: z.url(),\n VAULT_USERNAME: z.string().min(1),\n VAULT_PASSWORD: z.string().min(1),\n VAULT_SECRET_PATH: z.string().min(1),\n VAULT_MOUNT_POINT: z.string().default(\"release\"),\n});\n\nexport type VaultConfig = z.infer<typeof VaultConfigSchema>;\n","import fs from \"node:fs\";\nimport https from \"node:https\";\nimport path from \"node:path\";\nimport axios from \"axios\";\nimport { loadEnv } from \"vite\";\nimport { VaultConfigSchema } from \"../models/VaultConfig\";\nimport type { Resource } from \"i18next\";\nimport type { Plugin } from \"vite\";\n\nasync function fetchVaultSecrets(env: Record<string, string>): Promise<Record<string, string>> {\n const config = VaultConfigSchema.parse(env);\n const { VAULT_ADDRESS, VAULT_USERNAME, VAULT_PASSWORD, VAULT_SECRET_PATH, VAULT_MOUNT_POINT } =\n config;\n\n const client = axios.create({\n baseURL: VAULT_ADDRESS,\n httpsAgent: new https.Agent({ rejectUnauthorized: false }),\n });\n\n const { data: loginData } = await client.post(`/v1/auth/userpass/login/${VAULT_USERNAME}`, {\n password: VAULT_PASSWORD,\n });\n\n const { data: secretData } = await client.get(\n `/v1/${VAULT_MOUNT_POINT}/data/${VAULT_SECRET_PATH}`,\n {\n headers: { \"X-Vault-Token\": loginData.auth.client_token },\n },\n );\n\n const secrets = secretData?.data?.data;\n if (!secrets) throw new Error(\"No secrets found\");\n\n return Object.fromEntries(\n Object.entries(secrets).map(([key, value]) => [\n key,\n typeof value === \"string\" ? value : JSON.stringify(value),\n ]),\n );\n}\n\nasync function loadVaultSecrets(command: string): Promise<void> {\n if (command !== \"serve\") return;\n\n const env = loadEnv(\"development\", process.cwd(), \"\");\n if (!env.VAULT_ADDRESS) return;\n\n try {\n const secrets = await fetchVaultSecrets(env);\n Object.entries(secrets).forEach(([key, value]) => {\n process.env[key] ??= value;\n });\n } catch (e) {\n console.warn(\"[vite:wcz-layout] Vault failed:\", e instanceof Error ? e.message : e);\n }\n}\n\nfunction loadLocaleResources(localesPath: string, addWatchFile: (path: string) => void): Resource {\n if (!fs.existsSync(localesPath)) fs.mkdirSync(localesPath, { recursive: true });\n\n const enPath = path.join(localesPath, \"en.json\");\n if (!fs.existsSync(enPath)) fs.writeFileSync(enPath, JSON.stringify({}));\n\n const files = fs.readdirSync(localesPath);\n const resources: Resource = {};\n\n for (const file of files.filter((f) => f.endsWith(\".json\"))) {\n const lang = path.basename(file, \".json\");\n const filePath = path.join(localesPath, file);\n try {\n resources[lang] = { translation: JSON.parse(fs.readFileSync(filePath, \"utf-8\")) };\n } catch {\n resources[lang] = { translation: {} };\n }\n addWatchFile(filePath);\n }\n\n return resources;\n}\n\nfunction ensurePermissionsFile(\n permissionsPath: string,\n addWatchFile: (path: string) => void,\n): void {\n const dir = path.dirname(permissionsPath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n if (!fs.existsSync(permissionsPath)) {\n fs.writeFileSync(\n permissionsPath,\n 'export const permissions = {\\n admin: [\"wcz-developers\"]\\n} as const;',\n );\n }\n addWatchFile(permissionsPath);\n}\n\nfunction ensureScopesFile(scopesPath: string, addWatchFile: (path: string) => void): void {\n const dir = path.dirname(scopesPath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n if (!fs.existsSync(scopesPath)) {\n fs.writeFileSync(scopesPath, \"export const scopes = {\\n} as const;\");\n }\n addWatchFile(scopesPath);\n}\n\nexport function viteWczLayout(): Plugin {\n const virtualModuleId = \"virtual:wcz-layout\";\n const resolvedVirtualModuleId = \"\\0\" + virtualModuleId;\n\n let localesPath: string;\n let permissionsPath: string;\n let scopesPath: string;\n let envPath: string;\n\n return {\n name: \"vite:wcz-layout\",\n enforce: \"pre\",\n configResolved(resolvedConfig) {\n localesPath = path.resolve(resolvedConfig.root, \"src/lib/locales\");\n permissionsPath = path.resolve(resolvedConfig.root, \"src/lib/auth/permissions.ts\");\n scopesPath = path.resolve(resolvedConfig.root, \"src/lib/auth/scopes.ts\");\n envPath = path.resolve(resolvedConfig.root, \"src/env.ts\");\n },\n async config(_, { command }) {\n await loadVaultSecrets(command);\n\n return {\n optimizeDeps: {\n exclude: [virtualModuleId],\n include: [\n \"prop-types\",\n \"react-is\",\n \"hoist-non-react-statics\",\n \"url-parse\",\n \"file-saver\",\n \"attr-accept\",\n ],\n },\n };\n },\n configureServer(server) {\n const refresh = (filePath: string) => {\n if (\n filePath.includes(localesPath) ||\n filePath === permissionsPath ||\n filePath === scopesPath ||\n filePath === envPath\n ) {\n const module = server.moduleGraph.getModuleById(resolvedVirtualModuleId);\n if (module) server.moduleGraph.invalidateModule(module);\n server.ws.send({ type: \"full-reload\", path: \"*\" });\n }\n };\n\n server.watcher.add([localesPath, permissionsPath, scopesPath, envPath]);\n server.watcher.on(\"add\", refresh);\n server.watcher.on(\"change\", refresh);\n server.watcher.on(\"unlink\", refresh);\n },\n resolveId(id) {\n if (id === virtualModuleId) return resolvedVirtualModuleId;\n return null;\n },\n load(id) {\n if (id !== resolvedVirtualModuleId) return null;\n\n const resources = loadLocaleResources(localesPath, this.addWatchFile.bind(this));\n ensurePermissionsFile(permissionsPath, this.addWatchFile.bind(this));\n ensureScopesFile(scopesPath, this.addWatchFile.bind(this));\n\n const normalizedPermissionsPath = permissionsPath.split(path.sep).join(path.posix.sep);\n const normalizedScopesPath = scopesPath.split(path.sep).join(path.posix.sep);\n const normalizedEnvPath = envPath.split(path.sep).join(path.posix.sep);\n return `\n export const resources = ${JSON.stringify(resources)};\n export { permissions } from \"${normalizedPermissionsPath}\";\n export { scopes } from \"${normalizedScopesPath}\";\n export { serverEnv } from \"${normalizedEnvPath}\";\n `;\n },\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,62 +1,158 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "wcz-layout",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "wcz-layout",
|
|
3
|
+
"version": "8.3.2",
|
|
4
|
+
"private": false,
|
|
5
|
+
"keywords": [
|
|
6
|
+
"tanstack-intent"
|
|
7
|
+
],
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://gitlab.wistron.com/wcz/it-developers/layout/tanstack.git"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"skills",
|
|
15
|
+
"!skills/_artifacts"
|
|
16
|
+
],
|
|
17
|
+
"type": "module",
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"typesVersions": {
|
|
21
|
+
"*": {
|
|
22
|
+
"components": [
|
|
23
|
+
"./dist/components.d.ts"
|
|
24
|
+
],
|
|
25
|
+
"hooks": [
|
|
26
|
+
"./dist/hooks.d.ts"
|
|
27
|
+
],
|
|
28
|
+
"middleware": [
|
|
29
|
+
"./dist/middleware.d.ts"
|
|
30
|
+
],
|
|
31
|
+
"models": [
|
|
32
|
+
"./dist/models.d.ts"
|
|
33
|
+
],
|
|
34
|
+
"data": [
|
|
35
|
+
"./dist/data.d.ts"
|
|
36
|
+
],
|
|
37
|
+
"data/client": [
|
|
38
|
+
"./dist/data/client.d.ts"
|
|
39
|
+
],
|
|
40
|
+
"data/server": [
|
|
41
|
+
"./dist/data/server.d.ts"
|
|
42
|
+
],
|
|
43
|
+
"utils": [
|
|
44
|
+
"./dist/utils.d.ts"
|
|
45
|
+
],
|
|
46
|
+
"vite": [
|
|
47
|
+
"./dist/vite.d.ts"
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"exports": {
|
|
52
|
+
".": {
|
|
53
|
+
"types": "./dist/index.d.ts",
|
|
54
|
+
"import": "./dist/index.js"
|
|
55
|
+
},
|
|
56
|
+
"./components": {
|
|
57
|
+
"types": "./dist/components.d.ts",
|
|
58
|
+
"import": "./dist/components.js"
|
|
59
|
+
},
|
|
60
|
+
"./hooks": {
|
|
61
|
+
"types": "./dist/hooks.d.ts",
|
|
62
|
+
"import": "./dist/hooks.js"
|
|
63
|
+
},
|
|
64
|
+
"./middleware": {
|
|
65
|
+
"types": "./dist/middleware.d.ts",
|
|
66
|
+
"import": "./dist/middleware.js"
|
|
67
|
+
},
|
|
68
|
+
"./models": {
|
|
69
|
+
"types": "./dist/models.d.ts",
|
|
70
|
+
"import": "./dist/models.js"
|
|
71
|
+
},
|
|
72
|
+
"./data": {
|
|
73
|
+
"types": "./dist/data.d.ts",
|
|
74
|
+
"import": "./dist/data.js"
|
|
75
|
+
},
|
|
76
|
+
"./data/client": {
|
|
77
|
+
"types": "./dist/data/client.d.ts",
|
|
78
|
+
"import": "./dist/data/client.js"
|
|
79
|
+
},
|
|
80
|
+
"./data/server": {
|
|
81
|
+
"types": "./dist/data/server.d.ts",
|
|
82
|
+
"import": "./dist/data/server.js"
|
|
83
|
+
},
|
|
84
|
+
"./utils": {
|
|
85
|
+
"types": "./dist/utils.d.ts",
|
|
86
|
+
"import": "./dist/utils.js"
|
|
87
|
+
},
|
|
88
|
+
"./vite": {
|
|
89
|
+
"types": "./dist/vite.d.ts",
|
|
90
|
+
"import": "./dist/vite.js"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"scripts": {
|
|
94
|
+
"dev": "vp dev",
|
|
95
|
+
"vp:install": "vp install",
|
|
96
|
+
"vp:update": "vp update",
|
|
97
|
+
"ncu:install": "npx npm-check-updates -i",
|
|
98
|
+
"lint:package": "publint",
|
|
99
|
+
"build": "vp pack",
|
|
100
|
+
"prepublishOnly": "npm run build"
|
|
101
|
+
},
|
|
102
|
+
"dependencies": {
|
|
103
|
+
"@azure/msal-browser": "^5.11.0",
|
|
104
|
+
"@azure/msal-node": "^5.2.2",
|
|
105
|
+
"@azure/msal-react": "^5.4.2",
|
|
106
|
+
"@t3-oss/env-core": "^0.13.11",
|
|
107
|
+
"file-saver": "^2.0.5",
|
|
108
|
+
"i18next": "^26.3.0",
|
|
109
|
+
"i18next-browser-languagedetector": "^8.2.1",
|
|
110
|
+
"jose": "^6.2.3",
|
|
111
|
+
"react-dropzone": "^15.0.0",
|
|
112
|
+
"react-i18next": "^17.0.8",
|
|
113
|
+
"react-intersection-observer": "^10.0.3",
|
|
114
|
+
"react-number-format": "^5.4.5",
|
|
115
|
+
"tus-js-client": "^4.3.1",
|
|
116
|
+
"uuidv7": "^1.2.1"
|
|
117
|
+
},
|
|
118
|
+
"devDependencies": {
|
|
119
|
+
"@rolldown/plugin-babel": "^0.2.3",
|
|
120
|
+
"@tanstack/intent": "^0.0.41",
|
|
121
|
+
"@types/file-saver": "^2.0.7",
|
|
122
|
+
"@types/node": "^24.10.13",
|
|
123
|
+
"@types/react": "^19.2.16",
|
|
124
|
+
"@types/react-dom": "^19.2.3",
|
|
125
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
126
|
+
"babel-plugin-react-compiler": "^1.0.0",
|
|
127
|
+
"nitro": "npm:nitro-nightly@latest",
|
|
128
|
+
"publint": "^0.3.21",
|
|
129
|
+
"typescript": "^6.0.3",
|
|
130
|
+
"vite-plugin-checker": "^0.14.1"
|
|
131
|
+
},
|
|
132
|
+
"peerDependencies": {
|
|
133
|
+
"@emotion/react": "11.x",
|
|
134
|
+
"@emotion/styled": "11.x",
|
|
135
|
+
"@mui/icons-material": "9.x",
|
|
136
|
+
"@mui/material": "9.x",
|
|
137
|
+
"@mui/x-data-grid-premium": "9.x",
|
|
138
|
+
"@mui/x-date-pickers-pro": "9.x",
|
|
139
|
+
"@tanstack/query-db-collection": "1.x",
|
|
140
|
+
"@tanstack/react-db": "0.x",
|
|
141
|
+
"@tanstack/react-form": "1.x",
|
|
142
|
+
"@tanstack/react-query": "5.x",
|
|
143
|
+
"@tanstack/react-router": "1.x",
|
|
144
|
+
"@tanstack/react-router-ssr-query": "1.x",
|
|
145
|
+
"@tanstack/react-start": "1.x",
|
|
146
|
+
"axios": "1.x",
|
|
147
|
+
"dayjs": "1.x",
|
|
148
|
+
"react": "19.x",
|
|
149
|
+
"react-dom": "19.x",
|
|
150
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@latest",
|
|
151
|
+
"vite-plus": "latest",
|
|
152
|
+
"zod": "4.x"
|
|
153
|
+
},
|
|
154
|
+
"overrides": {
|
|
155
|
+
"vite": "npm:@voidzero-dev/vite-plus-core@latest"
|
|
156
|
+
},
|
|
157
|
+
"packageManager": "npm@11.16.0"
|
|
158
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: client-db
|
|
3
|
+
description: "Use when: creating or modifying TanStack DB collections, live queries, optimistic collection writes, subset loading, collection preloading."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Rules
|
|
7
|
+
|
|
8
|
+
- Use `eager` syncMode for top-level collections, `on-demand` for child/relational data.
|
|
9
|
+
- Use `useLiveQuery` for list/grid pages and `useLiveSuspenseQuery` for detail components wrapped in suspense.
|
|
10
|
+
- For mutations use `createOptimisticAction` — mirror the server mutation in `onMutate`, then call the server function and `collection.utils.refetch()` in `mutationFn`.
|
|
11
|
+
- Use `meta.loadSubsetOptions` for relational subset loading.
|
|
12
|
+
- Use Axios with auth interceptor `getAccessToken` but only for public REST APIs; use default `api` as a scope key.
|
|
13
|
+
|
|
14
|
+
## File Placement
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
src/db-collections/ — DB collections
|
|
18
|
+
src/server/actions/ — server functions (select/update/insert/delete)
|
|
19
|
+
src/lib/schemas/ — Zod schemas (shared between client and server)
|
|
20
|
+
src/lib/auth/scopes.ts — API scope keys
|
|
21
|
+
wcz-layout/data — queryClient instance
|
|
22
|
+
wcz-layout/utils — getAccessToken utility function
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Examples
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
// src/db-collections/<feature>.ts
|
|
29
|
+
export const api = axios.create({
|
|
30
|
+
baseURL: "/api/libraries",
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
api.interceptors.request.use(async (config) => {
|
|
34
|
+
const accessToken = await getAccessToken("api");
|
|
35
|
+
config.headers.set("Authorization", `Bearer ${accessToken}`);
|
|
36
|
+
return config;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// src/db-collections/<feature>.ts
|
|
40
|
+
export const librariesCollection = createCollection(
|
|
41
|
+
queryCollectionOptions({
|
|
42
|
+
queryKey: ["libraries"],
|
|
43
|
+
queryFn: () => selectLibraries(),
|
|
44
|
+
getKey: ({ id }) => id,
|
|
45
|
+
schema: LibrarySchema,
|
|
46
|
+
queryClient: queryClient,
|
|
47
|
+
syncMode: "eager",
|
|
48
|
+
}),
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// src/db-collections/<feature>.ts
|
|
52
|
+
export const bookCollection = createCollection(
|
|
53
|
+
queryCollectionOptions({
|
|
54
|
+
queryKey: ["books"],
|
|
55
|
+
queryFn: ({ meta }) => selectBooks({ data: meta?.loadSubsetOptions }),
|
|
56
|
+
getKey: ({ id }) => id,
|
|
57
|
+
schema: BookSchema,
|
|
58
|
+
queryClient: queryClient,
|
|
59
|
+
syncMode: "on-demand",
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
// simple query
|
|
64
|
+
const { data, isLoading } = useLiveQuery((q) =>
|
|
65
|
+
q.from({ library: libraryCollection }).orderBy(({ library }) => library.name, "asc"),
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
// advanced query with relational data
|
|
69
|
+
const { data } = useLiveQuery((q) =>
|
|
70
|
+
q
|
|
71
|
+
.from({ library: libraryCollection })
|
|
72
|
+
.where(({ library }) => eq(library.id, id))
|
|
73
|
+
.findOne()
|
|
74
|
+
.select(({ library }) => ({
|
|
75
|
+
...library,
|
|
76
|
+
books: toArray(
|
|
77
|
+
q
|
|
78
|
+
.from({ book: bookCollection })
|
|
79
|
+
.where(({ book }) => eq(book.libraryId, library.id))
|
|
80
|
+
.orderBy(({ book }) => book.title, "asc")
|
|
81
|
+
.select(({ book }) => ({
|
|
82
|
+
id: book.id,
|
|
83
|
+
title: book.title,
|
|
84
|
+
})),
|
|
85
|
+
),
|
|
86
|
+
})),
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
// form submission handler
|
|
90
|
+
const handleOnSubmit = createOptimisticAction<Library>({
|
|
91
|
+
onMutate: (formValues) => {
|
|
92
|
+
libraryCollection.update(id, (prev) => Object.assign(prev, formValues));
|
|
93
|
+
},
|
|
94
|
+
mutationFn: async (formValues) => {
|
|
95
|
+
await updateLibrary({ data: formValues });
|
|
96
|
+
await libraryCollection.utils.refetch();
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// calling the handler
|
|
101
|
+
try {
|
|
102
|
+
const transaction = handleOnSubmit(formValues);
|
|
103
|
+
await transaction.isPersisted.promise;
|
|
104
|
+
} catch (error) {
|
|
105
|
+
if (error instanceof Error) alert(error.message);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: data-grid
|
|
3
|
+
description: "Use when: building or configuring MUI X DataGrid tables, editable columns, toolbar actions, row selection, or TanStack DB-backed grids."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Rules
|
|
7
|
+
|
|
8
|
+
- Wrap DataGrid in `Fullscreen` when it is the only content on the page.
|
|
9
|
+
- Type columns as `Array<GridColDef<RowType>>` with the row interface.
|
|
10
|
+
- Use translation for all `headerName` values.
|
|
11
|
+
- Use `rows`, `columns`, `showToolbar`, `loading`, `ignoreDiacritics`, `cellSelection`, and `disableRowSelectionOnClick` on grids.
|
|
12
|
+
- For enums use `type: "singleSelect"` with `{ value, label }` options array used from enumObject.
|
|
13
|
+
- For editable columns, pair `editable: true` with `renderHeader: EditableColumnHeader`.
|
|
14
|
+
- Use `ChipInputCell`, `EditableColumnHeader`, and router button/grid action components from `wcz-layout/components` when they fit.
|
|
15
|
+
|
|
16
|
+
## File Placement
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
@mui/x-data-grid-premium — GridColDef, DataGridPremium
|
|
20
|
+
src/db-collections/ - TanStack DB collections to get data
|
|
21
|
+
@tanstack/react-db - useLiveQuery, useLiveSuspenseQuery
|
|
22
|
+
src/server/actions/ - server functions and enums
|
|
23
|
+
wcz-layout/components - ChipInputCell, EditableColumnHeader, Fullscreen
|
|
24
|
+
wcz-layout/hooks - useTranslation
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Examples
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
// src/routes/<feature>s/index.tsx
|
|
31
|
+
const { t } = useTranslation();
|
|
32
|
+
const { confirm, alert } = useDialogs();
|
|
33
|
+
const navigate = useNavigate();
|
|
34
|
+
const [cellSelectionModel, setCellSelectionModel] = useState<GridCellSelectionModel>({});
|
|
35
|
+
|
|
36
|
+
const { data, isLoading } = useLiveQuery((q) =>
|
|
37
|
+
q.from({ feature: featureCollection }).orderBy(({ feature }) => feature.name, "asc"),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const columns: Array<GridColDef<Feature>> = [
|
|
41
|
+
{
|
|
42
|
+
field: "name",
|
|
43
|
+
headerName: t("Feature.Name"),
|
|
44
|
+
width: 200,
|
|
45
|
+
editable: true,
|
|
46
|
+
renderHeader: EditableColumnHeader,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
field: "tags",
|
|
50
|
+
headerName: t("Feature.Tags"),
|
|
51
|
+
width: 200,
|
|
52
|
+
renderCell: (params) => <ChipInputCell params={params} />,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
field: "status",
|
|
56
|
+
headerName: t("Feature.Status"),
|
|
57
|
+
width: 200,
|
|
58
|
+
type: "singleSelect",
|
|
59
|
+
valueOptions: featureStatusEnum.enumValues.map((status) => ({
|
|
60
|
+
value: status,
|
|
61
|
+
label: t(`FeatureStatus.${status}`),
|
|
62
|
+
})),
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
const handleOnDelete = createOptimisticAction<Array<string>>({
|
|
67
|
+
onMutate: (ids) => {
|
|
68
|
+
ids.forEach((id) => {
|
|
69
|
+
featureCollection.delete(id);
|
|
70
|
+
});
|
|
71
|
+
},
|
|
72
|
+
mutationFn: async (ids) => {
|
|
73
|
+
deleteFeatures({ data: ids });
|
|
74
|
+
await featureCollection.utils.refetch();
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<Fullscreen>
|
|
80
|
+
<DataGridPremium
|
|
81
|
+
rows={data}
|
|
82
|
+
columns={columns}
|
|
83
|
+
showToolbar
|
|
84
|
+
loading={isLoading}
|
|
85
|
+
ignoreDiacritics
|
|
86
|
+
onRowDoubleClick={({ row }) => navigate({ to: "/features/$id", params: { id: row.id } })}
|
|
87
|
+
cellSelection
|
|
88
|
+
disableRowSelectionOnClick
|
|
89
|
+
cellSelectionModel={cellSelectionModel}
|
|
90
|
+
onCellSelectionModelChange={(newModel) => setCellSelectionModel(newModel)}
|
|
91
|
+
slots={{ toolbar: DataGridToolbar }}
|
|
92
|
+
slotProps={{
|
|
93
|
+
toolbar: {
|
|
94
|
+
title: t("Feature.Features"),
|
|
95
|
+
actions: [
|
|
96
|
+
<Tooltip key="create" title={t("Create")}>
|
|
97
|
+
<RouterIconButton to="/features/create">
|
|
98
|
+
<Add fontSize="small" />
|
|
99
|
+
</RouterIconButton>
|
|
100
|
+
</Tooltip>,
|
|
101
|
+
Object.keys(cellSelectionModel).length === 1 && (
|
|
102
|
+
<Tooltip key="edit" title={t("Edit")}>
|
|
103
|
+
<RouterIconButton
|
|
104
|
+
to="/features/edit/$id"
|
|
105
|
+
params={{ id: Object.keys(cellSelectionModel)[0].toString() }}
|
|
106
|
+
>
|
|
107
|
+
<Edit fontSize="small" />
|
|
108
|
+
</RouterIconButton>
|
|
109
|
+
</Tooltip>
|
|
110
|
+
),
|
|
111
|
+
Object.keys(cellSelectionModel).length > 0 && (
|
|
112
|
+
<Tooltip key="delete" title={t("Delete")}>
|
|
113
|
+
<IconButton
|
|
114
|
+
onClick={async () => {
|
|
115
|
+
const confirmed = await confirm(
|
|
116
|
+
t("DeleteConfirmation", { count: Object.keys(cellSelectionModel).length }),
|
|
117
|
+
);
|
|
118
|
+
if (confirmed) {
|
|
119
|
+
try {
|
|
120
|
+
const transaction = handleOnDelete(
|
|
121
|
+
Object.keys(cellSelectionModel).map((id) => id.toString()),
|
|
122
|
+
);
|
|
123
|
+
await transaction.isPersisted.promise;
|
|
124
|
+
setCellSelectionModel({});
|
|
125
|
+
} catch (error) {
|
|
126
|
+
if (error instanceof Error) await alert(error.message);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}}
|
|
130
|
+
>
|
|
131
|
+
<Badge
|
|
132
|
+
badgeContent={Object.keys(cellSelectionModel).length}
|
|
133
|
+
invisible={Object.keys(cellSelectionModel).length <= 1}
|
|
134
|
+
color="error"
|
|
135
|
+
>
|
|
136
|
+
<Delete fontSize="small" />
|
|
137
|
+
</Badge>
|
|
138
|
+
</IconButton>
|
|
139
|
+
</Tooltip>
|
|
140
|
+
),
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
}}
|
|
144
|
+
/>
|
|
145
|
+
</Fullscreen>
|
|
146
|
+
);
|
|
147
|
+
```
|