@simitgroup/simpleapp-generator 1.6.6-y-alpha → 1.6.7-a-alpha

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 (84) hide show
  1. package/ReleaseNote.md +37 -9
  2. package/dist/framework.js +1 -1
  3. package/dist/framework.js.map +1 -1
  4. package/dist/generate.js +4 -4
  5. package/dist/generate.js.map +1 -1
  6. package/package.json +1 -1
  7. package/publish.sh +1 -0
  8. package/src/framework.ts +2 -2
  9. package/src/generate.ts +4 -4
  10. package/templates/basic/nuxt/resource-bridge.service.ts.eta +11 -2
  11. package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +3 -3
  12. package/templates/nest/src/simpleapp/services/webhook.service.ts._eta +1 -1
  13. package/templates/nuxt/plugins/19.simpleapp-mini-app-store.ts.eta +379 -0
  14. package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +3 -3
  15. package/templates/nuxt/simpleapp/generate/features/customField/components/CustomFieldFormField.vue.eta +100 -0
  16. package/templates/nuxt/simpleapp/generate/features/customField/components/CustomFieldFormFieldInput.vue.eta +121 -0
  17. package/templates/nuxt/simpleapp/generate/features/customField/components/CustomFieldFormSection.vue.eta +40 -0
  18. package/templates/nuxt/simpleapp/generate/features/customField/components/CustomFieldMenuItem.vue.eta +37 -0
  19. package/templates/nuxt/simpleapp/generate/features/customField/components/CustomFieldMenuItemBadge.vue.eta +25 -0
  20. package/templates/nuxt/simpleapp/generate/features/customField/components/CustomFieldViewFormField.vue.eta +96 -0
  21. package/templates/nuxt/simpleapp/generate/features/customField/components/CustomFieldViewFormFieldInput.vue.eta +150 -0
  22. package/templates/nuxt/simpleapp/generate/features/customField/components/CustomFieldViewFormSection.vue.eta +38 -0
  23. package/templates/nuxt/simpleapp/generate/features/customField/composables/useCustomFieldDocList.ts.eta +48 -0
  24. package/templates/nuxt/simpleapp/generate/features/customField/enums/common.ts.eta +4 -0
  25. package/templates/nuxt/simpleapp/generate/features/customField/services/CustomFieldService.ts.eta +231 -0
  26. package/templates/nuxt/simpleapp/generate/features/customField/types/common.ts.eta +16 -0
  27. package/templates/nuxt/simpleapp/generate/features/customField/types/page.ts.eta +5 -0
  28. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/MiniAppMenuButton.vue.eta +104 -0
  29. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/MiniAppPageIcon.vue.eta +20 -0
  30. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/MiniAppPageIframe.vue.eta +79 -0
  31. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/MiniAppPermissionWrapper.vue.eta +17 -0
  32. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/MiniAppRestrictedWarning.vue.eta +25 -0
  33. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/MiniAppSettingLayout.vue.eta +29 -0
  34. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/MiniAppSettingPage.vue.eta +69 -0
  35. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/MiniAppWrapper.vue.eta +39 -0
  36. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/integration/MiniAppIntegrationItem.vue.eta +48 -0
  37. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/integration/MiniAppIntegrationItemBadge.vue.eta +31 -0
  38. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/integration/MiniAppIntegrationItemGroup.vue.eta +34 -0
  39. package/templates/nuxt/simpleapp/generate/features/miniApp/app/components/integration/MiniAppIntegrationPage.vue.eta +156 -0
  40. package/templates/nuxt/simpleapp/generate/features/miniApp/app/types/miniApp.ts.eta +25 -0
  41. package/templates/nuxt/simpleapp/generate/{miniApp → features/miniApp}/bridge/services/bridge-resource-accessor.service.ts.eta +3 -1
  42. package/templates/nuxt/simpleapp/generate/{miniApp → features/miniApp}/bridge/services/bridge.service.ts.eta +7 -4
  43. package/dist/buildinschemas/message.d.ts +0 -3
  44. package/dist/buildinschemas/message.d.ts.map +0 -1
  45. package/dist/buildinschemas/message.js +0 -34
  46. package/dist/buildinschemas/message.js.map +0 -1
  47. package/dist/buildinschemas/webhookhistory.d.ts +0 -3
  48. package/dist/buildinschemas/webhookhistory.d.ts.map +0 -1
  49. package/dist/buildinschemas/webhookhistory.js +0 -44
  50. package/dist/buildinschemas/webhookhistory.js.map +0 -1
  51. package/dist/createproject.js +0 -138
  52. package/dist/createproject.js.map +0 -1
  53. package/dist/generate-allow-changebackend.js +0 -305
  54. package/dist/generate-allow-changebackend.js.map +0 -1
  55. package/dist/index2.js +0 -118
  56. package/dist/index2.js.map +0 -1
  57. package/dist/installdependency.js +0 -20
  58. package/dist/installdependency.js.map +0 -1
  59. package/dist/installnest.js +0 -2
  60. package/dist/installnest.js.map +0 -1
  61. package/dist/installnuxt.js +0 -2
  62. package/dist/installnuxt.js.map +0 -1
  63. package/dist/processors/groupsbuilder.js +0 -2
  64. package/dist/processors/groupsbuilder.js.map +0 -1
  65. package/dist/schematype/baseschema.js +0 -25
  66. package/dist/schematype/baseschema.js.map +0 -1
  67. package/dist/schematype/default.js +0 -2
  68. package/dist/schematype/default.js.map +0 -1
  69. package/dist/schematype/index.js +0 -12
  70. package/dist/schematype/index.js.map +0 -1
  71. package/dist/schematype/primarymasterdata.js +0 -38
  72. package/dist/schematype/primarymasterdata.js.map +0 -1
  73. package/dist/schematype/simple.js +0 -24
  74. package/dist/schematype/simple.js.map +0 -1
  75. package/dist/schematype/simplemasterdata.js +0 -31
  76. package/dist/schematype/simplemasterdata.js.map +0 -1
  77. package/dist/schematype/transaction.js +0 -74
  78. package/dist/schematype/transaction.js.map +0 -1
  79. package/templates/nest/src/simpleapp/types/customfield.ts.eta +0 -14
  80. package/templates/nuxt/plugins/19.app-plugins.ts.eta +0 -422
  81. /package/templates/nuxt/simpleapp/generate/{miniApp → features/miniApp}/bridge/constants/common.constant.ts.eta +0 -0
  82. /package/templates/nuxt/simpleapp/generate/{miniApp → features/miniApp}/bridge/constants/resource.constant.ts.eta +0 -0
  83. /package/templates/nuxt/simpleapp/generate/{miniApp → features/miniApp}/bridge/types/bridge.type.ts.eta +0 -0
  84. /package/templates/nuxt/simpleapp/generate/{miniApp → features/miniApp}/bridge/types/resource-mapper.type.ts.eta +0 -0
