@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
@@ -0,0 +1,362 @@
1
+ <template>
2
+ <VcLoading
3
+ v-if="!isReady"
4
+ active
5
+ class="app__loader"
6
+ />
7
+ <VcApp
8
+ v-else
9
+ :menu-items="menuItems"
10
+ :mobile-menu-items="mobileMenuItems"
11
+ :toolbar-items="toolbarItems"
12
+ :is-ready="isReady"
13
+ :is-authorized="isAuthorized"
14
+ :logo="uiSettings.logo"
15
+ :title="uiSettings.title"
16
+ :version="version"
17
+ :pages="pages"
18
+ :blades-refs="bladesRefs"
19
+ @backlink:click="closeBlade($event)"
20
+ @close="closeBlade($event)"
21
+ @logo:click="openDashboard"
22
+ >
23
+ <!-- App Switcher -->
24
+ <template
25
+ v-if="appsList && appsList.length"
26
+ #appSwitcher
27
+ >
28
+ <VcAppSwitcher
29
+ :apps-list="appsList"
30
+ @on-click="switchApp($event)"
31
+ />
32
+ </template>
33
+
34
+ <template
35
+ v-if="isAuthorized"
36
+ #bladeNavigation
37
+ >
38
+ <VcBladeNavigation
39
+ ref="bladeNavigationRefs"
40
+ :blades="blades"
41
+ :workspace-options="workspaceOptions"
42
+ :workspace-param="workspaceParam"
43
+ @on-close="closeBlade($event)"
44
+ @on-parent-call="(e) => onParentCall(e.id, e.args)"
45
+ @vue:mounted="resolveLastBlade(pages)"
46
+ ></VcBladeNavigation>
47
+ </template>
48
+
49
+ <template #modals>
50
+ <VcPopupContainer />
51
+ </template>
52
+ </VcApp>
53
+ </template>
54
+
55
+ <script lang="ts" setup>
56
+ import {
57
+ useAppSwitcher,
58
+ useNotifications,
59
+ useSettings,
60
+ useUser,
61
+ useBladeNavigation,
62
+ VcNotificationDropdown,
63
+ usePopup,
64
+ useMenuComposer,
65
+ ChangePassword,
66
+ LanguageSelector,
67
+ UserDropdownButton,
68
+ BladePageComponent,
69
+ } from "@vc-shell/framework";
70
+ import { computed, inject, onMounted, reactive, ref, Ref, markRaw, watch, defineComponent, provide } from "vue";
71
+ import { useRoute, useRouter } from "vue-router";
72
+ // eslint-disable-next-line import/no-unresolved
73
+ import avatarImage from "/assets/avatar.jpg";
74
+ // eslint-disable-next-line import/no-unresolved
75
+ import logoImage from "/assets/logo.svg";
76
+ import { useI18n } from "vue-i18n";
77
+ import { List } from "./../modules/classic-module";
78
+
79
+ const { open } = usePopup({
80
+ component: ChangePassword,
81
+ });
82
+
83
+ const { t, locale: currentLocale, availableLocales, getLocaleMessage } = useI18n({ useScope: "global" });
84
+ const { user, signOut } = useUser();
85
+ const { getUiCustomizationSettings, uiSettings, applySettings } = useSettings();
86
+ const {
87
+ blades,
88
+ bladesRefs,
89
+ workspaceOptions,
90
+ workspaceParam,
91
+ closeBlade,
92
+ onParentCall,
93
+ resolveLastBlade,
94
+ } = useBladeNavigation();
95
+ const { navigationMenuComposer, toolbarComposer } = useMenuComposer();
96
+ const { appsList, switchApp, getApps } = useAppSwitcher();
97
+
98
+ const { notifications, loadFromHistory, markAllAsRead } = useNotifications();
99
+ const route = useRoute();
100
+ const router = useRouter();
101
+ const isAuthorized = ref(true);
102
+ const isReady = ref(false);
103
+ const pages = inject<BladePageComponent[]>("pages");
104
+ const isDesktop = inject<Ref<boolean>>("isDesktop");
105
+ const isMobile = inject<Ref<boolean>>("isMobile");
106
+ const version = import.meta.env.PACKAGE_VERSION;
107
+ const bladeNavigationRefs = ref();
108
+ const internalRoutes = inject("bladeRoutes");
109
+ provide("internalRoutes", internalRoutes);
110
+
111
+ onMounted(async () => {
112
+ try {
113
+ await getApps();
114
+ langInit();
115
+ await customizationHandler();
116
+ await loadFromHistory();
117
+
118
+ isReady.value = true;
119
+ } catch (e) {
120
+ console.log(e);
121
+ throw e;
122
+ }
123
+ });
124
+
125
+ watch(
126
+ () => bladeNavigationRefs.value?.bladesRefs,
127
+ (newVal) => {
128
+ bladesRefs.value = newVal;
129
+ },
130
+ { deep: true }
131
+ );
132
+
133
+ console.debug(`Initializing App`);
134
+
135
+ const toolbarItems = computed(() =>
136
+ toolbarComposer([
137
+ {
138
+ component: markRaw(LanguageSelector),
139
+ options: {
140
+ value: currentLocale.value as string,
141
+ title: t("SHELL.TOOLBAR.LANGUAGE"),
142
+ languageItems: availableLocales.map((locale: string) => ({
143
+ lang: locale,
144
+ title: (getLocaleMessage(locale) as { language_name: string }).language_name,
145
+ clickHandler(lang: string) {
146
+ currentLocale.value = lang;
147
+ localStorage.setItem("VC_LANGUAGE_SETTINGS", lang);
148
+ },
149
+ })),
150
+ },
151
+ isVisible: isDesktop.value ? isDesktop.value : isMobile.value ? route.path === "/" : false,
152
+ },
153
+ {
154
+ isAccent: notifications.value.some((item) => item.isNew),
155
+ component: markRaw(VcNotificationDropdown),
156
+ options: {
157
+ title: t("SHELL.TOOLBAR.NOTIFICATIONS"),
158
+ notifications: notifications.value,
159
+ onOpen() {
160
+ if (notifications.value.some((x) => x.isNew)) {
161
+ markAllAsRead();
162
+ }
163
+ },
164
+ },
165
+ },
166
+ {
167
+ component: markRaw(UserDropdownButton),
168
+ options: {
169
+ avatar: avatarImage,
170
+ name: user.value?.userName,
171
+ role: user.value?.isAdministrator ? "Administrator" : "Seller account",
172
+ menuItems: [
173
+ {
174
+ title: t("SHELL.ACCOUNT.CHANGE_PASSWORD"),
175
+ clickHandler() {
176
+ open();
177
+ },
178
+ },
179
+ {
180
+ title: t("SHELL.ACCOUNT.LOGOUT"),
181
+ async clickHandler() {
182
+ const isPrevented = await closeBlade(0);
183
+ if (!isPrevented) {
184
+ signOut();
185
+ router.push({ name: "Login" });
186
+ }
187
+ },
188
+ },
189
+ ],
190
+ },
191
+ isVisible: isDesktop.value,
192
+ },
193
+ ])
194
+ );
195
+
196
+ const mobileMenuItems = computed(() =>
197
+ toolbarComposer([
198
+ {
199
+ component: markRaw(UserDropdownButton),
200
+ options: {
201
+ avatar: avatarImage,
202
+ name: user.value?.userName,
203
+ role: user.value?.isAdministrator ? "Administrator" : "Seller account",
204
+ },
205
+ isVisible: isMobile.value,
206
+ },
207
+ ])
208
+ );
209
+
210
+ const menuItems = reactive(
211
+ navigationMenuComposer([
212
+ {
213
+ title: computed(() => t("SHELL.MENU.DASHBOARD")),
214
+ icon: "fas fa-home",
215
+ isVisible: true,
216
+ component: defineComponent({
217
+ url: "/",
218
+ }),
219
+ clickHandler() {
220
+ openDashboard();
221
+ },
222
+ },
223
+ {
224
+ title: computed(() => t("SHELL.ACCOUNT.CHANGE_PASSWORD")),
225
+ icon: "fas fa-key",
226
+ isVisible: isMobile.value,
227
+ clickHandler() {
228
+ open();
229
+ },
230
+ },
231
+ {
232
+ title: computed(() => t("MODULE.MENU.TITLE")),
233
+ icon: "fas fa-file-alt",
234
+ isVisible: true,
235
+ component: markRaw(List),
236
+ },
237
+ {
238
+ title: computed(() => t("SHELL.ACCOUNT.LOGOUT")),
239
+ icon: "fas fa-sign-out-alt",
240
+ isVisible: isMobile,
241
+ async clickHandler() {
242
+ const isPrevented = await closeBlade(0);
243
+ if (!isPrevented) {
244
+ signOut();
245
+ router.push({ name: "Login" });
246
+ }
247
+ },
248
+ },
249
+ ])
250
+ );
251
+
252
+ function langInit() {
253
+ const lang = localStorage.getItem("VC_LANGUAGE_SETTINGS");
254
+
255
+ if (lang) {
256
+ currentLocale.value = lang;
257
+ } else {
258
+ currentLocale.value = "en";
259
+ }
260
+ }
261
+ const openDashboard = async () => {
262
+ console.debug(`openDashboard() called.`);
263
+
264
+ // Close all opened pages with onBeforeClose callback
265
+ const isPrevented = await closeBlade(0);
266
+
267
+ !isPrevented && router.push("/");
268
+ };
269
+
270
+ async function customizationHandler() {
271
+ await getUiCustomizationSettings();
272
+
273
+ if (!uiSettings.value.logo) {
274
+ applySettings({ logo: logoImage });
275
+ }
276
+ if (!uiSettings.value.title) {
277
+ applySettings({ title: undefined });
278
+ }
279
+ }
280
+ </script>
281
+
282
+ <style lang="scss">
283
+ .vc-theme_light {
284
+ --background-color: #f5f6f9;
285
+ --top-bar-color: #161d25;
286
+ --basic-black-color: #333333;
287
+ --tooltips-color: #a5a5a5;
288
+
289
+ --primary-color: #43b0e6;
290
+ --primary-color-hover: #319ed4;
291
+ --primary-color-disabled: #a9ddf6;
292
+
293
+ --special-color: #f89406;
294
+ --special-color-hover: #eb8b03;
295
+ --special-color-disabled: #fed498;
296
+
297
+ /* Layout variables */
298
+ --app-bar-height: 60px;
299
+ --app-bar-background-color: var(--top-bar-color);
300
+ --app-bar-toolbar-icon-background-hover: #2e3d4e;
301
+ --app-bar-toolbar-item-width: 50px;
302
+ --app-bar-divider-color: #2e3d4e;
303
+ --app-bar-toolbar-icon-color: #7e8e9d;
304
+ --app-bar-account-info-role-color: #838d9a;
305
+ }
306
+
307
+ html,
308
+ body,
309
+ #app {
310
+ @apply tw-font-roboto tw-h-full tw-w-full tw-m-0 tw-fixed tw-overflow-hidden tw-overscroll-y-none;
311
+ }
312
+
313
+ body {
314
+ @apply tw-text-base;
315
+ }
316
+
317
+ h1,
318
+ h2,
319
+ h3,
320
+ h4,
321
+ h5,
322
+ h6,
323
+ button,
324
+ input,
325
+ select,
326
+ textarea {
327
+ @apply tw-font-roboto;
328
+ }
329
+ ::-webkit-input-placeholder {
330
+ @apply tw-font-roboto;
331
+ }
332
+ :-moz-placeholder {
333
+ @apply tw-font-roboto;
334
+ }
335
+ ::-moz-placeholder {
336
+ @apply tw-font-roboto;
337
+ }
338
+ :-ms-input-placeholder {
339
+ @apply tw-font-roboto;
340
+ }
341
+
342
+ .vc-app.vc-theme_light {
343
+ --background-color: #f2f2f2;
344
+ --top-bar-color: #ffffff;
345
+ --app-background: linear-gradient(180deg, #e4f5fb 5.06%, #e8f3f2 100%), linear-gradient(0deg, #e8f2f3, #e8f2f3),
346
+ #eef2f8;
347
+ --app-bar-background-color: #ffffff;
348
+ --app-bar-divider-color: #ffffff;
349
+ --app-bar-toolbar-item-width: 50px;
350
+ --app-bar-toolbar-icon-color: #7e8e9d;
351
+ --app-bar-toolbar-icon-color-hover: #465769;
352
+ --app-bar-toolbar-icon-background-hover: #ffffff;
353
+ --app-bar-account-info-name-color: #161d25;
354
+ --app-bar-account-info-role-color: #7e8e9d;
355
+ }
356
+
357
+ .app {
358
+ &__loader {
359
+ background: var(--app-background);
360
+ }
361
+ }
362
+ </style>
@@ -0,0 +1,42 @@
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 DynamicModule from "./modules/dynamic-module";
7
+
8
+ // Load required CSS
9
+ import "./styles/index.scss";
10
+ import "@fortawesome/fontawesome-free/css/all.min.css";
11
+ import "roboto-fontface/css/roboto/roboto-fontface.css";
12
+ import "@vc-shell/framework/dist/index.css";
13
+
14
+ async function startApp() {
15
+ const { loadUser } = useUser();
16
+
17
+ await loadUser();
18
+
19
+ const app = createApp(RouterView)
20
+ .use(VirtoShellFramework)
21
+ // Dynamic module based on page schemas
22
+ .use(DynamicModule, { router })
23
+ .use(router);
24
+
25
+ Object.entries(locales).forEach(([key, message]) => {
26
+ app.config.globalProperties.$mergeLocaleMessage(key, message);
27
+ });
28
+
29
+ app.provide("platformUrl", import.meta.env.APP_PLATFORM_URL);
30
+
31
+ app.config.errorHandler = (err) => {
32
+ notification.error(err.toString(), {
33
+ timeout: 5000,
34
+ });
35
+ };
36
+
37
+ await router.isReady();
38
+
39
+ app.mount("#app");
40
+ }
41
+
42
+ startApp();
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <div class="tw-border-b tw-border-solid tw-border-b-[#e3e7ec] tw-py-3 tw-px-4">
3
+ <div class="tw-w-full tw-flex tw-justify-evenly tw-mb-2">
4
+ <VcImage
5
+ class="tw-shrink-0"
6
+ aspect="1x1"
7
+ size="s"
8
+ :bordered="true"
9
+ :src="context.item.imgSrc"
10
+ ></VcImage>
11
+ <div class="tw-grow tw-basis-0 tw-ml-3">
12
+ <div class="tw-font-bold tw-text-lg">
13
+ {{ context.item.name }}
14
+ </div>
15
+ </div>
16
+ </div>
17
+ <div class="tw-truncate tw-grow-[2] tw-basis-0">
18
+ <VcHint>{{ $t("DYNAMICMODULE.PAGES.LIST.MOBILE.CREATED") }}</VcHint>
19
+ <div class="tw-truncate tw-mt-1">
20
+ {{ context.item.createdDate }}
21
+ </div>
22
+ </div>
23
+ </div>
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ export interface Props {
28
+ context: {
29
+ item: {
30
+ imgSrc: string;
31
+ name: string;
32
+ createdDate: Date;
33
+ id: string;
34
+ };
35
+ };
36
+ }
37
+
38
+ defineProps<Props>();
39
+ </script>
@@ -0,0 +1,3 @@
1
+ import DynamicItemsMobileGridView from "./DynamicItemsMobileGridView.vue";
2
+
3
+ export { DynamicItemsMobileGridView };
@@ -0,0 +1,2 @@
1
+ export { default as useList } from "./useList";
2
+ export { default as useDetails } from "./useDetails";
@@ -0,0 +1,92 @@
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 {
7
+ DetailsBaseBladeScope,
8
+ DynamicBladeForm,
9
+ IBladeToolbar,
10
+ useDetailsFactory,
11
+ } from "@vc-shell/framework";
12
+
13
+ export interface DynamicItemScope extends DetailsBaseBladeScope {
14
+ toolbarOverrides: {
15
+ refresh: IBladeToolbar;
16
+ };
17
+ }
18
+
19
+ export default (args: {
20
+ props: InstanceType<typeof DynamicBladeForm>["$props"];
21
+ emit: InstanceType<typeof DynamicBladeForm>["$emit"];
22
+ }) => {
23
+ const factory = useDetailsFactory<{ imgSrc: string; name: string; createdDate: Date; id: string }>({
24
+ load: async (payload) => {
25
+ return await new Promise((resolve) => {
26
+ setTimeout(() => {
27
+ const findMockedItem = [
28
+ {
29
+ imgSrc: img1,
30
+ name: "Item 1",
31
+ createdDate: new Date(),
32
+ id: "item-id-1",
33
+ },
34
+ {
35
+ imgSrc: img2,
36
+ name: "Item 2",
37
+ createdDate: new Date(),
38
+ id: "item-id-2",
39
+ },
40
+ {
41
+ imgSrc: img3,
42
+ name: "Item 3",
43
+ createdDate: new Date(),
44
+ id: "item-id-3",
45
+ },
46
+ ].find((x) => x.id === payload.id);
47
+ resolve(findMockedItem);
48
+ }, 1000);
49
+ });
50
+ },
51
+ saveChanges: () => {
52
+ throw new Error("Function not implemented.");
53
+ },
54
+ remove: () => {
55
+ throw new Error("Function not implemented.");
56
+ },
57
+ });
58
+
59
+ const { load, saveChanges, remove, loading, item, validationState } = factory();
60
+
61
+ // const item = ref({
62
+ // imgSrc: undefined,
63
+ // name: undefined,
64
+ // createdDate: undefined,
65
+ // id: undefined,
66
+ // });
67
+
68
+ const scope = ref<DynamicItemScope>({
69
+ toolbarOverrides: {
70
+ refresh: {
71
+ async clickHandler() {
72
+ await load({ id: args.props.param });
73
+ },
74
+ },
75
+ },
76
+ });
77
+
78
+ const bladeTitle = computed(() => {
79
+ return args.props.param ? item.value?.name : "Dynamic item details";
80
+ });
81
+
82
+ return {
83
+ load,
84
+ saveChanges,
85
+ remove,
86
+ loading,
87
+ item,
88
+ validationState,
89
+ bladeTitle,
90
+ scope: computed(() => scope.value),
91
+ };
92
+ };
@@ -0,0 +1,70 @@
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 { DynamicBladeList, ListBaseBladeScope, useBladeNavigation, useListFactory } from "@vc-shell/framework";
7
+
8
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
9
+ export interface DynamicItemsScope extends ListBaseBladeScope {}
10
+
11
+ export default (args: {
12
+ props: InstanceType<typeof DynamicBladeList>["$props"];
13
+ emit: InstanceType<typeof DynamicBladeList>["$emit"];
14
+ }) => {
15
+ const factory = useListFactory({
16
+ load: async () => {
17
+ return await new Promise((resolve) => {
18
+ setTimeout(
19
+ () =>
20
+ resolve([
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
+ ]),
40
+ 1000
41
+ );
42
+ }).then((res: any[]) => {
43
+ return { results: res, totalCount: res.length };
44
+ });
45
+ },
46
+ });
47
+
48
+ const { load, items, pagination, loading, query } = factory();
49
+ const { openBlade, resolveBladeByName } = useBladeNavigation();
50
+
51
+ function openDetailsBlade(data?: Omit<Parameters<typeof openBlade>["0"], "blade">) {
52
+ openBlade({
53
+ blade: resolveBladeByName("DynamicItem"),
54
+ ...data,
55
+ });
56
+ }
57
+
58
+ const scope = ref<DynamicItemsScope>({
59
+ openDetailsBlade,
60
+ });
61
+
62
+ return {
63
+ items,
64
+ load,
65
+ loading,
66
+ pagination,
67
+ query,
68
+ scope: computed(() => scope.value),
69
+ };
70
+ };
@@ -0,0 +1,9 @@
1
+ import * as schema from "./pages";
2
+ import * as locales from "./locales";
3
+ import * as composables from "./composables";
4
+ import * as components from "./components";
5
+ import { createDynamicAppModule } from "@vc-shell/framework";
6
+
7
+ export default createDynamicAppModule({ schema, locales, composables, moduleComponents: components });
8
+
9
+ export { schema, composables, locales, components };
@@ -0,0 +1,46 @@
1
+ {
2
+ "DYNAMICMODULE": {
3
+ "MENU": {
4
+ "TITLE": "Dynamic Module"
5
+ },
6
+ "PAGES": {
7
+ "LIST": {
8
+ "TITLE": "Module blade",
9
+ "TOOLBAR": {
10
+ "REFRESH": "Refresh",
11
+ "ADD": "Add",
12
+ "DELETE": "Delete selected"
13
+ },
14
+ "SEARCH": {
15
+ "PLACEHOLDER": "Search keywords"
16
+ },
17
+ "TABLE": {
18
+ "TOTALS": "Count:",
19
+ "HEADER": {
20
+ "PRODUCT_IMAGE": "Pic",
21
+ "PRODUCT_NAME": "Name",
22
+ "CREATED_DATE": "Created"
23
+ },
24
+ "EMPTY": {
25
+ "TITLE": "There are no content yet",
26
+ "ACTION": "Add content"
27
+ },
28
+ "NOT_FOUND": {
29
+ "TITLE": "No content found.",
30
+ "ACTION": "Reset search"
31
+ },
32
+ "ACTIONS": {
33
+ "UNPUBLISH": "Unpublish",
34
+ "PUBLISH": "Publish"
35
+ }
36
+ },
37
+ "MOBILE": {
38
+ "CREATED": "Created"
39
+ },
40
+ "EMPTY": {
41
+ "NO_ITEMS": "There are no items yet"
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,2 @@
1
+ import * as en from "./en.json";
2
+ export { en };