@vc-shell/create-vc-app 1.0.113 → 1.0.115

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 (110) hide show
  1. package/CHANGELOG.md +307 -5
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +100 -90
  5. package/dist/index.js.map +1 -0
  6. package/dist/templates/base/.env +4 -0
  7. package/dist/{template → templates}/base/.eslintrc.js +1 -2
  8. package/dist/templates/base/.yarn/plugins/@yarnpkg/plugin-version.cjs +550 -0
  9. package/dist/templates/base/.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs +28 -0
  10. package/dist/templates/base/.yarn/releases/yarn-3.6.4.cjs +874 -0
  11. package/dist/{template/base/index.html.ejs → templates/base/index.html} +1 -1
  12. package/dist/{template/base/package.json.ejs → templates/base/package.json} +7 -7
  13. package/dist/templates/base/public/assets/1.jpeg +0 -0
  14. package/dist/templates/base/public/assets/2.jpg +0 -0
  15. package/dist/templates/base/public/assets/3.jpg +0 -0
  16. package/dist/{template/code/commonPages → templates/base}/src/composables/useLogin/index.ts +1 -0
  17. package/dist/{template/base/src/router/index.ts.ejs → templates/base/src/router/index.ts} +4 -18
  18. package/dist/{template → templates}/base/tsconfig.json +1 -1
  19. package/dist/{template/base/vite.config.ts.ejs → templates/base/vite.config.ts} +5 -2
  20. package/dist/templates/variants/both/src/main.ts +45 -0
  21. package/dist/templates/variants/both/src/modules/classic-module/composables/index.ts +2 -0
  22. package/dist/templates/variants/both/src/modules/classic-module/composables/useDetails/index.ts +52 -0
  23. package/dist/templates/variants/both/src/modules/classic-module/composables/useList/index.ts +51 -0
  24. package/dist/{template/code/blade/src/modules/default/locales/en.json.ejs → templates/variants/both/src/modules/classic-module/locales/en.json} +6 -3
  25. package/dist/templates/variants/both/src/modules/classic-module/pages/details.vue +83 -0
  26. package/dist/templates/variants/both/src/modules/classic-module/pages/index.ts +2 -0
  27. package/dist/{template/code/blade/src/modules/default/pages/default-list.vue.ejs → templates/variants/both/src/modules/classic-module/pages/list.vue} +93 -30
  28. package/dist/templates/variants/both/src/modules/dynamic-module/components/DynamicItemsMobileGridView.vue +39 -0
  29. package/dist/templates/variants/both/src/modules/dynamic-module/components/index.ts +3 -0
  30. package/dist/templates/variants/both/src/modules/dynamic-module/composables/index.ts +2 -0
  31. package/dist/templates/variants/both/src/modules/dynamic-module/composables/useDetails/index.ts +92 -0
  32. package/dist/templates/variants/both/src/modules/dynamic-module/composables/useList/index.ts +70 -0
  33. package/dist/templates/variants/both/src/modules/dynamic-module/index.ts +9 -0
  34. package/dist/templates/variants/both/src/modules/dynamic-module/locales/en.json +46 -0
  35. package/dist/templates/variants/both/src/modules/dynamic-module/locales/index.ts +2 -0
  36. package/dist/templates/variants/both/src/modules/dynamic-module/pages/details.ts +40 -0
  37. package/dist/templates/variants/both/src/modules/dynamic-module/pages/index.ts +4 -0
  38. package/dist/templates/variants/both/src/modules/dynamic-module/pages/list.ts +50 -0
  39. package/dist/{template/base/src/pages/App.vue.ejs → templates/variants/both/src/pages/App.vue} +24 -28
  40. package/dist/{template/base/src/main.ts.ejs → templates/variants/classic/src/main.ts} +6 -12
  41. package/dist/templates/variants/classic/src/modules/classic-module/components/index.ts +1 -0
  42. package/dist/templates/variants/classic/src/modules/classic-module/composables/index.ts +2 -0
  43. package/dist/templates/variants/classic/src/modules/classic-module/composables/useDetails/index.ts +52 -0
  44. package/dist/templates/variants/classic/src/modules/classic-module/composables/useList/index.ts +51 -0
  45. package/dist/templates/variants/classic/src/modules/classic-module/index.ts +9 -0
  46. package/dist/templates/variants/classic/src/modules/classic-module/locales/en.json +43 -0
  47. package/dist/templates/variants/classic/src/modules/classic-module/locales/index.ts +2 -0
  48. package/dist/templates/variants/classic/src/modules/classic-module/pages/details.vue +83 -0
  49. package/dist/templates/variants/classic/src/modules/classic-module/pages/index.ts +2 -0
  50. package/dist/templates/variants/classic/src/modules/classic-module/pages/list.vue +260 -0
  51. package/dist/templates/variants/classic/src/pages/App.vue +362 -0
  52. package/dist/templates/variants/dynamic/src/main.ts +42 -0
  53. package/dist/templates/variants/dynamic/src/modules/dynamic-module/components/DynamicItemsMobileGridView.vue +39 -0
  54. package/dist/templates/variants/dynamic/src/modules/dynamic-module/components/index.ts +3 -0
  55. package/dist/templates/variants/dynamic/src/modules/dynamic-module/composables/index.ts +2 -0
  56. package/dist/templates/variants/dynamic/src/modules/dynamic-module/composables/useDetails/index.ts +92 -0
  57. package/dist/templates/variants/dynamic/src/modules/dynamic-module/composables/useList/index.ts +70 -0
  58. package/dist/templates/variants/dynamic/src/modules/dynamic-module/index.ts +9 -0
  59. package/dist/templates/variants/dynamic/src/modules/dynamic-module/locales/en.json +46 -0
  60. package/dist/templates/variants/dynamic/src/modules/dynamic-module/locales/index.ts +2 -0
  61. package/dist/templates/variants/dynamic/src/modules/dynamic-module/pages/details.ts +40 -0
  62. package/dist/templates/variants/dynamic/src/modules/dynamic-module/pages/index.ts +4 -0
  63. package/dist/templates/variants/dynamic/src/modules/dynamic-module/pages/list.ts +50 -0
  64. package/dist/templates/variants/dynamic/src/pages/App.vue +362 -0
  65. package/dist/tsconfig.tsbuildinfo +1 -1
  66. package/package.json +9 -8
  67. package/dist/template/base/.env.ejs +0 -6
  68. package/dist/template/code/blade/src/modules/default/composables/index.ts +0 -1
  69. package/dist/template/code/blade/src/modules/default/composables/useDefault/index.ts +0 -9
  70. package/dist/template/code/blade/src/modules/default/pages/index.ts +0 -1
  71. /package/dist/{template → templates}/base/.browserslistrc +0 -0
  72. /package/dist/{template → templates}/base/.commitlintrc.json +0 -0
  73. /package/dist/{template → templates}/base/.editorconfig +0 -0
  74. /package/dist/{template → templates}/base/.eslintignore +0 -0
  75. /package/dist/{template → templates}/base/.husky/commit-msg +0 -0
  76. /package/dist/{template → templates}/base/.husky/pre-commit +0 -0
  77. /package/dist/{template → templates}/base/.prettierignore +0 -0
  78. /package/dist/{template → templates}/base/.prettierrc +0 -0
  79. /package/dist/{template → templates}/base/.vscode/extensions.json +0 -0
  80. /package/dist/{template → templates}/base/.vscode/settings.json +0 -0
  81. /package/dist/{template → templates}/base/LICENSE +0 -0
  82. /package/dist/{template → templates}/base/README.md +0 -0
  83. /package/dist/{template → templates}/base/postcss.config.js +0 -0
  84. /package/dist/{template → templates}/base/public/assets/app-select.svg +0 -0
  85. /package/dist/{template → templates}/base/public/assets/avatar.jpg +0 -0
  86. /package/dist/{template → templates}/base/public/assets/background.jpg +0 -0
  87. /package/dist/{template → templates}/base/public/assets/empty.png +0 -0
  88. /package/dist/{template → templates}/base/public/assets/logo-white.svg +0 -0
  89. /package/dist/{template → templates}/base/public/assets/logo.svg +0 -0
  90. /package/dist/{template → templates}/base/public/img/icons/apple-touch-icon.png +0 -0
  91. /package/dist/{template → templates}/base/public/img/icons/favicon-16x16.png +0 -0
  92. /package/dist/{template → templates}/base/public/img/icons/favicon-32x32.png +0 -0
  93. /package/dist/{template → templates}/base/public/img/icons/favicon.ico +0 -0
  94. /package/dist/{template → templates}/base/public/img/icons/mstile-150x150.png +0 -0
  95. /package/dist/{template → templates}/base/public/img/icons/pwa-192x192.png +0 -0
  96. /package/dist/{template → templates}/base/public/img/icons/pwa-512x512.png +0 -0
  97. /package/dist/{template → templates}/base/public/img/icons/safari-pinned-tab.svg +0 -0
  98. /package/dist/{template → templates}/base/src/api_client/README.md +0 -0
  99. /package/dist/{template/code/commonPages → templates/base}/src/composables/index.ts +0 -0
  100. /package/dist/{template → templates}/base/src/env.d.ts +0 -0
  101. /package/dist/{template → templates}/base/src/locales/en.json +0 -0
  102. /package/dist/{template → templates}/base/src/locales/index.ts +0 -0
  103. /package/dist/{template/code/dashboard → templates/base}/src/pages/Dashboard.vue +0 -0
  104. /package/dist/{template → templates}/base/src/shims-vue.d.ts +0 -0
  105. /package/dist/{template → templates}/base/src/styles/index.scss +0 -0
  106. /package/dist/{template → templates}/base/src/types/index.ts +0 -0
  107. /package/dist/{template → templates}/base/tailwind.config.js +0 -0
  108. /package/dist/{template/code/blade/src/modules/default → templates/variants/both/src/modules/classic-module}/components/index.ts +0 -0
  109. /package/dist/{template/code/blade/src/modules/default → templates/variants/both/src/modules/classic-module}/index.ts +0 -0
  110. /package/dist/{template/code/blade/src/modules/default → templates/variants/both/src/modules/classic-module}/locales/index.ts +0 -0
