@simitgroup/simpleapp-generator 1.3.5-alpha → 1.4.1-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 (74) hide show
  1. package/dist/buildinschemas/permission.d.ts.map +1 -1
  2. package/dist/buildinschemas/permission.js +10 -6
  3. package/dist/buildinschemas/permission.js.map +1 -1
  4. package/dist/buildinschemas/user.d.ts.map +1 -1
  5. package/dist/buildinschemas/user.js +22 -2
  6. package/dist/buildinschemas/user.js.map +1 -1
  7. package/dist/generate.js +20 -6
  8. package/dist/generate.js.map +1 -1
  9. package/dist/type.d.ts +2 -0
  10. package/dist/type.d.ts.map +1 -1
  11. package/dist/type.js.map +1 -1
  12. package/package.json +1 -1
  13. package/src/buildinschemas/permission.ts +10 -6
  14. package/src/buildinschemas/user.ts +23 -3
  15. package/src/generate.ts +19 -6
  16. package/src/type.ts +3 -1
  17. package/templates/basic/nest/service.ts.eta +7 -3
  18. package/templates/basic/nuxt/pages.[id].vue.eta +4 -4
  19. package/templates/basic/nuxt/pages.mobile.[id].vue.eta +39 -0
  20. package/templates/basic/nuxt/pages.mobile.landing.vue.eta +69 -0
  21. package/templates/nest/src/simpleapp/apischemas/index.ts._eta +29 -0
  22. package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +22 -12
  23. package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +26 -1
  24. package/templates/nest/src/simpleapp/generate/types/simpleapp.type.ts.eta +2 -1
  25. package/templates/nest/src/simpleapp/generate/workflow/workflow.service.ts.eta +1 -1
  26. package/templates/nest/src/simpleapp/profile/profile.service.ts.eta +1 -1
  27. package/templates/nest/src/simpleapp/profile/profile.types.ts.eta +1 -1
  28. package/templates/nest/src/simpleapp/services/perm.service.ts.eta +5 -7
  29. package/templates/nest/src/simpleapp/services/user.service.ts.eta.old +118 -0
  30. package/templates/nest/src/simpleapp/types/index.ts._eta +8 -0
  31. package/templates/nuxt/app.vue._eta +31 -17
  32. package/templates/nuxt/assets/primevue/passthrough.ts._eta +1 -1
  33. package/templates/nuxt/components/calendar/CalendarByResource.vue.eta +181 -163
  34. package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +8 -6
  35. package/templates/nuxt/components/form/FormDocnoformat.vue.eta +174 -0
  36. package/templates/nuxt/components/form/FormUser.vue._eta +91 -0
  37. package/templates/nuxt/components/form/user/FormUserPermission.vue.eta +83 -0
  38. package/templates/nuxt/components/header/HeaderBar.vue._eta +43 -39
  39. package/templates/nuxt/components/header/button/HeaderButtonProfile.vue.eta +7 -9
  40. package/templates/nuxt/components/page/PageDocList.vue.eta +6 -4
  41. package/templates/nuxt/components/renderer/RendererDateTime.vue.eta +13 -0
  42. package/templates/nuxt/components/renderer/RendererForeignKey.vue.eta +6 -3
  43. package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +3 -4
  44. package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +48 -4
  45. package/templates/nuxt/composables/date.generate.ts.eta +3 -1
  46. package/templates/nuxt/composables/goTo.generate.ts.eta +4 -1
  47. package/templates/nuxt/layouts/mobile.vue._eta +26 -12
  48. package/templates/nuxt/nuxt.config.ts._eta +27 -20
  49. package/templates/nuxt/pages/[xorg]/{user/index.vue.eta → docnoformat/[id].vue.eta} +11 -9
  50. package/templates/nuxt/pages/[xorg]/docnoformat.vue.eta +51 -20
  51. package/templates/nuxt/pages/[xorg]/mobile/docnoformat/index.vue.eta +59 -0
  52. package/templates/nuxt/pages/[xorg]/mobile/index.vue._eta +19 -0
  53. package/templates/nuxt/pages/[xorg]/mobile/organization/index.vue.eta +138 -0
  54. package/templates/nuxt/pages/[xorg]/mobile/pickgroup.vue._eta +35 -0
  55. package/templates/nuxt/pages/[xorg]/mobile/user/index.vue.eta +231 -0
  56. package/templates/nuxt/pages/[xorg]/pickgroup.vue._eta +35 -0
  57. package/templates/nuxt/pages/[xorg]/user.vue.eta +91 -74
  58. package/templates/nuxt/pages/profile.vue.eta +7 -7
  59. package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +14 -3
  60. package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +18 -16
  61. package/templates/nuxt/simpleapp/generate/commons/documents.ts.eta +1 -1
  62. package/templates/nuxt/types/events.ts.eta +1 -0
  63. package/templates/nuxt/types/simpleappinput.ts.eta +3 -2
  64. package/templates/nuxt/types/user.ts.eta +2 -1
  65. package/tsconfig.tsbuildinfo +1 -1
  66. package/templates/nest/src/simpleapp/services/user.service.ts.etax +0 -66
  67. package/templates/nuxt/pages/[xorg]/docnoformat/[doctype]/[id].vue.eta +0 -13
  68. package/templates/nuxt/pages/[xorg]/docnoformat/[doctype]/new.vue.eta +0 -229
  69. package/templates/nuxt/pages/[xorg]/docnoformat/[doctype].vue.eta +0 -38
  70. package/templates/nuxt/pages/[xorg]/docnoformat/index.vue.eta +0 -11
  71. package/templates/nuxt/pages/[xorg]/user/[id].vue.eta +0 -39
  72. package/templates/nuxt/pages/[xorg]/user/form.vue.eta +0 -334
  73. package/templates/nuxt/pages/[xorg]/user/new.vue.eta +0 -18
  74. package/templates/nuxt/pages/[xorg]/user/viewer.vue.eta +0 -29
