@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
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div v-if="schema" class="
|
|
3
|
-
<
|
|
4
|
-
<label v-else
|
|
5
|
-
<label v-else
|
|
2
|
+
<div v-if="schema" :class="getLayoutClass()">
|
|
3
|
+
<label v-if="hidelabel"></label>
|
|
4
|
+
<label v-else :for="uuid" :class="getLabelClass()" @click="console.log(inputType)">{{ fieldlabel }} <span v-if="props.setting.isrequired && fieldlabel" class="text-danger-600">*</span></label>
|
|
5
|
+
<!-- <label v-else-if="error" class="simpleapp-input-label text-danger-600 overflow-hidden" :for="uuid">{{ fieldlabel }} <span v-if="props.setting.isrequired && fieldlabel" class="text-danger-600">*</span></label>
|
|
6
|
+
<label v-else :for="uuid" class="simpleapp-input-label whitespace-nowrap text-gray-500 truncate">{{ fieldlabel }} <span v-if="props.setting.isrequired && fieldlabel" class="text-danger-600">*</span></label> -->
|
|
6
7
|
|
|
7
8
|
<!-- <div :uuid="uuid" >{{ modelValue }}</div> -->
|
|
8
9
|
<!-- <div v-if="typeof modelValue =='object' && typeof modelValue['_id']!='undefined' && typeof modelValue['label']!='undefined' && readonly ==true " :uuid="uuid" class="simpleapp-value-readonly">{{ modelValue['label'] }}</div> -->
|
|
@@ -26,7 +27,7 @@ import SimpleAppValue from './SimpleAppValue.vue'
|
|
|
26
27
|
import {ref} from 'vue'
|
|
27
28
|
|
|
28
29
|
|
|
29
|
-
const uuid =
|
|
30
|
+
const uuid = randomUUID();
|
|
30
31
|
// const fieldlabel = ref('')
|
|
31
32
|
// const fielddesc = ref('')
|
|
32
33
|
const defaultcssclass='simpleapp-input-container'
|
|
@@ -34,6 +35,7 @@ const fieldcontainerclass = ref(defaultcssclass)
|
|
|
34
35
|
let instancepath = ref('')
|
|
35
36
|
const props = defineProps<{
|
|
36
37
|
label?: string,
|
|
38
|
+
inputType: string,
|
|
37
39
|
description?: string,
|
|
38
40
|
instancepath?:string,
|
|
39
41
|
hidelabel?:boolean,
|
|
@@ -45,17 +47,27 @@ const props = defineProps<{
|
|
|
45
47
|
const readonly = computed(()=>{
|
|
46
48
|
return props.readonly ?? props.setting.readonly ?? false
|
|
47
49
|
})
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
// }else if(props.setting.readonly !==undefined){
|
|
51
|
-
// readonly.value=props.readonly
|
|
52
|
-
// }
|
|
53
|
-
// console.log("props.setting.format",props.setting.format)
|
|
54
|
-
const modelValue = defineModel()
|
|
50
|
+
|
|
51
|
+
const modelValue = defineModel<any>() //this model value support all kind of data, string, number, autocomplete and etc
|
|
55
52
|
const readonlyclass="simpleapp-value-readonly"
|
|
56
53
|
// console.log('props.setting',modelValue.value,props.setting)
|
|
57
54
|
let schema:any
|
|
58
55
|
|
|
56
|
+
const getLayoutClass = () => `simpleapp-input-container flex ${ props.inputType == 'checkbox' ? " flex-row gap-4 mt-1 ml-1 " : "flex flex-col "}`
|
|
57
|
+
|
|
58
|
+
const getLabelClass = () => {
|
|
59
|
+
let class1= "simpleapp-input-label text-left text-gray-500 "
|
|
60
|
+
if(!isMobile()) class1 += "whitespace-nowrap truncate"
|
|
61
|
+
else if (props.inputType == 'checkbox' ) class1 += " ml-1 dark:text-grey-200"
|
|
62
|
+
else if (props.inputType != 'autocomplete' && modelValue.value) class1 += "-mb-4 ml-1 z-50 text-xs dark:text-grey-100"
|
|
63
|
+
else if (props.inputType == 'autocomplete' && modelValue.value?.label) class1 += "-mb-4 ml-1 z-50 text-xs dark:text-grey-100"
|
|
64
|
+
else if (props.inputType == 'number' && modelValue.value !== undefined) class1 += "-mb-4 ml-1 z-50 text-xs dark:text-grey-100"
|
|
65
|
+
else class1 += "-mb-4 ml-1 z-50 text-xs dark:text-grey-100 hidden"
|
|
66
|
+
return class1
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
59
71
|
const fielddesc = computed(()=>{
|
|
60
72
|
return props.description ?? ''
|
|
61
73
|
})
|
|
@@ -116,8 +128,3 @@ watch(props.setting.errors,(newvalue,oldvalue)=>{
|
|
|
116
128
|
})
|
|
117
129
|
|
|
118
130
|
</script>
|
|
119
|
-
<style scoped>
|
|
120
|
-
.simpleapp-input-container{
|
|
121
|
-
@apply flex flex-col
|
|
122
|
-
}
|
|
123
|
-
</style>
|
|
@@ -34,7 +34,7 @@ import _, { upperFirst } from 'lodash'
|
|
|
34
34
|
type keytype = keyof defaulttype
|
|
35
35
|
|
|
36
36
|
const x : keytype = 'Default'+ props.document.getDocName(true) as keytype
|
|
37
|
-
const defaultvalue = alldefaults[x](
|
|
37
|
+
const defaultvalue = alldefaults[x](randomUUID())
|
|
38
38
|
return {
|
|
39
39
|
path: path,
|
|
40
40
|
key: _.last(path.split('/')),
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
+
<!-- dont modify this component -->
|
|
2
3
|
<div class="simpleapp-tool-bar flex flex-row text-left gap-4">
|
|
3
4
|
<div v-for="(menu,index) in menus" :key="index">
|
|
4
5
|
<div>
|
|
5
|
-
<
|
|
6
|
+
<ButtonDefault v-if="showMenuButton(menu)" @click="emitEvent(menu,$event)">{{ menu.label }}</ButtonDefault>
|
|
6
7
|
</div>
|
|
7
8
|
|
|
8
9
|
</div>
|
|
9
10
|
<div v-for="(menu,index) in getDocActions()" :key="index">
|
|
10
11
|
<div>
|
|
11
|
-
<
|
|
12
|
+
<ButtonDefault @click="emitEvent(menu,$event)">{{ menu.label }}</ButtonDefault>
|
|
12
13
|
</div>
|
|
13
14
|
|
|
14
15
|
</div>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<SimpleAppFieldContainer :hidelabel="hidelabel" v-model="modelValue"
|
|
3
|
-
:label="label" :description="description" :pt="pt"
|
|
3
|
+
:label="label" :description="description" :pt="pt" :inputType="inputType"
|
|
4
4
|
:setting="setting" :instancepath="instancepath" :error="error" #default="slotprops">
|
|
5
5
|
<Checkbox v-if="inputType ==SimpleAppInputType.checkbox" :readonly="isReadonly" :pt="pt"
|
|
6
6
|
:inputId="slotprops.uuid" :path="setting.instancepath"
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
<Password
|
|
94
94
|
v-else-if="inputType == SimpleAppInputType.password"
|
|
95
95
|
:type="type" v-model="(modelValue as string)" :pt="pt"
|
|
96
|
+
@focus="setFocus"
|
|
96
97
|
:readonly="isReadonly" class="flex flex-col"
|
|
97
98
|
:inputId="slotprops.uuid" :path="setting.instancepath"
|
|
98
99
|
:placeholder="placeholder"
|
|
@@ -117,6 +118,7 @@
|
|
|
117
118
|
<!-- simple component -->
|
|
118
119
|
<InputNumber v-else-if="inputType == SimpleAppInputType.number"
|
|
119
120
|
:type="type" v-model="(modelValue as number)"
|
|
121
|
+
@focus="setFocus"
|
|
120
122
|
:readonly="isReadonly"
|
|
121
123
|
:pt="pt"
|
|
122
124
|
:class="!pt ? 'w-full flex flex-col' :''"
|
|
@@ -125,7 +127,8 @@
|
|
|
125
127
|
:placeholder="placeholder"
|
|
126
128
|
/>
|
|
127
129
|
<Textarea v-else-if="inputType == SimpleAppInputType.textarea"
|
|
128
|
-
|
|
130
|
+
v-model="(modelValue as string)"
|
|
131
|
+
:autofocus="autofocus"
|
|
129
132
|
:readonly="isReadonly"
|
|
130
133
|
:pt="pt"
|
|
131
134
|
:type="type"
|
|
@@ -136,7 +139,9 @@
|
|
|
136
139
|
v-bind="(componentProps as TextareaProps)"
|
|
137
140
|
/>
|
|
138
141
|
<InputText v-else
|
|
139
|
-
v-model="(modelValue as string)"
|
|
142
|
+
v-model="(modelValue as string)"
|
|
143
|
+
@focus="setFocus"
|
|
144
|
+
:autofocus="autofocus"
|
|
140
145
|
:readonly="isReadonly"
|
|
141
146
|
:pt="pt"
|
|
142
147
|
:type="type"
|
|
@@ -172,7 +177,7 @@ import Slider,{ SliderProps } from 'primevue/slider';
|
|
|
172
177
|
import Textarea, { TextareaProps } from 'primevue/textarea';
|
|
173
178
|
import {SimpleAppInputType} from '~/types'
|
|
174
179
|
|
|
175
|
-
const modelValue = defineModel()
|
|
180
|
+
const modelValue = defineModel({required:true})
|
|
176
181
|
const datevalue = ref('')
|
|
177
182
|
const timevalue = ref<Date>()
|
|
178
183
|
|
|
@@ -186,6 +191,7 @@ const props = withDefaults( defineProps<{
|
|
|
186
191
|
instancepath?:string,
|
|
187
192
|
hidelabel?: boolean
|
|
188
193
|
readonly?: boolean
|
|
194
|
+
autofocus?:boolean
|
|
189
195
|
pt?:any,
|
|
190
196
|
placeholder?:string
|
|
191
197
|
componentProps?: InputNumberProps | InputSwitchProps | InputTextProps | TextareaProps | DropdownProps | CalendarProps | RatingProps
|
|
@@ -221,6 +227,9 @@ const updateDate = (value:any)=>{
|
|
|
221
227
|
|
|
222
228
|
}
|
|
223
229
|
|
|
230
|
+
const setFocus = (ev:any) => {
|
|
231
|
+
if(!isMobile()) ev.target.select()
|
|
232
|
+
}
|
|
224
233
|
|
|
225
234
|
const getListOptions = () =>{
|
|
226
235
|
|
|
@@ -244,6 +253,7 @@ const getListOptions = () =>{
|
|
|
244
253
|
|
|
245
254
|
const emits = defineEmits(['change','update:modelValue','update:docNoFormat'])
|
|
246
255
|
|
|
256
|
+
|
|
247
257
|
watch(modelValue ,(newvalue:any)=>{
|
|
248
258
|
|
|
249
259
|
if([SimpleAppInputType.date,SimpleAppInputType.calendar].includes(props.inputType)){
|
|
@@ -259,7 +269,16 @@ watch(modelValue ,(newvalue:any)=>{
|
|
|
259
269
|
emits('change',modelValue.value)
|
|
260
270
|
emits('update:modelValue',modelValue.value)
|
|
261
271
|
})
|
|
262
|
-
|
|
272
|
+
onMounted(()=>{
|
|
273
|
+
if([SimpleAppInputType.date,SimpleAppInputType.calendar].includes(props.inputType)){
|
|
274
|
+
if(modelValue.value){
|
|
275
|
+
datevalue.value = moment(modelValue.value as string ).format('YYYY-MM-DD')
|
|
276
|
+
}else{
|
|
277
|
+
datevalue.value = ''
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
}
|
|
281
|
+
})
|
|
263
282
|
|
|
264
283
|
/************ start autocomplete only ***************/
|
|
265
284
|
|
|
@@ -272,6 +291,4 @@ watch(modelValue ,(newvalue:any)=>{
|
|
|
272
291
|
const triggerDocNoFormatChange=(formatdata:any)=>{
|
|
273
292
|
emits('update:docNoFormat',formatdata)
|
|
274
293
|
}
|
|
275
|
-
</script>
|
|
276
|
-
<style scoped>
|
|
277
|
-
</style>
|
|
294
|
+
</script>
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
<DataTable v-bind="$attrs" stripedRows resizableColumns
|
|
3
3
|
class="simpleapp-datatable p-datatable-sm" :value="modelValue">
|
|
4
4
|
<template #empty> <div class="text-center">No record found.</div> </template>
|
|
5
|
-
<template #header >
|
|
6
|
-
<div>
|
|
7
|
-
<Button
|
|
5
|
+
<template #header v-if="!setting.readonly && !readonly">
|
|
6
|
+
<div >
|
|
7
|
+
<Button icon="pi pi-plus" @click="addNew()" class="simpleapp-datatable-add btn-primary" type="button">Add</Button>
|
|
8
8
|
</div>
|
|
9
9
|
</template>
|
|
10
10
|
<slot>
|
|
@@ -35,6 +35,7 @@ const props = defineProps<{
|
|
|
35
35
|
// columns:InputTableColumn[],
|
|
36
36
|
setting:any,
|
|
37
37
|
getField:Function,
|
|
38
|
+
readonly?:boolean
|
|
38
39
|
}>()
|
|
39
40
|
|
|
40
41
|
|
|
@@ -22,7 +22,7 @@ import {camelCaseToWords} from './helper'
|
|
|
22
22
|
import {computed,watch} from 'vue'
|
|
23
23
|
import {ref} from 'vue'
|
|
24
24
|
const modelValue = defineModel()
|
|
25
|
-
const uuid =
|
|
25
|
+
const uuid = randomUUID()
|
|
26
26
|
const fieldlabel = ref('')
|
|
27
27
|
const fielddesc = ref('')
|
|
28
28
|
const defaultcssclass='simpleapp-input-container'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<!-- <ul role="list" class="divide-y divide-gray-100">
|
|
3
3
|
<li v-for="person in people" :key="person.email" class="flex justify-between gap-x-6 py-5"> -->
|
|
4
|
-
<div class="flex justify-between gap-x-6 py-5 cursor-pointer">
|
|
4
|
+
<div class="flex justify-between gap-x-6 py-5 cursor-pointer" @click="emits('click',data)">
|
|
5
5
|
<div class="flex min-w-0 gap-x-4">
|
|
6
6
|
<img class="h-12 w-12 flex-none rounded-full bg-gray-50" :src="`${getAvatarLink(data.email,32)}`" alt="" />
|
|
7
7
|
<div class="min-w-0 flex-auto">
|
|
@@ -38,7 +38,7 @@ import moment from 'moment'
|
|
|
38
38
|
const props = defineProps<{
|
|
39
39
|
data:any
|
|
40
40
|
}>()
|
|
41
|
-
|
|
41
|
+
const emits = defineEmits(['click'])
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
const datedifferent = computed(()=>{
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import moment from "moment";
|
|
2
|
+
|
|
3
|
+
export const dateExists = (date:Date,listDate:Date[]) => {
|
|
4
|
+
const existsrecord = listDate.find(item=>{
|
|
5
|
+
return date.getTime()===item.getTime()
|
|
6
|
+
})
|
|
7
|
+
return existsrecord===undefined ? false :true
|
|
8
|
+
}
|
|
9
|
+
export const getMoment = (startTime:string)=> moment(startTime)
|
|
10
|
+
export const lastDateOfMonth = (datestr:string) => moment(datestr).endOf('month').format('YYYY-MM-DD');
|
|
11
|
+
export const today = () => moment().format('YYYY-MM-DD')
|
|
12
|
+
export const dateToString = (date:Date) => moment(date).format('YYYY-MM-DD')
|
|
13
|
+
export const dateToDateTimeString = (date:Date)=> moment(date).format('YYYY-MM-DD HH:mm:ss')
|
|
14
|
+
export const toLocalDate = (dateiso8601:string)=> new Date(String(dateiso8601)).toLocaleDateString()
|
|
15
|
+
|
|
16
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const isMobile = () => window.innerWidth <= 640
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
2
|
import {Md5} from 'ts-md5'
|
|
3
3
|
import moment from "moment";
|
|
4
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
5
|
+
|
|
4
6
|
export const camelCaseToWords = (s: string) =>{
|
|
5
7
|
const result = s.replace(/([A-Z])/g, ' $1');
|
|
6
8
|
return result.charAt(0).toUpperCase() + result.slice(1);
|
|
7
9
|
}
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
export const randomUUID = ()=> uuidv4()
|
|
10
12
|
export const md5=(s:string)=> new Md5().appendStr(s).end()
|
|
11
13
|
|
|
12
14
|
export const getAvatarLink = (email:string, size:number):string=>{
|
|
@@ -14,10 +16,5 @@ export const getAvatarLink = (email:string, size:number):string=>{
|
|
|
14
16
|
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
export const toLocalDate = (dateiso8601:string)=> new Date(String(dateiso8601)).toLocaleDateString()
|
|
18
19
|
export const t = (txt:string,options?:any):string => !txt || txt.trim()=='' ? '' : useNuxtApp().$i18n.t(txt,options)
|
|
19
|
-
export const today = () => moment().format('YYYY-MM-DD')
|
|
20
|
-
export const dateToString = (date:Date) => moment(date).format('YYYY-MM-DD')
|
|
21
|
-
export const getMoment = (startTime:string)=> moment(startTime)
|
|
22
|
-
export const lastDateOfMonth = (datestr:string) => moment(datestr).endOf('month').format('YYYY-MM-DD');
|
|
23
20
|
export const upperFirst = (str:string) => _.upperFirst(str)
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="
|
|
3
|
-
<div class="bg-white border rounded-md flex items-center justify-center mx-4 md:w-2/3">
|
|
2
|
+
<div class="w w-full items-center justify-center py-12 bg bg-gray-500">
|
|
3
|
+
<div class="bg-white dark:bg-gray-600 p-1 border rounded-md flex items-center justify-center mx-4 w-7/8 md:w-2/3">
|
|
4
4
|
<div class="flex flex-col items-center py-16">
|
|
5
5
|
|
|
6
6
|
<div class="flex flex-row">
|
|
7
|
-
<div class="w w-
|
|
7
|
+
<div class="w w-full ">
|
|
8
8
|
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-13.59 -13.59 480.17 480.17" xml:space="preserve" fill="#000000" stroke="#000000" stroke-width="0.00452986"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <g> <g> <g> <path style="fill:#010002;" d="M0,0v452.986h452.986V0H0z M403.223,24.655c8.132,0,14.668,6.558,14.668,14.625 c0,8.111-6.536,14.711-14.668,14.711c-8.089,0-14.668-6.601-14.668-14.711C388.576,31.234,395.134,24.655,403.223,24.655z M352.035,24.655c8.046,0,14.647,6.558,14.647,14.625c0,8.111-6.601,14.711-14.647,14.711c-8.132,0-14.668-6.601-14.668-14.711 C337.389,31.234,343.903,24.655,352.035,24.655z M417.955,418.624H35.053V85.701h382.903V418.624z"></path> <path style="fill:#010002;" d="M226.493,398.952c80.394,0,145.495-65.101,145.495-145.43s-65.101-145.495-145.495-145.495 c-80.373,0-145.516,65.165-145.516,145.495C80.977,333.873,146.12,398.952,226.493,398.952z M142.044,198.516l29.444-29.444 l55.005,55.027l54.984-55.027l29.379,29.444L255.894,253.5l54.984,54.941l-29.423,29.444l-54.962-54.962l-55.005,54.984 l-29.444-29.444l54.984-54.941L142.044,198.516z"></path> </g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> </g> </g></svg>
|
|
9
9
|
</div>
|
|
10
10
|
<div>
|
|
11
11
|
<h1 class="px-4 pt-2 pb-4 text-left text-5xl font-bold leading-10 text-gray-800">OOPS!</h1>
|
|
12
|
-
<p class="px-4 mt mb-4 text-4xl text-left font font-bold">{{error?.statusCode}} Error</p>
|
|
12
|
+
<p class="px-4 mt mb-4 text-4xl text-left font font-bold">{{isNaN(error?.statusCode) ? t('server'): error?.statusCode}} Error</p>
|
|
13
13
|
<p class="px-4 pb-10 text-base leading-none text-left text-red-400">{{t(error?.statusMessage)}}</p>
|
|
14
14
|
<p> <Button @click="handleError" class="btn-primary">{{ t('backToHome') }}</Button></p>
|
|
15
15
|
</div>
|
|
@@ -1,10 +1,34 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
// import Menus from '~/components/Menus.vue'
|
|
3
|
-
</script>
|
|
4
1
|
<template>
|
|
5
|
-
<div>
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
<div class="h-full flex flex-row">
|
|
3
|
+
<div class="flex flex-col justify justify-between">
|
|
4
|
+
<div >
|
|
5
|
+
<HeaderButtonMenuPicker class="cursor-pointer p-2 text-6xl "></HeaderButtonMenuPicker>
|
|
6
|
+
<div class="" v-for="item in menus">
|
|
7
|
+
<div class="">
|
|
8
|
+
<NuxtLink
|
|
9
|
+
:class="`pi ${item.iconClass} p-2 text-6xl cursor-pointer`"
|
|
10
|
+
:to="getDocumentUrl(item.path)"
|
|
11
|
+
></NuxtLink>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
<HeaderButtonProfile class="p-6"/>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="flex-1">
|
|
18
|
+
<HeaderBar />
|
|
19
|
+
<UserInvitation/>
|
|
20
|
+
<slot></slot>
|
|
21
|
+
</div>
|
|
9
22
|
</div>
|
|
10
|
-
|
|
23
|
+
|
|
24
|
+
</template>
|
|
25
|
+
<script setup lang="ts">
|
|
26
|
+
const menus=[
|
|
27
|
+
// {iconClass:'pi-bars',path:'managestudents/profile'},
|
|
28
|
+
{iconClass:'pi-home text-white',path:''},
|
|
29
|
+
{iconClass:'pi-users text-white',path:'managestudents/profile'},
|
|
30
|
+
{iconClass:'pi-calendar text-white',path:`manageclasses`},
|
|
31
|
+
// {iconClass:'pi-database',path:'managedata'},
|
|
32
|
+
{iconClass:'pi-chart-pie text-white',path:'reports'},
|
|
33
|
+
]
|
|
34
|
+
</script>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="h-screen flex flex-col">
|
|
3
|
+
<div class="flex flex-col grow">
|
|
4
|
+
<slot></slot>
|
|
5
|
+
</div>
|
|
6
|
+
<!-- fixed -->
|
|
7
|
+
<div v-if="getCurrentXorg()" class="flex h-20 border-t-2 dark:border-t-gray-700 text-4xl flex-row left-0 w-full justify justify-between bottom-0 z-50 bg-white dark:bg-gray-600 pl-2 pr-2" >
|
|
8
|
+
<NuxtLink v-for="item in menus"
|
|
9
|
+
:class="`pi ${item.iconClass} pb-6 pt-6 cursor-pointer inline-block align-middle`"
|
|
10
|
+
:to="getDocumentUrl(item.path)"
|
|
11
|
+
></NuxtLink>
|
|
12
|
+
<HeaderButtonMenuPicker class=" cursor-pointer"></HeaderButtonMenuPicker>
|
|
13
|
+
<HeaderButtonProfile class=""/>
|
|
14
|
+
<UserInvitation/>
|
|
15
|
+
</div>
|
|
16
|
+
<!-- <HeaderBar class="border flex flex-row h-10 fixed left-0 w-full justify justify-between top-0 z-50 bg-white dark:bg-gray-800"/> -->
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
<script setup lang="ts">
|
|
21
|
+
const menus=[
|
|
22
|
+
// {iconClass:'pi-bars',path:'managestudents/profile'},
|
|
23
|
+
{iconClass:'pi-home text-white',path:''},
|
|
24
|
+
// {iconClass:'pi-users text-white',path:'managestudents/profile'},
|
|
25
|
+
// {iconClass:'pi-calendar text-white',path:`manageclasses`},
|
|
26
|
+
// {iconClass:'pi-database',path:'managedata'},
|
|
27
|
+
// {iconClass:'pi-chart-pie text-white',path:'reports'},
|
|
28
|
+
]
|
|
29
|
+
</script>
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import path from 'path'
|
|
8
8
|
export default defineNuxtConfig({
|
|
9
|
-
|
|
9
|
+
colorMode: {
|
|
10
|
+
classSuffix: ''
|
|
11
|
+
|
|
12
|
+
},
|
|
13
|
+
|
|
10
14
|
runtimeConfig:{
|
|
11
15
|
public:{
|
|
12
16
|
APP_URL: process.env.APP_URL,
|
|
@@ -26,13 +30,19 @@ export default defineNuxtConfig({
|
|
|
26
30
|
tailwindcss: {
|
|
27
31
|
// Options
|
|
28
32
|
},
|
|
33
|
+
devServer: {
|
|
34
|
+
host: "0.0.0.0",
|
|
35
|
+
},
|
|
29
36
|
modules: [
|
|
30
37
|
// "@hebilicious/authjs-nuxt",
|
|
38
|
+
'@nuxtjs/color-mode',
|
|
39
|
+
'@nuxtjs/device',
|
|
31
40
|
'@nuxtjs/i18n',
|
|
32
41
|
'@sidebase/nuxt-auth',
|
|
33
42
|
'nuxt-primevue',
|
|
43
|
+
// '@nuxtjs/pwa', //cannot turn on, will cause nuxt cant start
|
|
34
44
|
// "nuxt-security", //temporary avoid nuxt-security cause cors
|
|
35
|
-
'@vueuse/nuxt',
|
|
45
|
+
'@vueuse/nuxt',
|
|
36
46
|
'@nuxtjs/tailwindcss',
|
|
37
47
|
['@pinia/nuxt',{
|
|
38
48
|
autoImports: [
|
|
@@ -41,10 +51,13 @@ tailwindcss: {
|
|
|
41
51
|
['defineStore', 'definePiniaStore'], // import { defineStore as definePiniaStore } from 'pinia'
|
|
42
52
|
],
|
|
43
53
|
}],
|
|
44
|
-
|
|
54
|
+
|
|
45
55
|
|
|
46
56
|
|
|
47
|
-
],
|
|
57
|
+
],
|
|
58
|
+
device: {
|
|
59
|
+
refreshOnResize: true
|
|
60
|
+
},
|
|
48
61
|
i18n: {
|
|
49
62
|
lazy: true,
|
|
50
63
|
langDir: "lang/",
|
|
@@ -67,13 +80,14 @@ tailwindcss: {
|
|
|
67
80
|
iso: "cn",
|
|
68
81
|
name: "Chinese",
|
|
69
82
|
file: "cn.ts",
|
|
83
|
+
|
|
70
84
|
},
|
|
71
85
|
],
|
|
72
86
|
defaultLocale: "df",
|
|
73
87
|
},
|
|
74
88
|
primevue: {
|
|
75
89
|
options: {
|
|
76
|
-
unstyled: true,
|
|
90
|
+
//unstyled: true,
|
|
77
91
|
ripple: true,
|
|
78
92
|
inputStyle: 'filled'
|
|
79
93
|
},
|
|
@@ -82,7 +96,7 @@ tailwindcss: {
|
|
|
82
96
|
exclude: ['chart']
|
|
83
97
|
},
|
|
84
98
|
directives: {
|
|
85
|
-
include: ['Ripple', 'Tooltip','BadgeDirective']
|
|
99
|
+
include: ['Ripple', 'Tooltip','BadgeDirective','FocusTrap']
|
|
86
100
|
},
|
|
87
101
|
cssLayerOrder: 'tailwind-base, primevue, tailwind-utilities',
|
|
88
102
|
importPT: { as: 'SimpleAppPT', from: path.resolve(__dirname,'./assets/primevue/passthrough.ts') },
|
|
@@ -93,7 +107,7 @@ tailwindcss: {
|
|
|
93
107
|
|
|
94
108
|
// },
|
|
95
109
|
auth: {
|
|
96
|
-
globalAppMiddleware:
|
|
110
|
+
globalAppMiddleware: false
|
|
97
111
|
},
|
|
98
112
|
// security: {
|
|
99
113
|
// corsHandler:{
|
|
@@ -122,14 +136,14 @@ tailwindcss: {
|
|
|
122
136
|
// ],
|
|
123
137
|
css: [
|
|
124
138
|
'primeicons/primeicons.css',
|
|
125
|
-
path.resolve(__dirname,'./assets/css/style.css')
|
|
126
|
-
|
|
139
|
+
path.resolve(__dirname,'./assets/css/style.css'),
|
|
140
|
+
path.resolve(__dirname,'./assets/css/calendar.css'),
|
|
141
|
+
],
|
|
142
|
+
},
|
|
127
143
|
|
|
128
144
|
// devtools: { enabled: true },
|
|
129
145
|
// build: {
|
|
130
146
|
// // transpile: ["primevue"]
|
|
131
|
-
// },
|
|
132
|
-
|
|
133
|
-
|
|
147
|
+
// },
|
|
134
148
|
|
|
135
|
-
|
|
149
|
+
)
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
/**
|
|
3
|
-
* This file was automatically generated by simpleapp generator.
|
|
4
|
-
* YOU ALLOWED TO CHANGE THIS FILE, IT WONT OVERRIDE BY GENERATOR
|
|
5
|
-
* last change 2023-10-28
|
|
6
|
-
* Author: Ks Tan
|
|
7
|
-
*/
|
|
8
|
-
</script>
|
|
9
1
|
<template>
|
|
10
2
|
<div class="frontpage-container">
|
|
11
3
|
<client-only>
|
|
12
|
-
<title>{{ getUserProfile()
|
|
4
|
+
<title>{{ getUserProfile()?.branchName }}</title>
|
|
13
5
|
</client-only>
|
|
14
6
|
<h1 class="border text-3xl text-center m-20 p-20">
|
|
15
7
|
{{ t("createYourContentHere") }}
|
|
16
8
|
</h1>
|
|
17
9
|
</div>
|
|
18
10
|
</template>
|
|
11
|
+
<script lang="ts" setup>
|
|
12
|
+
/**
|
|
13
|
+
* This file was automatically generated by simpleapp generator.
|
|
14
|
+
* YOU ALLOWED TO CHANGE THIS FILE, IT WONT OVERRIDE BY GENERATOR
|
|
15
|
+
* last change 2023-10-28
|
|
16
|
+
* Author: Ks Tan
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
useNuxtApp().$event('SetTitle',t('home'))
|
|
20
|
+
</script>
|
|
@@ -114,6 +114,11 @@ getCurrentOrg();
|
|
|
114
114
|
v-model="data.timeZone"
|
|
115
115
|
:setting="o.getField('#/properties/timeZone')"
|
|
116
116
|
/>
|
|
117
|
+
<SimpleAppInput
|
|
118
|
+
:input-type="SimpleAppInputType.text"
|
|
119
|
+
v-model="data.currency"
|
|
120
|
+
:setting="o.getField('#/properties/currency')"
|
|
121
|
+
/>
|
|
117
122
|
</div>
|
|
118
123
|
<div>
|
|
119
124
|
<SimpleAppInput
|
|
@@ -22,21 +22,17 @@
|
|
|
22
22
|
/>
|
|
23
23
|
|
|
24
24
|
<SimpleAppInput
|
|
25
|
-
|
|
25
|
+
:input-type="SimpleAppInputType.checkbox"
|
|
26
26
|
:setting="o.getField('#/properties/active')"
|
|
27
27
|
v-model="userdata.active"
|
|
28
28
|
/>
|
|
29
29
|
<SimpleAppInput
|
|
30
|
-
|
|
30
|
+
:input-type="SimpleAppInputType.textarea"
|
|
31
31
|
:setting="o.getField('#/properties/description')"
|
|
32
32
|
v-model="userdata.description"
|
|
33
33
|
/>
|
|
34
34
|
<div>
|
|
35
|
-
<Button
|
|
36
|
-
@click="saveUser"
|
|
37
|
-
class="btn btn-primary"
|
|
38
|
-
>Save</Button
|
|
39
|
-
>
|
|
35
|
+
<Button @click="saveUser" class="btn btn-primary">Save</Button>
|
|
40
36
|
<Button
|
|
41
37
|
v-if="canPerform('user', 'delete')"
|
|
42
38
|
@click="deleteUser"
|
|
@@ -103,7 +99,7 @@
|
|
|
103
99
|
</template>
|
|
104
100
|
<script setup lang="ts">
|
|
105
101
|
// import Card from "primevue/card";
|
|
106
|
-
import {SimpleAppInputType} from "~/types"
|
|
102
|
+
import { SimpleAppInputType } from "~/types";
|
|
107
103
|
import { Permission, User } from "../../../simpleapp/generate/openapi/api";
|
|
108
104
|
import _ from "lodash";
|
|
109
105
|
import SelectButton from "primevue/selectbutton";
|
|
@@ -294,9 +290,11 @@ const getPermssionData = (userId: string, branchId: number) => {
|
|
|
294
290
|
return pm;
|
|
295
291
|
};
|
|
296
292
|
|
|
297
|
-
onMounted(() => {
|
|
298
|
-
const id =
|
|
299
|
-
|
|
300
|
-
|
|
293
|
+
onMounted(async () => {
|
|
294
|
+
const id = getPathPara('id')
|
|
295
|
+
if(id){
|
|
296
|
+
await onSelectUser(id);
|
|
297
|
+
}
|
|
298
|
+
|
|
301
299
|
});
|
|
302
300
|
</script>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="p-10 m-10 text-3xl border text-center dark:text-white">
|
|
3
|
+
{{ t('redirectToLoginPage') }}
|
|
4
|
+
<!-- <NuxtPage /> -->
|
|
5
|
+
</div>
|
|
6
|
+
</template>
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
/**
|
|
9
|
+
* This file was automatically generated by simpleapp generator. Every
|
|
10
|
+
* MODIFICATION OVERRIDE BY GENERATEOR
|
|
11
|
+
* last change 2024-02-13
|
|
12
|
+
* Author: Ks Tan
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
definePageMeta({
|
|
16
|
+
name: "Login",
|
|
17
|
+
auth: false,
|
|
18
|
+
layout: false
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const route = useRoute();
|
|
22
|
+
const { signIn } = useAuth();
|
|
23
|
+
const callbackUrl = ref("");
|
|
24
|
+
onMounted(async () => {
|
|
25
|
+
if (route.query.callbackUrl) {
|
|
26
|
+
callbackUrl.value = <string>route.query.callbackUrl;
|
|
27
|
+
} else {
|
|
28
|
+
callbackUrl.value = "/";
|
|
29
|
+
}
|
|
30
|
+
callbackUrl.value = decodeURIComponent(callbackUrl.value);
|
|
31
|
+
// console.log("callbackUrlcallbackUrlcallbackUrl", callbackUrl.value);
|
|
32
|
+
await signIn("keycloak", { callbackUrl: callbackUrl.value });
|
|
33
|
+
});
|
|
34
|
+
</script>
|