@simitgroup/simpleapp-generator 1.6.1-alpha → 1.6.2-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.
- package/README.md +8 -1
- package/package.json +1 -1
- package/templates/nest/src/simpleapp/services/userresolver.service.ts._eta +22 -25
- package/templates/nuxt/components/calendar/CalendarInput.vue.eta +24 -0
- package/templates/nuxt/components/list/ListView.vue.eta +60 -19
- package/templates/nuxt/composables/date.generate.ts.eta +1 -0
- package/templates/project/jsonschemas/invoice.json._eta +15 -7
package/README.md
CHANGED
|
@@ -104,7 +104,7 @@ simpleapp-generator -g init
|
|
|
104
104
|
|
|
105
105
|
5. prepare backend
|
|
106
106
|
```sh
|
|
107
|
-
|
|
107
|
+
bash build.sh backend
|
|
108
108
|
```
|
|
109
109
|
6. update backend configurations file by modify `~/project1/backend/.env`, change mongodb, keycloak settings according your requirements
|
|
110
110
|
7. start backend:
|
|
@@ -118,6 +118,13 @@ pnpm start:dev
|
|
|
118
118
|
sh build.sh frontend
|
|
119
119
|
```
|
|
120
120
|
9. modify frontend configuration by modify `~/project1/frontend/.env`, change keycloak settings
|
|
121
|
+
```sh
|
|
122
|
+
OAUTH2_BASEURL=https://server-url #keycloak server url
|
|
123
|
+
OAUTH2_CONFIGURL=https://server-url/realms/testing
|
|
124
|
+
OAUTH2_CLIENTID=client1
|
|
125
|
+
OAUTH2_CLIENTSECRET=aaaa-xxxxx-yyyy-zzzzz-www
|
|
126
|
+
ADMIN_EMAIL=your@ykeycloakemail.com #if you have multiple, separate by ','
|
|
127
|
+
```
|
|
121
128
|
10. start frontend:
|
|
122
129
|
```sh
|
|
123
130
|
cd ~/project1/frontend
|
package/package.json
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* This file was automatically generated by simpleapp generator. It is changable
|
|
3
|
-
* --remove-this-line-to-prevent-override--
|
|
4
3
|
* last change 2024-04-24
|
|
5
4
|
* Author: Ks Tan
|
|
6
5
|
*/
|
|
@@ -9,32 +8,30 @@ import { Injectable } from '@nestjs/common';
|
|
|
9
8
|
import { SimpleAppRobotUserService } from '../generate/commons/robotuser.service';
|
|
10
9
|
import { UserContext } from '../generate/commons/user.context';
|
|
11
10
|
import { UserService } from './user.service';
|
|
12
|
-
import { TeacherService } from './teacher.service';
|
|
13
|
-
|
|
11
|
+
// import { TeacherService } from './teacher.service';
|
|
14
12
|
|
|
15
13
|
@Injectable()
|
|
16
14
|
export class UserResolverService {
|
|
17
15
|
constructor(
|
|
18
16
|
private userService: UserService,
|
|
19
|
-
private teacherService: TeacherService,
|
|
17
|
+
// private teacherService: TeacherService,
|
|
20
18
|
private robotUserService: SimpleAppRobotUserService,
|
|
21
19
|
) {}
|
|
22
|
-
async teacher(assignvalue: string, data: any) {
|
|
23
|
-
console.log('assign value for teacher', assignvalue);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
20
|
+
// async teacher(assignvalue: string, data: any) {
|
|
21
|
+
// console.log('assign value for teacher', assignvalue);
|
|
22
|
+
// const appuser = this.robotUserService.prepareAppUser(data);
|
|
23
|
+
// console.log('gettenant', appuser.getBranchFilter());
|
|
24
|
+
// return this.resolve(appuser, 'teacher', assignvalue, data);
|
|
25
|
+
// }
|
|
29
26
|
async resolve(appuser: UserContext, usertype: string, id: string, data: any) {
|
|
30
27
|
let result = '';
|
|
31
28
|
switch (usertype) {
|
|
32
29
|
case 'user':
|
|
33
30
|
result = await this.resolveUser(appuser, id, data);
|
|
34
31
|
break;
|
|
35
|
-
case 'teacher':
|
|
36
|
-
|
|
37
|
-
|
|
32
|
+
// case 'teacher':
|
|
33
|
+
// result = await this.resolveTeacher(appuser, id, data);
|
|
34
|
+
// break;
|
|
38
35
|
|
|
39
36
|
case 'group':
|
|
40
37
|
// result = await this.resolveTeacher(appuser,id,data)
|
|
@@ -51,17 +48,17 @@ export class UserResolverService {
|
|
|
51
48
|
if (user && user.length > 0) return user[0].uid;
|
|
52
49
|
else return undefined;
|
|
53
50
|
}
|
|
54
|
-
async resolveTeacher(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
51
|
+
// async resolveTeacher(
|
|
52
|
+
// appuser: UserContext,
|
|
53
|
+
// id: string | undefined,
|
|
54
|
+
// data: any,
|
|
55
|
+
// ) {
|
|
56
|
+
// if (!id) return undefined;
|
|
57
|
+
// console.log('Find teacher::', id);
|
|
58
|
+
// const teacher = await this.teacherService.findById(appuser, id);
|
|
59
|
+
// console.log('teacher', teacher);
|
|
60
|
+
// return this.getUser(appuser, teacher.email);
|
|
61
|
+
// }
|
|
65
62
|
|
|
66
63
|
async resolveUser(appuser: UserContext, id: string | undefined, data: any) {
|
|
67
64
|
const user = await this.userService.findById(appuser, id);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="flex flex-col ">
|
|
3
|
+
<label v-if="label" :for="inputid">{{ label }}</label>
|
|
4
|
+
<Calendar
|
|
5
|
+
v-model="modelValue"
|
|
6
|
+
class="w-full"
|
|
7
|
+
:inputid="inputid"
|
|
8
|
+
:date-format="getPrimevueCalendarDateFormat()"
|
|
9
|
+
/>
|
|
10
|
+
</div>
|
|
11
|
+
</template>
|
|
12
|
+
<script setup lang="ts">
|
|
13
|
+
/**
|
|
14
|
+
* This file was automatically generated by simpleapp generator during initialization.
|
|
15
|
+
* IT IS NOT CHANGABLE
|
|
16
|
+
* last change 2024-04-16
|
|
17
|
+
* author: Ks Tan
|
|
18
|
+
*/
|
|
19
|
+
const modelValue = defineModel<Date>({required:true})
|
|
20
|
+
const inputid=randomUUID()
|
|
21
|
+
const props = defineProps<{
|
|
22
|
+
label?:string
|
|
23
|
+
}>()
|
|
24
|
+
</script>
|
|
@@ -1,21 +1,29 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="relative">
|
|
3
|
-
<div v-if="withFilter" class="flex flex-row">
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
<div v-if="withFilter" class="flex flex-row p-2">
|
|
4
|
+
<InputGroup>
|
|
5
|
+
<InputGroupAddon v-if="filter">
|
|
6
|
+
|
|
7
|
+
<ButtonDefault @click="showMoreFilter" v-if="Object.keys(filter)==0">
|
|
8
|
+
<i class="pi pi-filter"></i>
|
|
9
|
+
</ButtonDefault>
|
|
10
|
+
<ButtonWarning @click="showMoreFilter" v-else>
|
|
11
|
+
<i class="pi pi-filter"></i>
|
|
12
|
+
</ButtonWarning>
|
|
13
|
+
</InputGroupAddon>
|
|
14
|
+
<InputText
|
|
15
|
+
:placeholder="t('searchKeyword')"
|
|
16
|
+
v-model="searchvalue"
|
|
17
|
+
class="w-full dark:text-white text-sm "
|
|
18
|
+
type="search"
|
|
19
|
+
ref="listviewfilter"
|
|
20
|
+
/>
|
|
21
|
+
<InputGroupAddon v-if="withAddNew">
|
|
22
|
+
<ButtonPrimary @click="emits('add')">
|
|
23
|
+
<i class="pi pi-plus"></i>
|
|
24
|
+
</ButtonPrimary>
|
|
25
|
+
</InputGroupAddon>
|
|
26
|
+
</InputGroup>
|
|
19
27
|
</div>
|
|
20
28
|
|
|
21
29
|
<div
|
|
@@ -51,7 +59,10 @@
|
|
|
51
59
|
index > 0 ? 'border-t-2' : ''
|
|
52
60
|
}`"
|
|
53
61
|
>
|
|
54
|
-
<NuxtLink
|
|
62
|
+
<NuxtLink
|
|
63
|
+
:to="getUrl(item)"
|
|
64
|
+
:class="`p-2 ${showClickEffect ? 'listlink' : ''}`"
|
|
65
|
+
>
|
|
55
66
|
<slot name="default" :item="item" :index="index">
|
|
56
67
|
<div class="flex flex-row">
|
|
57
68
|
<div class="flex-1 mr-2 dark:text-white">
|
|
@@ -76,6 +87,23 @@
|
|
|
76
87
|
</slot>
|
|
77
88
|
</div>
|
|
78
89
|
</div>
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
<Dialog v-model:visible="visibleMoreFilter" :header="t('filter')">
|
|
93
|
+
<slot name="filter">
|
|
94
|
+
define filter in #filter
|
|
95
|
+
</slot>
|
|
96
|
+
<template #footer>
|
|
97
|
+
<div class="flex flex-row">
|
|
98
|
+
<ButtonDefault @click="clearFilter" class="flex flex-row p-2">
|
|
99
|
+
<i class="pi pi-times mr-1"/> <span class="mr-1">{{t('clear')}}</span>
|
|
100
|
+
</ButtonDefault>
|
|
101
|
+
<ButtonPrimary @click="runFilter" class="flex flex-row p-2">
|
|
102
|
+
<i class="pi pi-filter mr-1"/> <span class="mr-1">{{t('ok')}}</span>
|
|
103
|
+
</ButtonPrimary>
|
|
104
|
+
</div>
|
|
105
|
+
</template>
|
|
106
|
+
</Dialog>
|
|
79
107
|
</div>
|
|
80
108
|
</template>
|
|
81
109
|
<script setup lang="ts" generic="T extends { [key: string]: any }">
|
|
@@ -88,6 +116,7 @@
|
|
|
88
116
|
import { ref } from "vue";
|
|
89
117
|
import { ListItem } from "~/types/listview";
|
|
90
118
|
import _ from "lodash";
|
|
119
|
+
const visibleMoreFilter = ref(false)
|
|
91
120
|
const listviewfilter = ref();
|
|
92
121
|
const props = withDefaults(
|
|
93
122
|
defineProps<{
|
|
@@ -97,9 +126,10 @@ const props = withDefaults(
|
|
|
97
126
|
idField?: string;
|
|
98
127
|
subTitleField?: string;
|
|
99
128
|
withFilter?: boolean;
|
|
129
|
+
filter?:Object;
|
|
100
130
|
withAddNew?: boolean;
|
|
101
131
|
showIndex?: boolean;
|
|
102
|
-
showClickEffect?:boolean
|
|
132
|
+
showClickEffect?: boolean;
|
|
103
133
|
}>(),
|
|
104
134
|
{
|
|
105
135
|
idField: "_id",
|
|
@@ -108,7 +138,7 @@ const props = withDefaults(
|
|
|
108
138
|
const letters = ref<string[]>([]);
|
|
109
139
|
let lastchar = "";
|
|
110
140
|
|
|
111
|
-
const emits = defineEmits(["add", "click"]);
|
|
141
|
+
const emits = defineEmits(["add", "runFilter", "clearFilter","click"]);
|
|
112
142
|
const searchvalue = ref("");
|
|
113
143
|
const selecteditem = ref("");
|
|
114
144
|
const clickRow = (item: ListItem) => {
|
|
@@ -172,6 +202,17 @@ const onClick = (index: number, data: T) => {
|
|
|
172
202
|
emits("click", index, data);
|
|
173
203
|
};
|
|
174
204
|
|
|
205
|
+
const showMoreFilter = ()=>{
|
|
206
|
+
visibleMoreFilter.value=true
|
|
207
|
+
}
|
|
208
|
+
const clearFilter = () =>{
|
|
209
|
+
visibleMoreFilter.value = false
|
|
210
|
+
emits('clearFilter')
|
|
211
|
+
}
|
|
212
|
+
const runFilter = () => {
|
|
213
|
+
visibleMoreFilter.value = false
|
|
214
|
+
emits('runFilter')
|
|
215
|
+
}
|
|
175
216
|
onMounted(() => {
|
|
176
217
|
// if(props.withFilter) listviewfilter.value.$el.focus()
|
|
177
218
|
});
|
|
@@ -21,6 +21,7 @@ export const dateToISOString = (date:Date) => useDayjs()(date).toISOString()
|
|
|
21
21
|
export const dateToTimeString = (date:Date) => useDayjs()(date).format('HH:mm:ss')
|
|
22
22
|
export const stringToDate = (datestr:string) => new Date(datestr)
|
|
23
23
|
export const dateToDateTimeString = (date:Date)=> useDayjs().utc(date).format('YYYY-MM-DD HH:mm:ss')
|
|
24
|
+
export const toLocalDate = (date:string | Date)=> useDayjs().utc(date).format(getDateFormat())
|
|
24
25
|
export const toUTCDate = (date:string | Date)=> useDayjs().utc(date).format(getDateFormat())
|
|
25
26
|
export const toUTCDateTime = (date:string | Date)=> useDayjs().utc(date).format(getDateTimeFormat())
|
|
26
27
|
export const toUTCTime = (date:string | Date)=> useDayjs().utc(date).format('HH:mm')
|
|
@@ -8,18 +8,26 @@
|
|
|
8
8
|
"documentTitle": "invoiceTitle",
|
|
9
9
|
"documentDate": "invoiceDate",
|
|
10
10
|
"generateDocumentNumber": true,
|
|
11
|
-
"pageType": "crud",
|
|
11
|
+
"pageType": "crud",
|
|
12
12
|
"formulas": [
|
|
13
|
-
{ "jsonPath": "$.details[*]", "formula": "sharelibs.getSubtotal(
|
|
13
|
+
{ "jsonPath": "$.details[*]", "formula": "sharelibs.getSubtotal($item)" },
|
|
14
14
|
{
|
|
15
15
|
"jsonPath": "$.invoiceTotal",
|
|
16
|
-
"formula": "sharelibs.getTotal(data.details)"
|
|
16
|
+
"formula": "sharelibs.getTotal($data.details)"
|
|
17
17
|
}
|
|
18
18
|
],
|
|
19
|
-
"printFormats":[
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
"printFormats": [
|
|
20
|
+
{
|
|
21
|
+
"formatName": "invoice A4",
|
|
22
|
+
"formatId": "invoice-a4",
|
|
23
|
+
"description": ""
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"formatName": "invoice A5",
|
|
27
|
+
"formatId": "invoice-a5",
|
|
28
|
+
"description": ""
|
|
29
|
+
}
|
|
30
|
+
]
|
|
23
31
|
},
|
|
24
32
|
"properties": {
|
|
25
33
|
"_id": { "type": "string" },
|