@@ -0,0 +1,91 @@
1
+ <template>
2
+ <SimpleAppForm #default="o" :document="doc">
3
+ <SimpleAppFormToolBar
4
+ :document="doc"
5
+ @on="actionListener"
6
+ ></SimpleAppFormToolBar>
7
+ <title v-if="id">{{ data.fullName ?? data.email }}</title>
8
+ <TabView lazy>
9
+ <TabPanel :header="t('profile')">
10
+ <div
11
+ class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4 p-2"
12
+ >
13
+ <SimpleAppInput
14
+ :input-type="SimpleAppInputType.text"
15
+ :setting="o.getField('#/properties/fullName')"
16
+ v-model="data.fullName"
17
+ />
18
+
19
+ <SimpleAppInput
20
+ :input-type="SimpleAppInputType.text"
21
+ :setting="o.getField('#/properties/email')"
22
+ v-model="data.email"
23
+ readonly
24
+ type="email"
25
+ />
26
+
27
+ <SimpleAppInput
28
+ :input-type="SimpleAppInputType.checkbox"
29
+ :setting="o.getField('#/properties/active')"
30
+ v-model="data.active"
31
+ />
32
+
33
+ <SimpleAppInput
34
+ :input-type="SimpleAppInputType.text"
35
+ :setting="o.getField('#/properties/description')"
36
+ v-model="data.description"
37
+ />
38
+ </div>
39
+
40
+ <DebugDocumentData v-model="data" :label="doc.getDocName()" />
41
+ </TabPanel>
42
+ <TabPanel :header="t('permission')">
43
+ <!-- <UserButtonPermissionInfo></UserButtonPermissionInfo> -->
44
+ <form-user-permission :id="id"></form-user-permission>
45
+ </TabPanel>
46
+ </TabView>
47
+ </SimpleAppForm>
48
+ </template>
49
+
50
+ <script setup lang="ts">
51
+ /**
52
+ * This file was automatically generated by simpleapp generator.
53
+ * --remove-this-line-to-prevent-override--
54
+ * last change 2024-02-16
55
+ * Author: Ks Tan
56
+ */
57
+ import { SimpleAppInputType, FormCrudEvent } from "~/types";
58
+ import { User } from "~/simpleapp/generate/types";
59
+ import { UserDoc } from "~/simpleapp/docs/UserDoc";
60
+
61
+ const props = defineProps<{ _id?: string; doc?: UserDoc; paras?: User }>();
62
+ const doc = props.doc ?? useNuxtApp().$UserDoc();
63
+ const data = doc.getReactiveData();
64
+ const emits = defineEmits(["after"]);
65
+ const id = computed(() => props._id ?? "");
66
+
67
+ /************ start default methods ****************/
68
+
69
+ const newData = () => doc.setNew();
70
+
71
+ const getRecord = async () => {
72
+ if (id.value && id.value != "new") {
73
+ await doc.getById(id.value);
74
+ } else {
75
+ newData();
76
+ }
77
+ };
78
+
79
+ getRecord();
80
+ watch(id, async () => await getRecord());
81
+ /************ end default methods ****************/
82
+
83
+ const actionListener = async (actionName: string) => {
84
+ emits("after", actionName, data.value);
85
+ };
86
+
87
+ onMounted(async () => await actionListener(FormCrudEvent.mount));
88
+ /************ start api methods ****************/
89
+
90
+ /************ end api methods ****************/
91
+ </script>
@@ -0,0 +1,83 @@
1
+ <template>
2
+ <div class=" w-full">
3
+ <div v-for="(b, index) in branchList" :key="index" class="flex flex-col">
4
+ <div>{{ b.branchName }}</div>
5
+ <div>
6
+ <SelectButton :options="grouplist" v-model="permdata[b.branchId??0].groups"
7
+ @update:model-value="updatePermission($event,b.branchId ??0)"
8
+ multiple option-value="value" option-label="label"/>
9
+ </div>
10
+ </div>
11
+ </div>
12
+ </template>
13
+ <script lang="ts" setup>
14
+ import { Branch, Permission, UserPermission } from "~/simpleapp/generate/openapi";
15
+ import _ from 'lodash'
16
+ const props = defineProps<{ id: string }>();
17
+ const perm = useNuxtApp().$PermissionDoc();
18
+ const branchList = ref<Branch[]>()
19
+ const branch = useNuxtApp().$BranchDoc()
20
+ const grouplist = getAllGroups().map((item) => {
21
+ return { value: item, label: _.capitalize(item) };
22
+ });
23
+ const orgs = ref<UserPermission[]>();
24
+ const selectedGroup=ref()
25
+ type PermDataType = {[key:number]: {groups?:string[],permId?:string}}
26
+ const permdata=ref<PermDataType>({})
27
+ const loadBranches = async ()=>{
28
+ branchList.value=await branch.search({
29
+ filter:{orgId:getUserProfile()?.orgId},
30
+ fields:['branchCode','branchName','active','branchId'],
31
+ sorts:[['branchCode','asc']]
32
+ })
33
+
34
+ branchList.value?.forEach(b=>{
35
+ const branchId:number = b.branchId ?? 0
36
+ permdata.value[branchId] ={groups:[],permId:''}
37
+ })
38
+ }
39
+ const loadPermission = async () => {
40
+ const permissions:Permission[] = await perm.search({
41
+ filter:{userId:props.id},
42
+ fields:['groups','userId','uid','branchId']
43
+ })
44
+ console.log("load permissions" , permissions)
45
+ permissions.forEach(p=>{
46
+ console.log("PPP",p)
47
+ if(p.branchId && permdata.value[p.branchId]){
48
+ permdata.value[p.branchId].groups = p.groups ??[]
49
+ permdata.value[p.branchId].permId = p._id
50
+ }
51
+ })
52
+ };
53
+ const updatePermission = async (newgroups:string[],branchId:number)=>{
54
+ const data =perm.getReactiveData()
55
+ if(permdata.value[branchId] && permdata.value[branchId].permId){
56
+ await perm.getById(permdata.value[branchId].permId)
57
+ }else{
58
+ data.value._id=randomUUID()
59
+ data.value.userId=props.id
60
+ }
61
+ data.value.groups=newgroups
62
+
63
+
64
+ if(permdata.value[branchId] && permdata.value[branchId].permId){
65
+ await perm.update()
66
+ }else{
67
+ await perm.create()
68
+ }
69
+ await loadPermission()
70
+ }
71
+ onMounted(async () => {
72
+ await loadBranches()
73
+ await loadPermission()
74
+
75
+ });
76
+ watch(
77
+ () => props.id,
78
+ async () => {
79
+ await loadPermission()
80
+
81
+ }
82
+ );
83
+ </script>
@@ -1,62 +1,66 @@
1
1
  <template>
