@vc-shell/create-vc-app 1.2.4-beta.7 → 2.0.0-alpha.0

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.
Files changed (165) hide show
  1. package/README.md +44 -74
  2. package/dist/commands/add-module.d.ts +2 -0
  3. package/dist/commands/add-module.d.ts.map +1 -0
  4. package/dist/commands/init.d.ts +2 -0
  5. package/dist/commands/init.d.ts.map +1 -0
  6. package/dist/engine/codegen.d.ts +9 -0
  7. package/dist/engine/codegen.d.ts.map +1 -0
  8. package/dist/engine/helpers.d.ts +19 -0
  9. package/dist/engine/helpers.d.ts.map +1 -0
  10. package/dist/engine/template.d.ts +21 -0
  11. package/dist/engine/template.d.ts.map +1 -0
  12. package/dist/index.js +355 -526
  13. package/dist/output.d.ts +4 -0
  14. package/dist/output.d.ts.map +1 -0
  15. package/dist/templates/dynamic-module/_gitignore +4 -0
  16. package/dist/templates/dynamic-module/_package.json.ejs +26 -0
  17. package/dist/templates/dynamic-module/src/modules/index.ts.ejs +5 -0
  18. package/dist/templates/dynamic-module/tsconfig.json +14 -0
  19. package/dist/templates/dynamic-module/vite.config.mts.ejs +3 -0
  20. package/dist/templates/{base/_env → host-app/_env.ejs} +1 -1
  21. package/dist/templates/{base/_package.json → host-app/_package.json.ejs} +7 -7
  22. package/dist/templates/{base/index.html → host-app/index.html.ejs} +1 -1
  23. package/dist/templates/{base/src/bootstrap.ts → host-app/src/bootstrap.ts.ejs} +6 -3
  24. package/dist/templates/{base/src/main.ts → host-app/src/main.ts.ejs} +7 -5
  25. package/dist/templates/{base/src/pages/App.vue → host-app/src/pages/App.vue.ejs} +1 -1
  26. package/dist/templates/host-app/src/pages/Platform.vue +19 -0
  27. package/dist/templates/host-app/src/router/routes.ts.ejs +107 -0
  28. package/dist/templates/host-app/vite.config.mts.ejs +7 -0
  29. package/dist/templates/module/composables/index.ts.ejs +2 -0
  30. package/dist/templates/module/composables/useDetails.ts.ejs +38 -0
  31. package/dist/templates/module/composables/useList.ts.ejs +43 -0
  32. package/dist/templates/module/locales/en.json.ejs +22 -0
  33. package/dist/templates/module/pages/details.vue.ejs +111 -0
  34. package/dist/templates/module/pages/index.ts.ejs +2 -0
  35. package/dist/templates/module/pages/list.vue.ejs +117 -0
  36. package/dist/templates/{sample/classic-module → sample-module}/pages/details.vue +2 -2
  37. package/dist/templates/{sample/classic-module → sample-module}/pages/list.vue +3 -3
  38. package/dist/templates/standalone/LICENSE +12 -0
  39. package/dist/templates/standalone/README.md +54 -0
  40. package/dist/templates/standalone/_browserslistrc +3 -0
  41. package/dist/templates/standalone/_commitlintrc.json +3 -0
  42. package/dist/templates/standalone/_editorconfig +22 -0
  43. package/dist/templates/standalone/_env.ejs +3 -0
  44. package/dist/templates/standalone/_env.local.ejs +1 -0
  45. package/dist/templates/standalone/_eslintignore +3 -0
  46. package/dist/templates/standalone/_eslintrc.js +41 -0
  47. package/dist/templates/standalone/_github/COMMIT_CONVENTION.md +91 -0
  48. package/dist/templates/standalone/_github/PULL_REQUEST_TEMPLATE.md +8 -0
  49. package/dist/templates/standalone/_gitignore +71 -0
  50. package/dist/templates/standalone/_package.json.ejs +70 -0
  51. package/dist/templates/standalone/_prettierignore +4 -0
  52. package/dist/templates/standalone/_prettierrc +4 -0
  53. package/dist/templates/standalone/_vscode/extensions.json +14 -0
  54. package/dist/templates/standalone/_vscode/settings.json +14 -0
  55. package/dist/templates/standalone/_yarn/releases/yarn-4.9.1.cjs +948 -0
  56. package/dist/templates/standalone/_yarnrc.yml +7 -0
  57. package/dist/templates/standalone/index.html.ejs +26 -0
  58. package/dist/templates/standalone/postcss.config.cjs +6 -0
  59. package/dist/templates/standalone/public/assets/1.jpeg +0 -0
  60. package/dist/templates/standalone/public/assets/2.jpg +0 -0
  61. package/dist/templates/standalone/public/assets/3.jpg +0 -0
  62. package/dist/templates/standalone/public/assets/app-select.svg +11 -0
  63. package/dist/templates/standalone/public/assets/avatar.jpg +0 -0
  64. package/dist/templates/standalone/public/assets/background.jpg +0 -0
  65. package/dist/templates/standalone/public/assets/empty.png +0 -0
  66. package/dist/templates/standalone/public/assets/logo-white.svg +21 -0
  67. package/dist/templates/standalone/public/assets/logo.svg +8 -0
  68. package/dist/templates/standalone/public/assets/welcome.png +0 -0
  69. package/dist/templates/standalone/public/img/icons/apple-touch-icon.png +0 -0
  70. package/dist/templates/standalone/public/img/icons/favicon-16x16.png +0 -0
  71. package/dist/templates/standalone/public/img/icons/favicon-32x32.png +0 -0
  72. package/dist/templates/standalone/public/img/icons/favicon.ico +0 -0
  73. package/dist/templates/standalone/public/img/icons/mstile-150x150.png +0 -0
  74. package/dist/templates/standalone/public/img/icons/safari-pinned-tab.svg +32 -0
  75. package/dist/templates/standalone/src/api_client/README.md +199 -0
  76. package/dist/templates/standalone/src/bootstrap.ts.ejs +26 -0
  77. package/dist/templates/standalone/src/components/dashboard-widgets/Welcome.vue +51 -0
  78. package/dist/templates/standalone/src/composables/index.ts +1 -0
  79. package/dist/templates/standalone/src/env.d.ts +9 -0
  80. package/dist/templates/standalone/src/locales/en.json +16 -0
  81. package/dist/templates/standalone/src/locales/index.ts +2 -0
  82. package/dist/templates/{sample/overrides/main.ts → standalone/src/main.ts.ejs} +22 -9
  83. package/dist/templates/standalone/src/pages/App.vue.ejs +38 -0
  84. package/dist/templates/standalone/src/pages/Dashboard.vue.ejs +7 -0
  85. package/dist/templates/standalone/src/router/index.ts +10 -0
  86. package/dist/templates/{base/src/router/routes.ts → standalone/src/router/routes.ts.ejs} +27 -7
  87. package/dist/templates/standalone/src/shims-vue.d.ts +27 -0
  88. package/dist/templates/standalone/src/styles/custom.scss +116 -0
  89. package/dist/templates/standalone/src/styles/index.scss +8 -0
  90. package/dist/templates/standalone/src/vue-i18n.d.ts +10 -0
  91. package/dist/templates/standalone/tailwind.config.ts +7 -0
  92. package/dist/templates/standalone/tsconfig.json +16 -0
  93. package/dist/templates/standalone/yarn.lock +0 -0
  94. package/dist/types.d.ts +23 -0
  95. package/dist/types.d.ts.map +1 -0
  96. package/package.json +7 -4
  97. package/dist/templates/modules/classic-module/composables/index.ts +0 -2
  98. package/dist/templates/modules/classic-module/composables/use{{ModuleNamePascalCase}}Details/index.ts +0 -24
  99. package/dist/templates/modules/classic-module/composables/use{{ModuleNamePascalCase}}List/index.ts +0 -47
  100. package/dist/templates/modules/classic-module/locales/en.json +0 -37
  101. package/dist/templates/modules/classic-module/pages/details.vue +0 -87
  102. package/dist/templates/modules/classic-module/pages/list.vue +0 -257
  103. package/dist/templates/sample/classic-module/pages/index.ts +0 -2
  104. /package/dist/templates/{base → host-app}/LICENSE +0 -0
  105. /package/dist/templates/{base → host-app}/README.md +0 -0
  106. /package/dist/templates/{base → host-app}/_browserslistrc +0 -0
  107. /package/dist/templates/{base → host-app}/_commitlintrc.json +0 -0
  108. /package/dist/templates/{base → host-app}/_editorconfig +0 -0
  109. /package/dist/templates/{base/_env.local → host-app/_env.local.ejs} +0 -0
  110. /package/dist/templates/{base → host-app}/_eslintignore +0 -0
  111. /package/dist/templates/{base → host-app}/_eslintrc.js +0 -0
  112. /package/dist/templates/{base → host-app}/_github/COMMIT_CONVENTION.md +0 -0
  113. /package/dist/templates/{base → host-app}/_github/PULL_REQUEST_TEMPLATE.md +0 -0
  114. /package/dist/templates/{base → host-app}/_gitignore +0 -0
  115. /package/dist/templates/{base → host-app}/_prettierignore +0 -0
  116. /package/dist/templates/{base → host-app}/_prettierrc +0 -0
  117. /package/dist/templates/{base → host-app}/_vscode/extensions.json +0 -0
  118. /package/dist/templates/{base → host-app}/_vscode/settings.json +0 -0
  119. /package/dist/templates/{base → host-app}/_yarn/releases/yarn-4.9.1.cjs +0 -0
  120. /package/dist/templates/{base → host-app}/_yarnrc.yml +0 -0
  121. /package/dist/templates/{base → host-app}/postcss.config.cjs +0 -0
  122. /package/dist/templates/{base → host-app}/public/assets/1.jpeg +0 -0
  123. /package/dist/templates/{base → host-app}/public/assets/2.jpg +0 -0
  124. /package/dist/templates/{base → host-app}/public/assets/3.jpg +0 -0
  125. /package/dist/templates/{base → host-app}/public/assets/app-select.svg +0 -0
  126. /package/dist/templates/{base → host-app}/public/assets/avatar.jpg +0 -0
  127. /package/dist/templates/{base → host-app}/public/assets/background.jpg +0 -0
  128. /package/dist/templates/{base → host-app}/public/assets/empty.png +0 -0
  129. /package/dist/templates/{base → host-app}/public/assets/logo-white.svg +0 -0
  130. /package/dist/templates/{base → host-app}/public/assets/logo.svg +0 -0
  131. /package/dist/templates/{base → host-app}/public/assets/welcome.png +0 -0
  132. /package/dist/templates/{base → host-app}/public/img/icons/apple-touch-icon.png +0 -0
  133. /package/dist/templates/{base → host-app}/public/img/icons/favicon-16x16.png +0 -0
  134. /package/dist/templates/{base → host-app}/public/img/icons/favicon-32x32.png +0 -0
  135. /package/dist/templates/{base → host-app}/public/img/icons/favicon.ico +0 -0
  136. /package/dist/templates/{base → host-app}/public/img/icons/mstile-150x150.png +0 -0
  137. /package/dist/templates/{base → host-app}/public/img/icons/safari-pinned-tab.svg +0 -0
  138. /package/dist/templates/{base → host-app}/src/api_client/README.md +0 -0
  139. /package/dist/templates/{base → host-app}/src/components/dashboard-widgets/Welcome.vue +0 -0
  140. /package/dist/templates/{base → host-app}/src/composables/index.ts +0 -0
  141. /package/dist/templates/{base → host-app}/src/env.d.ts +0 -0
  142. /package/dist/templates/{base → host-app}/src/locales/en.json +0 -0
  143. /package/dist/templates/{base → host-app}/src/locales/index.ts +0 -0
  144. /package/dist/templates/{base/src/pages/Dashboard.vue → host-app/src/pages/Dashboard.vue.ejs} +0 -0
  145. /package/dist/templates/{base → host-app}/src/router/index.ts +0 -0
  146. /package/dist/templates/{base → host-app}/src/shims-vue.d.ts +0 -0
  147. /package/dist/templates/{base → host-app}/src/styles/custom.scss +0 -0
  148. /package/dist/templates/{base → host-app}/src/styles/index.scss +0 -0
  149. /package/dist/templates/{base → host-app}/src/vue-i18n.d.ts +0 -0
  150. /package/dist/templates/{base → host-app}/tailwind.config.ts +0 -0
  151. /package/dist/templates/{base → host-app}/tsconfig.json +0 -0
  152. /package/dist/templates/{base → host-app}/yarn.lock +0 -0
  153. /package/dist/templates/{modules/classic-module/index.ts → module/index.ts.ejs} +0 -0
  154. /package/dist/templates/{modules/classic-module → module}/locales/index.ts +0 -0
  155. /package/dist/templates/{sample/classic-module → sample-module}/composables/index.ts +0 -0
  156. /package/dist/templates/{sample/classic-module → sample-module}/composables/useDetails/index.ts +0 -0
  157. /package/dist/templates/{sample/classic-module → sample-module}/composables/useList/index.ts +0 -0
  158. /package/dist/templates/{sample/classic-module → sample-module}/index.ts +0 -0
  159. /package/dist/templates/{sample/classic-module → sample-module}/locales/en.json +0 -0
  160. /package/dist/templates/{sample/classic-module → sample-module}/locales/index.ts +0 -0
  161. /package/dist/templates/{modules/classic-module → sample-module}/pages/index.ts +0 -0
  162. /package/dist/templates/{mocks → sample-module}/sample-data/constants.ts +0 -0
  163. /package/dist/templates/{mocks → sample-module}/sample-data/index.ts +0 -0
  164. /package/dist/templates/{mocks → sample-module}/sample-data/methods.ts +0 -0
  165. /package/dist/templates/{base/vite.config.mts → standalone/vite.config.mts.ejs} +0 -0
