@simitgroup/simpleapp-generator 1.2.6 → 1.2.8

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 (91) hide show
  1. package/README.md +6 -0
  2. package/dist/buildinschemas/organization.js +2 -2
  3. package/dist/buildinschemas/organization.js.map +1 -1
  4. package/dist/framework.js +3 -3
  5. package/dist/framework.js.map +1 -1
  6. package/package.json +1 -1
  7. package/src/buildinschemas/organization.ts +2 -2
  8. package/src/framework.ts +3 -3
  9. package/templates/basic/nest/controller.ts.eta +25 -21
  10. package/templates/basic/nest/service.ts.eta +5 -5
  11. package/templates/basic/nuxt/default.ts.eta +1 -1
  12. package/templates/basic/nuxt/pages.form.vue.eta +4 -4
  13. package/templates/basic/nuxt/pages.landing.vue.eta +9 -0
  14. package/templates/basic/nuxt/pages.viewer.vue.eta +4 -3
  15. package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +6 -17
  16. package/templates/nest/src/simpleapp/apischemas/index.ts._eta +10 -0
  17. package/templates/nest/src/simpleapp/generate/apischemas/index.ts.eta +7 -19
  18. package/templates/nest/src/simpleapp/generate/apischemas/simpleapp.apischema.ts.eta +20 -0
  19. package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +9 -3
  20. package/templates/nest/src/simpleapp/generate/types/index.ts.eta +3 -3
  21. package/templates/nest/src/simpleapp/generate/types/simpleapp.type.ts.eta +1 -4
  22. package/templates/nest/src/simpleapp/types/index.ts._eta +7 -0
  23. package/templates/nuxt/app.vue.eta +7 -3
  24. package/templates/nuxt/assets/css/calendar.css._eta +50 -0
  25. package/templates/nuxt/assets/css/style.css._eta +1 -5
  26. package/templates/nuxt/assets/primevue/passthrough.ts._eta +38 -16
  27. package/templates/nuxt/components/button/ButtonDanger.vue._eta +6 -0
  28. package/templates/nuxt/components/button/ButtonDefault.vue._eta +6 -0
  29. package/templates/nuxt/components/button/ButtonPrimary.vue._eta +6 -0
  30. package/templates/nuxt/components/button/ButtonWarning.vue._eta +6 -0
  31. package/templates/nuxt/components/calendar/CalendarByResource.vue.eta +188 -0
  32. package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +74 -0
  33. package/templates/nuxt/components/docPage/DocPageList.vue.eta +48 -40
  34. package/templates/nuxt/components/event/EventDocumentViewer.vue._eta +12 -12
  35. package/templates/nuxt/components/event/EventNotification.vue._eta +23 -2
  36. package/templates/nuxt/components/header/HeaderBar.vue._eta +32 -19
  37. package/templates/nuxt/components/header/HeaderBreadcrumb.vue.eta +2 -2
  38. package/templates/nuxt/components/header/button/HeaderButtonMenuPicker.vue._eta +7 -15
  39. package/templates/nuxt/components/header/button/HeaderButtonProfile.vue.eta +23 -34
  40. package/templates/nuxt/components/list/ListView.vue.eta +10 -8
  41. package/templates/nuxt/components/renderer/RendererBoolean.vue.eta +6 -1
  42. package/templates/nuxt/components/renderer/RendererDate.vue.eta +6 -0
  43. package/templates/nuxt/components/renderer/RendererForeignKey.vue.eta +7 -1
  44. package/templates/nuxt/components/renderer/RendererLink.vue.eta +33 -0
  45. package/templates/nuxt/components/renderer/RendererMoney.vue.eta +20 -2
  46. package/templates/nuxt/components/renderer/RendererMultiText.vue.eta +6 -0
  47. package/templates/nuxt/components/renderer/RendererViewer.vue.eta +32 -0
  48. package/templates/nuxt/components/renderer/{index.ts.eta → index.ts._eta} +10 -2
  49. package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +37 -12
  50. package/templates/nuxt/components/simpleApp/SimpleAppDocumentNo.vue.eta +8 -2
  51. package/templates/nuxt/components/simpleApp/SimpleAppFieldContainer.vue.eta +24 -17
  52. package/templates/nuxt/components/simpleApp/SimpleAppForm.vue.eta +1 -1
  53. package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue.eta +3 -2
  54. package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +25 -8
  55. package/templates/nuxt/components/simpleApp/SimpleAppInputTable.vue.eta +4 -3
  56. package/templates/nuxt/components/simpleApp/pending/SimpleAppValue.vue +1 -1
  57. package/templates/nuxt/components/user/UserProfileListItem.vue.eta +2 -2
  58. package/templates/nuxt/composables/date.generate.ts.eta +16 -0
  59. package/templates/nuxt/composables/goTo.generate.ts.eta +1 -0
  60. package/templates/nuxt/composables/screensize.generate.ts.eta +1 -0
  61. package/templates/nuxt/composables/stringHelper.generate.ts.eta +3 -6
  62. package/templates/nuxt/error.vue._eta +4 -4
  63. package/templates/nuxt/layouts/default.vue._eta +32 -8
  64. package/templates/nuxt/layouts/loginlayout.vue._eta +3 -0
  65. package/templates/nuxt/layouts/mobile.vue._eta +29 -0
  66. package/templates/nuxt/nuxt.config.ts._eta +27 -13
  67. package/templates/nuxt/pages/[xorg]/index.vue._eta +11 -9
  68. package/templates/nuxt/pages/[xorg]/organization.vue.eta +5 -0
  69. package/templates/nuxt/pages/[xorg]/user/{index.vue._eta → index.vue.eta} +10 -12
  70. package/templates/nuxt/pages/login.vue._eta +34 -0
  71. package/templates/nuxt/plugins/10.simpleapp-event.ts.eta +35 -22
  72. package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +6 -0
  73. package/templates/nuxt/server/api/[xorg]/[...].ts.eta +7 -40
  74. package/templates/nuxt/server/api/profile/[...].ts.eta +3 -32
  75. package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +1 -1
  76. package/templates/nuxt/types/calendar.ts.eta +61 -0
  77. package/templates/nuxt/types/documentlist.ts.eta +6 -0
  78. package/templates/nuxt/types/events.ts.eta +5 -5
  79. package/templates/nuxt/types/index.ts._eta +4 -3
  80. package/templates/nuxt/types/listview.ts.eta +6 -0
  81. package/templates/nuxt/types/notifications.ts.eta +6 -1
  82. package/templates/nuxt/types/others.ts.eta +10 -2
  83. package/templates/nuxt/types/schema.ts.eta +8 -0
  84. package/templates/nuxt/types/simpleappinput.ts.eta +6 -0
  85. package/templates/nuxt/types/user.ts.eta +8 -0
  86. package/templates/nuxt/types/workflow.ts.eta +6 -1
  87. package/templates/project/lang/default._json +4 -1
  88. package/tsconfig.tsbuildinfo +1 -1
  89. package/templates/nuxt/pages/login.vue.eta +0 -30
  90. /package/templates/nuxt/pages/[xorg]/user/{[id].vue._eta → [id].vue.eta} +0 -0
  91. /package/templates/nuxt/pages/[xorg]/{user.vue._eta → user.vue.eta} +0 -0
