@simitgroup/simpleapp-generator 1.3.3-alpha → 1.3.4-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 (67) hide show
  1. package/dist/framework.js +2 -2
  2. package/dist/framework.js.map +1 -1
  3. package/dist/generate.d.ts.map +1 -1
  4. package/dist/generate.js +7 -11
  5. package/dist/generate.js.map +1 -1
  6. package/dist/processors/jsonschemabuilder.d.ts.map +1 -1
  7. package/dist/processors/jsonschemabuilder.js +8 -0
  8. package/dist/processors/jsonschemabuilder.js.map +1 -1
  9. package/package.json +1 -1
  10. package/src/framework.ts +2 -2
  11. package/src/generate.ts +15 -12
  12. package/src/processors/jsonschemabuilder.ts +12 -1
  13. package/templates/basic/nest/controller.ts.eta +16 -5
  14. package/templates/basic/nuxt/component.select.vue.eta +35 -0
  15. package/templates/basic/nuxt/pages.form.vue.eta +5 -8
  16. package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +3 -1
  17. package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +10 -9
  18. package/templates/nest/src/simpleapp/generate/controllers/simpleapp.controller.ts.eta +2 -2
  19. package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +38 -38
  20. package/templates/nest/src/simpleapp/generate/types/simpleapp.type.ts.eta +14 -9
  21. package/templates/nuxt/assets/css/style.css._eta +39 -3
  22. package/templates/nuxt/assets/primevue/passthrough.ts._eta +17 -12
  23. package/templates/nuxt/components/button/ButtonAction.vue._eta +19 -0
  24. package/templates/nuxt/components/button/ButtonDanger.vue._eta +13 -6
  25. package/templates/nuxt/components/button/ButtonDefault.vue._eta +13 -6
  26. package/templates/nuxt/components/button/ButtonMultiple.vue._eta +9 -7
  27. package/templates/nuxt/components/button/ButtonPrimary.vue._eta +13 -6
  28. package/templates/nuxt/components/button/ButtonText.vue._eta +16 -7
  29. package/templates/nuxt/components/button/ButtonWarning.vue._eta +13 -6
  30. package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +83 -69
  31. package/templates/nuxt/components/chart/card.vue._eta +32 -0
  32. package/templates/nuxt/components/event/EventDocumentViewer.vue._eta +44 -21
  33. package/templates/nuxt/components/event/EventNotification.vue._eta +119 -107
  34. package/templates/nuxt/components/header/button/HeaderButtonProfile.vue.eta +129 -75
  35. package/templates/nuxt/components/list/ListView.vue.eta +44 -13
  36. package/templates/nuxt/components/mobile/MobileToolbar.vue.eta +6 -5
  37. package/templates/nuxt/components/overlay/OverlayPanelWithToolBar.vue.eta +35 -37
  38. package/templates/nuxt/components/overlay/OverlaySideBarCrud.vue.eta +3 -4
  39. package/templates/nuxt/components/renderer/RendererDate.vue.eta +3 -2
  40. package/templates/nuxt/components/renderer/RendererForeignKey.vue.eta +38 -34
  41. package/templates/nuxt/components/select/SelectTemplate.vue.eta +79 -0
  42. package/templates/nuxt/components/select/readme.md +1 -0
  43. package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +181 -35
  44. package/templates/nuxt/components/simpleApp/SimpleAppChildrenList.vue.eta +70 -0
  45. package/templates/nuxt/components/simpleApp/SimpleAppDocumentNo.vue.eta +77 -73
  46. package/templates/nuxt/components/simpleApp/SimpleAppForm.vue.eta +113 -111
  47. package/templates/nuxt/components/simpleApp/{SimpleAppFormToolBar.vue.eta → SimpleAppFormToolBar.vue._eta} +125 -61
  48. package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +116 -42
  49. package/templates/nuxt/components/text/TextPrimary.vue._eta +13 -0
  50. package/templates/nuxt/components/user/UserButtonCreateTenant.vue._eta +68 -0
  51. package/templates/nuxt/components/user/UserTenantPicker.vue.eta +81 -70
  52. package/templates/nuxt/composables/date.generate.ts.eta +2 -0
  53. package/templates/nuxt/composables/getDocument.generate.ts.eta +35 -2
  54. package/templates/nuxt/composables/getOpenApi.generate.ts.eta +5 -1
  55. package/templates/nuxt/composables/refreshDocumentList.generate.ts.eta +2 -1
  56. package/templates/nuxt/lang/en.ts.eta +3 -1
  57. package/templates/nuxt/nuxt.config.ts._eta +3 -0
  58. package/templates/nuxt/pages/index.vue._eta +10 -56
  59. package/templates/nuxt/pages/picktenant.vue._eta +19 -0
  60. package/templates/nuxt/plugins/10.simpleapp-event.ts.eta +10 -2
  61. package/templates/nuxt/server/api/[xorg]/[...].ts.eta +9 -10
  62. package/templates/nuxt/types/calendar.ts.eta +2 -0
  63. package/templates/nuxt/types/events.ts.eta +3 -1
  64. package/templates/nuxt/types/simpleappinput.ts.eta +1 -0
  65. package/templates/project/lang/default._json +5 -1
  66. package/tsconfig.tsbuildinfo +1 -1
  67. package/templates/nuxt/components/user/UserButtonCreateTenant.vue.eta +0 -103