@@ -0,0 +1,4 @@
1
+ import { ProjectOptions } from './types.js';
2
+
3
+ export declare function printSuccess(options: ProjectOptions): void;
4
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQjD,wBAAgB,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAsB1D"}
@@ -0,0 +1,4 @@
1
+ node_modules
2
+ dist
3
+ .DS_Store
4
+ *.local
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "<%- PackageName %>",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "serve": "cross-env APP_ENV=development vite --force",
7
+ "build": "cross-env APP_ENV=production vite build",
8
+ "build:types": "vue-tsc --declaration --emitDeclarationOnly --outDir dist/types",
9
+ "type-check": "vue-tsc --noEmit"
10
+ },
11
+ "devDependencies": {
12
+ "@types/node": "^20.10.5",
13
+ "@vc-shell/ts-config": "^2.0.0-alpha.0",
14
+ "cross-env": "^7.0.3",
15
+ "sass": "^1.87.0",
16
+ "typescript": "^5.8.3",
17
+ "vite": "^6.3.3",
18
+ "vue-tsc": "^2.2.10"
19
+ },
20
+ "dependencies": {
21
+ "@vc-shell/config-generator": "^2.0.0-alpha.0",
22
+ "@vc-shell/framework": "^2.0.0-alpha.0",
23
+ "vue": "^3.5.13",
24
+ "vue-router": "^4.2.5"
25
+ }
26
+ }
@@ -0,0 +1,5 @@
1
+ import * as pages from "./pages";
2
+ import * as locales from "./locales";
3
+ import { createAppModule } from "@vc-shell/framework";
4
+
5
+ export default createAppModule(pages, locales);
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "@vc-shell/ts-config/tsconfig.json",
3
+ "compilerOptions": {
4
+ "baseUrl": ".",
5
+ "outDir": "dist",
6
+ "rootDir": "src",
7
+ "types": ["vite/client"]
8
+ },
9
+ "include": [
10
+ "./src/**/*.ts",
11
+ "./src/**/*.vue",
12
+ "./src/**/*.json"
13
+ ]
14
+ }
@@ -0,0 +1,3 @@
1
+ import { getDynamicModuleConfiguration } from "@vc-shell/config-generator";
2
+
3
+ export default getDynamicModuleConfiguration();
@@ -1,3 +1,3 @@
1
- APP_BASE_PATH={{BasePath}}
1
+ APP_BASE_PATH=<%- BasePath %>
2
2
  APP_I18N_LOCALE=en
