@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.
- package/README.md +6 -0
- package/dist/buildinschemas/organization.js +2 -2
- package/dist/buildinschemas/organization.js.map +1 -1
- package/dist/framework.js +3 -3
- package/dist/framework.js.map +1 -1
- package/package.json +1 -1
- package/src/buildinschemas/organization.ts +2 -2
- package/src/framework.ts +3 -3
- package/templates/basic/nest/controller.ts.eta +25 -21
- package/templates/basic/nest/service.ts.eta +5 -5
- package/templates/basic/nuxt/default.ts.eta +1 -1
- package/templates/basic/nuxt/pages.form.vue.eta +4 -4
- package/templates/basic/nuxt/pages.landing.vue.eta +9 -0
- package/templates/basic/nuxt/pages.viewer.vue.eta +4 -3
- package/templates/basic/nuxt/simpleapp.generate.client.ts.eta +6 -17
- package/templates/nest/src/simpleapp/apischemas/index.ts._eta +10 -0
- package/templates/nest/src/simpleapp/generate/apischemas/index.ts.eta +7 -19
- package/templates/nest/src/simpleapp/generate/apischemas/simpleapp.apischema.ts.eta +20 -0
- package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +9 -3
- package/templates/nest/src/simpleapp/generate/types/index.ts.eta +3 -3
- package/templates/nest/src/simpleapp/generate/types/simpleapp.type.ts.eta +1 -4
- package/templates/nest/src/simpleapp/types/index.ts._eta +7 -0
- package/templates/nuxt/app.vue.eta +7 -3
- package/templates/nuxt/assets/css/calendar.css._eta +50 -0
- package/templates/nuxt/assets/css/style.css._eta +1 -5
- package/templates/nuxt/assets/primevue/passthrough.ts._eta +38 -16
- package/templates/nuxt/components/button/ButtonDanger.vue._eta +6 -0
- package/templates/nuxt/components/button/ButtonDefault.vue._eta +6 -0
- package/templates/nuxt/components/button/ButtonPrimary.vue._eta +6 -0
- package/templates/nuxt/components/button/ButtonWarning.vue._eta +6 -0
- package/templates/nuxt/components/calendar/CalendarByResource.vue.eta +188 -0
- package/templates/nuxt/components/calendar/CalendarSmall.vue.eta +74 -0
- package/templates/nuxt/components/docPage/DocPageList.vue.eta +48 -40
- package/templates/nuxt/components/event/EventDocumentViewer.vue._eta +12 -12
- package/templates/nuxt/components/event/EventNotification.vue._eta +23 -2
- package/templates/nuxt/components/header/HeaderBar.vue._eta +32 -19
- package/templates/nuxt/components/header/HeaderBreadcrumb.vue.eta +2 -2
- package/templates/nuxt/components/header/button/HeaderButtonMenuPicker.vue._eta +7 -15
- package/templates/nuxt/components/header/button/HeaderButtonProfile.vue.eta +23 -34
- package/templates/nuxt/components/list/ListView.vue.eta +10 -8
- package/templates/nuxt/components/renderer/RendererBoolean.vue.eta +6 -1
- package/templates/nuxt/components/renderer/RendererDate.vue.eta +6 -0
- package/templates/nuxt/components/renderer/RendererForeignKey.vue.eta +7 -1
- package/templates/nuxt/components/renderer/RendererLink.vue.eta +33 -0
- package/templates/nuxt/components/renderer/RendererMoney.vue.eta +20 -2
- package/templates/nuxt/components/renderer/RendererMultiText.vue.eta +6 -0
- package/templates/nuxt/components/renderer/RendererViewer.vue.eta +32 -0
- package/templates/nuxt/components/renderer/{index.ts.eta → index.ts._eta} +10 -2
- package/templates/nuxt/components/simpleApp/SimpleAppAutocomplete.vue.eta +37 -12
- package/templates/nuxt/components/simpleApp/SimpleAppDocumentNo.vue.eta +8 -2
- package/templates/nuxt/components/simpleApp/SimpleAppFieldContainer.vue.eta +24 -17
- package/templates/nuxt/components/simpleApp/SimpleAppForm.vue.eta +1 -1
- package/templates/nuxt/components/simpleApp/SimpleAppFormToolBar.vue.eta +3 -2
- package/templates/nuxt/components/simpleApp/SimpleAppInput.vue.eta +25 -8
- package/templates/nuxt/components/simpleApp/SimpleAppInputTable.vue.eta +4 -3
- package/templates/nuxt/components/simpleApp/pending/SimpleAppValue.vue +1 -1
- package/templates/nuxt/components/user/UserProfileListItem.vue.eta +2 -2
- package/templates/nuxt/composables/date.generate.ts.eta +16 -0
- package/templates/nuxt/composables/goTo.generate.ts.eta +1 -0
- package/templates/nuxt/composables/screensize.generate.ts.eta +1 -0
- package/templates/nuxt/composables/stringHelper.generate.ts.eta +3 -6
- package/templates/nuxt/error.vue._eta +4 -4
- package/templates/nuxt/layouts/default.vue._eta +32 -8
- package/templates/nuxt/layouts/loginlayout.vue._eta +3 -0
- package/templates/nuxt/layouts/mobile.vue._eta +29 -0
- package/templates/nuxt/nuxt.config.ts._eta +27 -13
- package/templates/nuxt/pages/[xorg]/index.vue._eta +11 -9
- package/templates/nuxt/pages/[xorg]/organization.vue.eta +5 -0
- package/templates/nuxt/pages/[xorg]/user/{index.vue._eta → index.vue.eta} +10 -12
- package/templates/nuxt/pages/login.vue._eta +34 -0
- package/templates/nuxt/plugins/10.simpleapp-event.ts.eta +35 -22
- package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +6 -0
- package/templates/nuxt/server/api/[xorg]/[...].ts.eta +7 -40
- package/templates/nuxt/server/api/profile/[...].ts.eta +3 -32
- package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +1 -1
- package/templates/nuxt/types/calendar.ts.eta +61 -0
- package/templates/nuxt/types/documentlist.ts.eta +6 -0
- package/templates/nuxt/types/events.ts.eta +5 -5
- package/templates/nuxt/types/index.ts._eta +4 -3
- package/templates/nuxt/types/listview.ts.eta +6 -0
- package/templates/nuxt/types/notifications.ts.eta +6 -1
- package/templates/nuxt/types/others.ts.eta +10 -2
- package/templates/nuxt/types/schema.ts.eta +8 -0
- package/templates/nuxt/types/simpleappinput.ts.eta +6 -0
- package/templates/nuxt/types/user.ts.eta +8 -0
- package/templates/nuxt/types/workflow.ts.eta +6 -1
- package/templates/project/lang/default._json +4 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/templates/nuxt/pages/login.vue.eta +0 -30
- /package/templates/nuxt/pages/[xorg]/user/{[id].vue._eta → [id].vue.eta} +0 -0
- /package/templates/nuxt/pages/[xorg]/{user.vue._eta → user.vue.eta} +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
|
|
2
|
+
/* calendar */
|
|
3
|
+
|
|
4
|
+
#monthviewcal .vuecal__cell--current,
|
|
5
|
+
#monthviewcal .vuecal__cell--today {
|
|
6
|
+
background-color: lightblue;
|
|
7
|
+
}
|
|
8
|
+
#monthviewcal .vuecal__cell--selected {
|
|
9
|
+
background-color: lightgreen;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
#monthviewcal .vuecal__cell {
|
|
13
|
+
height: 3rem;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#resourceviewcal .vuecal__event {
|
|
17
|
+
border-radius: 0.5rem;
|
|
18
|
+
}
|
|
19
|
+
#resourceviewcal .vuecal__time-column {
|
|
20
|
+
margin-top: 3rem;
|
|
21
|
+
/* background-color: red; */
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#resourceviewcal .vuecal__split-days-headers{
|
|
25
|
+
min-height: 3rem;
|
|
26
|
+
/* background-color: blue; */
|
|
27
|
+
/* margin-left:-4rem; */
|
|
28
|
+
}
|
|
29
|
+
#resourceviewcal .vuecal__event {
|
|
30
|
+
border: solid 1px #ccc !important;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
#resourceviewcal .nostudent{
|
|
37
|
+
background-color: aqua;
|
|
38
|
+
}
|
|
39
|
+
#resourceviewcal .full{
|
|
40
|
+
@apply bg-orange-700 text-white
|
|
41
|
+
/* background-color: darkorange; */
|
|
42
|
+
/* color:white; */
|
|
43
|
+
}
|
|
44
|
+
#resourceviewcal .overlimit{
|
|
45
|
+
background-color: darkred;
|
|
46
|
+
color:white;
|
|
47
|
+
}
|
|
48
|
+
#resourceviewcal .default{
|
|
49
|
+
background-color: lightblue;
|
|
50
|
+
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
body {
|
|
18
|
-
@apply bg-gray-50 dark:bg-gray-800
|
|
18
|
+
@apply bg-gray-50 dark:bg-gray-800 h-screen w-screen overflow-y-scroll
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
input {
|
|
@@ -56,7 +56,3 @@ input {
|
|
|
56
56
|
.btn-warn {
|
|
57
57
|
@apply btn bg-warning-600 hover:bg-warning-400
|
|
58
58
|
}
|
|
59
|
-
|
|
60
|
-
.simpleapp-input-label{
|
|
61
|
-
@apply text-left
|
|
62
|
-
}
|
|
@@ -4,17 +4,19 @@ import Tailwind from "primevue/passthrough/tailwind";
|
|
|
4
4
|
|
|
5
5
|
const CustomTailwind = usePassThrough(
|
|
6
6
|
Tailwind,
|
|
7
|
-
{
|
|
8
|
-
|
|
7
|
+
{
|
|
8
|
+
avatar:{
|
|
9
|
+
root:{ class:'h-full w-full'},
|
|
10
|
+
},
|
|
9
11
|
toast:{
|
|
10
|
-
root:{ class:'w-1/3 '},
|
|
11
|
-
message:{},
|
|
12
|
-
container:{class:'w-full ' },
|
|
13
|
-
content:{class:'flex flex-row-reverse w-full'},
|
|
14
|
-
buttonContainer:{class:'hidden'},
|
|
12
|
+
root:{ class:'w-full md:w-1/2 lg:w-1/3 ml-4' , style:'position: fixed; top: 0px; right: 0px; z-index: 1102;'},
|
|
13
|
+
// message:{},
|
|
14
|
+
// container:{class:'w-full ' },
|
|
15
|
+
// content:{class:'flex flex-row-reverse w-full'},
|
|
16
|
+
// buttonContainer:{class:'hidden'},
|
|
15
17
|
},
|
|
16
18
|
card:{
|
|
17
|
-
root:{class:'shadow p-4 rounded-2xl m-2'},
|
|
19
|
+
root:{class:'bg-white dark:bg-gray-600 shadow p-4 rounded-2xl m-2'},
|
|
18
20
|
// title:{class:''},
|
|
19
21
|
// header:{class:''}
|
|
20
22
|
},
|
|
@@ -22,18 +24,33 @@ const CustomTailwind = usePassThrough(
|
|
|
22
24
|
headerTitle:{class:'m-0 p-0'},
|
|
23
25
|
},
|
|
24
26
|
selectbutton:{
|
|
25
|
-
root:{class:'flex flex-row gap-1'},
|
|
27
|
+
root:{class:'flex flex-row gap-1 '},
|
|
26
28
|
button: ({ context }) => ({
|
|
27
|
-
|
|
28
|
-
class: ['text-center border text-gray-300 dark:border-gray-700 dark:text-gray-300 rounded-lg p-2 cursor-pointer hover:bg-primary-400 dark:hover:bg-primary-800 hover:text-white', context.active ? 'bg-primary-600 dark:bg-primary-700 text-white' : '']
|
|
29
|
+
class: ` focus:outline-none transition duration-150 ease-in-out rounded p-2 m-1 border dark:border-gray-600 ${context.active ? 'bg-primary-600 border-primary-400 text-white' : ''}`
|
|
29
30
|
}),
|
|
30
|
-
|
|
31
|
+
// button: ( context) => ({
|
|
32
|
+
|
|
33
|
+
// class: ['text-center border text-gray-400 dark:border-gray-700 dark:text-gray-300 rounded-lg p-2 cursor-pointer hover:bg-primary-400 dark:hover:bg-primary-800 hover:text-white', context.active ? 'bg-primary-600 dark:bg-primary-700 text-white' : '']
|
|
34
|
+
// }),
|
|
35
|
+
label:{class: 'text-sm dark:text-white'},
|
|
36
|
+
},
|
|
37
|
+
checkbox:{
|
|
38
|
+
input:{ class:' flex items-center justify-center border-2 w-6 h-6 text-gray-600 rounded-lg transition-colors duration-200 border-gray-300 bg-white dark:border-blue-900/40 dark:bg-gray-500 hover:border-blue-500 dark:hover:border-blue-400 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[inset_0_0_0_0.2rem_rgba(147,197,253,0.5)]'}
|
|
39
|
+
// p-checkbox p-component cursor-pointer inline-flex relative select-none align-bottom w-6 h-6
|
|
40
|
+
|
|
31
41
|
},
|
|
32
42
|
button:{root:{class: 'focus:outline-none transition duration-150 ease-in-out rounded p-2 m-1 border dark:border-gray-600'}},
|
|
33
|
-
dialog:{
|
|
43
|
+
dialog:{
|
|
44
|
+
root:{class:['border w-full max-h-full max-w-full md:h-3/4 lg:h-1/2']},
|
|
45
|
+
header:{class: 'p-dialog-header flex items-center text-2xl justify-between shrink-0 bg-white text-gray-800 border-t-0 rounded-tl-lg rounded-tr-lg p-6 dark:bg-gray-900 dark:text-white/80'},
|
|
46
|
+
content:{class:'p-dialog-content overflow-y-auto bg-white text-gray-700 px-6 pb-8 pt-0 dark:bg-gray-900 dark:text-white/80 rounded-bl-lg rounded-br-lg h-full'}
|
|
47
|
+
},
|
|
48
|
+
calendar:{
|
|
49
|
+
root:{class:'border border-grey-900 dark:!border-blue-900/40 rounded-lg flex flex-row p-0'},
|
|
50
|
+
input:{class:'w-full p-inputtext p-component font-sans text-base text-gray-600 dark:text-white/80 bg-white dark:bg-gray-900 p-3 border border-gray-300 dark:border-blue-900/40 transition-colors duration-200 appearance-none hover:border-blue-500 rounded-lg'},
|
|
51
|
+
},
|
|
34
52
|
autocomplete:{
|
|
35
|
-
root:{class:'border border-gray-
|
|
36
|
-
input:{class:'w-full p-2 font-sans rounded-lg rounded-tr-none rounded-br-none transition-colors duration-200 appearance-none hover:border-blue-500 focus:outline-none focus:outline-offset-0 focus:shadow-[0_0_0_0.2rem_rgba(191,219,254,1)] dark:focus:shadow-[0_0_0_0.2rem_rgba(147,197,253,0.5)] text-base'},
|
|
53
|
+
root:{class:'border border-gray-400 dark:!border-blue-900/40 rounded-lg flex flex-row'},
|
|
37
54
|
loadingIcon:{class:'hidden'},
|
|
38
55
|
dropdownbutton: {
|
|
39
56
|
root:' btn-primary dark:shadow-primary-800 dark:border-primary-900 text-white rounded-lg flex flex-row p-3 rounded-tl-none rounded-bl-none '
|
|
@@ -41,8 +58,9 @@ const CustomTailwind = usePassThrough(
|
|
|
41
58
|
},
|
|
42
59
|
sidebar:{
|
|
43
60
|
root:{class:'w-full md:w-1/2 xl:w-1/4 bg-white dark:bg-gray-800 border p-0 h-full'},
|
|
61
|
+
header:{class:'dark:text-white text-2xl p-2'},
|
|
44
62
|
content:{class:'p-0 pt-0 h-full w-full grow overflow-y-auto'}
|
|
45
|
-
},
|
|
63
|
+
},
|
|
46
64
|
panel: {
|
|
47
65
|
root:{class:['border']},
|
|
48
66
|
title: {class: ['leading-none font-light text-2xl']},
|
|
@@ -51,6 +69,10 @@ const CustomTailwind = usePassThrough(
|
|
|
51
69
|
},
|
|
52
70
|
breadcrumb:{
|
|
53
71
|
root:{class:''}
|
|
72
|
+
},
|
|
73
|
+
inputnumber:{
|
|
74
|
+
// root:{class:''},
|
|
75
|
+
input:{class:'bg-white dark:bg-white text-black dark-text-black'}
|
|
54
76
|
}
|
|
55
77
|
},
|
|
56
78
|
);
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<VueCal
|
|
3
|
+
|
|
4
|
+
:id="id"
|
|
5
|
+
ref="vueresourcecal"
|
|
6
|
+
:disable-views="['years', 'year', 'month', 'week']"
|
|
7
|
+
:time-from="8 * 60"
|
|
8
|
+
:time-to="22 * 60"
|
|
9
|
+
:time-step="60"
|
|
10
|
+
active-view="day"
|
|
11
|
+
:snap-to-time="15"
|
|
12
|
+
hide-view-selector
|
|
13
|
+
:events="allevents"
|
|
14
|
+
:editable-events="calendarMode"
|
|
15
|
+
:split-days="allresources"
|
|
16
|
+
:min-split-width="100"
|
|
17
|
+
|
|
18
|
+
:sticky-split-labels="true"
|
|
19
|
+
sticky-split-labels
|
|
20
|
+
|
|
21
|
+
:selected-date="selectedDate"
|
|
22
|
+
:drag-to-create-threshold="15"
|
|
23
|
+
@event-drag-create="onDragNew"
|
|
24
|
+
@event-drop="onEventDrop"
|
|
25
|
+
@view-change="viewChange"
|
|
26
|
+
@cell-click="onCellClick"
|
|
27
|
+
@cell-contextmenu="eventHappend"
|
|
28
|
+
|
|
29
|
+
>
|
|
30
|
+
<!-- header template -->
|
|
31
|
+
<template #split-label="{ split, view }">
|
|
32
|
+
<div
|
|
33
|
+
@click="clickResource(split._id, split.label)"
|
|
34
|
+
class="cursor-pointer"
|
|
35
|
+
>
|
|
36
|
+
<!-- <div
|
|
37
|
+
v-if="resourceType == CalResourceType.teacher && split.email"
|
|
38
|
+
class="w-full text-center"
|
|
39
|
+
>
|
|
40
|
+
<img
|
|
41
|
+
:src="getAvatarLink(split.email, 48)"
|
|
42
|
+
class="overflow-hidden object-cover rounded-full border-2 border-white dark:border-gray-700 shadow"
|
|
43
|
+
/> -->
|
|
44
|
+
<div>{{ split.displayName }} <span v-if="split._id == '?'" class="pi pi-plus"></span></div>
|
|
45
|
+
<!-- </div>
|
|
46
|
+
<div v-else>{{ split.displayName }}</div> -->
|
|
47
|
+
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<!-- event template -->
|
|
52
|
+
<!-- @contextmenu="onRightClick($event, event)" -->
|
|
53
|
+
<template #event="{ event, view }">
|
|
54
|
+
<div
|
|
55
|
+
@click="onRightClick($event,event)"
|
|
56
|
+
class="cursor-pointer"
|
|
57
|
+
>
|
|
58
|
+
<slot name="default" :event="<CalEventType<T>>event">
|
|
59
|
+
<div>{{ event.title }}</div>
|
|
60
|
+
<div>{{ event.start }}</div>
|
|
61
|
+
<div>{{ event.end }}</div>
|
|
62
|
+
</slot>
|
|
63
|
+
</div>
|
|
64
|
+
</template>
|
|
65
|
+
</VueCal>
|
|
66
|
+
</template>
|
|
67
|
+
<script setup lang="ts" generic="T">
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
import "vue-cal/dist/vuecal.css";
|
|
71
|
+
import VueCal, { Event, SplitDaysAttributes } from "vue-cal";
|
|
72
|
+
import { CalEventType,CalViewClickSlotEvent,CalResource,CalResourceType,RelocateEvent } from '~/types'
|
|
73
|
+
import { emit } from "process";
|
|
74
|
+
import moment from 'moment'
|
|
75
|
+
const timezoneoffset = new Date().getTimezoneOffset()
|
|
76
|
+
const eventsdata = ref<CalEventType<T>[]>()
|
|
77
|
+
const vueresourcecal = ref()
|
|
78
|
+
const emits = defineEmits(['eventRghtClick','eventClick','eventDrop','eventDragNew','viewChange','resourceClick','slotClick'])
|
|
79
|
+
const props = defineProps<{
|
|
80
|
+
id:string
|
|
81
|
+
items:CalEventType<T>[]
|
|
82
|
+
resources:CalResource[]
|
|
83
|
+
resourceType:CalResourceType
|
|
84
|
+
}>()
|
|
85
|
+
const selectedDate = defineModel<Date>()
|
|
86
|
+
const selectedSchedule = ref<CalResource>();
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
const allevents = computed(()=>{
|
|
91
|
+
|
|
92
|
+
const list = props.items.map(item=>{
|
|
93
|
+
if(item.start instanceof Date) item.start =item.start.addMinutes(timezoneoffset).format('YYYY-MM-DD HH:mm')
|
|
94
|
+
if(item.end instanceof Date) item.end = item.end.addMinutes(timezoneoffset).format('YYYY-MM-DD HH:mm')
|
|
95
|
+
if(!item.split) item.split='?'
|
|
96
|
+
return item
|
|
97
|
+
})
|
|
98
|
+
return list
|
|
99
|
+
})
|
|
100
|
+
const eventHappend = (e:any)=>{
|
|
101
|
+
console.log("event happen eee",e)
|
|
102
|
+
// alert("event happend")
|
|
103
|
+
}
|
|
104
|
+
const viewChange = (e:any)=>{
|
|
105
|
+
console.log("calendar view change",e)
|
|
106
|
+
selectedDate.value=e.startDate
|
|
107
|
+
// endDate : Sat Feb 17 2024 23:59:59 GMT+0800 (Malaysia Time) {}
|
|
108
|
+
// events : []
|
|
109
|
+
// startDate : Sat Feb 17 2024 00:00:00 GMT+0800 (Malaysia Time) {}
|
|
110
|
+
// view : "day"
|
|
111
|
+
emits('viewChange',e)
|
|
112
|
+
}
|
|
113
|
+
const allresources = computed(()=>{
|
|
114
|
+
const tmplist = props.resources.map(r=>{
|
|
115
|
+
if(!r.id) r.id =r._id
|
|
116
|
+
if(r.hide===undefined) r.hide=false
|
|
117
|
+
if(!r.displayName) r.displayName=r.label
|
|
118
|
+
return r
|
|
119
|
+
})
|
|
120
|
+
tmplist.push({
|
|
121
|
+
_id:'?',
|
|
122
|
+
id:'?',
|
|
123
|
+
hide:false,
|
|
124
|
+
label:t('unknown'),
|
|
125
|
+
displayName:t('unknown'),
|
|
126
|
+
code:'',
|
|
127
|
+
email:'',
|
|
128
|
+
})
|
|
129
|
+
return tmplist
|
|
130
|
+
})
|
|
131
|
+
const onCellClick = async(e:CalViewClickSlotEvent)=>{
|
|
132
|
+
const date =e.date
|
|
133
|
+
date.setHours(date.getHours() + Math.floor(date.getMinutes()/60));
|
|
134
|
+
date.setMinutes(0, 0, 0); // Resets also seconds and milliseconds
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
const newevent:CalEventType<T> = {
|
|
138
|
+
id: 'new',
|
|
139
|
+
start: date,
|
|
140
|
+
end: date.addHours(1),
|
|
141
|
+
class: 'nostudent',
|
|
142
|
+
title: t('new'),
|
|
143
|
+
// content?: string | undefined;
|
|
144
|
+
split: e.split,
|
|
145
|
+
data: {} as T
|
|
146
|
+
}
|
|
147
|
+
// emits('slotClick',e)
|
|
148
|
+
emits('eventDragNew',newevent)
|
|
149
|
+
}
|
|
150
|
+
const onEventDrop = async (relocateData: RelocateEvent<T>)=>{
|
|
151
|
+
emits('eventDrop', relocateData)
|
|
152
|
+
}
|
|
153
|
+
const clickResource = async (splitid:string, splitlabel:string)=> emits('resourceClick', splitid,splitlabel)
|
|
154
|
+
const onDragNew = (e: CalEventType<T>)=> emits('eventDragNew', e)
|
|
155
|
+
|
|
156
|
+
const onRightClick = (clickevent: any, scheduledata: any) => {
|
|
157
|
+
selectedSchedule.value = scheduledata;
|
|
158
|
+
emits('eventRghtClick', clickevent,scheduledata)
|
|
159
|
+
};
|
|
160
|
+
const onEventClick = (eventdata: CalResource) => {
|
|
161
|
+
selectedSchedule.value = eventdata;
|
|
162
|
+
emits('eventClick',eventdata)
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const calendarMode = computed(()=>{
|
|
166
|
+
|
|
167
|
+
if(useDevice().isMobile){
|
|
168
|
+
return {
|
|
169
|
+
title: false,
|
|
170
|
+
drag: true,
|
|
171
|
+
resize: false,
|
|
172
|
+
delete: false,
|
|
173
|
+
// create: true,
|
|
174
|
+
}
|
|
175
|
+
}else{
|
|
176
|
+
return {
|
|
177
|
+
title: false,
|
|
178
|
+
drag: true,
|
|
179
|
+
resize: false,
|
|
180
|
+
delete: false,
|
|
181
|
+
create: true,
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
</script>
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<vue-cal
|
|
3
|
+
:id="id"
|
|
4
|
+
class="w-full"
|
|
5
|
+
hide-view-selector
|
|
6
|
+
click-to-navigate
|
|
7
|
+
:time="false"
|
|
8
|
+
today-button
|
|
9
|
+
active-view="month"
|
|
10
|
+
:disable-views="['week', 'day']"
|
|
11
|
+
:selected-date="selectedDate"
|
|
12
|
+
events-count-on-year-view
|
|
13
|
+
@view-change="viewChange"
|
|
14
|
+
:events="allevents"
|
|
15
|
+
@cell-focus="chooseDate"
|
|
16
|
+
xsmall
|
|
17
|
+
>
|
|
18
|
+
<template #cell-content="{ cell, view, events }" class="bg-red-300">
|
|
19
|
+
<div class="flex flex-col" @contextmenu="(mouseevent:MouseEvent)=>onRightClickDate(mouseevent,cell)">
|
|
20
|
+
<div>
|
|
21
|
+
<s
|
|
22
|
+
v-if="dateExists(new Date(cell.formattedDate),alloffdays)"
|
|
23
|
+
v-tooltip="getHolidayName(new Date(cell.formattedDate))"
|
|
24
|
+
class="text text-red-400 font-bold"
|
|
25
|
+
>{{ cell.content }}</s
|
|
26
|
+
>
|
|
27
|
+
<span v-else>{{ cell.content }} </span>
|
|
28
|
+
</div>
|
|
29
|
+
<div>
|
|
30
|
+
<slot name="default" :cell="cell" events="events">
|
|
31
|
+
<Badge v-if="events.length>0"
|
|
32
|
+
@contextmenu="(mouseevent:MouseEvent)=>onRightClickDate(mouseevent,cell)"
|
|
33
|
+
severity="info"
|
|
34
|
+
:value="events.length"/>
|
|
35
|
+
</slot>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
</vue-cal>
|
|
40
|
+
</template>
|
|
41
|
+
<script lang="ts" setup generic="T">
|
|
42
|
+
import VueCal, { Event, SplitDaysAttributes } from "vue-cal";
|
|
43
|
+
import { CalEventType,CalRightClickEvent,OffDay } from '~/types'
|
|
44
|
+
|
|
45
|
+
const props = defineProps<{
|
|
46
|
+
id:string
|
|
47
|
+
items:CalEventType<T>[]
|
|
48
|
+
offdays:OffDay[]
|
|
49
|
+
}>()
|
|
50
|
+
const emits = defineEmits(['chooseDate','rightClick'])
|
|
51
|
+
const alloffdays = computed(()=> props.offdays.map(item=>item.date))
|
|
52
|
+
const selectedDate = defineModel<Date>({required:true})
|
|
53
|
+
const getHolidayName = (date:Date) => props.offdays.find(item=>item.date.getTime() == date.getTime())?.title
|
|
54
|
+
const allevents = computed(()=>{
|
|
55
|
+
const list = props.items.map(item=>{
|
|
56
|
+
if(item.start instanceof Date) item.start = item.start.format('YYYY-MM-DD HH:mm')
|
|
57
|
+
if(item.end instanceof Date) item.end = item.end.format('YYYY-MM-DD HH:mm')
|
|
58
|
+
return item
|
|
59
|
+
})
|
|
60
|
+
return list
|
|
61
|
+
})
|
|
62
|
+
const viewChange = (event: any) => {
|
|
63
|
+
console.log("Calendar Small view change")
|
|
64
|
+
chooseDate(event.startDate);
|
|
65
|
+
};
|
|
66
|
+
const chooseDate = (date1: Date) => {
|
|
67
|
+
selectedDate.value = date1;
|
|
68
|
+
emits('chooseDate',selectedDate.value)
|
|
69
|
+
};
|
|
70
|
+
const onRightClickDate=(e: MouseEvent,cell:CalRightClickEvent)=>{
|
|
71
|
+
emits('rightClick',e,cell)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
</script>
|
|
@@ -1,8 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
<template>
|
|
3
|
+
<div class="simpleapp-crudsimple">
|
|
4
|
+
<TableDocuments :value="recordlist" :columns="columns" :title="doc.getDocName()" >
|
|
5
|
+
<template #toolbar>
|
|
6
|
+
<div class="w-full text-left">
|
|
7
|
+
<Button class=" btn-primary" @click="newData" v-tooltip="'Add new(ctrl+enter)'" v-if="canPerform(resourcename,'create')">{{ t('new') }}</Button>
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
<template #additionaltoolbar>
|
|
11
|
+
<Button class="bg-secondary-600 hover:bg-secondary-400 text-white" @click="refresh()" type="button" >{{ t('refresh') }}</Button>
|
|
12
|
+
</template>
|
|
13
|
+
</TableDocuments>
|
|
14
|
+
<Dialog v-model:visible="showDialog" modal>
|
|
15
|
+
<NuxtPage :_id="id" @after="after"></NuxtPage>
|
|
16
|
+
</Dialog>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
</template>
|
|
1
20
|
<script setup lang="ts">
|
|
2
21
|
/**
|
|
3
22
|
* This file was automatically generated by simpleapp generator during initialization.
|
|
4
23
|
* DO NOT MODIFY IT BY HAND.
|
|
5
|
-
* last change
|
|
24
|
+
* last change 2024-02-04
|
|
6
25
|
* author: Ks Tan
|
|
7
26
|
*/
|
|
8
27
|
import {ref} from 'vue'
|
|
@@ -10,20 +29,15 @@ import _ from 'lodash'
|
|
|
10
29
|
import { SimpleAppClient } from '~/simpleapp/generate/clients/SimpleAppClient' //'../SimpleAppClient';
|
|
11
30
|
|
|
12
31
|
import {SearchBody,CellSetting} from '~/types'
|
|
13
|
-
const props =
|
|
32
|
+
const props = defineProps<{
|
|
14
33
|
document:SimpleAppClient<any,any>
|
|
15
|
-
columns:CellSetting[]
|
|
16
|
-
layoutClass?:string
|
|
17
|
-
col1Class?:string
|
|
18
|
-
col2Class?:string
|
|
34
|
+
columns:CellSetting[]
|
|
19
35
|
sorts?: string[][]
|
|
20
|
-
}>()
|
|
21
|
-
|
|
22
|
-
col1Class:'p-4',
|
|
23
|
-
col2Class:'p-4'
|
|
24
|
-
})
|
|
36
|
+
}>()
|
|
37
|
+
const id= computed(()=>getPathPara('id'))
|
|
25
38
|
const resourcename = ref( _.upperFirst(props.document.getDocName()))
|
|
26
39
|
const visible = ref(false)
|
|
40
|
+
const showDialog = ref(false);
|
|
27
41
|
const doc = props.document
|
|
28
42
|
const data = doc.getReactiveData()
|
|
29
43
|
const disabled=ref(false)
|
|
@@ -84,34 +98,28 @@ const getWantedFields = (selectedCols:CellSetting[]) =>{
|
|
|
84
98
|
return cols
|
|
85
99
|
}
|
|
86
100
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
101
|
+
watch(showDialog,()=>{
|
|
102
|
+
if(!showDialog.value){
|
|
103
|
+
goTo(props.document.getDocName())
|
|
104
|
+
}
|
|
105
|
+
})
|
|
106
|
+
watch(()=>useRoute().path, async()=>{
|
|
107
|
+
if(getPathPara('id')){
|
|
108
|
+
showDialog.value=true
|
|
109
|
+
}else{
|
|
110
|
+
showDialog.value=false
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
const after = (eventType:string)=>{
|
|
114
|
+
if(eventType!='mount') goTo(resourcename.value)
|
|
115
|
+
//showDialog.value=false
|
|
90
116
|
}
|
|
117
|
+
onMounted(()=>{
|
|
118
|
+
if(id.value){
|
|
119
|
+
showDialog.value=true
|
|
120
|
+
}else{
|
|
121
|
+
showDialog.value=false
|
|
122
|
+
}
|
|
123
|
+
})
|
|
91
124
|
</script>
|
|
92
|
-
|
|
93
|
-
<template>
|
|
94
|
-
<div class="simpleapp-crudsimple">
|
|
95
|
-
<h1 v-if="systemwindows" class="error-text text-center">* system administration screen</h1>
|
|
96
|
-
<div :class="layoutClass">
|
|
97
|
-
<div v-if="recordlist" :class="col1Class">
|
|
98
|
-
<TableDocuments :value="recordlist" :columns="columns" :title="doc.getDocName()" @select-row="selectRow">
|
|
99
|
-
<template #toolbar>
|
|
100
|
-
<div class="w-full text-left">
|
|
101
|
-
<Button class=" btn-primary" @click="newData" v-tooltip="'Add new(ctrl+enter)'" v-if="canPerform(resourcename,'create')">{{ t('new') }}</Button>
|
|
102
|
-
</div>
|
|
103
|
-
</template>
|
|
104
|
-
<template #additionaltoolbar>
|
|
105
|
-
<Button class="bg-secondary-600 hover:bg-secondary-400 text-white" @click="refresh()" type="button" >{{ t('refresh') }}</Button>
|
|
106
|
-
</template>
|
|
107
|
-
</TableDocuments>
|
|
108
|
-
|
|
109
|
-
</div>
|
|
110
|
-
<div :class="col2Class">
|
|
111
|
-
<slot>
|
|
112
|
-
undefine page content
|
|
113
|
-
</slot>
|
|
114
|
-
</div>
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
117
|
-
</template>
|
|
125
|
+
|
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Dialog v-model:visible="visible"
|
|
3
|
-
:pt="{root:{class:'w-5/6 h-5/6'}}"
|
|
2
|
+
<Dialog v-model:visible="visible"
|
|
4
3
|
:modal="true"
|
|
5
|
-
:close-on-escape="false" >
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
:close-on-escape="false" >
|
|
8
5
|
<template #header>
|
|
9
6
|
<div class="flex flex-row gap-4">
|
|
10
7
|
<Chip v-for="(v,k) in allview" :label="v.label" @remove="deleteTab" :removable="true"
|
|
@@ -16,8 +13,9 @@
|
|
|
16
13
|
<component
|
|
17
14
|
:is="defineAsyncComponent(v.viewer)"
|
|
18
15
|
:_id="v._id"
|
|
19
|
-
:readonly="v.readonly"
|
|
20
|
-
|
|
16
|
+
:readonly="v.readonly"
|
|
17
|
+
:paras="v.paras"
|
|
18
|
+
@after="(eventType:string,data:any,result:any)=>after(v,eventType,data,result)"
|
|
21
19
|
/>
|
|
22
20
|
</div>
|
|
23
21
|
</template>
|
|
@@ -41,13 +39,14 @@ import Chip from 'primevue/chip';
|
|
|
41
39
|
const {$listen,} = useNuxtApp()
|
|
42
40
|
const visible = ref(false)
|
|
43
41
|
const allview = ref<{[key:string]:ViewRecord}>({})
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
const after = (v:ViewRecord,eventType:string,data:any,result:any)=>{
|
|
43
|
+
if(v.after){
|
|
44
|
+
v.after(eventType,data,result)
|
|
45
|
+
//only after mount consider no remove tab
|
|
46
|
+
if(eventType!='mount') deleteTab()
|
|
48
47
|
}
|
|
49
|
-
deleteTab()
|
|
50
48
|
}
|
|
49
|
+
|
|
51
50
|
onKeyStroke('Escape', (e) => {
|
|
52
51
|
e.preventDefault()
|
|
53
52
|
deleteTab()
|
|
@@ -66,6 +65,7 @@ const deleteTab=()=>{
|
|
|
66
65
|
}
|
|
67
66
|
|
|
68
67
|
$listen('ViewRecord',(setting)=>{
|
|
68
|
+
console.log("ViewRecord event received by listener")
|
|
69
69
|
visible.value=true
|
|
70
70
|
allview.value[setting.eventId]=setting
|
|
71
71
|
|
|
@@ -93,8 +93,29 @@ const getFieldName = (path:string)=>{
|
|
|
93
93
|
}
|
|
94
94
|
</script>
|
|
95
95
|
<template>
|
|
96
|
-
<Toast group="default"
|
|
96
|
+
<Toast group="default">
|
|
97
97
|
<template #message="p">
|
|
98
|
+
<div class="h-full w-full border">
|
|
99
|
+
<p class="text-lg text-red-800 font-semibold pb-1">{{ p.message.summary }}</p>
|
|
100
|
+
<div v-if="p.message.detail" class="flex flex-col gap-2 ">
|
|
101
|
+
<p v-if="Array.isArray(p.message.detail)" v-for="item in p.message.detail"
|
|
102
|
+
class="text-sm text-red-600 font-normal">
|
|
103
|
+
<span v-if="item.instancePath">{{ item.instancePath }} </span>
|
|
104
|
+
<span v-if="item.message"> {{ item.message }} </span>
|
|
105
|
+
|
|
106
|
+
</p>
|
|
107
|
+
<p v-else-if="typeof p.message.detail == 'string'" class="text-sm text-gray-600 dark:text-gray-400 font-normal">
|
|
108
|
+
{{ p.message.detail }}
|
|
109
|
+
</p>
|
|
110
|
+
<p v-else-if="typeof p.message.detail == 'object'" class="text-sm text-gray-600 dark:text-gray-400 font-normal">
|
|
111
|
+
{{ p.message.detail.message }}
|
|
112
|
+
</p>
|
|
113
|
+
<p v-else></p>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
</div>
|
|
117
|
+
</template>
|
|
118
|
+
<!-- <template #message="p">
|
|
98
119
|
|
|
99
120
|
<div class="bg-gray-200 dark:bg-gray-900 h-full w-full border">
|
|
100
121
|
<div class=" flex content content-end w-full">
|
|
@@ -126,7 +147,7 @@ const getFieldName = (path:string)=>{
|
|
|
126
147
|
</div>
|
|
127
148
|
</div>
|
|
128
149
|
</div>
|
|
129
|
-
</template>
|
|
150
|
+
</template> -->
|
|
130
151
|
</Toast>
|
|
131
152
|
<!-- <Toast group="list">
|
|
132
153
|
<template #message="p">
|