@@ -5,85 +5,139 @@
5
5
  * last change 2023-10-28
6
6
  * Author: Ks Tan
7
7
  */
8
- import Avatar from 'primevue/avatar';
9
- import Dropdown from 'primevue/dropdown';
10
- import OverlayPanel from 'primevue/overlaypanel';
11
- import {ref} from 'vue'
12
-
13
-
14
- const { locale,setLocale,locales } = useI18n()
15
- const colorMode = useColorMode()
16
- const modelValue = defineModel<boolean>()
17
- const mylocale = ref(locale)
18
- const colors = [{value:'light', name:t('light')},{value:'dark', name:t('dark')}]
19
-
20
- const toProfile = ()=>{
21
- modelValue.value=false
22
-
23
- if(getCurrentXorg()){
24
- navigateTo(`/${getCurrentXorg()}/profile`)
25
- }else{
26
- navigateTo(`/profile`)
27
- }
28
-
29
- }
30
- const saveLocale=async (v:string)=>{
31
- await setLocale(v)
32
- }
33
-
8
+ import Avatar from "primevue/avatar";
9
+ import Dropdown from "primevue/dropdown";
10
+ import OverlayPanel from "primevue/overlaypanel";
11
+ import { ref } from "vue";
34
12
 
13
+ const { locale, setLocale, locales } = useI18n();
14
+ const colorMode = useColorMode();
15
+ const modelValue = defineModel<boolean>();
16
+ const mylocale = ref(locale);
17
+ const colors = [
18
+ { value: "light", name: t("light") },
19
+ { value: "dark", name: t("dark") },
20
+ ];
21
+ const goTenantPicker = () => {
22
+ modelValue.value = false;
23
+ navigateTo("/picktenant");
24
+ };
25
+ const toProfile = () => {
26
+ modelValue.value = false;
35
27
 
28
+ if (getCurrentXorg()) {
29
+ navigateTo(`/${getCurrentXorg()}/profile`);
30
+ } else {
31
+ navigateTo(`/profile`);
32
+ }
33
+ };
34
+ const saveLocale = async (v: string) => {
35
+ await setLocale(v);
36
+ };
36
37
  </script>
37
38
 
38
- <template>
39
- <!-- <div class="bg-cover bg-center rounded-md p-3 cursor-pointer profile-button" @click="toggle">
39
+ <template>
40
+ <!-- <div class="bg-cover bg-center rounded-md p-3 cursor-pointer profile-button" @click="toggle">
40
41
  <i class="pi pi-user dark:text-white"></i> -->