@@ -0,0 +1,104 @@
1
+ <template>
2
+ <div>
3
+ <template v-if="$miniAppStore.isFetchingInstalledMiniApps">
4
+ <i class="pi pi-spinner animate-spin mx-3.5 mt-2 text-gray-300" />
5
+ </template>
6
+ <template v-else>
7
+ <template
8
+ v-for="miniApp in top3MenuItems"
9
+ :key="'app-miniApps-page-' + miniApp._id"
10
+ >
11
+ <div class="relative group">
12
+ <div
13
+ v-if="miniApp.pages.length > 1"
14
+ class="absolute -top-1 right-0.5 pointer-events-none"
15
+ >
16
+ <i class="pi pi-chevron-down text-[0.5rem] text-gray-500" />
17
+ </div>
18
+
19
+ <MainmenuButton
20
+ :id="'mainmenu-app-miniApps-item-' + miniApp._id"
21
+ icon=""
22
+ :to="
23
+ miniApp.pages[0]?.code === 'mini-app-setting'
24
+ ? $miniAppStore.getMiniAppSettingPageUrl(miniApp.code)
25
+ : $miniAppStore.getMiniAppPageUrl(
26
+ miniApp.code,
27
+ miniApp.pages[0]?.code ?? '',
28
+ )
29
+ "
30
+ :title="miniApp.name"
31
+ >
32
+ <template #icon>
33
+ <img
34
+ :src="miniApp.logo"
35
+ class="size-6 rounded-md object-contain"
36
+ />
37
+ </template>
38
+ <template #title>
39
+ <p class="line-clamp-1">
40
+ {{ miniApp.name }}
41
+ </p>
42
+ </template>
43
+ </MainmenuButton>
44
+
45
+ <div
46
+ v-if="miniApp.pages.length > 1"
47
+ class="absolute z-50 top-0 left-14 w-0 group-hover:w-[18.1rem] text-sm transition-all duration-100 ease-out overflow-hidden"
48
+ >
49
+ <div class="flex flex-wrap gap-2 w-[18.1rem]">
50
+ <div
51
+ class="flex flex-wrap gap-x-1 gap-y-3 bg-gray-50 border-2 border-gray-100 px-3 py-5 rounded-lg shadow-lg"
52
+ >
53
+ <template v-for="page in miniApp.pages" :key="page._id">
54
+ <div
55
+ class="shrink-0 flex flex-col items-center gap-2 w-[3.8rem] cursor-pointer text-gray-500 hover:text-cyan-500"
56
+ @click="
57
+ $miniAppStore.navigateToMiniAppPage(
58
+ miniApp.code,
59
+ page.code,
60
+ )
61
+ "
62
+ >
63
+ <MiniAppPageIcon
64
+ :iconType="page.iconType"
65
+ :icon="page.icon ?? ''"
66
+ />
67
+ <p
68
+ class="text-[0.5rem] line-clamp-2 leading-none text-center"
69
+ >
70
+ {{ page.title }}
71
+ </p>
72
+ </div>
73
+ </template>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </template>
79
+
80
+ <template v-if="$miniAppStore.isShowMiniAppMoreMenuButton">
81
+ <MainmenuButton
82
+ :id="'mainmenu-app-miniApps-page-more'"
83
+ :to="getDocumentUrl('miniapp')"
84
+ :title="t('miniAppLang.myMiniApp')"
85
+ v-tooltip.right="t('miniAppLang.myMiniApp')"
86
+ >
87
+ <template #icon>
88
+ <IconPuzzle class="size-7" />
89
+ </template>
90
+ </MainmenuButton>
91
+ </template>
92
+ </template>
93
+ </div>
94
+ </template>
95
+
96
+ <script setup lang="ts">
97
+ import IconPuzzle from "~/components/icon/IconPuzzle.vue";
98
+ import MiniAppPageIcon from "./MiniAppPageIcon.vue";
99
+
100
+ const { $miniAppStore } = useNuxtApp();
101
+ const displayItemCount = 3;
102
+ const items = computed(() => $miniAppStore.getMenuItems());
103
+ const top3MenuItems = computed(() => items.value.slice(0, displayItemCount));
104
+ </script>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <template v-if="icon === '' || !['class', 'imageSource'].includes(iconType)">
3
+ <i :class="'pi pi-file'" />
4
+ </template>
5
+ <template v-else>
6
+ <template v-if="iconType === 'class'">
7
+ <i :class="icon || 'pi pi-file'" />
8
+ </template>
9
+ <template v-else-if="iconType === 'imageSource'">
10
+ <img :src="icon" class="size-3.5 pointer-events-none object-contain" />
11
+ </template>
12
+ </template>
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ defineProps<{
17
+ iconType: "class" | "imageSource" | string;
18
+ icon: string;
19
+ }>();
20
+ </script>
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <div class="app-mini-app-iframe-container">
3
+ <iframe
4
+ v-if="iframeSource !== ''"
5
+ :ref="(el) => (iframeRef = el as HTMLIFrameElement)"
6
+ :src="
7
+ generateIframeSource(iframeSource, {
8
+ miniAppInstallationId: miniAppInstallationId,
9
+ })
10
+ "
11
+ :title="pageInfo.title || t('miniAppLang.content')"
12
+ sandbox="allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox allow-presentation allow-modals"
13
+ referrerpolicy="origin"
14
+ loading="lazy"
15
+ @error="handleError"
16
+ class="w-full h-full pb-7"
17
+ @load="onIframeLoad"
18
+ />
19
+ <div v-if="hasError" class="error-message">
20
+ {{ t("miniAppLang.ERR_FAILED_LOAD_CONTENT") }}
21
+ </div>
22
+ </div>
23
+ </template>
24
+
25
+ <script setup lang="ts">
26
+ import { MiniappIntegrationPages } from "~/simpleapp/generate/openapi";
27
+
28
+ const props = defineProps<{
29
+ pageInfo: MiniappIntegrationPages;
30
+ miniAppCode: string;
31
+ miniAppInstallationId: string;
32
+ }>();
33
+
34
+ const _xOrg = getPathPara("xorg", "");
35
+ const hasError = ref(false);
36
+
37
+ const handleError = () => {
38
+ hasError.value = true;
39
+ };
40
+
41
+ type Option = {
42
+ [key: string]: any;
43
+ };
44
+
45
+ function generateIframeSource(template: string, options: Option = {}) {
46
+ return template.replace(/{(\w+)}/g, (_, key) => {
47
+ return options[key] ?? `{${key}}`;
48
+ });
49
+ }
50
+
51
+ const { iframeRef, onIframeLoad } = useMiniAppBridge(
52
+ props.miniAppInstallationId,
53
+ props.pageInfo,
54
+ props.miniAppCode,
55
+ );
56
+
57
+ const iframeSource = computed(() => {
58
+ return isDevMode()
59
+ ? props.pageInfo.sources.development
60
+ : props.pageInfo.sources.production;
61
+ });
62
+ </script>
63
+
64
+ <style scoped>
65
+ .app-mini-app-iframe-container {
66
+ position: relative;
67
+ width: 100%;
68
+ height: 100%;
69
+ }
70
+
71
+ .app-mini-app-iframe-container .error-message {
72
+ position: absolute;
73
+ top: 50%;
74
+ left: 50%;
75
+ transform: translate(-50%, -50%);
76
+ color: #666;
77
+ text-align: center;
78
+ }
79
+ </style>
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <MiniAppRestrictedWarning
3
+ v-if="!actionAccess.isAllow"
4
+ :reason="actionAccess.reason"
5
+ class="flex items-center justify-center mt-10"
6
+ />
7
+ <slot v-else />
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ defineProps<{
12
+ actionAccess: {
13
+ isAllow: boolean;
14
+ reason: string;
15
+ };
16
+ }>();
17
+ </script>
@@ -0,0 +1,25 @@
1
+ <template>
2
+ <div class="flex items-center gap-4">
3
+ <span
4
+ class="px-3 py-1 text-sm font-semibold rounded bg-yellow-100 text-yellow-800"
5
+ >
6
+ {{ t(`miniAppLang.${reason}`) }}
7
+ </span>
8
+
9
+ <ButtonPrimary
10
+ v-if="reason === 'packageTypeRestricted'"
11
+ :label="t('miniAppLang.upgradePlan')"
12
+ @click="handleUpgradePlan"
13
+ />
14
+ </div>
15
+ </template>
16
+
17
+ <script setup lang="ts">
18
+ defineProps<{
19
+ reason: string;
20
+ }>();
21
+
22
+ function handleUpgradePlan() {
23
+ window.open("https://simitgroup.com/simtraineco/#simtrain-price", "_blank");
24
+ }
25
+ </script>
@@ -0,0 +1,29 @@
1
+ <template>
2
+ <div class="flex flex-col gap-4 h-screen p-6">
3
+ <title>{{ miniAppTitle }}</title>
4
+ <div class="flex justify-between items-center">
5
+ <h1 class="text-xl font-semibold text-gray-800">
6
+ {{ miniAppTitle }}
7
+ </h1>
8
+
9
+ <div v-if="$miniAppStore.isHasMiniAppFeature">
10
+ <slot v-if="$miniAppStore.isCanUpdateSetting" name="action" />
11
+ </div>
12
+ </div>
13
+
14
+ <MiniAppPermissionWrapper
15
+ :actionAccess="$miniAppStore.getActionAccess('updateSetting')"
16
+ >
17
+ <slot />
18
+ </MiniAppPermissionWrapper>
19
+ </div>
20
+ </template>
21
+
22
+ <script setup lang="ts">
23
+ import MiniAppPermissionWrapper from './MiniAppPermissionWrapper.vue';
24
+
25
+ defineProps<{
26
+ isFetching: boolean;
27
+ miniAppTitle: string;
28
+ }>();
29
+ </script>
@@ -0,0 +1,69 @@
1
+ <template>
2
+ <LoadingLine :loading="isFetching" />
3
+ <SimpleAppJsonSchemaForm
4
+ v-if="!_.isEmpty(schema)"
5
+ :schema="schema"
6
+ :data="data"
7
+ #default="o"
8
+ >
9
+ <MiniAppSettingLayout :isFetching="isFetching" :miniAppTitle="miniAppTitle">
10
+ <template #action>
11
+ <Button class="btn-primary" @click="o.validate(validateCallBack)">
12
+ {{ t('miniAppLang.saveSetting') }}
13
+ </Button>
14
+ </template>
15
+
16
+ <template #default>
17
+ <div class="space-y-4" v-if="!_.isEmpty(schema)">
18
+ <p
19
+ v-if="miniApp?.integration?.settings?.note"
20
+ class="text-sm text-gray-600 whitespace-pre-line"
21
+ >
22
+ {{
23
+ t('miniAppLang.miniAppSettingNote', {
24
+ miniAppNote: miniApp.integration.settings.note ?? ''
25
+ })
26
+ }}
27
+ </p>
28
+ <CustomFieldFormField
29
+ :jsonSchema="settingSchema"
30
+ :data="data"
31
+ :handleGetField="o.getField"
32
+ schemaName="setting"
33
+ hierarchy="setting"
34
+ schemaSource="miniAppSetting"
35
+ :isShowFieldset="false"
36
+ :isHideFieldsetLegend="true"
37
+ />
38
+ </div>
39
+ </template>
40
+ </MiniAppSettingLayout>
41
+ </SimpleAppJsonSchemaForm>
42
+ </template>
43
+
44
+ <script setup lang="ts" generic="T">
45
+ import _ from 'lodash';
46
+ import MiniAppSettingLayout from './MiniAppSettingLayout.vue';
47
+ import CustomFieldFormField from '../../../customField/components/CustomFieldFormField.vue';
48
+
49
+ const props = defineProps<{
50
+ miniAppCode?: string;
51
+ }>();
52
+
53
+ const _miniAppCode = props.miniAppCode ?? getPathPara('miniAppCode');
54
+
55
+ const {
56
+ isFetching,
57
+ miniApp,
58
+ miniAppTitle,
59
+ schema,
60
+ settingSchema,
61
+ data,
62
+ loadMiniAppDetail,
63
+ validateCallBack
64
+ } = useMiniAppSetting(_miniAppCode);
65
+
66
+ onMounted(async () => {
67
+ await loadMiniAppDetail();
68
+ });
69
+ </script>
@@ -0,0 +1,39 @@
1
+ <template>
2
+ <LoadingLine :loading="$miniAppStore.isFetchingInstalledMiniApps" />
3
+
4
+ <MiniAppPermissionWrapper
5
+ v-if="!$miniAppStore.isFetchingInstalledMiniApps"
6
+ :actionAccess="$miniAppStore.getActionAccess('plan')"
7
+ >
8
+ <MiniAppPermissionWrapper
9
+ :actionAccess="{
10
+ isAllow: $miniAppStore.checkIsMiniAppInstalled(miniAppCode),
11
+ reason: 'notYetInstall'
12
+ }"
13
+ >
14
+ <MiniAppPermissionWrapper
15
+ v-if="pageCode !== ''"
16
+ :actionAccess="{
17
+ isAllow: $miniAppStore.checkIsAllowAccessMiniAppPage(
18
+ miniAppCode,
19
+ pageCode
20
+ ),
21
+ reason: 'insufficientAccessPermission'
22
+ }"
23
+ >
24
+ <slot />
25
+ </MiniAppPermissionWrapper>
26
+
27
+ <slot v-else />
28
+ </MiniAppPermissionWrapper>
29
+ </MiniAppPermissionWrapper>
30
+ </template>
31
+
32
+ <script setup lang="ts">
33
+ import MiniAppPermissionWrapper from './MiniAppPermissionWrapper.vue';
34
+
35
+ defineProps<{
36
+ miniAppCode: string;
37
+ pageCode: string;
38
+ }>();
39
+ </script>
@@ -0,0 +1,48 @@
1
+ <template>
2
+ <div
3
+ class="relative rounded-lg h-50 p-4 border-2 flex flex-col items-center transition-all hover:border-primary-500"
4
+ :class="{
5
+ 'opacity-40 cursor-not-allowed ': item.status === 'upcoming',
6
+ 'cursor-pointer': item.status !== 'upcoming',
7
+ }"
8
+ @click="handleMiniAppClick(item)"
9
+ >
10
+ <div class="absolute top-2 right-2 flex space-x-1">
11
+ <MiniAppIntegrationItemBadge :item="item" />
12
+ </div>
13
+
14
+ <div class="text-lg font-semibold text-center">
15
+ {{ item.name }}
16
+ </div>
17
+
18
+ <div class="p-4">
19
+ <img :src="item.logo" class="size-16 object-contain" />
20
+ </div>
21
+
22
+ <div class="text-sm text-gray-600 text-center line-clamp-2">
23
+ {{ item.description }}
24
+ </div>
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import { MiniappStatusEnum } from "~/enums/enums.generate";
30
+ import { Miniapp } from "~/simpleapp/generate/openapi";
31
+ import MiniAppIntegrationItemBadge from "./MiniAppIntegrationItemBadge.vue";
32
+
33
+ defineProps<{
34
+ item: Miniapp;
35
+ }>();
36
+
37
+ const emits = defineEmits<{
38
+ (event: "miniAppClick", item: Miniapp): void;
39
+ }>();
40
+
41
+ function handleMiniAppClick(item: Miniapp) {
42
+ if (item.status === MiniappStatusEnum.UPCOMING) return;
43
+
44
+ if (item._id) {
45
+ emits("miniAppClick", item);
46
+ }
47
+ }
48
+ </script>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <span
3
+ class="text-white text-xs px-2 font-bold py-0.5 rounded-md shadow uppercase"
4
+ :class="{
5
+ 'bg-emerald-500': badgeType === 'free',
6
+ 'bg-yellow-400': badgeType === 'comingSoon',
7
+ }"
8
+ >
9
+ {{ t(badgeType) }}
10
+ </span>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ import { Miniapp } from "~/simpleapp/generate/openapi";
15
+
16
+ const props = defineProps<{
17
+ item: Miniapp;
18
+ }>();
19
+
20
+ const badgeType = computed(() => {
21
+ if (props.item.status === "published" && props.item.pricing === 0) {
22
+ return "free";
23
+ }
24
+
25
+ if (props.item.status === "upcoming") {
26
+ return "comingSoon";
27
+ }
28
+
29
+ return "";
30
+ });
31
+ </script>
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <div
3
+ class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-6"
4
+ >
5
+ <MiniAppIntegrationItem
6
+ v-if="items && items.length > 0"
7
+ v-for="item in items"
8
+ :key="item._id"
9
+ :item="item"
10
+ @miniAppClick="handleMiniAppClick"
11
+ />
12
+ <div
13
+ v-else
14
+ class="flex justify-center items-center bg-gray-50 rounded-lg p-4 h-48 col-span-full"
15
+ >
16
+ <NodataLarge :label="t('noDataFound')" :icon="UndrawNodata" />
17
+ </div>
18
+ </div>
19
+ </template>
20
+ <script setup lang="ts">
21
+ import UndrawNodata from '~/components/icon/UndrawNodata.vue';
22
+ import { Miniapp } from '~/simpleapp/generate/openapi';
23
+ import MiniAppIntegrationItem from './MiniAppIntegrationItem.vue';
24
+
25
+ defineProps<{ items: Miniapp[] | undefined }>();
26
+
27
+ const emits = defineEmits<{
28
+ (event: 'miniAppClick', item: Miniapp): void;
29
+ }>();
30
+
31
+ function handleMiniAppClick(item: Miniapp) {
32
+ emits('miniAppClick', item);
33
+ }
34
+ </script>
@@ -0,0 +1,156 @@
1
+ <template>
2
+ <title>{{ miniApp?.name }} - {{ t('miniAppLang.miniApp') }}</title>
3
+ <LoadingLine :loading="isFetching" />
4
+
5
+ <div
6
+ v-if="miniApp && !_.isEmpty(miniApp)"
7
+ class="p-8 max-w-4xl mx-auto mb-10 space-y-4"
8
+ >
9
+ <div class="flex items-start">
10
+ <img :src="miniApp.logo" class="size-16 mr-8 object-contain" />
11
+
12
+ <div class="space-y-1">
13
+ <h1 class="text-3xl font-bold mb-1">{{ miniApp.name }}</h1>
14
+ <div class="text-gray-400 text-sm flex items-center gap-2">
15
+ <div class="flex items-center gap-2">
16
+ <i class="pi pi-user" />
17
+ <span>{{ miniApp.author }}</span>
18
+ </div>
19
+ <span>|</span>
20
+ <div>v {{ miniApp.version }}</div>
21
+ </div>
22
+ <p class="text-gray-600">{{ miniApp.intro.description }}</p>
23
+ </div>
24
+ </div>
25
+
26
+ <div class="space-y-6">
27
+ <template v-if="$miniAppStore.isFetchingInstalledMiniApps">
28
+ <div class="flex items-center h-10">
29
+ <i class="pi pi-spinner animate-spin" />
30
+ </div>
31
+ </template>
32
+ <MiniAppPermissionWrapper
33
+ v-else
34
+ :actionAccess="$miniAppStore.getActionAccess('plan')"
35
+ >
36
+ <div class="flex space-x-2">
37
+ <template v-if="$miniAppStore.checkIsMiniAppInstalled(miniApp.code)">
38
+ <!-- Installed -->
39
+ <MiniAppPermissionWrapper
40
+ :actionAccess="$miniAppStore.getActionAccess('uninstall')"
41
+ >
42
+ <ButtonDefault
43
+ :label="t('miniAppLang.uninstallApp')"
44
+ :loading="isAppInstallationInProgress"
45
+ :disabled="isAppInstallationInProgress"
46
+ @click="handleUninstallApp"
47
+ />
48
+ </MiniAppPermissionWrapper>
49
+
50
+ <MiniAppPermissionWrapper
51
+ v-if="
52
+ miniApp.integration.settings &&
53
+ !_.isEmpty(miniApp.integration.settings)
54
+ "
55
+ :actionAccess="$miniAppStore.getActionAccess('updateSetting')"
56
+ >
57
+ <ButtonSecondary
58
+ :label="t('miniAppLang.openSetting')"
59
+ :disabled="isAppInstallationInProgress"
60
+ icon="pi pi-cog"
61
+ @click="handleOpenSetting"
62
+ />
63
+ </MiniAppPermissionWrapper>
64
+ </template>
65
+ <template v-else>
66
+ <!-- Not yet install -->
67
+ <MiniAppPermissionWrapper
68
+ :actionAccess="$miniAppStore.getActionAccess('install')"
69
+ >
70
+ <ButtonPrimary
71
+ :label="t('miniAppLang.installApp')"
72
+ :loading="isAppInstallationInProgress"
73
+ :disabled="isAppInstallationInProgress"
74
+ @click="handleInstallApp"
75
+ />
76
+ </MiniAppPermissionWrapper>
77
+ </template>
78
+ </div>
79
+ </MiniAppPermissionWrapper>
80
+
81
+ <div v-if="miniApp.intro.previewImages.length > 0">
82
+ <h2 class="text-xl font-semibold mb-2">Overview:</h2>
83
+ <div class="card flex justify-center py-4">
84
+ <Galleria
85
+ :value="miniApp.intro.previewImages"
86
+ :numVisible="5"
87
+ containerStyle="max-width: 640px"
88
+ :showThumbnails="false"
89
+ :showIndicators="true"
90
+ >
91
+ <template #item="slotProps">
92
+ <img
93
+ :src="slotProps.item"
94
+ :alt="miniApp.name"
95
+ style="width: 100%; display: block"
96
+ />
97
+ </template>
98
+ </Galleria>
99
+ </div>
100
+ </div>
101
+
102
+ <div>
103
+ <h2 class="text-xl font-semibold mb-2">Key Features:</h2>
104
+ <div class="mt-6 space-y-2 text-gray-700">
105
+ <div
106
+ v-for="feature in miniApp.intro.features"
107
+ :key="feature.title"
108
+ class="flex space-x-2"
109
+ >
110
+ <div>✅</div>
111
+ <div>
112
+ <div>
113
+ <span class="font-semibold">{{ feature.title }}</span> -
114
+ {{ feature.description }}
115
+ </div>
116
+ </div>
117
+ </div>
118
+ </div>
119
+ </div>
120
+ </div>
121
+ </div>
122
+ <div v-else>
123
+ <template v-if="!isFetching"> Not found... </template>
124
+ </div>
125
+ </template>
126
+
127
+ <script setup lang="ts">
128
+ import _ from 'lodash';
129
+ import { MiniAppDetail } from '~/simpleapp/generate/openapi';
130
+ import MiniAppPermissionWrapper from '../MiniAppPermissionWrapper.vue';
131
+
132
+ defineProps<{
133
+ miniApp?: MiniAppDetail;
134
+ isFetching: boolean;
135
+ isAppInstallationInProgress: boolean;
136
+ }>();
137
+
138
+ const emits = defineEmits<{
139
+ (e: 'installApp'): void;
140
+ (e: 'uninstallApp'): void;
141
+ (e: 'openSetting'): void;
142
+ (e: 'upgradePlan'): void;
143
+ }>();
144
+
145
+ function handleInstallApp() {
146
+ emits('installApp');
147
+ }
148
+
149
+ function handleUninstallApp() {
150
+ emits('uninstallApp');
151
+ }
152
+
153
+ function handleOpenSetting() {
154
+ emits('openSetting');
155
+ }
156
+ </script>
@@ -0,0 +1,25 @@
1
+ import type {
2
+ MiniAppDetail,
3
+ MiniappIntegrationForms,
4
+ MiniappIntegrationPages,
5
+ } from "~/simpleapp/generate/openapi";
6
+
7
+ export enum MiniAppFrameworkCompatibility {
8
+ "COMPATIBLE" = "COMPATIBLE",
9
+ "TO_BE_DEPRECATED" = "TO_BE_DEPRECATED", // Still compatible, but will be deprecated in the future.
10
+ "DEPRECATED" = "DEPRECATED",
11
+ }
12
+
13
+ export type MiniAppPageWithMiniAppCode = MiniappIntegrationPages & {
14
+ miniAppCode: string;
15
+ };
16
+
17
+ export type MiniAppFormWithMiniAppCode = MiniappIntegrationForms & {
18
+ miniAppCode: string;
19
+ };
20
+
21
+ export type CategorizedMiniApp = {
22
+ installedMiniApps: MiniAppDetail[];
23
+ upcomingMiniApps: MiniAppDetail[];
24
+ availableMiniApps: MiniAppDetail[];
25
+ };