3
3
  APP_I18N_FALLBACK_LOCALE=en
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "{{PackageName}}",
2
+ "name": "<%- PackageName %>",
3
3
  "version": "0.0.0",
4
4
  "private": true,
5
5
  "scripts": {
@@ -22,14 +22,14 @@
22
22
  "@types/node": "^20.10.5",
23
23
  "@typescript-eslint/eslint-plugin": "^7.4.0",
24
24
  "@typescript-eslint/parser": "^7.4.0",
25
- "@vc-shell/api-client-generator": "^1.2.4-beta.7",
26
- "@vc-shell/release-config": "^1.2.4-beta.7",
27
- "@vc-shell/ts-config": "^1.2.4-beta.7",
25
+ "@vc-shell/api-client-generator": "^2.0.0-alpha.0",
26
+ "@vc-shell/release-config": "^2.0.0-alpha.0",
27
+ "@vc-shell/ts-config": "^2.0.0-alpha.0",
28
28
  "@vitejs/plugin-vue": "^5.2.3",
29
29
  "@vue/eslint-config-prettier": "^9.0.0",
30
30
  "@vue/eslint-config-typescript": "^13.0.0",
31
31
  "autoprefixer": "^10.4.16",
32
- "conventional-changelog-cli": "^4.1.0",
32
+ "conventional-changelog-cli": "^5.0.0",
33
33
  "cross-env": "^7.0.3",
34
34
  "eslint": "^8.57.0",
35
35
  "eslint-import-resolver-typescript": "^3.6.1",
@@ -52,8 +52,8 @@
52
52
  "vue-tsc": "^2.2.10"
53
53
  },