41
- <!-- <img :src="getAvatarLink(<string>getProfileEmail(),32)" alt="" class="h-full w-full overflow-hidden object-cover rounded-full border-2 border-white dark:border-gray-700 shadow" /> -->
42
- <!-- </div> -->
43
-
44
- <Dialog appendTo="body" ref="userprofileoverlay" v-model:visible="modelValue" close-on-escape :header="t('profile')">
45
- <!-- <div> -->
46
- <!-- <div class="py-2 transition duration-150 ease-in-out z-10 absolute top-0 right-0 bottom-0 left-0" id="modal"> -->
47
- <div class="p-4">
48
- <!-- <div class="relative p-4 md:p-8 bg-white dark:bg-gray-800 shadow-md rounded border border-gray-400"> -->
49
- <div class="w-full flex items-center justify-start text-gray-600 dark:text-gray-400 mb-5" >
50
- <div class="w-12 h-12 bg-cover bg-center rounded-md">
51
- <img :src="getAvatarLink(<string>getProfileEmail(),32)" alt="" class="h-full w-full overflow-hidden object-cover rounded-full border-2 border-white dark:border-gray-700 shadow" />
52
- </div>
53
- <div class="flex flex-col" >
54
- <h1 class="text-left text-gray-800 dark:text-gray-100 font-lg font-bold tracking-normal leading-tight ml-2">{{ getUserProfile()?.fullName }}</h1>
55
- <p class="text-gray-400 dark:text-gray-100 font-normal text-base tracking-normal ml-2 mr-4">{{getUserProfile()?.group }}</p>
56
- </div>
57
-
58
- </div>
59
- <div class="col-span-full">
60
- <label for="pick-lang" class="block text-sm font-medium leading-6 text-gray-900 dark:text-gray-300">{{ t('language') }}</label>
61
- <div class="mt-2">
62
- <Dropdown inputId="pick-lang" @update:model-value="saveLocale" v-model="mylocale" option-value="code" option-label="name" :options="locales" >
63
- </Dropdown>
64
- </div>
65
- </div>
66
- <div class="mt-3 col-span-full">
67
- <label for="pick-theme" class="block text-sm font-medium leading-6 text-gray-900 dark:text-gray-300">{{ t('theme') }}</label>
68
- <div class="mt-2">
69
- <h1>Color mode: {{ $colorMode.value }}</h1>
42
+ <!-- <img :src="getAvatarLink(<string>getProfileEmail(),32)" alt="" class="h-full w-full overflow-hidden object-cover rounded-full border-2 border-white dark:border-gray-700 shadow" /> -->
43
+ <!-- </div> -->
44
+
45
+ <Dialog
46
+ appendTo="body"
47
+ ref="userprofileoverlay"
48
+ v-model:visible="modelValue"
49
+ close-on-escape
50
+ :header="t('profile')"
51
+ >
52
+ <!-- <div> -->
53
+ <!-- <div class="py-2 transition duration-150 ease-in-out z-10 absolute top-0 right-0 bottom-0 left-0" id="modal"> -->
54
+ <div class="p-4">
55
+ <!-- <div class="relative p-4 md:p-8 bg-white dark:bg-gray-800 shadow-md rounded border border-gray-400"> -->
56
+ <div
57
+ class="w-full flex items-center justify-start text-gray-600 dark:text-gray-400 mb-5"
58
+ >
59
+ <div class="w-12 h-12 bg-cover bg-center rounded-md">
60
+ <img
61
+ :src="getAvatarLink(<string>getProfileEmail(), 32)"
62
+ alt=""
63
+ class="h-full w-full overflow-hidden object-cover rounded-full border-2 border-white dark:border-gray-700 shadow"
64
+ />
65
+ </div>
66
+ <div class="flex flex-col">
67
+ <h1
68
+ class="text-left text-gray-800 dark:text-gray-100 font-lg font-bold tracking-normal leading-tight ml-2"
69
+ >
70
+ {{ getUserProfile()?.fullName }}
71
+ </h1>
72
+ <p
73
+ class="text-gray-400 dark:text-gray-100 font-normal text-base tracking-normal ml-2 mr-4"
74
+ >
75
+ {{ getUserProfile()?.group }}
76
+ </p>
77
+ </div>
78
+ </div>
79
+ <div class="pt-2 pb-2">
80
+ <TextTitle>{{ getUserProfile()?.branchName }}</TextTitle>
81
+ <TextPrimary @click="goTenantPicker">{{
82
+ t("switchDatabase")
83
+ }} </TextPrimary>
84
+ </div>
85
+ <div class="col-span-full">
86
+ <label
87
+ for="pick-lang"
88
+ class="block text-sm font-medium leading-6 text-gray-900 dark:text-gray-300"
89
+ >{{ t("language") }}</label
90
+ >
91
+ <div class="mt-2">
92
+ <Dropdown
93
+ inputId="pick-lang"
94
+ @update:model-value="saveLocale"
95
+ v-model="mylocale"
96
+ option-value="code"
97
+ option-label="name"
98
+ :options="locales"
99
+ >
100
+ </Dropdown>
101
+ </div>
102
+ </div>
103
+ <div class="mt-3 col-span-full">
104
+ <label
105
+ for="pick-theme"
106
+ class="block text-sm font-medium leading-6 text-gray-900 dark:text-gray-300"
107
+ >{{ t("theme") }}</label
108
+ >
109
+ <div class="mt-2">
110
+ <h1>Color mode: {{ $colorMode.value }}</h1>
111
+
112
+ <Dropdown
113
+ inputId="pick-theme"
114
+ v-model="colorMode.preference"
115
+ option-value="value"
116
+ option-label="name"
117
+ :options="colors"
118
+ >
119
+ </Dropdown>
120
+ </div>
121
+ </div>
70
122
 