2
- <!-- <header> -->
3
- <!-- <MegaMenu :model="getMenus()" orientation="horizontal" /> -->
4
-
5
- <div >
6
- <client-only>
7
-
8
- <div class="flex-1 flex flex-row gap-2 p-2">
9
- <!-- <div class="">
2
+ <!-- <header> -->
3
+ <!-- <MegaMenu :model="getMenus()" orientation="horizontal" /> -->
4
+
5
+ <div>
6
+ <client-only>
7
+ <div class="flex-1 flex flex-row gap-2 p-2">
8
+ <!-- <div class="">
10
9
  <HeaderButtonMenuPicker/>
11
10
  </div> -->
12
-
13
- <!-- <div class="">
11
+
12
+ <!-- <div class="">
14
13
  <HeaderButtonHome/>
15
14
  </div> -->
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
-
15
+ <div
16
+ v-if="isMobile()"
17
+ class="dark:text-white max-w-[15rem] truncate ..."
18
+ >
19
+ <div v-if="useRoute().fullPath.split('/').length <= 3">
20
+ {{ t("home") }}
21
+ </div>
22
+ <div v-else>{{ _.last(useRoute().fullPath.split("/")) }}</div>
24
23
  </div>
25
- <div class="flex-1 flex flex-row-reverse gap-2 p-2">
26
- <!--
24
+ <div v-else>
25
+ <HeaderBreadcrumb
26
+ class="hidden md:block"
27
+ v-if="useRoute().fullPath != '/'"
28
+ ></HeaderBreadcrumb>
29
+ </div>
30
+ </div>
31
+ <!-- <div class="flex-1 flex flex-row-reverse gap-2 p-2">
32
+
27
33
  <div class=" text-right" v-if="!isMobile()">