54
54
  "dependencies": {
55
- "@vc-shell/config-generator": "^1.2.4-beta.7",
56
- "@vc-shell/framework": "^1.2.4-beta.7",
55
+ "@vc-shell/config-generator": "^2.0.0-alpha.0",
56
+ "@vc-shell/framework": "^2.0.0-alpha.0",
57
57
  "@vueuse/core": "^10.7.1",
58
58
  "@vueuse/integrations": "^10.7.1",
59
59
  "cross-spawn": "^7.0.3",
@@ -11,7 +11,7 @@
11
11
  <link rel="icon" type="image/png" sizes="32x32" href="img/icons/favicon-32x32.png">
12
12
  <link rel="icon" type="image/png" sizes="16x16" href="img/icons/favicon-16x16.png">
13
13
  <meta name="theme-color" content="#ffffff">
14
- <title>{{AppNameSentenceCase}}</title>
14
+ <title><%- AppNameSentenceCase %></title>
15
15
  </head>
16
16
 
17
17
  <body>
@@ -1,10 +1,13 @@
1
+ import { App } from "vue";
2
+ <% if (dashboard) { %>
1
3
  import { addMenuItem, registerDashboardWidget } from "@vc-shell/framework";
2
- import { App, markRaw } from "vue";
4
+ import { markRaw } from "vue";
3
5
  import Welcome from "./components/dashboard-widgets/Welcome.vue";
6
+ <% } %>
4
7
 
5
8
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
6
9
  export function bootstrap(app: App) {
7
- // Add Dashboard to main menu item
10
+ <% if (dashboard) { %>
8
11
  addMenuItem({
9
12
  title: "SHELL.MENU.DASHBOARD",
10
13
  icon: "lucide-home",
@@ -12,7 +15,6 @@ export function bootstrap(app: App) {
12
15
  url: "/",
13
16
  });
14
17
 
15
- // Register Dashboard Welcome Widget
16
18
  registerDashboardWidget({
17
19
  id: "welcome-widget",
18
20
  name: "Welcome",
@@ -20,4 +22,5 @@ export function bootstrap(app: App) {
20
22
  size: { width: 6, height: 6 },
21
23
  position: { x: 0, y: 0 },
22
24
  });
25
+ <% } %>
23
26
  }
@@ -3,16 +3,13 @@ import { createApp } from "vue";
3
3
  import { router } from "./router";
4
4
  import * as locales from "./locales";
5
5
  import { RouterView } from "vue-router";
6
- import {{ModuleNamePascalCase}} from "./modules/{{ModuleName}}";
7
6
  import { bootstrap } from "./bootstrap";
8
7
 
9
- // Load required CSS
10
8
  import "@vc-shell/framework/dist/index.css";
11
9
 
12
10
  async function startApp() {
13
11
  const { loadUser } = useUser();
14
12
 
15
-
16
13
  try {
17
14
  await loadUser();
18
15
  } catch (e) {
@@ -26,9 +23,14 @@ async function startApp() {
26
23
  locale: import.meta.env.APP_I18N_LOCALE,
27
24
  fallbackLocale: import.meta.env.APP_I18N_FALLBACK_LOCALE,
28
25
  },
26
+ <% if (aiAgent) { %>
27
+ aiAgent: {
28
+ config: {
29
+ url: import.meta.env.APP_AI_AGENT_URL,
30
+ },
31
+ },
32
+ <% } %>
29
33
  })
30
- // {{ModuleNamePascalCase}} module initialization
31
- .use({{ModuleNamePascalCase}}, { router })
32
34
  .use(router);
33
35
 
34
36
  const { currentLocale, setLocale } = app.runWithContext(() => useLanguages());
@@ -2,7 +2,7 @@
2
2
  <VcApp
3
3
  :is-ready="isReady"
4
4
  :logo="logoImage"
5
- title="{{AppNameSentenceCase}}"
5
+ title="<%- AppNameSentenceCase %>"
6
6
  :version="version"
7
7
  >
8
8
  </VcApp>
@@ -0,0 +1,19 @@
1
+ <template>
2
+ <div class="tw-w-full tw-h-full">
3
+ <iframe
4
+ v-if="url"
5
+ ref="iframeRef"
6
+ :src="url"
7
+ class="tw-w-full tw-h-full tw-border-0"
8
+ allow="clipboard-read; clipboard-write"
9
+ />
10
+ </div>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ import { computed } from "vue";
15
+ import { useRoute } from "vue-router";
16
+
17
+ const route = useRoute();
18
+ const url = computed(() => route.query.url as string | undefined);
19
+ </script>
@@ -0,0 +1,107 @@
1
+ import { RouteRecordRaw } from "vue-router";
2
+ import App from "../pages/App.vue";
3
+ <% if (dashboard) { %>
4
+ import Dashboard from "../pages/Dashboard.vue";
5
+ <% } %>
6
+ import Platform from "../pages/Platform.vue";
7
+ import { Invite, Login, ResetPassword, ForgotPassword, ChangePasswordPage } from "@vc-shell/framework";
8
+ // eslint-disable-next-line import/no-unresolved
9
+ import whiteLogoImage from "/assets/logo-white.svg";
10
+ // eslint-disable-next-line import/no-unresolved
11
+ import bgImage from "/assets/background.jpg";
12
+
13
+ <% if (tenantRoutes) { %>
14
+ const tenantIdRegex = "[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}";
15
+ <% } %>
16
+
17
+ export const routes: RouteRecordRaw[] = [
18
+ {
19
+ <% if (tenantRoutes) { %>
20
+ path: `/:tenantId(${tenantIdRegex})?`,
21
+ <% } else { %>
22
+ path: "/",
23
+ <% } %>
24
+ component: App,
25
+ name: "App",
26
+ meta: {
27
+ root: true,
28
+ },
29
+ children: [
30
+ <% if (dashboard) { %>
31
+ {
32
+ name: "Dashboard",
33
+ path: "",
34
+ component: Dashboard,
35
+ },
36
+ <% } %>
37
+ {
38
+ name: "Platform",
39
+ path: "platform",
40
+ component: Platform,
41
+ props: (route) => ({
42
+ url: route.query.url,
43
+ }),
44
+ },
45
+ ],
46
+ <% if (tenantRoutes) { %>
47
+ beforeEnter: (to) => {
48
+ const { tenantId } = to.params;
49
+ if (!tenantId || new RegExp(tenantIdRegex).test(tenantId as string)) {
50
+ return true;
51
+ }
52
+ return { path: "/" };
53
+ },
54
+ <% } %>
55
+ },
56
+ {
57
+ name: "Login",
58
+ path: "/login",
59
+ component: Login,
60
+ props: () => ({
61
+ logo: whiteLogoImage,
62
+ title: "<%- AppNameSentenceCase %>",
63
+ }),
64
+ },
65
+ {
66
+ name: "Invite",
67
+ path: "/invite",
68
+ component: Invite,
69
+ props: (_route) => ({
70
+ userId: _route.query.userId,
71
+ token: _route.query.token,
72
+ userName: _route.query.userName,
73
+ logo: whiteLogoImage,
74
+ }),
75
+ },
76
+ {
77
+ name: "ResetPassword",
78
+ path: "/resetpassword",
79
+ component: ResetPassword,
80
+ props: (_route) => ({
81
+ userId: _route.query.userId,
82
+ token: _route.query.token,
83
+ userName: _route.query.userName,
84
+ logo: whiteLogoImage,
85
+ }),
86
+ },
87
+ {
88
+ name: "ForgotPassword",
89
+ path: "/forgot-password",
90
+ component: ForgotPassword,
91
+ props: () => ({
92
+ logo: whiteLogoImage,
93
+ }),
94
+ },
95
+ {
96
+ name: "ChangePassword",
97
+ path: "/changepassword",
98
+ component: ChangePasswordPage,
99
+ meta: {
100
+ forced: true,
101
+ },
102
+ props: (_route) => ({
103
+ forced: _route.meta.forced,
104
+ logo: whiteLogoImage,
105
+ }),
106
+ },
107
+ ];
@@ -0,0 +1,7 @@
1
+ import { getApplicationConfiguration, getHostFederationConfig } from "@vc-shell/config-generator";
2
+ import { mergeConfig } from "vite";
3
+
4
+ export default mergeConfig(
5
+ getApplicationConfiguration(),
6
+ getHostFederationConfig(),
7
+ );
@@ -0,0 +1,2 @@
1
+ export { default as use<%- ModuleNamePascalCase %>List } from "./useList";
2
+ export { default as use<%- ModuleNamePascalCase %>Details } from "./useDetails";
@@ -0,0 +1,38 @@
1
+ import { ref } from "vue";
2
+ import { useAsync, useLoading } from "@vc-shell/framework";
3
+
4
+ export default function use<%- ModuleNamePascalCase %>Details() {
5
+ const item = ref<Record<string, unknown>>({});
6
+
7
+ const { loading: itemLoading, action: fetchItem } = useAsync(async (id?: string) => {
8
+ // TODO: Replace with real API call
9
+ // const result = await apiClient.getById(id);
10
+ // item.value = result;
11
+ });
12
+
13
+ const { loading: saveLoading, action: saveAction } = useAsync(async () => {
14
+ // TODO: Replace with real API call
15
+ // if (item.value.id) {
16
+ // await apiClient.update(item.value);
17
+ // } else {
18
+ // await apiClient.create(item.value);
19
+ // }
20
+ });
21
+
22
+ const loading = useLoading(itemLoading, saveLoading);
23
+
24
+ async function getItem(id: string) {
25
+ await fetchItem(id);
26
+ }
27
+
28
+ async function saveItem() {
29
+ await saveAction();
30
+ }
31
+
32
+ return {
33
+ item,
34
+ loading,
35
+ getItem,
36
+ saveItem,
37
+ };
38
+ }
@@ -0,0 +1,43 @@
1
+ import { ref, type Ref } from "vue";
2
+ import { useAsync, useLoading } from "@vc-shell/framework";
3
+
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
+ export default function use<%- ModuleNamePascalCase %>List() {
6
+ const data: Ref<Record<string, any>[]> = ref([]);
7
+ const totalCount = ref(0);
8
+ const currentPage = ref(1);
9
+ const searchQuery = ref("");
10
+
11
+ const { loading: itemsLoading, action: fetchItems } = useAsync(async () => {
12
+ // TODO: Replace with real API call
13
+ // const result = await apiClient.search({
14
+ // keyword: searchQuery.value,
15
+ // skip: (currentPage.value - 1) * 20,
16
+ // take: 20,
17
+ // });
18
+ // data.value = result.results ?? [];
19
+ // totalCount.value = result.totalCount ?? 0;
20
+ });
21
+
22
+ const { loading: deleteLoading, action: removeItems } = useAsync(async (ids?: string[]) => {
23
+ // TODO: Replace with real API call
24
+ // await Promise.all((ids ?? []).map((id) => apiClient.delete(id)));
25
+ // await fetchItems();
26
+ });
27
+
28
+ const loading = useLoading(itemsLoading, deleteLoading);
29
+
30
+ async function getItems() {
31
+ await fetchItems();
32
+ }
33
+
34
+ return {
35
+ data,
36
+ loading,
37
+ totalCount,
38
+ currentPage,
39
+ searchQuery,
40
+ getItems,
41
+ removeItems,
42
+ };
43
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "<%- ModuleNameScreamingSnake %>": {
3
+ "MENU": {
4
+ "TITLE": "<%- ModuleNameSentenceCase %>"
5
+ },
6
+ "PAGES": {
7
+ "LIST": {
8
+ "TITLE": "<%- ModuleNameSentenceCase %>",
9
+ "TOOLBAR": {
10
+ "REFRESH": "Refresh",
11
+ "ADD": "Add"
12
+ }
13
+ },
14
+ "DETAILS": {
15
+ "TITLE": "<%- ModuleNameSentenceCase %> Details"
16
+ },
17
+ "ALERTS": {
18
+ "CLOSE_CONFIRMATION": "You have unsaved changes. Close anyway?"
19
+ }
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,111 @@
1
+ <template>
2
+ <VcBlade
3
+ :title="title"
4
+ :toolbar-items="bladeToolbar"
5
+ :loading="loading"
6
+ :expanded="expanded"
7
+ :closable="closable"
8
+ width="70%"
9
+ @close="$emit('close:blade')"
10
+ @expand="$emit('expand:blade')"
11
+ @collapse="$emit('collapse:blade')"
12
+ >
13
+ <VcContainer>
14
+ <VcForm>
15
+ <!-- Add your form fields here -->
16
+ <VcInput
17
+ v-model="item.name"
18
+ :label="'Name'"
19
+ required
20
+ />
21
+ </VcForm>
22
+ </VcContainer>
23
+ </VcBlade>
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import {
28
+ VcBlade,
29
+ VcContainer,
30
+ VcForm,
31
+ VcInput,
32
+ useBladeNavigation,
33
+ useModificationTracker,
34
+ usePopup,
35
+ useBeforeUnload,
36
+ type IBladeToolbar,
37
+ type IParentCallArgs,
38
+ } from "@vc-shell/framework";
39
+ import { ref, computed, onMounted } from "vue";
40
+ import use<%- ModuleNamePascalCase %>Details from "../composables/useDetails";
41
+
42
+ export interface Props {
43
+ expanded?: boolean;
44
+ closable?: boolean;
45
+ param?: string;
46
+ }
47
+
48
+ export interface Emits {
49
+ (event: "parent:call", args: IParentCallArgs): void;
50
+ (event: "collapse:blade"): void;
51
+ (event: "expand:blade"): void;
52
+ (event: "close:blade"): void;
53
+ }
54
+
55
+ defineOptions({
56
+ url: "/<%- ModuleName %>-details",
57
+ name: "<%- ModuleNamePascalCase %>Details",
58
+ });
59
+
60
+ const props = withDefaults(defineProps<Props>(), {
61
+ expanded: true,
62
+ closable: true,
63
+ param: undefined,
64
+ });
65
+
66
+ const emit = defineEmits<Emits>();
67
+
68
+ const { onBeforeClose } = useBladeNavigation();
69
+ const { showConfirmation } = usePopup();
70
+
71
+ const { item, loading, getItem, saveItem } = use<%- ModuleNamePascalCase %>Details();
72
+ const { isModified, resetModificationState } = useModificationTracker(item);
73
+
74
+ const title = computed(() => {
75
+ return props.param
76
+ ? String(item.value?.name || "<%- ModuleNameSentenceCase %> Details")
77
+ : "New <%- ModuleNameSentenceCase %>";
78
+ });
79
+
80
+ const bladeToolbar = ref<IBladeToolbar[]>([
81
+ {
82
+ id: "save",
83
+ title: "Save",
84
+ icon: "lucide-save",
85
+ disabled: computed(() => !isModified.value),
86
+ async clickHandler() {
87
+ await saveItem();
88
+ resetModificationState();
89
+ emit("parent:call", { method: "reload" });
90
+ },
91
+ },
92
+ ]);
93
+
94
+ onMounted(async () => {
95
+ if (props.param) {
96
+ await getItem(props.param);
97
+ }
98
+ });
99
+
100
+ onBeforeClose(async () => {
101
+ if (isModified.value) {
102
+ return await showConfirmation("You have unsaved changes. Are you sure you want to close?");
103
+ }
104
+ });
105
+
106
+ useBeforeUnload(computed(() => isModified.value));
107
+
108
+ defineExpose({
109
+ title,
110
+ });
111
+ </script>
@@ -0,0 +1,2 @@
1
+ export { default as <%- ModuleNamePascalCase %>List } from "./list.vue";
2
+ export { default as <%- ModuleNamePascalCase %>Details } from "./details.vue";
@@ -0,0 +1,117 @@
1
+ <template>
2
+ <VcBlade
3
+ :title="$t('<%- ModuleNameScreamingSnake %>.PAGES.LIST.TITLE')"
4
+ :toolbar-items="bladeToolbar"
5
+ :loading="loading"
6
+ :expanded="expanded"
7
+ :closable="closable"
8
+ width="50%"
9
+ @close="$emit('close:blade')"
10
+ @expand="$emit('expand:blade')"
11
+ @collapse="$emit('collapse:blade')"
12
+ >
13
+ <VcDataTable
14
+ :items="data"
15
+ :total-count="totalCount"
16
+ :current-page="currentPage"
17
+ :search-value="searchQuery"
18
+ :state-key="'<%- ModuleNameScreamingSnake %>'"
19
+ @search:change="(val: string) => { searchQuery = val; getItems(); }"
20
+ @item-click="openDetails"
21
+ @pagination-click="(page: number) => { currentPage = page; getItems(); }"
22
+ >
23
+ <!-- Add your columns here -->
24
+ <VcColumn id="name" :header="'Name'" sortable />
25
+ <VcColumn id="createdDate" :header="'Created'" type="datetime" sortable />
26
+ </VcDataTable>
27
+ </VcBlade>
28
+ </template>
29
+
30
+ <script setup lang="ts">
31
+ import {
32
+ VcBlade,
33
+ VcDataTable,
34
+ VcColumn,
35
+ useBladeNavigation,
36
+ type IBladeToolbar,
37
+ type IParentCallArgs,
38
+ } from "@vc-shell/framework";
39
+ import { ref, computed, markRaw } from "vue";
40
+ import use<%- ModuleNamePascalCase %>List from "../composables/useList";
41
+ import Details from "./details.vue";
42
+
43
+ export interface Props {
44
+ expanded?: boolean;
45
+ closable?: boolean;
46
+ param?: string;
47
+ options?: Record<string, unknown>;
48
+ }
49
+
50
+ export interface Emits {
51
+ (event: "parent:call", args: IParentCallArgs): void;
52
+ (event: "collapse:blade"): void;
53
+ (event: "expand:blade"): void;
54
+ (event: "close:blade"): void;
55
+ }
56
+
57
+ defineOptions({
58
+ url: "/<%- ModuleName %>",
59
+ name: "<%- ModuleNamePascalCase %>List",
60
+ isWorkspace: true,
61
+ menuItem: {
62
+ title: "<%- ModuleNameScreamingSnake %>.MENU.TITLE",
63
+ icon: "lucide-box",
64
+ priority: 10,
65
+ },
66
+ });
67
+
68
+ const props = withDefaults(defineProps<Props>(), {
69
+ expanded: true,
70
+ closable: true,
71
+ });
72
+
73
+ defineEmits<Emits>();
74
+
75
+ const { openBlade } = useBladeNavigation();
76
+
77
+ const {
78
+ data,
79
+ loading,
80
+ totalCount,
81
+ currentPage,
82
+ searchQuery,
83
+ getItems,
84
+ } = use<%- ModuleNamePascalCase %>List();
85
+
86
+ const bladeToolbar = ref<IBladeToolbar[]>([
87
+ {
88
+ id: "refresh",
89
+ title: "Refresh",
90
+ icon: "lucide-refresh-cw",
91
+ clickHandler: () => getItems(),
92
+ },
93
+ {
94
+ id: "add",
95
+ title: "Add",
96
+ icon: "lucide-plus",
97
+ clickHandler: () => openDetails(),
98
+ },
99
+ ]);
100
+
101
+ function openDetails(item?: { id?: string }) {
102
+ openBlade({
103
+ blade: markRaw(Details),
104
+ param: item?.id,
105
+ onClose() {
106
+ getItems();
107
+ },
108
+ });
109
+ }
110
+
111
+ getItems();
112
+
113
+ defineExpose({
114
+ title: computed(() => "<%- ModuleNameSentenceCase %>"),
115
+ reload: getItems,
116
+ });
117
+ </script>