71
- <Dropdown inputId="pick-theme" v-model="colorMode.preference" option-value="value" option-label="name" :options="colors" >
72
- </Dropdown>
73
-
74
- </div>
75
- </div>
123
+ <div class="mt-3 flex items-center justify-start w-full">
124
+ <button
125
+ class="focus:outline-none transition duration-150 ease-in-out hover:bg-gray-600 bg-gray-700 rounded text-white px-8 py-2 text-sm"
126
+ @click="toProfile"
127
+ >
128
+ {{ t("profile") }}
129
+ </button>
130
+ <button
131
+ class="focus:outline-none ml-3 bg-warning-100 dark:bg-warning-700 dark:border-warning-700 dark:hover:bg-warning-600 transition duration-150 text-gray-600 dark:text-white ease-in-out hover:border-gray-400 hover:bg-gray-300 border rounded px-8 py-2 text-sm"
132
+ @click="logout()"
133
+ >
134
+ {{ t("logout") }}
135
+ </button>
136
+ </div>
137
+ <!-- </div> -->
138
+ </div>
139
+ <!-- </div> -->
76
140
 
77
-
78
- <div class="mt-3 flex items-center justify-start w-full">
79
- <button class="focus:outline-none transition duration-150 ease-in-out hover:bg-gray-600 bg-gray-700 rounded text-white px-8 py-2 text-sm" @click="toProfile">{{ t('profile') }}</button>
80
- <button class="focus:outline-none ml-3 bg-warning-100 dark:bg-warning-700 dark:border-warning-700 dark:hover:bg-warning-600 transition duration-150 text-gray-600 dark:text-white ease-in-out hover:border-gray-400 hover:bg-gray-300 border rounded px-8 py-2 text-sm" @click="logout()">{{ t('logout') }}</button>
81
- </div>
82
- <!-- </div> -->
83
- </div>
84
- <!-- </div> -->
85
-
86
- <!-- </div> -->
87
- </Dialog>
88
-
89
- </template>
141
+ <!-- </div> -->
142
+ </Dialog>
143
+ </template>
@@ -2,19 +2,25 @@
2
2
  <div class="relative">
3
3
  <div v-if="withFilter" class="flex flex-row">
4
4
  <InputText
5
- placeholder="search"
5
+ :placeholder="t('searchKeyword')"
6
6
  v-model="searchvalue"
7
7
  class="w-full dark:text-white"
8
8
  type="search"
