@simitgroup/simpleapp-generator 1.0.8 → 1.0.14

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 (43) hide show
  1. package/README.md +128 -1
  2. package/dist/createproject.js +39 -18
  3. package/dist/createproject.js.map +1 -1
  4. package/dist/generate.js +49 -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 +60 -9
  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 +62 -28
  15. package/src/index.ts +31 -20
  16. package/src/processors/jsonschemabuilder.ts +70 -15
  17. package/src/storage.ts +3 -0
  18. package/src/type.ts +24 -2
  19. package/templates/SimpleAppClient.eta +10 -5
  20. package/templates/SimpleAppController.eta +4 -1
  21. package/templates/SimpleAppService.eta +87 -11
  22. package/templates/basic/controller.eta +17 -1
  23. package/templates/basic/model.eta +1 -1
  24. package/templates/basic/pageindex.vue.eta +50 -0
  25. package/templates/basic/pageindexwithid.vue.eta +1 -0
  26. package/templates/basic/service.eta +2 -0
  27. package/templates/basic/{apiclient.eta → simpleappclient.eta} +15 -7
  28. package/templates/nuxt/app.vue.eta +8 -0
  29. package/templates/nuxt/components.crudsimple.vue.eta +95 -0
  30. package/templates/nuxt/components.debugdocdata.vue.eta +20 -0
  31. package/templates/nuxt/components.eventmonitor.vue.eta +79 -0
  32. package/templates/nuxt/components.menus.vue.eta +8 -0
  33. package/templates/nuxt/composables.getautocomplete.ts.eta +24 -0
  34. package/templates/nuxt/composables.getmenus.ts.eta +8 -0
  35. package/templates/nuxt/env.eta +3 -0
  36. package/templates/nuxt/layouts.default.vue.eta +10 -0
  37. package/templates/{nuxt.config.eta → nuxt/nuxt.config.ts.eta} +6 -3
  38. package/templates/nuxt/pages.index.vue.eta +3 -0
  39. package/templates/{nuxt.plugins.eta → nuxt/plugins.simpleapp.ts.eta} +12 -2
  40. package/templates/nuxt/server.api.ts.eta +131 -0
  41. package/templates/nuxt/tailwind.config.ts.eta +9 -0
  42. package/templates/nuxt/tailwind.css.eta +28 -0
  43. package/templates/nuxt.env.eta +0 -2
