@simitgroup/simpleapp-generator 1.0.9 → 1.0.15
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 +148 -1
- package/dist/createproject.js +39 -18
- package/dist/createproject.js.map +1 -1
- package/dist/generate.js +47 -20
- package/dist/generate.js.map +1 -1
- package/dist/index.js +36 -25
- package/dist/index.js.map +1 -1
- package/dist/processors/jsonschemabuilder.js +38 -8
- package/dist/processors/jsonschemabuilder.js.map +1 -1
- package/dist/storage.js +5 -0
- package/dist/storage.js.map +1 -0
- package/package.json +10 -5
- package/src/createproject.ts +40 -14
- package/src/generate.ts +60 -28
- package/src/index.ts +31 -20
- package/src/processors/jsonschemabuilder.ts +48 -14
- package/src/storage.ts +3 -0
- package/src/type.ts +23 -1
- package/templates/SimpleAppClient.eta +10 -5
- package/templates/SimpleAppService.eta +65 -17
- package/templates/basic/model.eta +1 -1
- package/templates/basic/pageindex.vue.eta +50 -0
- package/templates/basic/pageindexwithid.vue.eta +1 -0
- package/templates/basic/{apiclient.eta → simpleappclient.eta} +6 -3
- package/templates/nuxt/app.vue.eta +8 -0
- package/templates/nuxt/components.crudsimple.vue.eta +95 -0
- package/templates/nuxt/components.debugdocdata.vue.eta +20 -0
- package/templates/nuxt/components.eventmonitor.vue.eta +79 -0
- package/templates/nuxt/components.menus.vue.eta +18 -0
- package/templates/nuxt/composables.getautocomplete.ts.eta +24 -0
- package/templates/nuxt/composables.getmenus.ts.eta +9 -0
- package/templates/nuxt/env.eta +3 -0
- package/templates/nuxt/layouts.default.vue.eta +10 -0
- package/templates/{nuxt.config.eta → nuxt/nuxt.config.ts.eta} +6 -3
- package/templates/nuxt/pages.index.vue.eta +3 -0
- package/templates/{nuxt.plugins.eta → nuxt/plugins.simpleapp.ts.eta} +11 -4
- package/templates/nuxt/server.api.ts.eta +131 -0
- package/templates/nuxt/tailwind.config.ts.eta +9 -0
- package/templates/nuxt/tailwind.css.eta +28 -0
- package/templates/nuxt.env.eta +0 -2
|
@@ -3,7 +3,7 @@ import { InjectModel } from '@nestjs/mongoose';
|
|
|
3
3
|
import { Model } from 'mongoose';
|
|
4
4
|
import Ajv from 'ajv';
|
|
5
5
|
import addFormats from 'ajv-formats';
|
|
6
|
-
|
|
6
|
+
import foreignkeys from '../dicts/foreignkeys.json';
|
|
7
7
|
import {
|
|
8
8
|
NotFoundException,
|
|
9
9
|
InternalServerErrorException,
|
|
@@ -11,9 +11,11 @@ import {
|
|
|
11
11
|
@Injectable()
|
|
12
12
|
export class SimpleAppService<T extends { _id?: string }> {
|
|
13
13
|
protected jsonschema = { type: 'object', properties: {}, required: [] };
|
|
14
|
-
protected documentIdentityCode='code'
|
|
15
|
-
protected documentIdentityName='label'
|
|
16
|
-
protected
|
|
14
|
+
protected documentIdentityCode = 'code';
|
|
15
|
+
protected documentIdentityName = 'label';
|
|
16
|
+
protected documentName = 'category';
|
|
17
|
+
protected documentType = 'CAT';
|
|
18
|
+
protected LIMITPERPAGE = 20;
|
|
17
19
|
protected data: T = { _id: '' } as T;
|
|
18
20
|
protected doc: Model<T>;
|
|
19
21
|
protected errorlist = [];
|
|
@@ -24,7 +26,7 @@ export class SimpleAppService<T extends { _id?: string }> {
|
|
|
24
26
|
setSchema = (newschema) => (this.jsonschema = newschema);
|
|
25
27
|
getSchema = () => this.doc.schema.obj;
|
|
26
28
|
getData = () => {
|
|
27
|
-
console.log('thisdata', this.data);
|
|
29
|
+
//console.log('thisdata', this.data);
|
|
28
30
|
return this.data;
|
|
29
31
|
};
|
|
30
32
|
setData = (newdata: T) => {
|
|
@@ -44,7 +46,7 @@ export class SimpleAppService<T extends { _id?: string }> {
|
|
|
44
46
|
throw new InternalServerErrorException(err.message);
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
|
-
|
|
49
|
+
async getAutoComplete(keyword: string) {
|
|
48
50
|
try {
|
|
49
51
|
const filter1 = {};
|
|
50
52
|
const filter2 = {};
|
|
@@ -69,9 +71,9 @@ export class SimpleAppService<T extends { _id?: string }> {
|
|
|
69
71
|
}
|
|
70
72
|
async findById(id: string) {
|
|
71
73
|
try {
|
|
72
|
-
console.log('findById', id);
|
|
74
|
+
//console.log('findById', id);
|
|
73
75
|
this.data = await this.doc.findById(id);
|
|
74
|
-
console.log('findById done', this.data);
|
|
76
|
+
//console.log('findById done', this.data);
|
|
75
77
|
} catch (err) {
|
|
76
78
|
//error
|
|
77
79
|
throw new InternalServerErrorException(err.message);
|
|
@@ -81,7 +83,7 @@ export class SimpleAppService<T extends { _id?: string }> {
|
|
|
81
83
|
//data not found
|
|
82
84
|
throw new NotFoundException('Document Not found:');
|
|
83
85
|
}
|
|
84
|
-
console.log('this.data', this.data);
|
|
86
|
+
//console.log('this.data', this.data);
|
|
85
87
|
return this.data;
|
|
86
88
|
// return this;
|
|
87
89
|
}
|
|
@@ -104,8 +106,14 @@ export class SimpleAppService<T extends { _id?: string }> {
|
|
|
104
106
|
this.findIdThenUpdate(id, this.data);
|
|
105
107
|
}
|
|
106
108
|
async delete() {
|
|
109
|
+
|
|
107
110
|
const id: string = this.getRecordId();
|
|
108
|
-
this.
|
|
111
|
+
const dependency = await this.getRelatedRecords(id);
|
|
112
|
+
if (!dependency) {
|
|
113
|
+
return await this.findIdThenDelete(id);
|
|
114
|
+
} else {
|
|
115
|
+
return dependency;
|
|
116
|
+
}
|
|
109
117
|
}
|
|
110
118
|
hook(type: string, data: T) {
|
|
111
119
|
return true;
|
|
@@ -113,9 +121,12 @@ export class SimpleAppService<T extends { _id?: string }> {
|
|
|
113
121
|
validateData(data: T) {
|
|
114
122
|
const ajv = new Ajv({ allErrors: true });
|
|
115
123
|
addFormats(ajv);
|
|
116
|
-
ajv.addFormat('field-autocomplete-code', /.*$/)
|
|
117
|
-
ajv.addFormat('field-autocomplete-name', /.*$/)
|
|
118
|
-
ajv.
|
|
124
|
+
ajv.addFormat('field-autocomplete-code', /.*$/);
|
|
125
|
+
ajv.addFormat('field-autocomplete-name', /.*$/);
|
|
126
|
+
ajv.addKeyword({
|
|
127
|
+
keyword: 'x-foreignkey',
|
|
128
|
+
type: 'string',
|
|
129
|
+
});
|
|
119
130
|
if (!this.hook('pre-validation', data)) {
|
|
120
131
|
const erromsg: string[] = [];
|
|
121
132
|
for (let i = 0; i < this.errorlist.length; i++) {
|
|
@@ -126,7 +137,7 @@ export class SimpleAppService<T extends { _id?: string }> {
|
|
|
126
137
|
const validate = ajv.compile(this.jsonschema);
|
|
127
138
|
const valid = validate(data);
|
|
128
139
|
if (!valid) {
|
|
129
|
-
console.log(validate.errors);
|
|
140
|
+
//console.log(validate.errors);
|
|
130
141
|
const erromsg: string[] = [];
|
|
131
142
|
for (let i = 0; i < validate.errors.length; i++) {
|
|
132
143
|
erromsg.push(validate.errors[i].message);
|
|
@@ -139,8 +150,14 @@ export class SimpleAppService<T extends { _id?: string }> {
|
|
|
139
150
|
async findIdThenDelete(id: string) {
|
|
140
151
|
// const data = await this.findById(id);
|
|
141
152
|
try {
|
|
142
|
-
|
|
143
|
-
|
|
153
|
+
//console.log('deletedeletedeletedelete');
|
|
154
|
+
const dependency = await this.getRelatedRecords(id);
|
|
155
|
+
if (!dependency) {
|
|
156
|
+
const deleteresult = await this.doc.findByIdAndDelete(id);
|
|
157
|
+
return deleteresult;
|
|
158
|
+
} else {
|
|
159
|
+
return Promise.reject(dependency);
|
|
160
|
+
}
|
|
144
161
|
} catch (err) {
|
|
145
162
|
throw new InternalServerErrorException(err.message);
|
|
146
163
|
}
|
|
@@ -150,13 +167,44 @@ export class SimpleAppService<T extends { _id?: string }> {
|
|
|
150
167
|
// const existingdata = await this.findById(id);
|
|
151
168
|
|
|
152
169
|
try {
|
|
153
|
-
console.log('findIdThenUpdate', id);
|
|
170
|
+
//console.log('findIdThenUpdate', id);
|
|
154
171
|
this.validateData(data);
|
|
155
172
|
// const result = await existingdata.doc.updateOne(data);
|
|
156
173
|
const result = await this.doc.findByIdAndUpdate(id, data);
|
|
174
|
+
|
|
157
175
|
return result;
|
|
158
176
|
} catch (err) {
|
|
159
177
|
throw new InternalServerErrorException(err.message);
|
|
160
178
|
}
|
|
161
179
|
}
|
|
180
|
+
|
|
181
|
+
//find what foreign key constraint
|
|
182
|
+
async getRelatedRecords(id: string) {
|
|
183
|
+
const foreignkeysettings = foreignkeys[this.documentName];
|
|
184
|
+
//console.log('foreignkeysettings', foreignkeysettings);
|
|
185
|
+
const propkeys = Object.getOwnPropertyNames(foreignkeysettings);
|
|
186
|
+
|
|
187
|
+
if (propkeys.length > 0) {
|
|
188
|
+
//console.log('Have properties');
|
|
189
|
+
for (let i = 0; i < propkeys.length; i++) {
|
|
190
|
+
const collectionname = propkeys[i];
|
|
191
|
+
//console.log('run ', i, collectionname);
|
|
192
|
+
const fobjs = foreignkeysettings[propkeys[i]];
|
|
193
|
+
const collection = this.doc.db.collection(collectionname);
|
|
194
|
+
//single schema may have multiple foreign key link here, loop all
|
|
195
|
+
for (let j = 0; j < fobjs.length; j++) {
|
|
196
|
+
const fkey = fobjs[j];
|
|
197
|
+
const filter = {};
|
|
198
|
+
filter[fkey] = id;
|
|
199
|
+
//console.log('getRelatedRecords get filter', collectionname, filter);
|
|
200
|
+
const result = await collection.findOne(filter);
|
|
201
|
+
//console.log('getRelatedRecords', result);
|
|
202
|
+
if (result) {
|
|
203
|
+
return Promise.reject(result);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return Promise.resolve(null);
|
|
209
|
+
}
|
|
162
210
|
}
|
|
@@ -30,6 +30,6 @@ const schemasetting = {
|
|
|
30
30
|
<%}) %>
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
-
export const <%= it.doctype %>MongoSchema = new Schema(schemasetting)
|
|
33
|
+
export const <%= it.doctype %>MongoSchema = new Schema(schemasetting,{collection: '<%= it.name %>'})
|
|
34
34
|
.post('validate', (doc: <%= it.typename %>) => beforeSave(doc))
|
|
35
35
|
.pre('save', () => {});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<% let skipcolumns = ['_id','createdby','created','updatedby','updated','organization_id','branch_id','tenant_id','doctype'] %>
|
|
3
|
+
<div>
|
|
4
|
+
<CrudSimple :document="doc" title="<%= it.typename %>" #default="o"
|
|
5
|
+
:listColumns="columns">
|
|
6
|
+
|
|
7
|
+
<%Object.keys(it.jsonschema.properties).forEach(function(key) { %>
|
|
8
|
+
<% let obj=it.jsonschema.properties[key] %>
|
|
9
|
+
<% if(skipcolumns.indexOf(key)>=0){ %>
|
|
10
|
+
<% } else if(obj.type=='boolean'){ %>
|
|
11
|
+
<SimpleAppCheckbox :setting="o.getField('#/properties/<%= key %>')" v-model="data.<%= key %>"/>
|
|
12
|
+
<% } else if(obj.type=='number' || obj.type=='integer'){ %>
|
|
13
|
+
<SimpleAppNumber :setting="o.getField('#/properties/<%= key %>')" v-model="data.<%= key %>"/>
|
|
14
|
+
<% } else if(obj.type=='array' && obj.items && obj.items.type =='string' ){ %>
|
|
15
|
+
<SimpleAppChip :setting="o.getField('#/properties/<%= key %>')" v-model="data.<%= key %>"/>
|
|
16
|
+
<% } else if(obj.type=='object' && typeof obj['x-foreignkey']!='undefined'){ %>
|
|
17
|
+
<SimpleAppAutocomplete :setting="o.getField('#/properties/<%= key %>')"
|
|
18
|
+
v-model="data.<%= key %>" optionLabel="label" :remote-src="getAutocomplete('<%=obj['x-foreignkey']%>')"/>
|
|
19
|
+
<% } else if(obj.type=='string'){ %>
|
|
20
|
+
<% if(obj.format=='date'){ %>
|
|
21
|
+
<SimpleAppText type="<%=formattype%>" :setting="o.getField('#/properties/<%= key %>')" v-model="data.<%= key %>"/>
|
|
22
|
+
<% } else if(obj.format=='email'){ %>
|
|
23
|
+
<SimpleAppText type="<%=formattype%>" :setting="o.getField('#/properties/<%= key %>')" v-model="data.<%= key %>"/>
|
|
24
|
+
<% } else if(obj.enum){ %>
|
|
25
|
+
<SimpleAppRadio :setting="o.getField('#/properties/<%= key %>')" v-model="data.<%= key %>"/>
|
|
26
|
+
<% } else {%>
|
|
27
|
+
<SimpleAppText :setting="o.getField('#/properties/<%= key %>')" v-model="data.<%= key %>"/>
|
|
28
|
+
<% }%>
|
|
29
|
+
<% } else { %>
|
|
30
|
+
<SimpleAppText :setting="o.getField('#/properties/<%= key %>')" v-model="data.<%= key %>"/>
|
|
31
|
+
<% }%>
|
|
32
|
+
<%})%>
|
|
33
|
+
|
|
34
|
+
</CrudSimple>
|
|
35
|
+
</div>
|
|
36
|
+
</template>
|
|
37
|
+
<script setup lang="ts">
|
|
38
|
+
import { <%= it.typename %>Doc } from "../../simpleapp/simpleappdocs/<%= it.typename %>Doc";
|
|
39
|
+
const { $event, $listen } = useNuxtApp();
|
|
40
|
+
const doc = new <%= it.typename %>Doc($event, $listen);
|
|
41
|
+
const data = doc.getReactiveData();
|
|
42
|
+
const columns = [
|
|
43
|
+
<%Object.keys(it.jsonschema.properties).forEach(function(key) { %>
|
|
44
|
+
<%let obj=it.jsonschema.properties[key] %>
|
|
45
|
+
<%if(skipcolumns.indexOf(key)>=0){%>/* skip system columns <%=key%>*/
|
|
46
|
+
<%} else if(['string','number','integer'].indexOf(obj.type)>=0){%>'<%=key%>',<%}%>
|
|
47
|
+
<%})%>
|
|
48
|
+
]
|
|
49
|
+
</script>
|
|
50
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<template></template>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* and regenerate this file.
|
|
5
5
|
*/
|
|
6
6
|
import { SimpleAppClient } from "@simitgroup/simpleapp-vue-component/src/SimpleAppClient";
|
|
7
|
+
|
|
7
8
|
// import { JSONSchema7 } from 'json-schema';
|
|
8
9
|
import { Configuration,
|
|
9
10
|
<%= it.doctype.toUpperCase()%>Api,
|
|
@@ -20,10 +21,12 @@ export class <%= it.typename%>Doc extends SimpleAppClient<<%= it.typename%>,<%=
|
|
|
20
21
|
public readonly schema= <%~ JSON.stringify(it.jsonschema) %>;
|
|
21
22
|
protected documentIdentityCode='<%~ it.autocompletecode %>'
|
|
22
23
|
protected documentIdentityName='<%~ it.autocompletename %>'
|
|
23
|
-
constructor() {
|
|
24
|
-
const apiconfig = new Configuration({ basePath: useRuntimeConfig().public.
|
|
24
|
+
constructor(event:any,listen?:any) {
|
|
25
|
+
const apiconfig = new Configuration({ basePath: useRuntimeConfig().public.APP_URL+'/api' });
|
|
25
26
|
const apiobj = new <%= it.doctype.toUpperCase()%>Api(apiconfig)
|
|
26
|
-
super(apiobj)
|
|
27
|
+
super(apiobj,'<%= it.doctype %>','<%=it.name %>')
|
|
28
|
+
this.event=event
|
|
29
|
+
this.listen=listen
|
|
27
30
|
|
|
28
31
|
this.setNew();
|
|
29
32
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="simpleapp-crudsimple">
|
|
3
|
+
<button class="bg-primary" type="reset" @click="newData">New</button>
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
<SimpleAppDatatable
|
|
7
|
+
@row-dblclick="editRecord"
|
|
8
|
+
v-model="recordlist"
|
|
9
|
+
:setting="{}"
|
|
10
|
+
:columns="listColumns"
|
|
11
|
+
></SimpleAppDatatable>
|
|
12
|
+
|
|
13
|
+
<DebugDocumentData v-model="data"/>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<Dialog v-model:visible="visible" modal header="Header" class="crudsimple-dialog" :autoZIndex="false" :style="{zIndex:100, width: '80vw' }">
|
|
17
|
+
<SimpleAppForm :document="obj" :title="title" #default="o">
|
|
18
|
+
<div class="simpleapp-tool-bar" >
|
|
19
|
+
<button class="bg-default" @click="newData" type="reset">New</button>
|
|
20
|
+
<button class="bg-primary" @click="saveData" type="submit">Save</button>
|
|
21
|
+
<button class="bg-danger" @click="deleteData($event)">Delete</button>
|
|
22
|
+
<ConfirmPopup></ConfirmPopup>
|
|
23
|
+
</div>
|
|
24
|
+
<slot :data="o.data" :getField="o.getField" name="default"></slot>
|
|
25
|
+
</SimpleAppForm>
|
|
26
|
+
</Dialog>
|
|
27
|
+
</template>
|
|
28
|
+
<script setup lang="ts">
|
|
29
|
+
|
|
30
|
+
import { SimpleAppClient } from '@simitgroup//simpleapp-vue-component/src/SimpleAppClient';
|
|
31
|
+
import SimpleAppForm from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppForm.vue';
|
|
32
|
+
import SimpleAppDatatable from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppDatatable.vue';
|
|
33
|
+
import Dialog from 'primevue/dialog';
|
|
34
|
+
import ConfirmPopup from 'primevue/confirmpopup';
|
|
35
|
+
import { useConfirm } from "primevue/useconfirm";
|
|
36
|
+
|
|
37
|
+
const confirm = useConfirm();
|
|
38
|
+
const props = defineProps<{
|
|
39
|
+
document:SimpleAppClient<any,any>
|
|
40
|
+
listColumns:string[]
|
|
41
|
+
title:string
|
|
42
|
+
}>()
|
|
43
|
+
const visible = ref(false)
|
|
44
|
+
const obj = props.document
|
|
45
|
+
const data = obj.getReactiveData()
|
|
46
|
+
const recordlist = ref();
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
const refresh = () => {
|
|
50
|
+
obj.list().then((res:any) => {
|
|
51
|
+
recordlist.value = res;
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
const newData = () => {
|
|
55
|
+
obj.setNew()
|
|
56
|
+
visible.value=true;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const editRecord = (event: any) => {
|
|
60
|
+
obj.getById(event.data._id);
|
|
61
|
+
visible.value=true
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const saveData = () => {
|
|
65
|
+
if (data.value._id == "") {
|
|
66
|
+
obj.create().then(()=>visible.value=false).finally(() => refresh());
|
|
67
|
+
} else {
|
|
68
|
+
obj.update().then(()=>visible.value=false).finally(() => refresh());
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const deleteData = (event:Event) => {
|
|
72
|
+
console.log("deleteData")
|
|
73
|
+
confirm.require({
|
|
74
|
+
target: event.currentTarget as HTMLElement,
|
|
75
|
+
message:'Delete?',
|
|
76
|
+
icon: 'pi pi-exclamation-triangle',
|
|
77
|
+
acceptClass: 'p-button-danger',
|
|
78
|
+
accept: ()=>{
|
|
79
|
+
obj.delete(data.value._id ?? "").then(()=>visible.value=false).finally(() => {
|
|
80
|
+
refresh();
|
|
81
|
+
});
|
|
82
|
+
},
|
|
83
|
+
reject: () => {
|
|
84
|
+
console.log("Cancel delete")
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
};
|
|
89
|
+
refresh();
|
|
90
|
+
</script>
|
|
91
|
+
<style scoped>
|
|
92
|
+
.crudsimple-dialog{
|
|
93
|
+
z-index: 100;
|
|
94
|
+
}
|
|
95
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="floatright">
|
|
3
|
+
<h3>data in json</h3>
|
|
4
|
+
<pre>
|
|
5
|
+
{{ modelValue }}
|
|
6
|
+
</pre>
|
|
7
|
+
</div>
|
|
8
|
+
</template>
|
|
9
|
+
<script setup lang="ts">
|
|
10
|
+
const modelValue = defineModel()
|
|
11
|
+
</script>
|
|
12
|
+
<style scoped>
|
|
13
|
+
.floatright{
|
|
14
|
+
position: fixed;
|
|
15
|
+
right: 0;
|
|
16
|
+
background-color: antiquewhite;
|
|
17
|
+
font-size: large;
|
|
18
|
+
top: 0;
|
|
19
|
+
}
|
|
20
|
+
</style>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Toast group="default"/>
|
|
3
|
+
<Toast group="list">
|
|
4
|
+
<template #message="p">
|
|
5
|
+
<ol>
|
|
6
|
+
<li v-for="(item,index) in p.message.detail" :key="index">{{item.instancePath}} {{ item.message }}</li>
|
|
7
|
+
</ol>
|
|
8
|
+
</template>
|
|
9
|
+
</Toast>
|
|
10
|
+
</template>
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
|
|
13
|
+
import { useToast, } from 'primevue/usetoast';
|
|
14
|
+
import type { ToastMessageOptions } from 'primevue/toast';
|
|
15
|
+
import Toast from 'primevue/toast';
|
|
16
|
+
import { stringify } from 'ajv';
|
|
17
|
+
const toast = useToast();
|
|
18
|
+
const { $event,$listen } = useNuxtApp()
|
|
19
|
+
let resmsg:ToastMessageOptions = {} as ToastMessageOptions
|
|
20
|
+
|
|
21
|
+
$listen('*',(type:string,data:any)=>{
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
let duration = 3000
|
|
25
|
+
let severity:typeof resmsg['severity']
|
|
26
|
+
let isshow=true
|
|
27
|
+
let toastgroup='default'
|
|
28
|
+
if(type.indexOf('error')>=0){
|
|
29
|
+
duration = 0
|
|
30
|
+
severity='error'
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
else if(type.indexOf('warn')>=0){
|
|
34
|
+
duration = 10000
|
|
35
|
+
severity='warn'
|
|
36
|
+
}
|
|
37
|
+
else if(type.indexOf('info')>=0){
|
|
38
|
+
duration = 3000
|
|
39
|
+
severity='info'
|
|
40
|
+
isshow=false
|
|
41
|
+
}
|
|
42
|
+
else if(type.indexOf('success')>=0){
|
|
43
|
+
duration = 3000
|
|
44
|
+
severity='success'
|
|
45
|
+
}
|
|
46
|
+
if(Array.isArray(data)){
|
|
47
|
+
toastgroup='list'
|
|
48
|
+
}
|
|
49
|
+
// let msg:string=prepareMsg(data,severity?.toString()??'')
|
|
50
|
+
|
|
51
|
+
if(isshow){
|
|
52
|
+
toast.removeAllGroups()
|
|
53
|
+
resmsg = { severity: severity, summary: type, detail :data, life: duration, group:toastgroup}
|
|
54
|
+
toast.add(resmsg)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
})
|
|
59
|
+
const prepareMsg=(data:any,msgtype:string):string=>{
|
|
60
|
+
let res : string =''
|
|
61
|
+
|
|
62
|
+
if(typeof data == 'string'){
|
|
63
|
+
res = data
|
|
64
|
+
}else if(Array.isArray(data)){
|
|
65
|
+
res+='<ul>'
|
|
66
|
+
for(let i=0;i<data.length;i++){
|
|
67
|
+
const d=data[i]
|
|
68
|
+
res+= '<li>'+d['instancePath']+':'+(d['message']?? JSON.stringify(d))+'</li>'
|
|
69
|
+
}
|
|
70
|
+
res+='</ul>'
|
|
71
|
+
}else if(typeof data =='object'){
|
|
72
|
+
res=JSON.stringify(data)
|
|
73
|
+
}
|
|
74
|
+
return res
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
</script>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<header>
|
|
3
|
+
<!-- <MegaMenu :model="getMenus()" orientation="horizontal" /> -->
|
|
4
|
+
<Menubar :model="getMenus()">
|
|
5
|
+
<template #start>
|
|
6
|
+
<h1>[Logo Container]</h1>
|
|
7
|
+
</template>
|
|
8
|
+
<template #end>
|
|
9
|
+
<InputText placeholder="Search" type="text" />
|
|
10
|
+
</template>
|
|
11
|
+
</Menubar>
|
|
12
|
+
</header>
|
|
13
|
+
</template>
|
|
14
|
+
<script setup lang="ts">
|
|
15
|
+
// import MegaMenu from 'primevue/megamenu';
|
|
16
|
+
import Menubar from 'primevue/menubar';
|
|
17
|
+
|
|
18
|
+
</script>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
import * as o from "../simpleapp/openapi";
|
|
3
|
+
|
|
4
|
+
const getAutoComplete = (apiname: string): any => {
|
|
5
|
+
const config: o.Configuration = {
|
|
6
|
+
basePath: useRuntimeConfig().public.APP_URL + "/api",
|
|
7
|
+
isJsonMime: () => true,
|
|
8
|
+
};
|
|
9
|
+
const docsOpenapi: any = {
|
|
10
|
+
<% for(let i=0;i<it.length; i++){ %>
|
|
11
|
+
<% let obj = it[i]%>
|
|
12
|
+
'<%=obj.docname.toLowerCase()%>' : new o.<%=obj.doctype.toUpperCase()%>Api(config),
|
|
13
|
+
<%}%>
|
|
14
|
+
};
|
|
15
|
+
if (!docsOpenapi[apiname]) {
|
|
16
|
+
console.error(
|
|
17
|
+
`api for '${apiname}' does not exists, most probably define wrong x-foreignkey`,
|
|
18
|
+
);
|
|
19
|
+
return undefined;
|
|
20
|
+
} else {
|
|
21
|
+
return docsOpenapi[apiname];
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
export default getAutoComplete;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const getMenus =()=>[
|
|
2
|
+
{label: 'Cruds',icon: 'pi pi-fw pi-pencil',items:[
|
|
3
|
+
<% for(let i=0;i<it.length; i++){ %>
|
|
4
|
+
<% let obj = it[i]%>
|
|
5
|
+
{label: '<%=obj.docname.toLowerCase()%>', to:'/<%=obj.docname.toLowerCase()%>'},
|
|
6
|
+
<%}%>
|
|
7
|
+
]},
|
|
8
|
+
{label: 'Profile',icon: 'pi pi-fw pi-user'},
|
|
9
|
+
]
|
|
@@ -3,6 +3,7 @@ export default defineNuxtConfig({
|
|
|
3
3
|
runtimeConfig:{
|
|
4
4
|
public:{
|
|
5
5
|
SIMPLEAPP_BACKEND_URL: process.env.SIMPLEAPP_BACKEND_URL,
|
|
6
|
+
APP_URL: process.env.APP_URL,
|
|
6
7
|
}
|
|
7
8
|
},
|
|
8
9
|
vite: {
|
|
@@ -13,14 +14,16 @@ export default defineNuxtConfig({
|
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
16
|
},
|
|
17
|
+
tailwindcss: {
|
|
18
|
+
// Options
|
|
19
|
+
},
|
|
16
20
|
modules: [
|
|
17
|
-
|
|
21
|
+
'@nuxtjs/tailwindcss',
|
|
18
22
|
// '@nuxtjs/color-mode'
|
|
19
23
|
|
|
20
24
|
],
|
|
21
|
-
ssr:
|
|
25
|
+
ssr: true,
|
|
22
26
|
css: [
|
|
23
|
-
// "assets/css/index.css",
|
|
24
27
|
"primevue/resources/themes/lara-light-blue/theme.css",
|
|
25
28
|
'primeicons/primeicons.css'
|
|
26
29
|
],
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { defineNuxtPlugin } from "#app";
|
|
2
2
|
import PrimeVue from "primevue/config";
|
|
3
|
-
import ToastService from 'primevue/toastservice';
|
|
4
|
-
|
|
5
3
|
import SimpleAppAutocomplete from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppAutocomplete.vue'
|
|
6
4
|
import SimpleAppAutocompletemulti from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppAutocompletemulti.vue'
|
|
7
5
|
import SimpleAppCalendar from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppCalendar.vue'
|
|
@@ -25,8 +23,11 @@ import SimpleAppTextarea from '@simitgroup/simpleapp-vue-component/src/component
|
|
|
25
23
|
import SimpleAppValue from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppValue.vue'
|
|
26
24
|
import SimpleFieldContainer from '@simitgroup/simpleapp-vue-component/src/components/SimpleFieldContainer.vue'
|
|
27
25
|
import SimpleAppDatatable from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppDatatable.vue'
|
|
26
|
+
import mitt from 'mitt'
|
|
27
|
+
import ToastService from 'primevue/toastservice';
|
|
28
|
+
import ConfirmationService from 'primevue/confirmationservice';
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
const emitter = mitt()
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
|
|
@@ -55,7 +56,13 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|
|
55
56
|
.component("SimpleAppTextarea",SimpleAppTextarea)
|
|
56
57
|
.component("SimpleAppValue",SimpleAppValue)
|
|
57
58
|
.component("SimpleFieldContainer",SimpleFieldContainer)
|
|
58
|
-
.use(ToastService)
|
|
59
|
+
.use(ToastService).use(ConfirmationService)
|
|
59
60
|
;
|
|
61
|
+
return {
|
|
62
|
+
provide: {
|
|
63
|
+
event: emitter.emit, // Will emit an event
|
|
64
|
+
listen: emitter.on // Will register a listener for an event
|
|
65
|
+
}
|
|
66
|
+
}
|
|
60
67
|
//other components that you need
|
|
61
68
|
});
|