9
+ ref="listviewfilter"
9
10
  />
10
- <ButtonPrimary v-if="withAddNew" @click="emits('add')"
11
- ><i class="pi pi-plus"></i
12
- ></ButtonPrimary>
11
+ <template v-if="withAddNew">
12
+ <ButtonText v-if="isMobile()" @click="emits('add')"
13
+ ><i class="pi pi-plus"></i
14
+ ></ButtonText>
15
+ <ButtonPrimary v-else @click="emits('add')"
16
+ ><i class="pi pi-plus"></i
17
+ ></ButtonPrimary>
18
+ </template>
13
19
  </div>
14
20
 
15
21
  <div
16
22
  v-if="showIndex"
17
- class="flex flex-col fixed left-1 top-1/5 gap-2 z-10 rounded border bg-white dark:bg-black opacity-90"
23
+ class="flex flex-col fixed left-1 top-1/5 gap-2 z-10 rounded border bg-white dark:bg-black opacity-90"
18
24
  >
19
25
  <NuxtLink
20
26
  class="text-primary-600 dark:text-primary-400 text-lg p-2"
@@ -28,7 +34,9 @@
28
34
  <div>
29
35
  <div v-for="(item, index) in filterlist">
30
36
  <!-- :class="isMobile() ? '' : 'overflow overflow-y-scroll overflow-auto '" -->
31
- <div :id="titleField && item[titleField][0]"></div>
37
+ <div
38
+ :id="titleField && item[titleField] && item[titleField][0]"
39
+ ></div>
32
40
  <div
33
41
  class="w-full bg-gray-400 dark:bg-gray-500 p-1 pl-2 top-0 sticky opacity-90"
34
42
  v-if="
@@ -37,8 +45,16 @@
37
45
  >
38
46
  <span>{{ item[titleField][0] }}</span>
39
47
  </div>