@@ -3,24 +3,46 @@ import { JSONSchema7, JSONSchema7Definition,JSONSchema7Array,JSONSchema7TypeName
3
3
  import * as js7 from 'json-schema';
4
4
  import { capitalizeFirstLetter } from '../libs';
5
5
  import {JsonSchemaProperties} from "../type"
6
+ import { Logger, ILogObj } from "tslog";
7
+ import $RefParser from "@apidevtools/json-schema-ref-parser";
8
+ import {foreignkeys} from '../storage'
6
9
  // import { ConflictException } from '@nestjs/common';
7
10
  import {
8
11
  FieldModel,
9
12
  Fieldtypes,
10
13
  ChildModels,
11
14
  SchemaModel,
15
+ TypeForeignKey,
16
+ TypeForeignKeyCatalogue
12
17
  } from '../type';
13
18
  import { json } from 'stream/consumers';
14
-
19
+ const log: Logger<ILogObj> = new Logger();
20
+ const FIELD_AUTOCOMPLETE_CODE='field-autocomplete-code'
21
+ const FIELD_AUTOCOMPLETE_NAME='field-autocomplete-name'
22
+ const FOREIGNKEY_PROPERTY='x-foreignkey'
15
23
  let allmodels: ChildModels = {};
16
- export const readJsonSchemaBuilder = (
24
+ let fullschema={}
25
+ let fieldAutoCompleteCode=''
26
+ let fieldAutoCompleteName=''
27
+
28
+ export const readJsonSchemaBuilder = async (
17
29
  doctype: string,
18
30
  docname: string,
19
- jsondata:JSONSchema7,
20
- ): ChildModels => {
31
+ orijsondata:JSONSchema7,
32
+ allforeignkeys:TypeForeignKeyCatalogue
33
+ ) => {
34
+
35
+ fieldAutoCompleteCode=''
36
+ fieldAutoCompleteName=''
21
37
  allmodels = {};
22
- const validateddata: JSONSchema7 = { ...jsondata };
38
+ const validateddata: JSONSchema7 = { ...orijsondata };
23
39
  let schema: SchemaModel | SchemaModel[];
40
+ const tmpjsondata = await $RefParser.dereference(orijsondata).then((schema)=>{
41
+ // console.log("schema",doctype, schema['properties']['category']? schema['properties']['category']:'')
42
+ return schema
43
+ })
44
+ const jsondata:JSONSchema7 = {...tmpjsondata} as JSONSchema7
45
+
24
46
 
25
47
  if (jsondata && jsondata.type == 'object') {
26
48
  //no _id then need add
@@ -30,14 +52,22 @@ export const readJsonSchemaBuilder = (
30
52
  } else if (jsondata.type == 'array') {
31
53
  throw(`unsupport array type for ${docname}.${doctype}`)
32
54
  }
33
-
34
- return allmodels;
55
+ if(fieldAutoCompleteCode=='') {
56
+ log.error(`you shall define 1 field with format:'${FIELD_AUTOCOMPLETE_CODE}'`)
57
+ throw "missing field format"
58
+ }
59
+ if(fieldAutoCompleteName=='') {
60
+ log.error(`you shall define 1 field with format: '${FIELD_AUTOCOMPLETE_NAME}'}`)
61
+ throw "missing field format"
62
+ }
63
+
64
+ return Promise.resolve(allmodels);
35
65
  };
36
66
 
37
67
 
38
- const processObject = (doctype: string,
68
+ const processObject = (doctype: string,
39
69
  docname: string,
40
- jsondata:JSONSchema7,) : SchemaModel =>{
70
+ jsondata:JSONSchema7,) =>{
41
71
  if(!jsondata['properties']){
42
72
  throw ("Invalid json schema {doctype}.{docname}, no 'properties' defined")
43
73
  }
@@ -79,14 +109,39 @@ const genSchema = (
79
109
  const objectitem:JSONSchema7= {} as JSONSchema7
80
110
  Object.assign(objectitem,obj.items);
81
111
 
82
- // Object.assign(objtmp,jsondata?[key]:{});
83
112
  const isrequired = requiredlist && requiredlist.includes(key);
84
- // console.log('----', key, isrequired, obj);
85
113
  const newName: string = docname + capitalizeFirstLetter(key);
86
- // console.log(key);
87
- //need create sub model
88
- // console.log("----",key,obj.type,objectitem.type)
114
+ if(obj.format && obj.format==FIELD_AUTOCOMPLETE_CODE){
115
+ fieldAutoCompleteCode=key
116
+ }
117
+ if(obj.format && obj.format==FIELD_AUTOCOMPLETE_NAME){
118
+ fieldAutoCompleteName=key
119
+ }
120
+ // if (obj.type == 'object' && obj.items ){
121
+ // console.log("Refer to another object",docname,': ',key,obj,obj.items)
122
+
123
+ // obj,obj.items
124
+ //foreignkeys
125
+ //FOREIGNKEY_PROPERTY
126
+ // newmodel[key] = 'Object';
127
+ // }
128
+ // else
89
129
  if (obj.type == 'object') {
130
+
131
+ if(obj[FOREIGNKEY_PROPERTY]){
132
+ console.warn("FOREIGNKEY_PROPERTY exists",FOREIGNKEY_PROPERTY,obj[FOREIGNKEY_PROPERTY])
133
+ const masterdatacollection = obj[FOREIGNKEY_PROPERTY]
134
+ const clientdatacollection = docname.toLowerCase()
135
+ const foreignkeyidentity= key+'._id'
136
+ if(!foreignkeys[masterdatacollection]){
137
+ let tmp:TypeForeignKey = {} as TypeForeignKey
138
+ tmp[clientdatacollection]=[foreignkeyidentity]
139
+ foreignkeys[masterdatacollection] = tmp
140
+ }else{
141
+ foreignkeys[masterdatacollection][clientdatacollection].push(foreignkeyidentity)
142
+ }
143
+
144
+ }
90
145
  genSchema(newName, obj.type, obj.properties, obj.required);
91
146
  newmodel[key] = newName;
92
147
  } else if (obj.type == 'array' && obj.items && objectitem?.type == 'object') {
@@ -104,7 +159,7 @@ const genSchema = (
104
159
  // console.log(key,'--------newmodel',obj, newmodel[key]);
105
160
  }
106
161
  }
107
- allmodels[docname] = { type: schematype, model: newmodel };
162
+ allmodels[docname] = { type: schematype, model: newmodel,codeField: fieldAutoCompleteCode ,nameField: fieldAutoCompleteName };
108
163
  return newmodel;
109
164
  };
110
165
 
package/src/storage.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { TypeForeignKeyCatalogue } from './type'
2
+
3
+ export let foreignkeys:TypeForeignKeyCatalogue = {}
package/src/type.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { JSONSchema7, JSONSchema7Definition } from 'json-schema';
2
2
  export type ChildModels = {
3
- [key: string]: { type: string; model: SchemaModel };
3
+ [key: string]: { type: string; model: SchemaModel,codeField:string,nameField:string };
4
4
  };
5
5
  export enum Fieldtypes {
6
6
  'string' = 'string',
@@ -35,8 +35,30 @@ export type JsonSchemaProperties= {
35
35
  // JSONSchema7Definition ,JSONSchema7
36
36
  }
37
37
 
38
-
38
+ export type TypeForeignKeyCatalogue = {
39
+ [cataloguename:string]:TypeForeignKey
40
+ }
41
+ export type TypeForeignKey={
42
+ [collection:string]:string[]
43
+ }
39
44
  export type ModuleObject = {
40
45
  doctype:string
41
46
  docname:string
47
+ }
48
+ export type TypeGenerateDocumentVariable ={
49
+ name: string
50
+ doctype: string
51
+ models: ChildModels
52
+ autocompletecode:string
53
+ autocompletename:string
54
+ schema: SchemaModel
55
+ apiSchemaName: string
56
+ typename: string
57
+ fullApiSchemaName: string
58
+ fullTypeName:string
59
+ jsonschema: JSONSchema7
60
+ bothEndCode: string
61
+ frontEndCode: string
62
+ backEndCode: string
63
+ controllerCode:string
42
64
  }
@@ -14,6 +14,7 @@ type crudType = {
14
14
  export class SimpleAppClient<
15
15
  TData extends { _id?: string },
16
16
  TApi extends crudType,
17
+ defaultTimeout:number = 5000;
17
18
  > {
18
19
  protected docapi;
19
20
  protected data = <Ref<TData>>ref({} as TData);
@@ -36,7 +37,7 @@ export class SimpleAppClient<
36
37
  };
37
38
 
38
39
  async getById(id: string) {
39
- return await this.docapi.runFindOne(id).then((res: AxiosResponse) => {
40
+ return await this.docapi.runFindOne(id,{timeout:this.defaultTimeout}).then((res: AxiosResponse) => {
40
41
  // this.data.value = { ...res.data };
41
42
  Object.assign(this.data.value, res.data);
42
43
  return res;
@@ -48,7 +49,7 @@ export class SimpleAppClient<
48
49
  return await Promise.reject(errors);
49
50
  } else {
50
51
  return await this.docapi
51
- .runCreate(this.data.value)
52
+ .runCreate(this.data.value,{timeout:this.defaultTimeout})
52
53
  .then((res: AxiosResponse) => {
53
54
  this.data.value = { ...res.data };
54
55
  return res;
@@ -62,17 +63,17 @@ export class SimpleAppClient<
62
63
  return await Promise.reject(errors);
63
64
  } else {
64
65
  return await this.docapi
65
- .runUpdate(recordid, this.data.value)
66
+ .runUpdate(recordid, this.data.value,{timeout:this.defaultTimeout})
66
67
  .then((res: AxiosResponse) => {
67
68
  return res;
68
69
  });
69
70
  }
70
71
  }
71
72
  async delete(id: string) {
72
- return await this.docapi.runDelete(id);
73
+ return await this.docapi.runDelete(id,{timeout:this.defaultTimeout});
73
74
  }
74
75
  async list() {
75
- return await this.docapi.runList();
76
+ return await this.docapi.runList({timeout:this.defaultTimeout});
76
77
  }
77
78
  find() {}
78
79
  hook(type: string, data: TData) {
@@ -81,6 +82,10 @@ export class SimpleAppClient<
81
82
  }
82
83
  validateFailed() {
83
84
  const ajv = new Ajv({ allErrors: true });
85
+ ajv.addKeyword({
86
+ keyword:'autocompletesrc',
87
+ type:'string'
88
+ });
84
89
  addFormats(ajv);
85
90
  this.errorlist.value = {};
86
91
  this.hook('pre-validation', this.data.value);
@@ -20,6 +20,7 @@ type ServiceType = {
20
20
  findIdThenDelete: Function;
21
21
  findIdThenUpdate: Function;
22
22
  setData: Function;
23
+ getAutoComplete: Function;
23
24
  };
24
25
 
25
26
  // @ApiTags(doctype)
@@ -37,7 +38,9 @@ export class SimpleAppController<TService extends ServiceType, TApiSchema, T> {
37
38
  async _list() {
38
39
  return this.service.list();
39
40
  }
40
-
41
+ async _autocomplete(keyword: string) {
42
+ return this.service.getAutoComplete(keyword);
43
+ }
41
44
  async _findOne(id: string) {
42
45
  const result = (await this.service.findById(id)) as TApiSchema;
43
46
 
@@ -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,6 +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 documentName = 'category';
17
+ protected documentType = 'CAT';
18
+ protected LIMITPERPAGE = 20;
14
19
  protected data: T = { _id: '' } as T;
15
20
  protected doc: Model<T>;
16
21
  protected errorlist = [];
@@ -21,7 +26,7 @@ export class SimpleAppService<T extends { _id?: string }> {
21
26
  setSchema = (newschema) => (this.jsonschema = newschema);
22
27
  getSchema = () => this.doc.schema.obj;
23
28
  getData = () => {
24
- console.log('thisdata', this.data);
29
+ //console.log('thisdata', this.data);
25
30
  return this.data;
26
31
  };
27
32
  setData = (newdata: T) => {
@@ -41,11 +46,34 @@ export class SimpleAppService<T extends { _id?: string }> {
41
46
  throw new InternalServerErrorException(err.message);
42
47
  }
43
48
  }
49
+ async getAutoComplete(keyword: string) {
50
+ try {
51
+ const filter1 = {};
52
+ const filter2 = {};
53
+ filter1[this.documentIdentityCode] = { $regex: keyword };
54
+ filter2[this.documentIdentityName] = { $regex: keyword };
55
+ const filterobj = { $or: [filter1, filter2] };
56
+ const projections = {
57
+ id: `\$_id`,
58
+ label: `\$${this.documentIdentityCode}`,
59
+ name: `\$${this.documentIdentityName}`,
60
+ };
61
+ const products = await this.doc.find(filterobj, projections, {
62
+ limit: this.LIMITPERPAGE,
63
+ });
64
+ const productlist = products.map((p: T) => {
65
+ return p;
66
+ });
67
+ return productlist;
68
+ } catch (err) {
69
+ throw new InternalServerErrorException(err.message);
70
+ }
71
+ }
44
72
  async findById(id: string) {
45
73
  try {
46
- console.log('findById', id);
74
+ //console.log('findById', id);
47
75
  this.data = await this.doc.findById(id);
48
- console.log('findById done', this.data);
76
+ //console.log('findById done', this.data);
49
77
  } catch (err) {
50
78
  //error
51
79
  throw new InternalServerErrorException(err.message);
@@ -55,7 +83,7 @@ export class SimpleAppService<T extends { _id?: string }> {
55
83
  //data not found
56
84
  throw new NotFoundException('Document Not found:');
57
85
  }
58
- console.log('this.data', this.data);
86
+ //console.log('this.data', this.data);
59
87
  return this.data;
60
88
  // return this;
61
89
  }
@@ -78,8 +106,14 @@ export class SimpleAppService<T extends { _id?: string }> {
78
106
  this.findIdThenUpdate(id, this.data);
79
107
  }
80
108
  async delete() {
109
+
81
110
  const id: string = this.getRecordId();
82
- 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
+ }
83
117
  }
84
118
  hook(type: string, data: T) {
85
119
  return true;
@@ -87,7 +121,12 @@ export class SimpleAppService<T extends { _id?: string }> {
87
121
  validateData(data: T) {
88
122
  const ajv = new Ajv({ allErrors: true });
89
123
  addFormats(ajv);
90
-
124
+ ajv.addFormat('field-autocomplete-code', /.*$/);
125
+ ajv.addFormat('field-autocomplete-name', /.*$/);
126
+ ajv.addKeyword({
127
+ keyword: 'x-foreignkey',
128
+ type: 'string',
129
+ });
91
130
  if (!this.hook('pre-validation', data)) {
92
131
  const erromsg: string[] = [];
93
132
  for (let i = 0; i < this.errorlist.length; i++) {
@@ -98,7 +137,7 @@ export class SimpleAppService<T extends { _id?: string }> {
98
137
  const validate = ajv.compile(this.jsonschema);
99
138
  const valid = validate(data);
100
139
  if (!valid) {
101
- console.log(validate.errors);
140
+ //console.log(validate.errors);
102
141
  const erromsg: string[] = [];
103
142
  for (let i = 0; i < validate.errors.length; i++) {
104
143
  erromsg.push(validate.errors[i].message);
@@ -111,8 +150,14 @@ export class SimpleAppService<T extends { _id?: string }> {
111
150
  async findIdThenDelete(id: string) {
112
151
  // const data = await this.findById(id);
113
152
  try {
114
- const deleteresult = await this.doc.findByIdAndDelete(id);
115
- 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
+ }
116
161
  } catch (err) {
117
162
  throw new InternalServerErrorException(err.message);
118
163
  }
@@ -122,13 +167,44 @@ export class SimpleAppService<T extends { _id?: string }> {
122
167
  // const existingdata = await this.findById(id);
123
168
 
124
169
  try {
125
- console.log('findIdThenUpdate', id);
170
+ //console.log('findIdThenUpdate', id);
126
171
  this.validateData(data);
127
172
  // const result = await existingdata.doc.updateOne(data);
128
173
  const result = await this.doc.findByIdAndUpdate(id, data);
174
+
129
175
  return result;
130
176
  } catch (err) {
131
177
  throw new InternalServerErrorException(err.message);
132
178
  }
133
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
+ }
134
210
  }
@@ -10,6 +10,7 @@ import {
10
10
  Post,
11
11
  Delete,
12
12
  Body,
13
+ Query,
13
14
  Param,
14
15
  Type,
15
16
  } from '@nestjs/common';
@@ -42,7 +43,20 @@ export class <%= it.typename %>Controller extends SimpleAppController<
42
43
  async list() {
43
44
  return this._list();
44
45
  }
45
-
46
+ //autocomplete shall above :id
47
+ @Get('/autocomplete')
48
+ @ApiResponse({
49
+ status: 200,
50
+ description: 'Found',
51
+ type: ()=>[{id:'100',label:'label1'}],
52
+ })
53
+ @ApiResponse({ status: 500, description: 'Internal error' })
54
+ @ApiOperation({ operationId: 'autoComplete' })
55
+ async autoComplete(@Query('keyword') keyword: string) {
56
+ return this._autocomplete(keyword);
57
+ }
58
+
59
+
46
60
  @Get(':id')
47
61
  @ApiResponse({
48
62
  status: 200,
@@ -55,6 +69,8 @@ export class <%= it.typename %>Controller extends SimpleAppController<
55
69
  async findOne(@Param('id') id: string) {
56
70
  return await this._findOne(id);
57
71
  }
72
+
73
+
58
74
 
59
75
  @Post()
60
76
  @ApiResponse({
@@ -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>
@@ -13,6 +13,8 @@ import { <%Object.keys(it.models).forEach(function(key) { %> <%=key %>, <%})%> }
13
13
 
14
14
  @Injectable()
15
15
  export class <%= it.typename %>Service extends SimpleAppService<<%= it.typename %>> {
16
+ protected documentIdentityCode='<%~ it.autocompletecode %>'
17
+ protected documentIdentityName='<%~ it.autocompletename %>'
16
18
  constructor(@InjectModel('<%= it.name %>') mydoc: Model<<%= it.typename %>>,
17
19
  ) {
18
20
  super(mydoc);
@@ -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,
@@ -18,11 +19,14 @@ import { Configuration,
18
19
 
19
20
  export class <%= it.typename%>Doc extends SimpleAppClient<<%= it.typename%>,<%= it.doctype.toUpperCase()%>Api>{
20
21
  public readonly schema= <%~ JSON.stringify(it.jsonschema) %>;
21
-
22
- constructor() {
23
- const apiconfig = new Configuration({ basePath: useRuntimeConfig().public.SIMPLEAPP_BACKEND_URL });
22
+ protected documentIdentityCode='<%~ it.autocompletecode %>'
23
+ protected documentIdentityName='<%~ it.autocompletename %>'
24
+ constructor(event:any,listen?:any) {
25
+ const apiconfig = new Configuration({ basePath: useRuntimeConfig().public.APP_URL+'/api' });
24
26
  const apiobj = new <%= it.doctype.toUpperCase()%>Api(apiconfig)
25
- super(apiobj)
27
+ super(apiobj,'<%= it.doctype %>','<%=it.name %>')
28
+ this.event=event
29
+ this.listen=listen
26
30
 
27
31
  this.setNew();
28
32
  }
@@ -30,9 +34,13 @@ export class <%= it.typename%>Doc extends SimpleAppClient<<%= it.typename%>,<%=
30
34
  const newdata = {
31
35
 
32
36
  <%Object.keys(it.schema).forEach(function(key){%>
33
- <%let field=it.schema[key]%>
34
- <% if(field.type=='boolean' ){%>
35
- <%=key%> : <%=field.default%>,
37
+ <%let field=it.schema[key]%>
38
+ <% if(typeof field.default !='undefined' && field.type=='string'){%>
39
+ <%=key%> : '<%= field.default %>',
40
+ <%} else if(typeof field.default !='undefined'){%>
41
+ <%=key%> : <%= field.default %>,
42
+ <%} else if(field.type=='boolean' ){%>
43
+ <%=key%> :false ,
36
44
  <%} else if(typeof field=='string'){%>
37
45
  <%=key%> : <<%= field %>>{},
38
46
  <%} else if(field.type=='string'){%>
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <div>
3
+ <NuxtLayout>
4
+ <EventMonitor/>
5
+ <NuxtPage />
6
+ </NuxtLayout>
7
+ </div>
8
+ </template>