@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.
Files changed (40) hide show
  1. package/README.md +148 -1
  2. package/dist/createproject.js +39 -18
  3. package/dist/createproject.js.map +1 -1
  4. package/dist/generate.js +47 -20
  5. package/dist/generate.js.map +1 -1
  6. package/dist/index.js +36 -25
  7. package/dist/index.js.map +1 -1
  8. package/dist/processors/jsonschemabuilder.js +38 -8
  9. package/dist/processors/jsonschemabuilder.js.map +1 -1
  10. package/dist/storage.js +5 -0
  11. package/dist/storage.js.map +1 -0
  12. package/package.json +10 -5
  13. package/src/createproject.ts +40 -14
  14. package/src/generate.ts +60 -28
  15. package/src/index.ts +31 -20
  16. package/src/processors/jsonschemabuilder.ts +48 -14
  17. package/src/storage.ts +3 -0
  18. package/src/type.ts +23 -1
  19. package/templates/SimpleAppClient.eta +10 -5
  20. package/templates/SimpleAppService.eta +65 -17
  21. package/templates/basic/model.eta +1 -1
  22. package/templates/basic/pageindex.vue.eta +50 -0
  23. package/templates/basic/pageindexwithid.vue.eta +1 -0
  24. package/templates/basic/{apiclient.eta → simpleappclient.eta} +6 -3
  25. package/templates/nuxt/app.vue.eta +8 -0
  26. package/templates/nuxt/components.crudsimple.vue.eta +95 -0
  27. package/templates/nuxt/components.debugdocdata.vue.eta +20 -0
  28. package/templates/nuxt/components.eventmonitor.vue.eta +79 -0
  29. package/templates/nuxt/components.menus.vue.eta +18 -0
  30. package/templates/nuxt/composables.getautocomplete.ts.eta +24 -0
  31. package/templates/nuxt/composables.getmenus.ts.eta +9 -0
  32. package/templates/nuxt/env.eta +3 -0
  33. package/templates/nuxt/layouts.default.vue.eta +10 -0
  34. package/templates/{nuxt.config.eta → nuxt/nuxt.config.ts.eta} +6 -3
  35. package/templates/nuxt/pages.index.vue.eta +3 -0
  36. package/templates/{nuxt.plugins.eta → nuxt/plugins.simpleapp.ts.eta} +11 -4
  37. package/templates/nuxt/server.api.ts.eta +131 -0
  38. package/templates/nuxt/tailwind.config.ts.eta +9 -0
  39. package/templates/nuxt/tailwind.css.eta +28 -0
  40. 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 LIMITPERPAGE=20
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
- async getAutoComplete(keyword: string) {
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.findIdThenDelete(id);
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.addFormat('autocomplete', /.*$/)
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
- const deleteresult = await this.doc.findByIdAndDelete(id);
143
- return deleteresult;
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.SIMPLEAPP_BACKEND_URL });
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,8 @@
1
+ <template>
2
+ <div>
3
+ <NuxtLayout>
4
+ <EventMonitor/>
5
+ <NuxtPage />
6
+ </NuxtLayout>
7
+ </div>
8
+ </template>
@@ -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
+ ]
@@ -0,0 +1,3 @@
1
+ PORT=8800
2
+ SIMPLEAPP_BACKEND_URL=http://localhost:8000
3
+ APP_URL=http://localhost:8800
@@ -0,0 +1,10 @@
1
+
2
+ <template>
3
+ <div>
4
+ <Menus />
5
+ <slot></slot>
6
+ </div>
7
+ </template>
8
+ <script lang="ts" setup>
9
+ import Menus from '~/components/Menus.vue'
10
+ </script>
@@ -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
- // '@nuxtjs/tailwindcss',
21
+ '@nuxtjs/tailwindcss',
18
22
  // '@nuxtjs/color-mode'
19
23
 
20
24
  ],
21
- ssr: false,
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
  ],
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <div>index page</div>
3
+ </template>
@@ -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
  });