@@ -1,43 +1,56 @@
1
- <script setup lang="ts">
2
- //import ButtonMenuPicker from "./ButtonMenuPicker.vue"
3
-
4
- //import ButtonProfile from './ButtonProfile.vue';
5
-
6
-
7
- </script>
8
1
  <template>
9
2
  <!-- <header> -->
10
3
  <!-- <MegaMenu :model="getMenus()" orientation="horizontal" /> -->
11
- <client-only>
12
- <div class="flex flex-row">
13
-
4
+
5
+ <div >
6
+ <client-only>
14
7
 
15
8
  <div class="flex-1 flex flex-row gap-2 p-2">
16
- <div class="">
9
+ <!-- <div class="">
17
10
  <HeaderButtonMenuPicker/>
18
- </div>
11
+ </div> -->
19
12
 
20
13
  <!-- <div class="">
21
14
  <HeaderButtonHome/>
22
15
  </div> -->
23
- <HeaderBreadcrumb class="hidden md:block" v-if="useRoute().fullPath!='/'"></HeaderBreadcrumb>
16
+ <div v-if="isMobile()" class="dark:text-white max-w-[15rem] truncate ...">
17
+ <div v-if="useRoute().fullPath.split('/').length<=3">{{ t('home') }}</div>
18
+ <div v-else>{{ _.last(useRoute().fullPath.split('/')) }}</div>
19
+ </div>
20
+ <div v-else>
21
+ <HeaderBreadcrumb class="hidden md:block" v-if="useRoute().fullPath!='/'"></HeaderBreadcrumb>
22
+ </div>
23
+
24
24
  </div>