@@ -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><%= appName %></title>
14
+ <title>App</title>
15
15
  </head>
16
16
 
17
17
  <body>
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "<%= appName %>",
2
+ "name": "app-boilerplate",
3
3
  "version": "0.0.0",
4
4
  "private": true,
5
5
  "scripts": {
@@ -24,7 +24,7 @@
24
24
  "@types/lodash-es": "^4.17.7",
25
25
  "@typescript-eslint/eslint-plugin": "^5.59.7",
26
26
  "@typescript-eslint/parser": "^5.59.7",
27
- "@vc-shell/api-client-generator": "^1.0.88",
27
+ "@vc-shell/api-client-generator": "*",
28
28
  "@vitejs/plugin-vue": "^4.2.3",
29
29
  "@vue/eslint-config-prettier": "^7.1.0",
30
30
  "@vue/eslint-config-typescript": "^11.0.3",
@@ -55,18 +55,18 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@fortawesome/fontawesome-free": "^5.15.3",
58
- "@vc-shell/config-generator": "^1.0.88",
59
- "@vc-shell/framework": "^1.0.88",
58
+ "@vc-shell/config-generator": "*",
59
+ "@vc-shell/framework": "*",
60
60
  "@vueuse/core": "^10.1.2",
61
61
  "@vueuse/integrations": "^10.1.2",
62
62
  "moment": "^2.29.4",
63
63
  "roboto-fontface": "^0.10.0",
64
64
  "vee-validate": "^4.9.4",
65
65
  "vue": "^3.3.7",
66
- "vue-router": "^4.2.7",
67
- "yarn": "^1.22.19"
66
+ "vue-router": "^4.2.5"
68
67
  },