40
- <div class=" border-l-none border-r-none listview-item border-t-2 dark:border-t-gray-700 hover:" >
41
- <NuxtLink :to="url ? `${url}/${item[idField]}` : undefined" class="p-2">
48
+ <div
49
+ @click="onClick(index, item)"
50
+ :class="`border-l-none border-r-none listview-item dark:border-t-gray-700 ${
51
+ index > 0 ? 'border-t-2' : ''
52
+ }`"
53
+ >
54
+ <NuxtLink :to="getUrl(item)"
55
+
56
+ class="p-2"
57
+ >
42
58
  <slot name="default" :item="item" :index="index">
43
59
  <div class="flex flex-row">
44
60
  <div class="flex-1 mr-2 dark:text-white">
@@ -55,9 +71,7 @@
55
71
  </div>
56
72
  </div>
57
73
  <div v-else>
58
- <div
59
- class="w-full h-20 p-2 border-l-none border-r-none "
60
- >
74
+ <div class="w-full h-20 p-2 border-l-none border-r-none">
61
75
  <slot name="nodata">
62
76
  <div class="border-round border-1 surface-border p-4 surface-card">
63
77
  {{ t("noDataFound") }}
@@ -76,6 +90,8 @@
76
90
  */
77
91
  import { ref } from "vue";
78
92
  import { ListItem } from "~/types/listview";
93
+ import _ from 'lodash'
94
+ const listviewfilter = ref();
79
95
  const props = withDefaults(
80
96
  defineProps<{
81
97
  list: T[];
@@ -94,13 +110,21 @@ const props = withDefaults(
94
110
  const letters = ref<string[]>([]);
95
111
  let lastchar = "";
96
112
 
97
- const emits = defineEmits(["add"]);
113
+ const emits = defineEmits(["add", "click"]);
98
114
  const searchvalue = ref("");
99
115
  const selecteditem = ref("");
100
116
  const clickRow = (item: ListItem) => {
101
117
  // emit('clickitem',item)
102
118
  // selecteditem.value = item.code
103
119
  };
120
+ const getUrl = (item:any)=>{
121
+ if(props.url && props.idField) {
122
+ if(_.last(props.url)=='/') return `${props.url}${item[props.idField]}`
123
+ else return `${props.url}/${item[props.idField]}`
124
+ }
125
+ else return undefined
126
+ // :to="url ? `${url}/${item[idField]}` : undefined"
127
+ }
104
128
  const filterlist = computed(() => {
105
129
  let newlist: T[] = [];
106
130
  if (!Array.isArray(props.list)) {
@@ -122,7 +146,6 @@ const filterlist = computed(() => {
122
146
  return newlist;
123
147
  });
124
148
 
125
-
126
149
  const allLetters = computed(() => {
127
150
  if (props.titleField && props.list) {
128
151
  return props.list
@@ -147,4 +170,12 @@ const showCategoryBar = (letter: string) => {
147
170
  return false;
148
171
  }
149
172
  };
173
+
174
+ const onClick = (index: number, data: T) => {
175
+ emits("click", index, data);
176
+ };
177
+
178
+ onMounted(() => {
179
+ // if(props.withFilter) listviewfilter.value.$el.focus()
180
+ });
150
181
  </script>
@@ -1,9 +1,10 @@
1
1
  <template>
2
- <div class="w-full dark:bg-gray-800 z-20 justify justify-between absolute h h-14 flex flex-row place-items-center opacity-90 dark:text-white"
2
+ <div
3
+ class="w-full dark:bg-gray-800 z-20 justify justify-between absolute h h-14 flex flex-row place-items-center opacity-90 dark:text-white"
3
4
  >
4
- <div class="w-full text-left"><slot name="start"></slot></div>
5
- <div class="w-full text-center"><slot name="center"></slot></div>
6
- <div class="w-full text-right"><slot name="end"></slot></div>
5
+ <div class="text-left"><slot name="start"></slot></div>
6
+ <div class="flex-1 text-center line-clamp-2"><slot name="center"></slot></div>
7
+ <div class=" text-right"><slot name="end"></slot></div>
7
8
  </div>
8
9
  </template>
9
10
  <script setup lang="ts">
@@ -13,4 +14,4 @@
13
14
  * last change 2023-10-28
14
15
  * Author: Ks Tan
15
16
  */
16
- </script>
17
+ </script>
@@ -1,44 +1,42 @@
1
1
  <template>
2
- <Sidebar
3
- position="right"
4
- v-if="showDialog"
5
- v-model:visible="showDialog"
6
- modal
7
- :show-close-icon="false"
8
- #container
9
- >
10
- <div class="overflow-y-scroll">
11
- <MobileToolbar class="bg-gray-800 text-white">
12
- <template #start>
13
- <slot name="headerLeft"></slot>
14
- </template>
15
- <template #center>
16
- <slot name="headerCenter"></slot>
17
- </template>
18
- <template #end>
19
- <slot name="headerRight"></slot>
20
- </template>
21
- </MobileToolbar>
22
- <div class="mt-14">
23
- <slot name="default"></slot>
24
- </div>
2
+ <Sidebar
3
+ position="right"
4
+ v-if="showDialog"
5
+ v-model:visible="showDialog"
6
+ modal
7
+ :show-close-icon="false"
8
+ #container
9
+ >
10
+ <div class="overflow-y-scroll">
11
+ <MobileToolbar class="bg-gray-800 text-white">
12
+ <template #start>
13
+ <slot name="headerLeft"></slot>
14
+ </template>
15
+ <template #center>
16
+ <slot name="headerCenter"></slot>
17
+ </template>
18
+ <template #end>
19
+ <slot name="headerRight"></slot>
20
+ </template>
21
+ </MobileToolbar>
22
+ <div class="mt-14">
23
+ <slot name="default"></slot>
25
24
  </div>
26
- </Sidebar>
27
- </template>
28
- <script lang="ts" setup>
29
- /**
25
+ </div>
26
+ </Sidebar>
27
+ </template>
28
+ <script lang="ts" setup>
29
+ /**
30
30
  * This file was automatically generated by simpleapp generator. Every
31
31
  * MODIFICATION OVERRIDE BY GENERATEOR
32
32
  * last change 2023-10-28
33
33
  * Author: Ks Tan
34
34
  */
35
- const showDialog = defineModel<boolean>({ required: true });
36
- const props = defineProps<{ closeEventName: string }>();
37
- useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
38
- if (props.closeEventName == closeEventName){
39
- showDialog.value = false;
40
- }
41
- });
42
-
43
- </script>
44
-
35
+ const showDialog = defineModel<boolean>({ required: true });
36
+ const props = defineProps<{ closeEventName: string }>();
37
+ useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
38
+ if (props.closeEventName == closeEventName) {
39
+ showDialog.value = false;
40
+ }
41
+ });
42
+ </script>
@@ -22,9 +22,8 @@
22
22
  const showDialog = defineModel<boolean>({ required: true });
23
23
  const props = defineProps<{ closeEventName: string }>();
24
24
  useNuxtApp().$listen("CloseDialog", (closeEventName: string) => {
25
- if (props.closeEventName == closeEventName){
26
- showDialog.value = false;
27
- }
25
+ if (props.closeEventName == closeEventName) {
26
+ showDialog.value = false;
27
+ }
28
28
  });
29
-
30
29
  </script>
@@ -1,5 +1,6 @@
1
1
  <template>
2
- <span>{{ toLocalDate(value ?? "") }}</span>
2
+ <span v-if="modelValue">{{ toLocalDate(modelValue) }}</span>
3
+ <span v-else>-</span>
3
4
  </template>
4
5
  <script lang="ts" setup>
5
6
  /**
@@ -8,5 +9,5 @@
8
9
  * last change 2024-02-04
9
10
  * author: Ks Tan
10
11
  */
11
- const props = defineProps<{ value?: string }>();
12
+ const modelValue = defineModel<Date|string>()
12
13
  </script>
@@ -1,8 +1,15 @@
1
- <template>
2
- <span v-if="setting?.collection" @click="viewRecord" class="text-primary-700 hover:text-primary-500 cursor-pointer">
3
- {{ displayText }}
4
- </span>
5
- <span v-else>{{ displayText }}</span>
1
+ <template>
2
+ <span
3
+ v-if="setting?.collection"
4
+ @click="viewRecord"
5
+ class="text-primary-700 hover:text-primary-500 dark:text-primary-400 cursor-pointer"
6
+ >
7
+ <slot>
8
+ {{ displayText }}
9
+ </slot>
10
+
11
+ </span>
12
+ <span v-else>{{ displayText }}</span>
6
13
  </template>
7
14
  <script setup lang="ts">
8
15
  /**
@@ -11,35 +18,32 @@
11
18
  * last change 2024-02-04
12
19
  * author: Ks Tan
13
20
  */
14
- import { ForeignKey } from '~/types';
15
-
21
+ import { ForeignKey } from "~/types";
16
22
 
17
- type SettingProp = {collection:string, displayField?:string}
18
- const modelValue = defineModel<ForeignKey>()
19
- const props = defineProps<{setting:SettingProp}>()
20
- const displayText = computed(()=>{
21
- const s = props.setting
22
- if (!modelValue.value) return undefined
23
- else if(!s.collection) return modelValue.value
24
- else if(s.displayField) return modelValue.value[s.displayField]
25
- else return modelValue.value.label
26
- })
27
- const {$event} = useNuxtApp()
28
- const viewer=ref()
23
+ type SettingProp = { collection: string; displayField?: string };
24
+ const modelValue = defineModel<ForeignKey>();
25
+ const props = defineProps<{ setting: SettingProp }>();
26
+ const displayText = computed(() => {
27
+ const s = props.setting;
28
+ if (!modelValue.value) return undefined;
29
+ else if (!s.collection) return modelValue.value;
30
+ else if (s.displayField) return modelValue.value[s.displayField];
31
+ else return modelValue.value.label;
32
+ });
33
+ const { $event } = useNuxtApp();
34
+ const viewer = ref();
29
35
  const viewRecord = () => {
30
- viewer.value = getDocument(props.setting.collection)?.viewer
31
-
32
- // getDocumentUrl(setting.collection,modelValue ? modelValue['_id']:'')
33
- //getDocumentUrl(setting.collection,modelValue ? modelValue['_id']:'')
34
- $event('ViewRecord',{
35
- _id: modelValue.value?._id as string,
36
- label: modelValue.value?.label as string,
37
- eventId: randomUUID(),
38
- documentName: props.setting.collection,
39
- viewer: viewer.value,
40
- readonly:true
41
-
42
- })
36
+ viewer.value = getDocument(props.setting.collection)?.viewer;
43
37
 
44
- }
45
- </script>
38
+ // getDocumentUrl(setting.collection,modelValue ? modelValue['_id']:'')
39
+ //getDocumentUrl(setting.collection,modelValue ? modelValue['_id']:'')
40
+ $event("ViewRecord", {
41
+ _id: modelValue.value?._id as string,
42
+ label: modelValue.value?.label as string,
43
+ eventId: randomUUID(),
44
+ documentName: props.setting.collection,
45
+ viewer: viewer.value,
46
+ readonly: true,
47
+ });
48
+ };
49
+ </script>
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <Dropdown
3
+ @update:modelValue="change"
4
+ v-model="modelValue"
5
+ :options="options"
6
+ optionLabel="label"
7
+ optionValue="value"
8
+ :placeholder="placeholder"
9
+ />
10
+ </template>
11
+ <script setup lang="ts">
12
+ /**
13
+ * This file was automatically generated by simpleapp generator. Every
14
+ * MODIFICATION OVERRIDE BY GENERATEOR
15
+ * last change 2024-02-26
16
+ * Author: Ks Tan
17
+ */
18
+ import Dropdown from "primevue/dropdown";
19
+ import { ForeignKey, FormCrudEvent } from "~/types";
20
+ const emits = defineEmits(["change"]);
21
+ const modelValue = defineModel<string>();
22
+ const list = ref<ForeignKey[]>([]);
23
+
24
+ const props = defineProps<{
25
+ documentName: string;
26
+ placeholder?: string;
27
+ showNull?: boolean;
28
+ allowAddNew?: boolean;
29
+ filter?: any
30
+ }>();
31
+ const options = ref<
32
+ {
33
+ value: string;
34
+ label: string;
35
+ }[]
36
+ >([]);
37
+ const getListOptions = async () => {
38
+ const filter = props.filter ?? {}
39
+ const res = await getDocumentApi(props.documentName).autoComplete("", filter);
40
+ list.value = res.data as ForeignKey[];
41
+ if (props.allowAddNew)
42
+ list.value.unshift({ _id: "new", code: "", label: t("addNew") });
43
+ if (props.showNull)
44
+ list.value.unshift({ _id: "", code: "", label: t("null") });
45
+ options.value = list.value.map((item) => ({
46
+ value: item._id,
47
+ label: item.label,
48
+ }));
49
+ };
50
+ onMounted(async () => {
51
+ await getListOptions();
52
+ if (modelValue.value) change(modelValue.value);
53
+ });
54
+ const getItem = (id: string) => list.value?.find((item) => item._id == id);
55
+
56
+ const change = (id: string) => {
57
+ const selectedItem = getItem(id);
58
+ if (selectedItem?._id == "new") {
59
+ const doc = getDocument(props.documentName)?.docClass;
60
+ if (doc) {
61
+ const tmpdata = doc?.getReactiveData();
62
+ type DataType = typeof tmpdata.value;
63
+ onScreenAddDocument<DataType>(
64
+ props.documentName,
65
+ undefined,
66
+ async (eventType: FormCrudEvent, data: DataType) => {
67
+ if (eventType == FormCrudEvent.create) {
68
+ await getListOptions();
69
+ modelValue.value = data._id;
70
+ emits("change", data._id, getItem(data._id));
71
+ }
72
+ },
73
+ );
74
+ }
75
+ } else {
76
+ emits("change", id, selectedItem);
77
+ }
78
+ };
79
+ </script>
@@ -0,0 +1 @@
1
+ all static select filter