28
34
  <HeaderButtonProfile/>
29
35
  </div>
30
36
  <div class=" text-right">
31
37
  <HeaderButtonTaskList/>
32
- </div> -->
33
- <!-- <div class="">
38
+ </div>
39
+ <div class="">
34
40
  <HeaderSelectBranch/>
35
- </div> -->
36
- </div>
41
+ </div>
42
+ </div>-->
43
+ </client-only>
44
+ </div>
37
45
 
38
-
39
- </client-only>
40
- </div>
41
-
42
- <!-- </header> -->
46
+ <!-- </header> -->
43
47
  </template>
44
48
  <script setup lang="ts">
45
49
  /**
46
50
  * This file was automatically generated by simpleapp generator during initialization. It is changable.
47
51
  * --remove-this-line-to-prevent-override--
48
- * last change 2024-02-22
52
+ * last change 2024-04-10
49
53
  * author: Ks Tan
50
54
  */
51
-
52
- import _ from 'lodash'
55
+
56
+ import _ from "lodash";
53
57
  //import ButtonMenuPicker from "./ButtonMenuPicker.vue"
54
58
 
55
59
  //import ButtonProfile from './ButtonProfile.vue';
56
- const pageTitle = ref<string>('')
57
- onMounted(()=>{
58
- // useNuxtApp().$listen('SetTitle',(title:string)=>{
59
- // pageTitle.value = title
60
- // })
61
- })
62
- </script>
60
+ const pageTitle = ref<string>("");
61
+ onMounted(() => {
62
+ // useNuxtApp().$listen('SetTitle',(title:string)=>{
63
+ // pageTitle.value = title
64
+ // })
65
+ });
66
+ </script>
@@ -67,22 +67,20 @@ const saveLocale = async (v: string) => {
67
67
  </div>
68
68
  <div class="flex flex-col">
69
69
  <h1
70
- class="text-left text-gray-800 dark:text-gray-100 font-lg font-bold tracking-normal leading-tight ml-2"
70
+ class="text-left text-gray-800 dark:text-gray-100 font-lg font-bold tracking-normal leading-tight"
71
71
  >
72
72
  {{ getUserProfile()?.fullName }}
73
73
  </h1>
74
- <p
75
- class="text-gray-400 dark:text-gray-100 font-normal text-base tracking-normal ml-2 mr-4"
76
- >
77
- {{ getUserProfile()?.group }}
78
- </p>
74
+ <NuxtLink :to="getDocumentUrl('pickgroup')" @click="modelValue=false">
75
+ <TextPrimary>{{ getUserProfile()?.currentGroup }} </TextPrimary>
76
+ </NuxtLink>
79
77
  </div>
80
78
  </div>
81
79
  <div class="pt-2 pb-2">
82
80
  <TextTitle>{{ getUserProfile()?.branchName }}</TextTitle>
83
- <TextPrimary @click="goTenantPicker">{{
84
- t("switchDatabase")
85
- }} </TextPrimary>
81
+ <TextPrimary @click="goTenantPicker"
82
+ >{{ t("switchDatabase") }}
83
+ </TextPrimary>
86
84
  </div>
87
85
  <div class="col-span-full">
88
86
  <label
@@ -154,10 +154,12 @@ watch(showDialog, () => {
154
154
  watch(
155
155
  () => useRoute().path,
156
156
  async () => {
157
- if (getPathPara("id")) {
158
- showDialog.value = true;
159
- } else {
160
- showDialog.value = false;
157
+ if(!isMobile()){
158
+ if (getPathPara("id")) {
159
+ showDialog.value = true;
160
+ } else {
161
+ showDialog.value = false;
162
+ }
161
163
  }
162
164
  },
163
165
  );
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <span v-if="modelValue">{{ toLocalDateTime(modelValue) }}</span>
3
+ <span v-else>-</span>
4
+ </template>
5
+ <script lang="ts" setup>
6
+ /**
7
+ * This file was automatically generated by simpleapp generator during initialization.
8
+ * DONT CHANGE THIS FILE CAUSE IT OVERRIDE
9
+ * last change 2024-03-10
10
+ * author: Ks Tan
11
+ */
12
+ const modelValue = defineModel<Date | string>();
13
+ </script>
@@ -2,12 +2,11 @@
2
2
  <span
3
3
  v-if="setting?.collection"
4
4
  @click="viewRecord"
5
- class="text-primary-700 hover:text-primary-500 dark:text-primary-400 cursor-pointer"
5
+ class="text-primary-700 hover:text-primary-500 dark:text-primary-400 cursor-pointer"
6
6
  >
7
7
  <slot>
8
8
  {{ displayText }}
9
9
  </slot>
10
-
11
10
  </span>
12
11
  <span v-else>{{ displayText }}</span>
13
12
  </template>
@@ -18,10 +17,11 @@
18
17
  * last change 2024-02-04
19
18
  * author: Ks Tan
20
19
  */
21
- import { ForeignKey } from "~/types";
20
+ import { ForeignKey, FormCrudEvent } from "~/types";
22
21
 
23
22
  type SettingProp = { collection: string; displayField?: string };
24
23
  const modelValue = defineModel<ForeignKey>();
24
+ const emits = defineEmits(['after'])
25
25
  const props = defineProps<{ setting: SettingProp }>();
26
26
  const displayText = computed(() => {
27
27
  const s = props.setting;
@@ -44,6 +44,9 @@ const viewRecord = () => {
44
44
  documentName: props.setting.collection,
45
45
  viewer: viewer.value,
46
46
  readonly: true,
47
+ after: async(actionName:FormCrudEvent,data)=>{
48
+ emits('after',actionName,data)
49
+ }
47
50
  });
48
51
  };
49
52
  </script>
@@ -91,8 +91,7 @@
91
91
  <i class="pi pi-plus"></i>
92
92
  </ButtonText> -->
93
93
  </template>
94
- </mobile-toolbar>
95
- <div class="h-16"></div>
94
+ </mobile-toolbar>
96
95
  <ListView
97
96
  :list="list"
98
97
  :withFilter="true"
@@ -229,7 +228,7 @@ const onBlurAutocomplete = () => {
229
228
  };
230
229
 
231
230
  const showAutocompleteDialog = (isbutton: boolean) => {
232
- mobileListMode.value='list'
231
+ mobileListMode.value = "list";
233
232
  if (modelValue.value && isbutton) {
234
233
  openViewer(false);
235
234
  } else {
@@ -300,7 +299,7 @@ const setFocus = (ev: any) => {
300
299
 
301
300
  //pop up records
302
301
  const openViewer = (readonly: boolean) => {
303
- if (remotedoc) {
302
+ if (remotedoc) {
304
303
  $event("ViewRecord", {
305
304
  _id: modelValue.value?._id as string,
306
305
  eventId: randomUUID(),
@@ -83,6 +83,22 @@
83
83
  v-bind="componentProps as CalendarProps"
84
84
  />
85
85
 
86
+ <Calendar
87
+ :pt="pt"
88
+ v-else-if="inputType == SimpleAppInputType.datetime"
89
+ :inputId="slotprops.uuid"
90
+ :path="setting.instancepath"
91
+ v-model="datetimevalue"
92
+ @update:modelValue="updateDateTime"
93
+ :touchUI="isMobile()"
94
+ showButtonBar
95
+ :readonly="isReadonly"
96
+ :placeholder="placeholder"
97
+ :date-format="getDateFormat()"
98
+ showTime
99
+ hourFormat="12"
100
+ v-bind="componentProps as CalendarProps"
101
+ />
86
102
  <!-- select/list component -->
87
103
  <Listbox
88
104
  v-model="modelValue"
@@ -300,11 +316,12 @@ import Rating, { RatingProps } from "primevue/rating";
300
316
  import Slider, { SliderProps } from "primevue/slider";
301
317
  import Textarea, { TextareaProps } from "primevue/textarea";
302
318
  import { SimpleAppInputType } from "~/types";
303
- const resetcount = ref(0)
319
+ const resetcount = ref(0);
304
320
  const instancepath = ref("");
305
321
  const modelValue = defineModel({ required: true });
306
322
 
307
323
  const datevalue = ref<Date>();
324
+ const datetimevalue = ref<Date>();
308
325
  const timevalue = ref<Date>();
309
326
  let watchOnChange = 0;
310
327
  const props = withDefaults(
@@ -341,6 +358,11 @@ if (props.inputType == SimpleAppInputType.date && modelValue.value) {
341
358
  } else {
342
359
  datevalue.value = undefined;
343
360
  }
361
+ if (props.inputType == SimpleAppInputType.datetime && modelValue.value) {
362
+ datetimevalue.value = stringToDate(<string>modelValue.value);
363
+ } else {
364
+ datetimevalue.value = undefined;
365
+ }
344
366
 
345
367
  if (props.inputType == SimpleAppInputType.time) {
346
368
  if (modelValue.value) {
@@ -405,6 +427,14 @@ const updateDate = (value: any) => {
405
427
  }
406
428
  onChange();
407
429
  };
430
+ const updateDateTime = (value:any)=>{
431
+ if (value) {
432
+ modelValue.value = dateToISOString(value);
433
+ } else {
434
+ modelValue.value = "";
435
+ }
436
+ onChange();
437
+ }
408
438
 
409
439
  const setFocus = (ev: any) => {
410
440
  if (!isMobile()) ev.target.select();
@@ -446,7 +476,15 @@ watch(modelValue, (newvalue: any) => {
446
476
  } else {
447
477
  timevalue.value = undefined;
448
478
  }
449
- } else if (props.inputType == SimpleAppInputType.time) {
479
+
480
+ } else if (props.inputType == SimpleAppInputType.datetime) {
481
+ if (modelValue.value) {
482
+ datetimevalue.value = stringToDate(modelValue.value as string);
483
+ } else {
484
+ timevalue.value = undefined;
485
+ }
486
+ }
487
+ else if (props.inputType == SimpleAppInputType.time) {
450
488
  if (modelValue.value) {
451
489
  timevalue.value = stringToDate(
452
490
  (today() + "T" + modelValue.value) as string,
@@ -467,6 +505,12 @@ onMounted(() => {
467
505
  } else {
468
506
  datevalue.value = undefined;
469
507
  }
508
+ } else if (props.inputType == SimpleAppInputType.datetime) {
509
+ if (modelValue.value) {
510
+ datetimevalue.value = stringToDate(modelValue.value as string);
511
+ } else {
512
+ datetimevalue.value = undefined;
513
+ }
470
514
  } else if (props.inputType == SimpleAppInputType.time) {
471
515
  if (modelValue.value) {
472
516
  timevalue.value = stringToDate(
@@ -479,8 +523,8 @@ onMounted(() => {
479
523
  });
480
524
 
481
525
  const onChange = () => {
482
- pt.value=undefined
483
- resetcount.value++
526
+ pt.value = undefined;
527
+ resetcount.value++;
484
528
  emits("change", modelValue.value);
485
529
  };
486
530
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * This file was automatically generated by simpleapp generator. Every
3
3
  * MODIFICATION OVERRIDE BY GENERATEOR
4
- * last change 2023-10-28
4
+ * last change 2024-03-08
5
5
  * Author: Ks Tan
6
6
  */
7
7
  export const setDateLocale = (localename:string) => useDayjs().locale(localename)
@@ -15,11 +15,13 @@ export const getDayJs = ()=>useDayjs()
15
15
  export const lastDateOfMonth = (datestr:string) => useDayjs()(datestr).endOf('month').format('YYYY-MM-DD');
16
16
  export const today = () => useDayjs()().format('YYYY-MM-DD')
17
17
  export const dateToString = (date:Date) => useDayjs()(date).format('YYYY-MM-DD')
18
+ export const dateToISOString = (date:Date) => useDayjs()(date).toISOString()
18
19
  export const dateToTimeString = (date:Date) => useDayjs()(date).format('HH:mm:ss')
19
20
  export const stringToDate = (datestr:string) => new Date(datestr)
20
21
  export const dateToDateTimeString = (date:Date)=> useDayjs()(date).format('YYYY-MM-DD HH:mm:ss')
21
22
  export const toLocalDate = (date:string | Date)=> useDayjs()(date).format(getDateFormat())
22
23
  export const getDateFormat = ():string=> 'DD-MM-YYYY'
24
+ export const calculateHourDifferent = (date1:Date, date2:Date) => (date1.getTime() - date2.getTime())/60/60/1000
23
25
  export const getPrimevueCalendarDateFormat = () => {
24
26
  const country = <string>getUserProfile()?.country
25
27
  return 'dd/mm/yy'
@@ -5,7 +5,10 @@
5
5
  * Author: Ks Tan
6
6
  */
7
7
  export const getDocumentUrl = (document:string,id?:string,querystr?:string)=>{
8
- let path = `/${getCurrentXorg()}/${document}`
8
+
9
+ let path = useRoute().path.includes('/mobile/') || isMobile() ?
10
+ `/${getCurrentXorg()}/mobile/${document}`
11
+ : `/${getCurrentXorg()}/${document}`
9
12
  if(id){
10
13
  path = path + '/'+id
11
14
  }
@@ -9,7 +9,7 @@
9
9
 
10
10
  </div>
11
11
  <!-- fixed -->
12
- <div v-if="getCurrentXorg()" class="flex h-16 border-t-2 dark:border-t-gray-700 text-3xl flex-row left-0 w-full justify justify-between bottom-0 fixed z-50 bg-white dark:bg-slate-800 opacity opacity-95 " >
12
+ <div v-if="getCurrentXorg()" class="flex h-16 border-t-2 dark:border-t-gray-700 text-3xl flex-row left-0 w-full justify justify-between bottom-0 fixed z-50 bg-white dark:bg-slate-900 opacity opacity-95 " >
13
13
  <div v-for="item in menus">
14
14
  <NuxtLink v-if="item.path !== undefined"
15
15
  :class="`pi ${item.iconClass} p-4 cursor-pointer inline-block align-middle`"
@@ -33,7 +33,6 @@
33
33
  <script setup lang="ts">
34
34
  /**
35
35
  * This file was automatically generated by simpleapp generator during initialization. It is changable.
36
- * --remove-this-line-to-prevent-override--
37
36
  * last change 2024-02-22
38
37
  * author: Ks Tan
39
38
  */
@@ -42,17 +41,32 @@ const showProfile =ref(false)
42
41
 
43
42
  const openMenu = ()=>showMenu.value=true
44
43
  const openProfile = ()=>showProfile.value=true
45
- const menus=[
44
+ type MenuType = {iconClass:string,path?:string,command?:Function}
45
+ type AllMenus = {[key:string]:MenuType[]}
46
+ const menus=ref<MenuType[]>([])
46
47
  // {iconClass:'pi-bars',path:'managestudents/profile'},
47
- {iconClass:'pi-home dark:text-white',path:''},
48
- //{iconClass:'pi-users dark:text-white',path:'managestudents'},
49
- //{iconClass:'pi-calendar dark:text-white',path:`manageclasses`},
50
- {iconClass:'pi-chart-pie dark:text-white',path:'reports'},
51
- {iconClass:'pi-bars dark:text-white',command: openMenu},
52
- {iconClass:'pi-user dark:text-white',command: openProfile},
53
- // {iconClass:'pi-database',path:'managedata'},
54
-
55
- ]
48
+ const allmenus:AllMenus = {
49
+ admin:[
50
+ {iconClass:'pi-home dark:text-white',path:''},
51
+ //{iconClass:'pi-users dark:text-white',path:'managestudents'},
52
+ //{iconClass:'pi-calendar dark:text-white',path:`manageclasses`},
53
+ {iconClass:'pi-bars dark:text-white',command: openMenu},
54
+ {iconClass:'pi-user dark:text-white',command: openProfile},
55
+ ],
56
+ teacher: [{iconClass:'pi-home dark:text-white',path:''},
57
+ {iconClass:'pi-user dark:text-white',command: openProfile},],
58
+ unknown:[]
59
+ }
56
60
 
61
+ const readGroup=()=>{
62
+ if(getUserProfile()?.currentGroup) {
63
+ menus.value = allmenus[getUserProfile()?.currentGroup ?? 'unknown']
64
+ }
65
+ }
66
+
67
+ onMounted(()=>{
68
+ readGroup()
69
+ useNuxtApp().$listen('pickGroup',()=>readGroup())
70
+ })
57
71
 
58
72
  </script>