69
68
  "lint-staged": {
70
69
  "*.{js,ts,vue}": "eslint --fix"
71
- }
70
+ },
71
+ "packageManager": "yarn@3.6.4"
72
72
  }
@@ -6,6 +6,7 @@ export default (): IUseLogin => {
6
6
  /**
7
7
  * @description Forgot password functionality
8
8
  */
9
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
9
10
  async function forgotPassword(args: { loginOrEmail: string }) {
10
11
  console.log("Forgot password click");
11
12
  }
@@ -1,26 +1,22 @@
1
1
  import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
2
- <% if(commonPages === true || bladeModuleStarter === true) { -%>
3
2
  import { inject } from "vue";
4
3
  import { useLogin } from "../composables";
5
- <% } -%>
6
4
  import {
7
5
  usePermissions,
8
6
  useUser,
9
7
  BladePageComponent,
10
8
  notification,
11
9
  useBladeNavigation,
12
- <% if(commonPages === true) { -%>
13
10
  Login,
14
11
  ResetPassword,
15
12
  Invite,
16
- <% } -%>} from "@vc-shell/framework";
13
+ } from "@vc-shell/framework";
17
14
 
18
15
  /**
19
16
  * Pages
20
17
  */
21
- <% if(dashboard === true) { -%>
22
18
  import Dashboard from "../pages/Dashboard.vue";
23
- <% } -%>
19
+ // eslint-disable-next-line import/no-unresolved
24
20
  import App from "./../pages/App.vue";
