create-cundi-app 1.0.15 → 1.0.17
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/index.js +44 -2
- package/package.json +1 -1
- package/template/package.json.template +1 -1
- package/template/src/App.no-samples.tsx +249 -0
- package/template/src/App.tsx +129 -0
- package/template/src/accessControlProvider.ts +2 -2
- package/template/src/i18n.no-samples.ts +49 -0
- package/template/src/i18n.ts +76 -0
- package/template/src/pages/samples/article/create.tsx +29 -0
- package/template/src/pages/samples/article/edit.tsx +29 -0
- package/template/src/pages/samples/article/list.tsx +46 -0
- package/template/src/pages/samples/basic-type-test/create.tsx +68 -0
- package/template/src/pages/samples/basic-type-test/edit.tsx +68 -0
- package/template/src/pages/samples/basic-type-test/list.tsx +79 -0
- package/template/src/pages/samples/drawio-test/create.tsx +32 -0
- package/template/src/pages/samples/drawio-test/edit.tsx +32 -0
- package/template/src/pages/samples/drawio-test/list.tsx +47 -0
- package/template/src/pages/samples/drawio-test/show.tsx +30 -0
- package/template/src/pages/samples/product/create.tsx +29 -0
- package/template/src/pages/samples/product/edit.tsx +29 -0
- package/template/src/pages/samples/product/list.tsx +47 -0
- package/template/src/pages/samples/tiptap-test/create.tsx +30 -0
- package/template/src/pages/samples/tiptap-test/edit.tsx +30 -0
- package/template/src/pages/samples/tiptap-test/list.tsx +50 -0
- package/template/src/pages/samples/tiptap-test/show.tsx +25 -0
package/index.js
CHANGED
|
@@ -44,6 +44,14 @@ async function main() {
|
|
|
44
44
|
projectName = response.projectName;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// Ask if samples should be included
|
|
48
|
+
const { includeSamples } = await prompts({
|
|
49
|
+
type: "confirm",
|
|
50
|
+
name: "includeSamples",
|
|
51
|
+
message: "Include sample pages? (Article, Product, BasicTypeTest, TiptapTest, DrawioTest)",
|
|
52
|
+
initial: false,
|
|
53
|
+
});
|
|
54
|
+
|
|
47
55
|
const targetDir = path.resolve(process.cwd(), projectName);
|
|
48
56
|
|
|
49
57
|
// Check if directory already exists
|
|
@@ -65,6 +73,9 @@ async function main() {
|
|
|
65
73
|
|
|
66
74
|
console.log();
|
|
67
75
|
console.log(kleur.blue(`Creating project in ${kleur.bold(targetDir)}...`));
|
|
76
|
+
if (includeSamples) {
|
|
77
|
+
console.log(kleur.gray("Including sample pages..."));
|
|
78
|
+
}
|
|
68
79
|
console.log();
|
|
69
80
|
|
|
70
81
|
// Copy template files
|
|
@@ -73,12 +84,39 @@ async function main() {
|
|
|
73
84
|
try {
|
|
74
85
|
await fs.copy(templateDir, targetDir, {
|
|
75
86
|
filter: (src) => {
|
|
76
|
-
// Skip node_modules and dist if they exist
|
|
77
87
|
const relativePath = path.relative(templateDir, src);
|
|
78
|
-
|
|
88
|
+
// Skip node_modules and dist if they exist
|
|
89
|
+
if (relativePath.includes("node_modules") || relativePath.includes("dist")) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
// Skip samples if not requested
|
|
93
|
+
if (!includeSamples && relativePath.includes("pages/samples")) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
// Skip the alternative version files (they will be handled separately)
|
|
97
|
+
if (relativePath.endsWith(".no-samples.tsx") || relativePath.endsWith(".no-samples.ts")) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
79
101
|
},
|
|
80
102
|
});
|
|
81
103
|
|
|
104
|
+
// Handle App.tsx and i18n.ts based on sample choice
|
|
105
|
+
if (!includeSamples) {
|
|
106
|
+
// If not including samples, use the no-samples versions
|
|
107
|
+
const appNoSamplesPath = path.join(templateDir, "src/App.no-samples.tsx");
|
|
108
|
+
const appPath = path.join(targetDir, "src/App.tsx");
|
|
109
|
+
if (fs.existsSync(appNoSamplesPath)) {
|
|
110
|
+
await fs.copy(appNoSamplesPath, appPath, { overwrite: true });
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const i18nNoSamplesPath = path.join(templateDir, "src/i18n.no-samples.ts");
|
|
114
|
+
const i18nPath = path.join(targetDir, "src/i18n.ts");
|
|
115
|
+
if (fs.existsSync(i18nNoSamplesPath)) {
|
|
116
|
+
await fs.copy(i18nNoSamplesPath, i18nPath, { overwrite: true });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
82
120
|
// Generate package.json with project name
|
|
83
121
|
const pkgTemplatePath = path.join(targetDir, "package.json.template");
|
|
84
122
|
const pkgTargetPath = path.join(targetDir, "package.json");
|
|
@@ -129,6 +167,10 @@ VITE_REDIRECT_URI=http://localhost:5173/auth/callback
|
|
|
129
167
|
// console.log(` ${kleur.gray("$")} cp .env.example .env ${kleur.gray("# Configure your environment")}`);
|
|
130
168
|
console.log(` ${kleur.gray("$")} npm run dev`);
|
|
131
169
|
console.log();
|
|
170
|
+
if (includeSamples) {
|
|
171
|
+
console.log(kleur.yellow("Note: Sample pages are included. Make sure your backend has the corresponding Business Objects."));
|
|
172
|
+
console.log();
|
|
173
|
+
}
|
|
132
174
|
console.log(kleur.gray("────────────────────────────────────"));
|
|
133
175
|
console.log(kleur.blue("Happy coding! 🎉"));
|
|
134
176
|
console.log();
|
package/package.json
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ant-design/icons": "^5.5.1",
|
|
26
26
|
"@ant-design/v5-patch-for-react-19": "^1.0.3",
|
|
27
|
-
"@cundi/refine-xaf": "^1.0.
|
|
27
|
+
"@cundi/refine-xaf": "^1.0.14",
|
|
28
28
|
"@refinedev/antd": "^6.0.3",
|
|
29
29
|
"@refinedev/cli": "^2.16.50",
|
|
30
30
|
"@refinedev/core": "^5.0.6",
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Refine,
|
|
3
|
+
Authenticated,
|
|
4
|
+
} from "@refinedev/core";
|
|
5
|
+
import {
|
|
6
|
+
useNotificationProvider,
|
|
7
|
+
ThemedLayout,
|
|
8
|
+
ErrorComponent,
|
|
9
|
+
} from "@refinedev/antd";
|
|
10
|
+
import {
|
|
11
|
+
DashboardOutlined,
|
|
12
|
+
UserOutlined,
|
|
13
|
+
SettingOutlined,
|
|
14
|
+
TeamOutlined,
|
|
15
|
+
FieldTimeOutlined,
|
|
16
|
+
ThunderboltOutlined,
|
|
17
|
+
CopyOutlined,
|
|
18
|
+
} from "@ant-design/icons";
|
|
19
|
+
import routerProvider, {
|
|
20
|
+
NavigateToResource,
|
|
21
|
+
CatchAllNavigate,
|
|
22
|
+
UnsavedChangesNotifier,
|
|
23
|
+
DocumentTitleHandler,
|
|
24
|
+
} from "@refinedev/react-router";
|
|
25
|
+
import { BrowserRouter, Routes, Route, Outlet } from "react-router";
|
|
26
|
+
import { App as AntdApp } from "antd";
|
|
27
|
+
import { useTranslation } from "react-i18next";
|
|
28
|
+
import "./i18n";
|
|
29
|
+
|
|
30
|
+
import "@ant-design/v5-patch-for-react-19";
|
|
31
|
+
import "@refinedev/antd/dist/reset.css";
|
|
32
|
+
|
|
33
|
+
import { DashboardPage } from "./pages/dashboard";
|
|
34
|
+
import {
|
|
35
|
+
authProvider,
|
|
36
|
+
dataProvider,
|
|
37
|
+
Header,
|
|
38
|
+
LoginPage,
|
|
39
|
+
KeycloakLoginPage,
|
|
40
|
+
AuthCallback,
|
|
41
|
+
ApplicationUserList,
|
|
42
|
+
ApplicationUserCreate,
|
|
43
|
+
ApplicationUserEdit,
|
|
44
|
+
RoleList,
|
|
45
|
+
RoleCreate,
|
|
46
|
+
RoleEdit,
|
|
47
|
+
ColorModeContextProvider,
|
|
48
|
+
BackgroundJobList,
|
|
49
|
+
TriggerRuleList,
|
|
50
|
+
TriggerRuleCreate,
|
|
51
|
+
TriggerRuleEdit,
|
|
52
|
+
TriggerLogList,
|
|
53
|
+
MirrorTypeMappingConfigList,
|
|
54
|
+
MirrorTypeMappingConfigCreate,
|
|
55
|
+
MirrorTypeMappingConfigEdit,
|
|
56
|
+
} from "@cundi/refine-xaf";
|
|
57
|
+
|
|
58
|
+
import { accessControlProvider } from "./accessControlProvider";
|
|
59
|
+
|
|
60
|
+
const API_URL = import.meta.env.VITE_API_URL + "/api/odata";
|
|
61
|
+
|
|
62
|
+
const InnerApp: React.FC = () => {
|
|
63
|
+
const { t, i18n } = useTranslation();
|
|
64
|
+
|
|
65
|
+
const i18nProvider = {
|
|
66
|
+
translate: (key: string, params: any) => t(key, params) as string,
|
|
67
|
+
changeLocale: (lang: string) => i18n.changeLanguage(lang),
|
|
68
|
+
getLocale: () => i18n.language,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<BrowserRouter>
|
|
73
|
+
<AntdApp>
|
|
74
|
+
<Refine
|
|
75
|
+
authProvider={authProvider}
|
|
76
|
+
accessControlProvider={accessControlProvider}
|
|
77
|
+
dataProvider={{ default: dataProvider(API_URL) }}
|
|
78
|
+
i18nProvider={i18nProvider}
|
|
79
|
+
routerProvider={routerProvider}
|
|
80
|
+
resources={[
|
|
81
|
+
{
|
|
82
|
+
name: "dashboard",
|
|
83
|
+
list: "/",
|
|
84
|
+
meta: {
|
|
85
|
+
label: t("sider.dashboard"),
|
|
86
|
+
icon: <DashboardOutlined />,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: "ApplicationUser",
|
|
91
|
+
list: "/ApplicationUsers",
|
|
92
|
+
create: "/ApplicationUsers/create",
|
|
93
|
+
edit: "/ApplicationUsers/edit/:id",
|
|
94
|
+
meta: {
|
|
95
|
+
label: t("sider.users"),
|
|
96
|
+
icon: <UserOutlined />,
|
|
97
|
+
parent: "Settings",
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: "PermissionPolicyRole",
|
|
102
|
+
list: "/PermissionPolicyRoles",
|
|
103
|
+
create: "/PermissionPolicyRoles/create",
|
|
104
|
+
edit: "/PermissionPolicyRoles/edit/:id",
|
|
105
|
+
meta: {
|
|
106
|
+
label: t("sider.roles"),
|
|
107
|
+
parent: "Settings",
|
|
108
|
+
icon: <TeamOutlined />,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "BackgroundJobs",
|
|
113
|
+
list: "/background-jobs",
|
|
114
|
+
meta: {
|
|
115
|
+
label: t("sider.backgroundJobs"),
|
|
116
|
+
icon: <FieldTimeOutlined />,
|
|
117
|
+
parent: "Settings",
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "TriggerRule",
|
|
122
|
+
list: "/TriggerRules",
|
|
123
|
+
create: "/TriggerRules/create",
|
|
124
|
+
edit: "/TriggerRules/edit/:id",
|
|
125
|
+
meta: {
|
|
126
|
+
label: t("sider.triggerRules"),
|
|
127
|
+
parent: "Settings",
|
|
128
|
+
icon: <ThunderboltOutlined />,
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: "TriggerLog",
|
|
133
|
+
list: "/TriggerLogs",
|
|
134
|
+
meta: {
|
|
135
|
+
label: t("sider.triggerLogs"),
|
|
136
|
+
parent: "Settings",
|
|
137
|
+
icon: <ThunderboltOutlined />,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "MirrorTypeMappingConfig",
|
|
142
|
+
list: "/MirrorTypeMappingConfigs",
|
|
143
|
+
create: "/MirrorTypeMappingConfigs/create",
|
|
144
|
+
edit: "/MirrorTypeMappingConfigs/edit/:id",
|
|
145
|
+
meta: {
|
|
146
|
+
label: t("sider.mirrorConfigs"),
|
|
147
|
+
parent: "Settings",
|
|
148
|
+
icon: <CopyOutlined />,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: "Settings",
|
|
153
|
+
meta: {
|
|
154
|
+
label: t("sider.settings"),
|
|
155
|
+
icon: <SettingOutlined />,
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
]}
|
|
159
|
+
notificationProvider={useNotificationProvider}
|
|
160
|
+
options={{
|
|
161
|
+
syncWithLocation: true,
|
|
162
|
+
warnWhenUnsavedChanges: true,
|
|
163
|
+
}}
|
|
164
|
+
>
|
|
165
|
+
<Routes>
|
|
166
|
+
<Route
|
|
167
|
+
element={
|
|
168
|
+
<Authenticated
|
|
169
|
+
key="authenticated-routes"
|
|
170
|
+
fallback={<CatchAllNavigate to="/login" />}
|
|
171
|
+
>
|
|
172
|
+
<ThemedLayout Header={Header}>
|
|
173
|
+
<Outlet />
|
|
174
|
+
</ThemedLayout>
|
|
175
|
+
</Authenticated>
|
|
176
|
+
}
|
|
177
|
+
>
|
|
178
|
+
<Route index element={<DashboardPage />} />
|
|
179
|
+
|
|
180
|
+
<Route path="/ApplicationUsers">
|
|
181
|
+
<Route index element={<ApplicationUserList />} />
|
|
182
|
+
<Route path="create" element={<ApplicationUserCreate />} />
|
|
183
|
+
<Route path="edit/:id" element={<ApplicationUserEdit />} />
|
|
184
|
+
</Route>
|
|
185
|
+
|
|
186
|
+
<Route path="/PermissionPolicyRoles">
|
|
187
|
+
<Route index element={<RoleList />} />
|
|
188
|
+
<Route path="create" element={<RoleCreate />} />
|
|
189
|
+
<Route path="edit/:id" element={<RoleEdit />} />
|
|
190
|
+
</Route>
|
|
191
|
+
|
|
192
|
+
<Route path="/background-jobs" element={<BackgroundJobList title={t("sider.backgroundJobs")} />} />
|
|
193
|
+
|
|
194
|
+
<Route path="/TriggerRules">
|
|
195
|
+
<Route index element={<TriggerRuleList />} />
|
|
196
|
+
<Route path="create" element={<TriggerRuleCreate />} />
|
|
197
|
+
<Route path="edit/:id" element={<TriggerRuleEdit />} />
|
|
198
|
+
</Route>
|
|
199
|
+
<Route path="/TriggerLogs">
|
|
200
|
+
<Route index element={<TriggerLogList />} />
|
|
201
|
+
</Route>
|
|
202
|
+
<Route path="/MirrorTypeMappingConfigs">
|
|
203
|
+
<Route index element={<MirrorTypeMappingConfigList />} />
|
|
204
|
+
<Route path="create" element={<MirrorTypeMappingConfigCreate />} />
|
|
205
|
+
<Route path="edit/:id" element={<MirrorTypeMappingConfigEdit />} />
|
|
206
|
+
</Route>
|
|
207
|
+
</Route>
|
|
208
|
+
|
|
209
|
+
<Route
|
|
210
|
+
element={
|
|
211
|
+
<Authenticated key="auth-pages" fallback={<Outlet />}>
|
|
212
|
+
<NavigateToResource resource="dashboard" />
|
|
213
|
+
</Authenticated>
|
|
214
|
+
}
|
|
215
|
+
>
|
|
216
|
+
<Route path="/login" element={<KeycloakLoginPage />} />
|
|
217
|
+
<Route path="/login/api" element={<LoginPage />} />
|
|
218
|
+
<Route path="/auth/callback" element={<AuthCallback />} />
|
|
219
|
+
</Route>
|
|
220
|
+
|
|
221
|
+
<Route
|
|
222
|
+
element={
|
|
223
|
+
<Authenticated key="catch-all">
|
|
224
|
+
<ThemedLayout Header={Header}>
|
|
225
|
+
<Outlet />
|
|
226
|
+
</ThemedLayout>
|
|
227
|
+
</Authenticated>
|
|
228
|
+
}
|
|
229
|
+
>
|
|
230
|
+
<Route path="*" element={<ErrorComponent />} />
|
|
231
|
+
</Route>
|
|
232
|
+
</Routes>
|
|
233
|
+
<UnsavedChangesNotifier />
|
|
234
|
+
<DocumentTitleHandler />
|
|
235
|
+
</Refine>
|
|
236
|
+
</AntdApp>
|
|
237
|
+
</BrowserRouter>
|
|
238
|
+
);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const App: React.FC = () => {
|
|
242
|
+
return (
|
|
243
|
+
<ColorModeContextProvider>
|
|
244
|
+
<InnerApp />
|
|
245
|
+
</ColorModeContextProvider>
|
|
246
|
+
);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
export default App;
|
package/template/src/App.tsx
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
FieldTimeOutlined,
|
|
16
16
|
ThunderboltOutlined,
|
|
17
17
|
CopyOutlined,
|
|
18
|
+
AppstoreOutlined,
|
|
18
19
|
} from "@ant-design/icons";
|
|
19
20
|
import routerProvider, {
|
|
20
21
|
NavigateToResource,
|
|
@@ -57,6 +58,25 @@ import {
|
|
|
57
58
|
|
|
58
59
|
import { accessControlProvider } from "./accessControlProvider";
|
|
59
60
|
|
|
61
|
+
// Sample pages
|
|
62
|
+
import { ArticleList } from "./pages/samples/article/list";
|
|
63
|
+
import { ArticleCreate } from "./pages/samples/article/create";
|
|
64
|
+
import { ArticleEdit } from "./pages/samples/article/edit";
|
|
65
|
+
import { ProductList } from "./pages/samples/product/list";
|
|
66
|
+
import { ProductCreate } from "./pages/samples/product/create";
|
|
67
|
+
import { ProductEdit } from "./pages/samples/product/edit";
|
|
68
|
+
import { BasicTypeTestList } from "./pages/samples/basic-type-test/list";
|
|
69
|
+
import { BasicTypeTestCreate } from "./pages/samples/basic-type-test/create";
|
|
70
|
+
import { BasicTypeTestEdit } from "./pages/samples/basic-type-test/edit";
|
|
71
|
+
import { TiptapTestList } from "./pages/samples/tiptap-test/list";
|
|
72
|
+
import { TiptapTestCreate } from "./pages/samples/tiptap-test/create";
|
|
73
|
+
import { TiptapTestEdit } from "./pages/samples/tiptap-test/edit";
|
|
74
|
+
import { TiptapTestShow } from "./pages/samples/tiptap-test/show";
|
|
75
|
+
import { DrawioTestList } from "./pages/samples/drawio-test/list";
|
|
76
|
+
import { DrawioTestCreate } from "./pages/samples/drawio-test/create";
|
|
77
|
+
import { DrawioTestEdit } from "./pages/samples/drawio-test/edit";
|
|
78
|
+
import { DrawioTestShow } from "./pages/samples/drawio-test/show";
|
|
79
|
+
|
|
60
80
|
const API_URL = import.meta.env.VITE_API_URL + "/api/odata";
|
|
61
81
|
|
|
62
82
|
const InnerApp: React.FC = () => {
|
|
@@ -86,6 +106,81 @@ const InnerApp: React.FC = () => {
|
|
|
86
106
|
icon: <DashboardOutlined />,
|
|
87
107
|
},
|
|
88
108
|
},
|
|
109
|
+
// Sample resources
|
|
110
|
+
{
|
|
111
|
+
name: "Samples",
|
|
112
|
+
meta: {
|
|
113
|
+
label: t("sider.samples"),
|
|
114
|
+
icon: <AppstoreOutlined />,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: "Model",
|
|
119
|
+
meta: {
|
|
120
|
+
label: t("sider.model"),
|
|
121
|
+
parent: "Samples",
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: "BasicTypeTest",
|
|
126
|
+
list: "/BasicTypeTests",
|
|
127
|
+
create: "/BasicTypeTests/create",
|
|
128
|
+
edit: "/BasicTypeTests/edit/:id",
|
|
129
|
+
meta: {
|
|
130
|
+
label: t("sider.basicTypeTest"),
|
|
131
|
+
parent: "Model",
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: "TiptapTest",
|
|
136
|
+
list: "/TiptapTests",
|
|
137
|
+
create: "/TiptapTests/create",
|
|
138
|
+
edit: "/TiptapTests/edit/:id",
|
|
139
|
+
show: "/TiptapTests/show/:id",
|
|
140
|
+
meta: {
|
|
141
|
+
label: t("sider.tiptapTest"),
|
|
142
|
+
parent: "Model",
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: "DrawioTest",
|
|
147
|
+
list: "/DrawioTests",
|
|
148
|
+
create: "/DrawioTests/create",
|
|
149
|
+
edit: "/DrawioTests/edit/:id",
|
|
150
|
+
show: "/DrawioTests/show/:id",
|
|
151
|
+
meta: {
|
|
152
|
+
label: t("sider.drawioTest"),
|
|
153
|
+
parent: "Model",
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: "FullTextSearch",
|
|
158
|
+
meta: {
|
|
159
|
+
label: t("sider.fullTextSearch"),
|
|
160
|
+
parent: "Samples",
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "Article",
|
|
165
|
+
list: "/Articles",
|
|
166
|
+
create: "/Articles/create",
|
|
167
|
+
edit: "/Articles/edit/:id",
|
|
168
|
+
meta: {
|
|
169
|
+
label: t("types.Article"),
|
|
170
|
+
parent: "FullTextSearch",
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: "Product",
|
|
175
|
+
list: "/Products",
|
|
176
|
+
create: "/Products/create",
|
|
177
|
+
edit: "/Products/edit/:id",
|
|
178
|
+
meta: {
|
|
179
|
+
label: t("types.Product"),
|
|
180
|
+
parent: "FullTextSearch",
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
// Core resources
|
|
89
184
|
{
|
|
90
185
|
name: "ApplicationUser",
|
|
91
186
|
list: "/ApplicationUsers",
|
|
@@ -177,6 +272,40 @@ const InnerApp: React.FC = () => {
|
|
|
177
272
|
>
|
|
178
273
|
<Route index element={<DashboardPage />} />
|
|
179
274
|
|
|
275
|
+
{/* Sample routes */}
|
|
276
|
+
<Route path="/Articles">
|
|
277
|
+
<Route index element={<ArticleList />} />
|
|
278
|
+
<Route path="create" element={<ArticleCreate />} />
|
|
279
|
+
<Route path="edit/:id" element={<ArticleEdit />} />
|
|
280
|
+
</Route>
|
|
281
|
+
|
|
282
|
+
<Route path="/Products">
|
|
283
|
+
<Route index element={<ProductList />} />
|
|
284
|
+
<Route path="create" element={<ProductCreate />} />
|
|
285
|
+
<Route path="edit/:id" element={<ProductEdit />} />
|
|
286
|
+
</Route>
|
|
287
|
+
|
|
288
|
+
<Route path="/BasicTypeTests">
|
|
289
|
+
<Route index element={<BasicTypeTestList />} />
|
|
290
|
+
<Route path="create" element={<BasicTypeTestCreate />} />
|
|
291
|
+
<Route path="edit/:id" element={<BasicTypeTestEdit />} />
|
|
292
|
+
</Route>
|
|
293
|
+
|
|
294
|
+
<Route path="/TiptapTests">
|
|
295
|
+
<Route index element={<TiptapTestList />} />
|
|
296
|
+
<Route path="create" element={<TiptapTestCreate />} />
|
|
297
|
+
<Route path="edit/:id" element={<TiptapTestEdit />} />
|
|
298
|
+
<Route path="show/:id" element={<TiptapTestShow />} />
|
|
299
|
+
</Route>
|
|
300
|
+
|
|
301
|
+
<Route path="/DrawioTests">
|
|
302
|
+
<Route index element={<DrawioTestList />} />
|
|
303
|
+
<Route path="create" element={<DrawioTestCreate />} />
|
|
304
|
+
<Route path="edit/:id" element={<DrawioTestEdit />} />
|
|
305
|
+
<Route path="show/:id" element={<DrawioTestShow />} />
|
|
306
|
+
</Route>
|
|
307
|
+
|
|
308
|
+
{/* Core routes */}
|
|
180
309
|
<Route path="/ApplicationUsers">
|
|
181
310
|
<Route index element={<ApplicationUserList />} />
|
|
182
311
|
<Route path="create" element={<ApplicationUserCreate />} />
|
|
@@ -11,8 +11,8 @@ const ADMIN_ONLY_RESOURCES = ["ApplicationUser", "PermissionPolicyRole", "Settin
|
|
|
11
11
|
*/
|
|
12
12
|
export const accessControlProvider: AccessControlProvider = {
|
|
13
13
|
can: async ({ resource, action, params }) => {
|
|
14
|
-
const isAdmin = localStorage.getItem("user_is_admin") === "true";
|
|
15
|
-
const roles = JSON.parse(localStorage.getItem("user_roles") || "[]") as string[];
|
|
14
|
+
const isAdmin = (localStorage.getItem("user_is_admin") || sessionStorage.getItem("user_is_admin")) === "true";
|
|
15
|
+
const roles = JSON.parse(localStorage.getItem("user_roles") || sessionStorage.getItem("user_roles") || "[]") as string[];
|
|
16
16
|
|
|
17
17
|
// Admin-only resources check
|
|
18
18
|
if (resource && ADMIN_ONLY_RESOURCES.includes(resource) && !isAdmin) {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import i18n from "i18next";
|
|
2
|
+
import { initReactI18next } from "react-i18next";
|
|
3
|
+
import LanguageDetector from "i18next-browser-languagedetector";
|
|
4
|
+
import { refineXafTranslations } from "@cundi/refine-xaf";
|
|
5
|
+
|
|
6
|
+
// Use translations from the SDK
|
|
7
|
+
const { en, "zh-TW": zhTW } = refineXafTranslations;
|
|
8
|
+
|
|
9
|
+
const enExtended = {
|
|
10
|
+
...en,
|
|
11
|
+
sider: {
|
|
12
|
+
...((en as any).sider || {}),
|
|
13
|
+
triggerRules: "Trigger Rules",
|
|
14
|
+
triggerLogs: "Trigger Logs",
|
|
15
|
+
mirrorConfigs: "Mirror Configs",
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const zhTWExtended = {
|
|
20
|
+
...zhTW,
|
|
21
|
+
sider: {
|
|
22
|
+
...((zhTW as any).sider || {}),
|
|
23
|
+
triggerRules: "觸發規則",
|
|
24
|
+
triggerLogs: "觸發紀錄",
|
|
25
|
+
mirrorConfigs: "鏡射設定",
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
i18n
|
|
30
|
+
.use(LanguageDetector)
|
|
31
|
+
.use(initReactI18next)
|
|
32
|
+
.init({
|
|
33
|
+
resources: {
|
|
34
|
+
en: {
|
|
35
|
+
translation: enExtended,
|
|
36
|
+
},
|
|
37
|
+
"zh-TW": {
|
|
38
|
+
translation: zhTWExtended,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
lng: "zh-TW", // Default language
|
|
42
|
+
fallbackLng: "en",
|
|
43
|
+
debug: false,
|
|
44
|
+
interpolation: {
|
|
45
|
+
escapeValue: false,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export default i18n;
|
package/template/src/i18n.ts
CHANGED
|
@@ -13,6 +13,44 @@ const enExtended = {
|
|
|
13
13
|
triggerRules: "Trigger Rules",
|
|
14
14
|
triggerLogs: "Trigger Logs",
|
|
15
15
|
mirrorConfigs: "Mirror Configs",
|
|
16
|
+
// Sample translations
|
|
17
|
+
samples: "Samples",
|
|
18
|
+
model: "Model",
|
|
19
|
+
basicTypeTest: "Basic Type",
|
|
20
|
+
tiptapTest: "Tiptap Editor",
|
|
21
|
+
drawioTest: "Drawio Editor",
|
|
22
|
+
fullTextSearch: "Full Text Search",
|
|
23
|
+
},
|
|
24
|
+
// Sample field translations
|
|
25
|
+
article: {
|
|
26
|
+
title: "Title",
|
|
27
|
+
content: "Content",
|
|
28
|
+
},
|
|
29
|
+
product: {
|
|
30
|
+
name: "Name",
|
|
31
|
+
description: "Description",
|
|
32
|
+
},
|
|
33
|
+
tiptapTest: {
|
|
34
|
+
name: "Name",
|
|
35
|
+
content: "Content",
|
|
36
|
+
},
|
|
37
|
+
drawioTest: {
|
|
38
|
+
name: "Name",
|
|
39
|
+
xmlContent: "Diagram Content",
|
|
40
|
+
},
|
|
41
|
+
basicTypeTest: {
|
|
42
|
+
stringValue: "String Value",
|
|
43
|
+
memoValue: "Memo Value",
|
|
44
|
+
intValue: "Int Value",
|
|
45
|
+
doubleValue: "Double Value",
|
|
46
|
+
dateTimeValue: "DateTime Value",
|
|
47
|
+
boolValue: "Bool Value",
|
|
48
|
+
imageValue: "Image Value",
|
|
49
|
+
},
|
|
50
|
+
types: {
|
|
51
|
+
Article: "Article",
|
|
52
|
+
Product: "Product",
|
|
53
|
+
BasicTypeTest: "Basic Type",
|
|
16
54
|
},
|
|
17
55
|
};
|
|
18
56
|
|
|
@@ -23,6 +61,44 @@ const zhTWExtended = {
|
|
|
23
61
|
triggerRules: "觸發規則",
|
|
24
62
|
triggerLogs: "觸發紀錄",
|
|
25
63
|
mirrorConfigs: "鏡射設定",
|
|
64
|
+
// Sample translations
|
|
65
|
+
samples: "範例",
|
|
66
|
+
model: "資料模型",
|
|
67
|
+
basicTypeTest: "基本型別",
|
|
68
|
+
tiptapTest: "Tiptap 編輯器",
|
|
69
|
+
drawioTest: "Drawio 編輯器",
|
|
70
|
+
fullTextSearch: "全文檢索",
|
|
71
|
+
},
|
|
72
|
+
// Sample field translations
|
|
73
|
+
article: {
|
|
74
|
+
title: "標題",
|
|
75
|
+
content: "內容",
|
|
76
|
+
},
|
|
77
|
+
product: {
|
|
78
|
+
name: "名稱",
|
|
79
|
+
description: "描述",
|
|
80
|
+
},
|
|
81
|
+
tiptapTest: {
|
|
82
|
+
name: "名稱",
|
|
83
|
+
content: "內容",
|
|
84
|
+
},
|
|
85
|
+
drawioTest: {
|
|
86
|
+
name: "名稱",
|
|
87
|
+
xmlContent: "圖表內容",
|
|
88
|
+
},
|
|
89
|
+
basicTypeTest: {
|
|
90
|
+
stringValue: "字串",
|
|
91
|
+
memoValue: "長文字",
|
|
92
|
+
intValue: "整數",
|
|
93
|
+
doubleValue: "浮點數",
|
|
94
|
+
dateTimeValue: "日期時間",
|
|
95
|
+
boolValue: "布林值",
|
|
96
|
+
imageValue: "圖片",
|
|
97
|
+
},
|
|
98
|
+
types: {
|
|
99
|
+
Article: "文章",
|
|
100
|
+
Product: "產品",
|
|
101
|
+
BasicTypeTest: "基本型別",
|
|
26
102
|
},
|
|
27
103
|
};
|
|
28
104
|
|