25
25
  <div class="flex-1 flex flex-row-reverse gap-2 p-2">
26
-
27
- <div class=" text-right">
26
+ <!--
27
+ <div class=" text-right" v-if="!isMobile()">
28
28
  <HeaderButtonProfile/>
29
29
  </div>
30
- <div class=" text-right">
30
+ <div class=" text-right">
31
31
  <HeaderButtonTaskList/>
32
- </div>
32
+ </div> -->
33
33
  <!-- <div class="">
34
34
  <HeaderSelectBranch/>
35
35
  </div> -->
36
36
  </div>
37
37
 
38
38
 
39
-
39
+ </client-only>
40
40
  </div>
41
- </client-only>
41
+
42
42
  <!-- </header> -->
43
43
  </template>
44
+
45
+ <script setup lang="ts">
46
+ import _ from 'lodash'
47
+ //import ButtonMenuPicker from "./ButtonMenuPicker.vue"
48
+
49
+ //import ButtonProfile from './ButtonProfile.vue';
50
+ const pageTitle = ref<string>('')
51
+ onMounted(()=>{
52
+ // useNuxtApp().$listen('SetTitle',(title:string)=>{
53
+ // pageTitle.value = title
54
+ // })
55
+ })
56
+ </script>
@@ -52,11 +52,11 @@ const getBranches = ()=>{
52
52
  <template>
53
53
  <Breadcrumb :home="home" :model="items" class="!p-0 border-none ">
54
54
  <template #item="{ item }">
55
- <NuxtLink :to="item.url" v-if="item.url" :active-class="'-'" :exact-active-class="'-'">
55
+ <NuxtLink :to="item.url" v-if="item.url" class="dark:text-white" :active-class="'-'" :exact-active-class="'-'">
56
56
  <span :class="item.icon"></span>{{ item.label }}
57
57
  </NuxtLink>
58
58
  <div v-else>
59
- <span class="cursor-pointer" @click="showSwitcher">{{ item.label }}</span>
59
+ <span class="cursor-pointer dark:text-white" @click="showSwitcher">{{ item.label }}</span>
60
60
  <OverlayPanel ref="op">
61
61
  <div>
62
62
  <ul class="flex flex-col">
@@ -27,29 +27,21 @@ getMenustFromPageMeta().reduce((r, item) => {
27
27
 
28
28
  </script>
29
29
  <template>
30
- <div>
31
- <button class="text-center border-none cursor-pointer" v-if="getCurrentXorg()" @click="visible=true">
32
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
33
- <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
34
- </svg>
35
- </button>
36
-
37
- <Dialog v-model:visible="visible" modal :header="t('pickDocument')" :pt="{dialog:{ class:' bg-primary-800 ' }}">
30
+
31
+ <button class="text-center border-none cursor-pointer pi pi-bars dark:text-white" v-if="getCurrentXorg()" @click="visible=true">
32
+ <Dialog v-model:visible="visible" modal :header="t('pickDocument')" :pt="{dialog:{ class:' bg-primary-800 ' }}">
38
33
  <div class="">
39
34
  <div v-for="m in treemenu" class="m-4">
40
35
  <h3>{{ t(m.name) }}</h3>
41
- <div class="grid grid-cols-6 gap-4">
42
- <button v-for="submenu in m.children" class="border rounded-lg p-2" @click="selectMenu(submenu)">
36
+ <div class="grid md:grid-cols-2 lg:grid-cols-6 gap-4">
37
+ <ButtonPrimary v-for="submenu in m.children" class="border rounded-lg p-2" @click="selectMenu(submenu)">
43
38
  {{ t(submenu.name) }}
44
- </button>
39
+ </ButtonPrimary>
45
40
  </div>
46
41
 
47
42
  </div>
48
43
 
49
44
  </div>
50
45
  </Dialog>
51
- </div>
46
+ </button>
52
47
  </template>
53
- <style scoped>
54
-
55
- </style>
@@ -6,9 +6,11 @@ import {ref} from 'vue'
6
6
 
7
7
 
8
8
  const { locale,setLocale,locales } = useI18n()
9
+ const colorMode = useColorMode()
10
+
9
11
  const mylocale = ref(locale)
10
12
  const userprofileoverlay = ref();
11
- const colors = [{value:'light', name:'Light'},{value:'dark', name:'Dark'}]
13
+ const colors = [{value:'light', name:t('light')},{value:'dark', name:t('dark')}]
12
14
  const toggle = (event:any) => {
13
15
  userprofileoverlay.value.toggle(event);
14
16
  }
@@ -34,50 +36,39 @@ const saveLocale=async (v:string)=>{
34
36
 
35
37
  </script>
36
38
 
37
- <template>
38
- <div>
39
- <div class=" w-[120px] truncate ...">
40
-
41
- <div class="flex flex-row-reverse cursor-pointer border-none w-full" @click="toggle">
42
- <p>{{ getProfileFullName() }}</p>
43
- <!-- <Avatar :image="getUserStore().getAvatarLink(32)" class="" size="normal" shape="circle" /> -->
44
- <div class="w-8 h-8 bg-cover bg-center rounded-md">
45
- <img :src="getAvatarLink(getProfileEmail(),32)" alt="" class="h-full w-full overflow-hidden object-cover rounded-full border-2 border-white dark:border-gray-700 shadow" />
46
- </div>
47
- </div>
48
-
39
+ <template>
40
+ <div class="bg-cover bg-center rounded-md p-3 cursor-pointer profile-button" @click="toggle">
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" />
49
42
  </div>
50
- <OverlayPanel :pt="{root:{class:'w w-80'}}" ref="userprofileoverlay">
51
- <div>
52
- <div class="py-2 transition duration-150 ease-in-out z-10 absolute top-0 right-0 bottom-0 left-0" id="modal">
53
- <div role="alert" class="container mx-auto w-full md:w-full max-w-lg">
54
- <div class="relative p-4 md:p-8 bg-white dark:bg-gray-800 shadow-md rounded border border-gray-400">
43
+
44
+ <OverlayPanel appendTo="body" ref="userprofileoverlay" >
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="">
48
+ <!-- <div class="relative p-4 md:p-8 bg-white dark:bg-gray-800 shadow-md rounded border border-gray-400"> -->
55
49
  <div class="w-full flex items-center justify-start text-gray-600 dark:text-gray-400 mb-5" >
56
50
  <div class="w-12 h-12 bg-cover bg-center rounded-md">
57
- <img :src="getAvatarLink(getProfileEmail(),32)" alt="" class="h-full w-full overflow-hidden object-cover rounded-full border-2 border-white dark:border-gray-700 shadow" />
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" />
58
52
  </div>
59
53
  <div class="flex flex-col" >
60
- <h1 class="text-left text-gray-800 dark:text-gray-100 font-lg font-bold tracking-normal leading-tight ml-2">{{ getUserProfile().fullName }}</h1>
61
- <p class="text-gray-400 dark:text-gray-100 font-normal text-base tracking-normal ml-2 mr-4">{{getUserProfile().group }}</p>
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>
62
56
  </div>
63
57
 
64
58
  </div>
65
- <!-- language -->
66
59
  <div class="col-span-full">
67
60
  <label for="pick-lang" class="block text-sm font-medium leading-6 text-gray-900 dark:text-gray-300">{{ t('language') }}</label>
68
61
  <div class="mt-2">
69
62
  <Dropdown inputId="pick-lang" @update:model-value="saveLocale" v-model="mylocale" option-value="code" option-label="name" :options="locales" >
70
- </Dropdown>
71
- <!-- <select v-model="$colorMode.preference" id="picklang">
72
- <option value="light">Light</option>
73
- <option value="dark">Dark</option>
74
- </select> -->
63
+ </Dropdown>
75
64
  </div>
76
65
  </div>
77
66
  <div class="mt-3 col-span-full">
78
67
  <label for="pick-theme" class="block text-sm font-medium leading-6 text-gray-900 dark:text-gray-300">{{ t('theme') }}</label>
79
68
  <div class="mt-2">
80
- <Dropdown inputId="pick-theme" v-model="$colorMode.preference" option-value="value" option-label="name" :options="colors" >
69
+ <h1>Color mode: {{ $colorMode.value }}</h1>
70
+
71
+ <Dropdown inputId="pick-theme" v-model="colorMode.preference" option-value="value" option-label="name" :options="colors" >
81
72
  </Dropdown>
82
73
 
83
74
  </div>
@@ -86,15 +77,13 @@ const saveLocale=async (v:string)=>{
86
77
 
87
78
  <div class="mt-3 flex items-center justify-start w-full">
88
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>
89
- <!-- <button class="focus:outline-none transition duration-150 ease-in-out bg-gray-600 rounded text-white px-8 py-2 text-sm" @click="toFrontpage">Pick Tenant</button> -->
90
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-gray-400 ease-in-out hover:border-gray-400 hover:bg-gray-300 border rounded px-8 py-2 text-sm" @click="logout()">{{ t('logout') }}</button>
91
81
  </div>
92
- </div>
82
+ <!-- </div> -->
93
83
  </div>
94
- </div>
84
+ <!-- </div> -->
95
85
 
96
- </div>
97
-
86
+ <!-- </div> -->
98
87
  </OverlayPanel>
99
- </div>
88
+
100
89
  </template>
@@ -1,14 +1,13 @@
1
1
  <template>
2
2
  <div>
3
- <div v-if="withFilter">
4
- <input
5
- autofocus
3
+ <div v-if="withFilter" class="">
4
+ <InputText
6
5
  placeholder="search"
7
6
  v-model="searchvalue"
8
- class="w-full border p-2"
9
- type="search" />
7
+ class="w-full dark:text-white"
8
+ type="search" />
10
9
  </div>
11
- <div class="max-h-screen overflow-auto">
10
+ <div class=" overflow-auto" v-if="filterlist.length>0">
12
11
  <ul >
13
12
  <li v-for="(item,index) in filterlist">
14
13
  <div :class="getSelectedCSS(item)">
@@ -23,6 +22,9 @@
23
22
  </li>
24
23
  </ul>
25
24
  </div>
25
+ <div v-else class="p-10">
26
+ <div class="text-xl text-center dark:text-gray-400 border p-10" >{{ t('noDataFound') }}</div>
27
+ </div>
26
28
  </div>
27
29
  </template>
28
30
  <script setup lang="ts" generic="T extends {[key:string]:any}">
@@ -56,9 +58,9 @@ const filterlist = computed(()=>{
56
58
  })
57
59
  const getSelectedCSS= (item:T)=>{
58
60
  if(selecteditem.value == item.code){
59
- return "p-2 border bg-sky-200"
61
+ return "p-2 border-l-none border-r-none bg-sky-200 border-t-2"
60
62
  }else{
61
- return "p-2 border hover-list-primary"
63
+ return "p-2 border-l-none border-r-none hover-list-primary border-t-2 dark:border-t-gray-700"
62
64
  }
63
65
 
64
66
  }
@@ -2,6 +2,11 @@
2
2
  <i class="pi" :class="{ 'pi-check-circle text-green-500 ': modelValue, 'pi-times-circle text-red-500': !modelValue }"></i>
3
3
  </template>
4
4
  <script lang="ts" setup>
5
-
5
+ /**
6
+ * This file was automatically generated by simpleapp generator during initialization.
7
+ * DONT CHANGE THIS FILE CAUSE IT OVERRIDE
8
+ * last change 2024-02-04
9
+ * author: Ks Tan
10
+ */
6
11
  const modelValue = defineModel()
7
12
  </script>
@@ -2,5 +2,11 @@
2
2
  <span>{{ toLocalDate(value??'') }}</span>
3
3
  </template>
4
4
  <script lang="ts" setup>
5
+ /**
6
+ * This file was automatically generated by simpleapp generator during initialization.
7
+ * DONT CHANGE THIS FILE CAUSE IT OVERRIDE
8
+ * last change 2024-02-04
9
+ * author: Ks Tan
10
+ */
5
11
  const props = defineProps<{value?:string}>()
6
12
  </script>
@@ -5,6 +5,12 @@
5
5
  <span v-else>{{ displayText }}</span>
6
6
  </template>
7
7
  <script setup lang="ts">
8
+ /**
9
+ * This file was automatically generated by simpleapp generator during initialization.
10
+ * DONT CHANGE THIS FILE CAUSE IT OVERRIDE
11
+ * last change 2024-02-04
12
+ * author: Ks Tan
13
+ */
8
14
  import { ForeignKey } from '~/types';
9
15
 
10
16
 
@@ -28,7 +34,7 @@ const viewRecord = () => {
28
34
  $event('ViewRecord',{
29
35
  _id: modelValue.value?._id as string,
30
36
  label: modelValue.value?.label as string,
31
- eventId: crypto.randomUUID(),
37
+ eventId: randomUUID(),
32
38
  documentName: props.setting.collection,
33
39
  viewer: viewer.value,
34
40
  readonly:true
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <a @click="go" class="text-primary-700 hover:text-primary-500 cursor-pointer">
3
+ <slot name="default">
4
+ <div >{{ value[fields[0]] }}</div>
5
+ </slot>
6
+ </a>
7
+ </template>
8
+ <script setup lang="ts">
9
+ /**
10
+ * This file was automatically generated by simpleapp generator during initialization.
11
+ * DONT CHANGE THIS FILE CAUSE IT OVERRIDE
12
+ * last change 2024-02-04
13
+ * author: Ks Tan
14
+ */
15
+
16
+ const props = defineProps<{
17
+ fields:any,
18
+ setting:any,
19
+ value:any
20
+ }>()
21
+
22
+ const go = ()=>{
23
+ goTo(props.setting.path,props.value._id)
24
+ // useNuxtApp().$event('ViewRecord',{
25
+ // _id: props.value._id ,
26
+ // documentName: props.setting.documentName,
27
+ // viewer: getDocument(props.setting.documentName)?.viewer,
28
+ // label: props.setting.documentName,
29
+ // document:getDocument(props.setting.documentName)?.docClass,
30
+ // eventId: crypto.randomUUID()
31
+ // })
32
+ }
33
+ </script>
@@ -1,7 +1,25 @@
1
1
 
2
2
  <template>
3
- <span>{{ Intl.NumberFormat('en-US',{style:'currency',currency:'USD'}).format(modelValue) }}</span>
3
+ <span v-if="showCurrency"> {{ Intl.NumberFormat( useI18n().defaultLocale,{
4
+ style:'currency',
5
+ currency: getUserProfile()?.currency,
6
+ currencyDisplay: 'symbol',
7
+ }).format(modelValue) }}</span>
8
+ <span v-else> {{ modelValue.toLocaleString(useI18n().defaultLocale,options) }}</span>
4
9
  </template>
5
10
  <script lang="ts" setup>
6
- const props = defineProps(['modelValue'])
11
+ /**
12
+ * This file was automatically generated by simpleapp generator during initialization.
13
+ * DONT CHANGE THIS FILE CAUSE IT OVERRIDE
14
+ * last change 2024-02-04
15
+ * author: Ks Tan
16
+ */
17
+
18
+ const options = {
19
+ style: 'decimal', // Other options: 'currency', 'percent', etc.
20
+ minimumFractionDigits: 2,
21
+ maximumFractionDigits: 2,
22
+ };
23
+ const modelValue = defineModel<number>({required:true})
24
+ const props = defineProps<{showCurrency?:boolean}>()
7
25
  </script>
@@ -6,6 +6,12 @@
6
6
  </p>
7
7
  </template>
8
8
  <script lang="ts" setup>
9
+ /**
10
+ * This file was automatically generated by simpleapp generator during initialization.
11
+ * DONT CHANGE THIS FILE CAUSE IT OVERRIDE
12
+ * last change 2024-02-04
13
+ * author: Ks Tan
14
+ */
9
15
  const props = defineProps(['value','fields'])
10
16
 
11
17
  </script>
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <a @click="openViewer" class="text-primary-700 dark:text-primary-400 hover:text-primary-500 cursor-pointer">
3
+ <slot name="default">
4
+ <div v-if="fields">{{ value[fields[0]] }}</div>
5
+ </slot>
6
+ </a>
7
+ </template>
8
+ <script setup lang="ts">
9
+ /**
10
+ * This file was automatically generated by simpleapp generator during initialization.
11
+ * DONT CHANGE THIS FILE CAUSE IT OVERRIDE
12
+ * last change 2024-02-04
13
+ * author: Ks Tan
14
+ */
15
+ import { RendererSetting } from '~/types';
16
+ const props = defineProps<{
17
+ fields?:string[],
18
+ setting:RendererSetting,
19
+ value:any
20
+ }>()
21
+
22
+ const openViewer = ()=>{
23
+ useNuxtApp().$event('ViewRecord',{
24
+ _id: props.value._id ,
25
+ documentName: props.setting.documentName,
26
+ viewer: getDocument(props.setting.documentName)?.viewer,
27
+ label: props.setting.documentName,
28
+ document:getDocument(props.setting.documentName)?.docClass,
29
+ eventId: randomUUID()
30
+ })
31
+ }
32
+ </script>
@@ -1,12 +1,20 @@
1
+ /**
2
+ * This file was automatically generated by simpleapp generator during initialization.
3
+ * YOU CAN MODIFY IT.
4
+ * last change 2024-02-04
5
+ * author: Ks Tan
6
+ */
1
7
  import RendererBoolean from './RendererBoolean.vue'
2
8
  import RendererDate from './RendererDate.vue'
3
9
  import RendererForeignKey from './RendererForeignKey.vue'
4
10
  import RendererMoney from './RendererMoney.vue'
5
11
  import RendererMultiText from './RendererMultiText.vue'
6
-
12
+ import RendererViewer from './RendererViewer.vue'
13
+ import RendererLink from './RendererLink.vue'
7
14
 
8
15
  export default {
9
16
 
10
- RendererBoolean,RendererDate,RendererForeignKey,RendererMoney,RendererMultiText
17
+ RendererBoolean,RendererDate,RendererForeignKey,RendererMoney,RendererMultiText,RendererViewer,
18
+ RendererLink
11
19
 
12
20
  };
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <AutoComplete v-model="modelValue" v-if="!readonly" ref="autocompleteinput"
3
3
  forceSelection optionLabel="label"
4
- @focus="($event.target as HTMLInputElement).select()"
4
+ @focus="setFocus"
5
5
  @item-select="pickAutoComplete"
6
6
  @complete="getListFromAutocompleteApi"
7
7
  :placeholder="t('keyword')"
@@ -17,7 +17,25 @@
17
17
  @blur="onBlurAutocomplete"
18
18
  :inputId="inputId" :path="setting.instancepath"
19
19
  :readonly="readonly"
20
- />
20
+ >
21
+ <template #header>
22
+ <slot name="header">
23
+ <div class="flex flex-row font font-bold dark:text-white">
24
+ <div class="w w-1/3">{{ t(codefield) ?? t('code') }}</div>
25
+ <div class="w w-2/3" >{{ t(labelfield) ?? t('label') }}</div>
26
+ </div>
27
+ </slot>
28
+ </template>
29
+ <template #option="{index,option}">
30
+ <slot name="option" :index="index" :option="option">
31
+ <div class="flex flex-row dark:text-white">
32
+ <div class="w w-1/3" >{{ option.code }}</div>
33
+ <div class="w w-2/3" >{{ option.label }}</div>
34
+ </div>
35
+ </slot>
36
+ </template>
37
+ <!-- </slot> -->
38
+ </AutoComplete>
21
39
  <div v-else class="p-3 border rounded-lg border-gray-300 dark:border-blue-900/40 ">
22
40
  <span :readonly="readonly" class="cursor-pointer text-primary-600 dark:text-primary-400 "
23
41
  tabindex="0" @click="openViewer(true)">{{ modelValue && modelValue.label ? modelValue.label:'-' }}</span>
@@ -44,11 +62,17 @@ allowAddNew:true,showNull:true
44
62
  const path = '$'+props.setting.instancepath
45
63
  const modifiedpath = path.replaceAll('/','.')
46
64
  const queryresult = jsonpath.query(props.setting.defaultValue,modifiedpath)[0]
65
+ const remotedoc = getDocument(props.setting.fieldsetting['x-foreignkey'])
66
+ const schema:SchemaType = <SchemaType>remotedoc?.docClass.getSchema()
67
+
68
+ const labelfield = schema['x-simpleapp-config'].documentTitle as string
69
+ const codefield = schema['x-simpleapp-config'].uniqueKey as string
70
+ const docname = props.setting.fieldsetting['x-foreignkey']
47
71
 
48
72
  const emptyautocomplete = computed(():autocompletetype=> queryresult)
49
73
 
50
74
  const autocompleteitem = ref<autocompletetype>(emptyautocomplete.value)
51
- const modelValue = defineModel<autocompletetype>()
75
+ const modelValue = defineModel<autocompletetype>({required:true})
52
76
  if(modelValue.value && modelValue.value._id){
53
77
  autocompleteitem.value={...modelValue.value}
54
78
  }
@@ -124,25 +148,26 @@ const emitChanges = () =>{
124
148
 
125
149
  }
126
150
 
151
+
152
+ const setFocus = (ev:any) => {
153
+ if(!isMobile()) ev.target.select()
154
+ }
155
+
127
156
  //pop up records
128
- const openViewer = (readonly:boolean) =>{
129
- const remotedoc = getDocument(props.setting.fieldsetting['x-foreignkey'])
157
+ const openViewer = (readonly:boolean) =>{
130
158
 
131
159
  if(remotedoc){
132
- const schema:SchemaType = remotedoc.docClass.getSchema()
133
- const labelfield = schema['x-simpleapp-config'].documentTitle as string
134
- const codefield = schema['x-simpleapp-config'].uniqueKey as string
135
- const docname = props.setting.fieldsetting['x-foreignkey']
160
+
136
161
  $event('ViewRecord',{
137
162
  _id: modelValue.value?._id as string,
138
- eventId: crypto.randomUUID(),
163
+ eventId: randomUUID(),
139
164
  label: (readonly ? modelValue.value?.label : `${t('new') + ' '+ t(docname) }`) as string,
140
165
  readonly:readonly,
141
166
  viewer : getDocument(docname)?.viewer,
142
167
  documentName: docname,
143
168
 
144
169
  //after create, auto copy value into auto complete
145
- afterCreate:(data:any)=>{
170
+ after:(eventType:string,data:any,result:any)=>{
146
171
  autocompleteitem.value = {
147
172
  _id: data._id,
148
173
  code: data[codefield],
@@ -157,7 +182,7 @@ const openViewer = (readonly:boolean) =>{
157
182
  }
158
183
  modelValue.value = {...autocompleteitem.value}
159
184
  emitChanges()
160
- console.log("autocompleteitem.value",autocompleteitem.value ,modelValue.value)
185
+
161
186
 
162
187
  }
163
188
  })
@@ -3,11 +3,12 @@
3
3
 
4
4
  <div class="flex flex-row w-full">
5
5
  <InputText
6
+ @focus="setFocus"
6
7
  :readonly="readonly"
7
8
  v-model="modelValue"
8
9
  :placeholder="placeholder"
9
10
  :pt="pt"
10
- :class=" !pt ? 'flex-1 w-full rounded-lg '+ ( props.readonly?'':'dark:!bg-gray-700 rounded-tr-none rounded-br-none') : ''"
11
+ :class=" !pt ? 'flex-1 w-full rounded-lg '+ ( props.readonly?'':'rounded-tr-none rounded-br-none') : ''"
11
12
  />
12
13
  <span class="" v-if="!readonly">
13
14
  <button type="button" @click="toggle" tabindex="-1"
@@ -45,7 +46,7 @@ const props = defineProps<{
45
46
  const op = ref();
46
47
  const placeholder = ref('')
47
48
  const docFormatlist = ref()
48
- const modelValue = defineModel<string>()
49
+ const modelValue = defineModel<string>({required:true})
49
50
  const docNoFormat = props.setting.document.getReactiveData().value.docNoFormat
50
51
  const emits = defineEmits(['update:docNoFormat'])
51
52
 
@@ -72,6 +73,11 @@ const loadDocFormats = async () =>{
72
73
  }
73
74
  }
74
75
 
76
+
77
+ const setFocus = (ev:any) => {
78
+ if(!isMobile()) ev.target.select()
79
+ }
80
+
75
81
  onMounted(()=>{
76
82
  loadDocFormats()
77
83