25
21
 
26
22
  // eslint-disable-next-line import/no-unresolved
@@ -37,17 +33,14 @@ const routes: RouteRecordRaw[] = [
37
33
  root: true,
38
34
  },
39
35
  children: [
40
- <% if(dashboard === true) { -%>
41
36
  {
42
37
  name: "Dashboard",
43
38
  path: "",
44
39
  alias: "/",
45
40
  component: Dashboard,
46
41
  },
47
- <% } -%>
48
42
  ],
49
43
  },
50
- <% if(commonPages === true) { -%>
51
44
  {
52
45
  path: "/login",
53
46
  name: "Login",
@@ -56,7 +49,7 @@ const routes: RouteRecordRaw[] = [
56
49
  composable: useLogin,
57
50
  logo: whiteLogoImage,
58
51
  background: bgImage,
59
- title: "<%= appName %>",
52
+ title: "application",
60
53
  }),
61
54
  },
62
55
  {
@@ -79,7 +72,6 @@ const routes: RouteRecordRaw[] = [
79
72
  userName: route.query.userName,
80
73
  }),
81
74
  },
82
- <% } -%>
83
75
  {
84
76
  path: "/:pathMatch(.*)*",
85
77
  component: App,
@@ -96,14 +88,12 @@ export const router = createRouter({
96
88
  routes,
97
89
  });
98
90
 
99
- <% if(commonPages === true || bladeModuleStarter === true) { -%>
100
91
  router.beforeEach(async (to, from) => {
101
92
  const { hasAccess } = usePermissions();
102
93
  const { resolveBlades } = useBladeNavigation();
103
94
  const { isAuthenticated } = useUser();
104
95
  const pages = inject<BladePageComponent[]>("pages");
105
96
 
106
- <% if(commonPages === true) { -%>
107
97
  if (to.name !== "Login" && to.name !== "ResetPassword" && to.name !== "Invite") {
108
98
  try {
109
99
  const component = pages.find((blade) => blade?.url === to.path);
@@ -115,7 +105,7 @@ router.beforeEach(async (to, from) => {
115
105
  } else if (_hasAccess && to.name !== "Login") {
116
106
  const resolvedBladeUrl = resolveBlades(to);
117
107
  return resolvedBladeUrl ? resolvedBladeUrl : true;
118
- } else if (!hasAccess) {
108
+ } else if (!_hasAccess) {
119
109
  notification.error("Access restricted", {
120
110
  timeout: 3000,
121
111
  });
@@ -125,8 +115,4 @@ router.beforeEach(async (to, from) => {
125
115
  return { name: "Login" };
126
116
  }
127
117
  } else return true;
128
- <% } else {-%>
129
- return resolvedBladeUrl ? resolvedBladeUrl : true;
130
- <% } -%>
131
118
  });
132
- <% } -%>
@@ -17,7 +17,7 @@
17
17
  "useDefineForClassFields": true,
18
18
  "outDir": "dist",
19
19
  "rootDir": "src",
20
- "strict": false,
20
+
21
21
  "lib": [
22
22
  "esnext",
23
23
  "dom"
@@ -9,7 +9,7 @@ export default getApplicationConfiguration({
9
9
  VitePWA({
10
10
  includeAssets: ["favicon.ico", "apple-touch-icon.png"],
11
11
  manifest: {
12
- name: "<%= appName %>",
12
+ name: "App",
13
13
  theme_color: "#319ED4",
14
14
  display: "fullscreen",
15
15
  start_url: "/index.html",
@@ -42,6 +42,9 @@ export default getApplicationConfiguration({
42
42
  splitVendorChunkPlugin(),
43
43
  ],
44
44
  optimizeDeps: {
45
- include: mode === "development" ? ["ace-builds", "client-oauth2", "quill-delta", "quill", "url-pattern", "vee-validate"] : [],
45
+ include:
46
+ mode === "development"
47
+ ? ["ace-builds", "client-oauth2", "quill-delta", "quill", "url-pattern", "vee-validate"]
48
+ : [],
46
49
  },
47
50
  });
@@ -0,0 +1,45 @@
1
+ import VirtoShellFramework, { notification, useUser } from "@vc-shell/framework";
2
+ import { createApp } from "vue";
3
+ import { router } from "./router";
4
+ import * as locales from "./locales";
5
+ import { RouterView } from "vue-router";
6
+ import ClassicModule from "./modules/classic-module";
7
+ import DynamicModule from "./modules/dynamic-module";
8
+
9
+ // Load required CSS
10
+ import "./styles/index.scss";
11
+ import "@fortawesome/fontawesome-free/css/all.min.css";
12
+ import "roboto-fontface/css/roboto/roboto-fontface.css";
13
+ import "@vc-shell/framework/dist/index.css";
14
+
15
+ async function startApp() {
16
+ const { loadUser } = useUser();
17
+
18
+ await loadUser();
19
+
20
+ const app = createApp(RouterView)
21
+ .use(VirtoShellFramework)
22
+ // Classic module based on composables, pages and components
23
+ .use(ClassicModule, { router })
24
+ // Dynamic module based on page schemas
25
+ .use(DynamicModule, { router })
26
+ .use(router);
27
+
28
+ Object.entries(locales).forEach(([key, message]) => {
29
+ app.config.globalProperties.$mergeLocaleMessage(key, message);
30
+ });
31
+
32
+ app.provide("platformUrl", import.meta.env.APP_PLATFORM_URL);
33
+
34
+ app.config.errorHandler = (err) => {
35
+ notification.error(err.toString(), {
36
+ timeout: 5000,
37
+ });
38
+ };
39
+
40
+ await router.isReady();
41
+
42
+ app.mount("#app");
43
+ }
44
+
45
+ startApp();
@@ -0,0 +1,2 @@
1
+ export { default as useList } from "./useList";
2
+ export { default as useDetails } from "./useDetails";
@@ -0,0 +1,52 @@
1
+ /* eslint-disable import/no-unresolved */
2
+ import { computed, ref } from "vue";
3
+ import img1 from "/assets/1.jpeg";
4
+ import img2 from "/assets/2.jpg";
5
+ import img3 from "/assets/3.jpg";
6
+ import { useAsync, useLoading } from "@vc-shell/framework";
7
+
8
+ export default () => {
9
+ const item = ref({
10
+ imgSrc: undefined,
11
+ name: undefined,
12
+ createdDate: undefined,
13
+ id: undefined,
14
+ });
15
+
16
+ // Example mocked method for 'fetching' list data
17
+ const { loading: itemLoading, action: getItem } = useAsync<{ id: string }>(async (payload) => {
18
+ item.value = await new Promise((resolve) => {
19
+ setTimeout(() => {
20
+ const findMockedItem = [
21
+ {
22
+ imgSrc: img1,
23
+ name: "Item 1",
24
+ createdDate: new Date(),
25
+ id: "item-id-1",
26
+ },
27
+ {
28
+ imgSrc: img2,
29
+ name: "Item 2",
30
+ createdDate: new Date(),
31
+ id: "item-id-2",
32
+ },
33
+ {
34
+ imgSrc: img3,
35
+ name: "Item 3",
36
+ createdDate: new Date(),
37
+ id: "item-id-3",
38
+ },
39
+ ].find((x) => x.id === payload.id);
40
+ resolve(findMockedItem);
41
+ }, 1000);
42
+ });
43
+ });
44
+
45
+ const loading = useLoading(itemLoading);
46
+
47
+ return {
48
+ item: computed(() => item.value),
49
+ loading: computed(() => loading.value),
50
+ getItem,
51
+ };
52
+ };
@@ -0,0 +1,51 @@
1
+ /* eslint-disable import/no-unresolved */
2
+ import { computed, ref } from "vue";
3
+ import img1 from "/assets/1.jpeg";
4
+ import img2 from "/assets/2.jpg";
5
+ import img3 from "/assets/3.jpg";
6
+ import { useAsync, useLoading } from "@vc-shell/framework";
7
+
8
+ export default () => {
9
+ const data = ref([]);
10
+
11
+ // Example mocked method for 'fetching' list data
12
+ const { loading: itemLoading, action: getItems } = useAsync(async (payload) => {
13
+ data.value = await new Promise((resolve) => {
14
+ setTimeout(
15
+ () =>
16
+ resolve([
17
+ {
18
+ imgSrc: img1,
19
+ name: "Item 1",
20
+ createdDate: new Date(),
21
+ id: "item-id-1",
22
+ },
23
+ {
24
+ imgSrc: img2,
25
+ name: "Item 2",
26
+ createdDate: new Date(),
27
+ id: "item-id-2",
28
+ },
29
+ {
30
+ imgSrc: img3,
31
+ name: "Item 3",
32
+ createdDate: new Date(),
33
+ id: "item-id-3",
34
+ },
35
+ ]),
36
+ 1000
37
+ );
38
+ });
39
+ });
40
+
41
+ const loading = useLoading(itemLoading);
42
+
43
+ return {
44
+ data: computed(() => data.value),
45
+ loading: computed(() => loading.value),
46
+ totalCount: computed(() => data.value.length),
47
+ pages: computed(() => Math.ceil(data.value.length / 20)),
48
+ currentPage: 0 / Math.max(1, 20) + 1,
49
+ getItems,
50
+ };
51
+ };
@@ -1,11 +1,11 @@
1
1
  {
2
- "<%= bladeModuleName.toUpperCase() %>": {
2
+ "MODULE": {
3
3
  "MENU": {
4
- "TITLE": "<%= bladeModuleName %>"
4
+ "TITLE": "Classic Module"
5
5
  },
6
6
  "PAGES": {
7
7
  "LIST": {
8
- "TITLE": "<%= bladeModuleName %> blade",
8
+ "TITLE": "Module blade",
9
9
  "TOOLBAR": {
10
10
  "REFRESH": "Refresh",
11
11
  "ADD": "Add",
@@ -33,6 +33,9 @@
33
33
  "UNPUBLISH": "Unpublish",
34
34
  "PUBLISH": "Publish"
35
35
  }
36
+ },
37
+ "MOBILE": {
38
+ "CREATED": "Created"
36
39
  }
37
40
  }
38
41
  }
@@ -0,0 +1,83 @@
1
+ <template>
2
+ <VcBlade
3
+ v-loading="loading"
4
+ :title="item.name"
5
+ :expanded="expanded"
6
+ :closable="closable"
7
+ width="70%"
8
+ :toolbar-items="bladeToolbar"
9
+ @close="$emit('close:blade')"
10
+ @expand="$emit('expand:blade')"
11
+ @collapse="$emit('collapse:blade')"
12
+ >
13
+ <VcContainer class="tw-p-2">
14
+ <VcForm>
15
+ <VcInput
16
+ :model-value="item.name"
17
+ label="Name"
18
+ class="tw-mb-4"
19
+ ></VcInput>
20
+ <VcInput
21
+ :model-value="item.createdDate"
22
+ label="Date"
23
+ type="datetime-local"
24
+ ></VcInput>
25
+ </VcForm>
26
+ </VcContainer>
27
+ </VcBlade>
28
+ </template>
29
+
30
+ <script lang="ts" setup>
31
+ import { IBladeToolbar, IParentCallArgs } from "@vc-shell/framework";
32
+ import { useDetails } from "./../composables";
33
+ import { computed, onMounted, ref } from "vue";
34
+ import { useI18n } from "vue-i18n";
35
+
36
+ export interface Props {
37
+ expanded?: boolean;
38
+ closable?: boolean;
39
+ param?: string;
40
+ }
41
+
42
+ export interface Emits {
43
+ (event: "parent:call", args: IParentCallArgs): void;
44
+ (event: "collapse:blade"): void;
45
+ (event: "expand:blade"): void;
46
+ (event: "close:blade"): void;
47
+ }
48
+
49
+ defineOptions({
50
+ url: "/classic-module-details",
51
+ });
52
+
53
+ const props = withDefaults(defineProps<Props>(), {
54
+ expanded: true,
55
+ closable: true,
56
+ param: undefined,
57
+ });
58
+
59
+ const emit = defineEmits<Emits>();
60
+
61
+ const { t } = useI18n({ useScope: "global" });
62
+
63
+ const { item, loading, getItem } = useDetails();
64
+
65
+ const bladeToolbar = ref<IBladeToolbar[]>([
66
+ {
67
+ id: "refresh",
68
+ title: computed(() => t("MODULE.PAGES.LIST.TOOLBAR.REFRESH")),
69
+ icon: "fas fa-sync-alt",
70
+ async clickHandler() {
71
+ await getItem({ id: props.param });
72
+ },
73
+ },
74
+ ]);
75
+
76
+ onMounted(async () => {
77
+ if (props.param) {
78
+ await getItem({ id: props.param });
79
+ }
80
+ });
81
+ </script>
82
+
83
+ <style lang="scss" scoped></style>
@@ -0,0 +1,2 @@
1
+ export { default as List } from "./list.vue";
2
+ export {default as Details } from './details.vue'
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <VcBlade
3
- :title="$t('<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TITLE')"
3
+ :title="$t('MODULE.PAGES.LIST.TITLE')"
4
4
  width="50%"
5
5
  :expanded="expanded"
6
6
  :closable="closable"
@@ -16,35 +16,65 @@
16
16
  :notfound="notfound"
17
17
  class="tw-grow tw-basis-0"
18
18
  :multiselect="true"
19
+ :loading="loading"
19
20
  :columns="columns"
20
21
  :item-action-builder="actionBuilder"
21
22
  :sort="sort"
23
+ :pages="pages"
24
+ :total-count="totalCount"
22
25
  :search-value="searchValue"
23
- :search-placeholder="$t('<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.SEARCH.PLACEHOLDER')"
24
- :total-label="$t('<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.TOTALS')"
26
+ :current-page="currentPage"
27
+ :search-placeholder="$t('MODULE.PAGES.LIST.SEARCH.PLACEHOLDER')"
28
+ :total-label="$t('MODULE.PAGES.LIST.TABLE.TOTALS')"
25
29
  :selected-item-id="selectedItemId"
26
- state-key="<%= bladeModuleName.toLowerCase() %>"
30
+ state-key="module"
31
+ :items="data"
27
32
  @item-click="onItemClick"
28
33
  @header-click="onHeaderClick"
29
34
  >
35
+ <template #mobile-item="itemData">
36
+ <div class="tw-border-b tw-border-solid tw-border-b-[#e3e7ec] tw-py-3 tw-px-4">
37
+ <div class="tw-w-full tw-flex tw-justify-evenly tw-mb-2">
38
+ <VcImage
39
+ class="tw-shrink-0"
40
+ aspect="1x1"
41
+ size="s"
42
+ :bordered="true"
43
+ :src="itemData.item.imgSrc"
44
+ ></VcImage>
45
+ <div class="tw-grow tw-basis-0 tw-ml-3">
46
+ <div class="tw-font-bold tw-text-lg">
47
+ {{ itemData.item.name }}
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <div class="tw-truncate tw-grow-[2] tw-basis-0">
52
+ <VcHint>{{ $t("MODULE.PAGES.LIST.MOBILE.CREATED") }}</VcHint>
53
+ <div class="tw-truncate tw-mt-1">
54
+ {{ itemData.item.createdDate }}
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </template>
30
59
  </VcTable>
31
60
  </VcBlade>
32
61
  </template>
33
62
 
34
63
  <script lang="ts" setup>
35
- import { computed, inject, reactive, ref, markRaw } from "vue";
64
+ import { computed, inject, reactive, ref, markRaw, onMounted, watch } from "vue";
36
65
  import {
37
66
  IBladeEvent,
38
67
  IBladeToolbar,
39
68
  IParentCallArgs,
40
- useFunctions,
41
69
  IActionBuilderResult,
42
70
  ITableColumns,
71
+ useBladeNavigation,
43
72
  } from "@vc-shell/framework";
44
- import moment from "moment";
45
73
  // eslint-disable-next-line import/no-unresolved
46
74
  import emptyImage from "/assets/empty.png";
47
75
  import { useI18n } from "vue-i18n";
76
+ import { useList } from "./../composables";
77
+ import Details from "./details.vue";
48
78
 
49
79
  export interface Props {
50
80
  expanded?: boolean;
@@ -62,37 +92,64 @@ export interface Emits {
62
92
  }
63
93
 
64
94
  defineOptions({
65
- url: "/<%= bladeModuleName.toLowerCase() %>",
66
- })
95
+ url: "/classic-module-list",
96
+ });
67
97
 
68
98
  const props = withDefaults(defineProps<Props>(), {
69
99
  expanded: true,
70
100
  closable: true,
71
101
  });
72
102
 
73
- const emit = defineEmits<Emits>();
103
+ defineEmits<Emits>();
74
104
 
75
105
  const { t } = useI18n({ useScope: "global" });
76
- const { debounce } = useFunctions();
106
+ const { openBlade } = useBladeNavigation();
107
+ const { getItems, data, loading, totalCount, pages, currentPage } = useList();
77
108
 
78
109
  const sort = ref("createdDate:DESC");
79
110
  const searchValue = ref();
80
111
  const selectedItemId = ref<string>();
81
- const isDesktop = inject("isDesktop");
112
+
113
+ watch(
114
+ () => props.param,
115
+ (newVal) => {
116
+ if (newVal) {
117
+ selectedItemId.value = newVal;
118
+
119
+ openBlade({
120
+ blade: markRaw(Details),
121
+ param: newVal,
122
+ onOpen() {
123
+ selectedItemId.value = newVal;
124
+ },
125
+ onClose() {
126
+ selectedItemId.value = undefined;
127
+ },
128
+ });
129
+ }
130
+ },
131
+ { immediate: true }
132
+ );
133
+
134
+ onMounted(async () => {
135
+ await getItems();
136
+ });
82
137
 
83
138
  const bladeToolbar = ref<IBladeToolbar[]>([
84
139
  {
85
140
  id: "refresh",
86
- title: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TOOLBAR.REFRESH")),
141
+ title: computed(() => t("MODULE.PAGES.LIST.TOOLBAR.REFRESH")),
87
142
  icon: "fas fa-sync-alt",
88
- // async clickHandler() {},
143
+ async clickHandler() {
144
+ await reload();
145
+ },
89
146
  },
90
147
  ]);
91
148
 
92
149
  const tableColumns = ref<ITableColumns[]>([
93
150
  {
94
151
  id: "imgSrc",
95
- title: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.HEADER.PRODUCT_IMAGE")),
152
+ title: computed(() => t("MODULE.PAGES.LIST.TABLE.HEADER.PRODUCT_IMAGE")),
96
153
  width: 60,
97
154
  alwaysVisible: true,
98
155
  type: "image",
@@ -100,30 +157,28 @@ const tableColumns = ref<ITableColumns[]>([
100
157
  {
101
158
  id: "name",
102
159
  field: "name",
103
- title: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.HEADER.PRODUCT_NAME")),
104
- sortable: true,
160
+ title: computed(() => t("MODULE.PAGES.LIST.TABLE.HEADER.PRODUCT_NAME")),
105
161
  alwaysVisible: true,
106
162
  },
107
163
  {
108
164
  id: "createdDate",
109
- title: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.HEADER.CREATED_DATE")),
165
+ title: computed(() => t("MODULE.PAGES.LIST.TABLE.HEADER.CREATED_DATE")),
110
166
  width: 140,
111
- sortable: true,
112
167
  type: "date-ago",
113
168
  },
114
169
  ]);
115
170
 
116
171
  const empty = reactive({
117
172
  image: emptyImage,
118
- text: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.EMPTY.TITLE")),
119
- action: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.EMPTY.ACTION")),
173
+ text: computed(() => t("MODULE.PAGES.LIST.TABLE.EMPTY.TITLE")),
174
+ action: computed(() => t("MODULE.PAGES.LIST.TABLE.EMPTY.ACTION")),
120
175
  // clickHandler: () => {},
121
176
  });
122
177
 
123
178
  const notfound = reactive({
124
179
  image: emptyImage,
125
- text: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.NOT_FOUND.TITLE")),
126
- action: computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TABLE.NOT_FOUND.ACTION")),
180
+ text: computed(() => t("MODULE.PAGES.LIST.TABLE.NOT_FOUND.TITLE")),
181
+ action: computed(() => t("MODULE.PAGES.LIST.TABLE.NOT_FOUND.ACTION")),
127
182
  clickHandler: async () => {
128
183
  searchValue.value = "";
129
184
  },
@@ -137,15 +192,23 @@ const columns = computed(() => {
137
192
  }
138
193
  });
139
194
 
140
- const title = computed(() => t("<%= bladeModuleName.toUpperCase() %>.PAGES.LIST.TITLE"));
195
+ const title = computed(() => t("MODULE.PAGES.LIST.TITLE"));
196
+
197
+ const reload = async () => {
198
+ await getItems();
199
+ };
141
200
 
142
201
  const onItemClick = (item: { id: string }) => {
143
- // openBlade({
144
- // blade: markRaw(),
145
- // param: item.id,
146
- // onOpen() {},
147
- // onClose() {},
148
- // });
202
+ openBlade({
203
+ blade: markRaw(Details),
204
+ param: item.id,
205
+ onOpen() {
206
+ selectedItemId.value = item.id;
207
+ },
208
+ onClose() {
209
+ selectedItemId.value = undefined;
210
+ },
211
+ });
149
212
  };
150
213
 
151
214
  const onHeaderClick = (item: ITableColumns) => {