@simitgroup/simpleapp-generator 1.0.29 → 1.0.32

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 (39) hide show
  1. package/README.md +136 -16
  2. package/dist/framework.js +8 -3
  3. package/dist/framework.js.map +1 -1
  4. package/dist/generate.js +14 -3
  5. package/dist/generate.js.map +1 -1
  6. package/dist/processors/jsonschemabuilder.js +109 -16
  7. package/dist/processors/jsonschemabuilder.js.map +1 -1
  8. package/dist/type.js.map +1 -1
  9. package/package.json +1 -1
  10. package/src/framework.ts +8 -3
  11. package/src/generate.ts +18 -5
  12. package/src/processors/jsonschemabuilder.ts +129 -20
  13. package/src/type.ts +45 -1
  14. package/templates/basic/controller.eta +34 -17
  15. package/templates/basic/model.eta +4 -1
  16. package/templates/basic/pageindex.vue.eta +60 -5
  17. package/templates/basic/service.eta +29 -3
  18. package/templates/basic/simpleappclient.eta +54 -1
  19. package/templates/nest/SimpleAppService.eta +136 -39
  20. package/templates/nest/TenantMiddleware.eta +8 -13
  21. package/templates/nest/UserProvider.eta +127 -0
  22. package/templates/nest/Workflow.eta +75 -0
  23. package/templates/nest/app.controller.eta +12 -0
  24. package/templates/nest/app.module.eta +6 -2
  25. package/templates/nest/app.service.eta +8 -0
  26. package/templates/nest/nest.env.eta +7 -0
  27. package/templates/nest/nest.main.eta +2 -2
  28. package/templates/nuxt/components.crudsimple.vue.eta +2 -2
  29. package/templates/nuxt/components.debugdocdata.vue.eta +12 -6
  30. package/templates/nuxt/components.menus.vue.eta +22 -7
  31. package/templates/nuxt/composables.getautocomplete.ts.eta +3 -5
  32. package/templates/nuxt/composables.getmenus.ts.eta +12 -2
  33. package/templates/nuxt/pages.[xorg].index.vue.eta +9 -8
  34. package/templates/nuxt/pages.index.vue.eta +61 -8
  35. package/templates/nuxt/plugins.simpleapp.ts.eta +7 -0
  36. package/templates/nuxt/server.api.ts.eta +2 -1
  37. package/templates/nuxt/tailwind.css.eta +22 -1
  38. package/tsconfig.json +4 -1
  39. package/templates/nest/User.eta +0 -115
@@ -10,6 +10,8 @@ import { ConfigModule } from '@nestjs/config';
10
10
  import { ServeStaticModule } from '@nestjs/serve-static';
11
11
  import { join } from 'path';
12
12
  import {TenantMiddleware} from './class/TenantMiddleware'
13
+ import {AppController} from './app.controller'
14
+ import {AppService} from './app.service'
13
15
  <% for(let i=0;i<it.length; i++){ %>
14
16
  import {<%= it[i].docname %>Module} from './docs/<%= it[i].doctype %>/<%= it[i].doctype %>.module'
15
17
  <%}%>
@@ -32,8 +34,10 @@ import {<%= it[i].docname %>Module} from './docs/<%= it[i].doctype %>/<%= it[i].
32
34
  tokenValidation: TokenValidation.ONLINE,
33
35
  }),
34
36
  <% for(let i=0;i<it.length; i++){ %><%= it[i].docname %>Module,<%}%>],
35
- controllers: [],
36
- providers: [ {
37
+ controllers: [AppController],
38
+ providers: [
39
+ AppService,
40
+ {
37
41
  provide: APP_GUARD,
38
42
  useClass: AuthGuard,
39
43
  },
@@ -0,0 +1,8 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { Workflow } from './class/Workflow';
3
+ @Injectable()
4
+ export class AppService {
5
+ async getMyTask() {
6
+ return await Workflow.getInstance().getMyUserTask()
7
+ }
8
+ }
@@ -6,6 +6,13 @@ PROJECT_NAME=SimpleApp Demo1
6
6
  PROJECT_DESCRIPTION=Try CRUD
7
7
  PROJECT_Version=1.0.0
8
8
 
9
+ BPMN_HOST=<%=it.bpmnsetting.BPMN_HOST%>
10
+
11
+ BPMN_PORT=<%=it.bpmnsetting.BPMN_PORT%>
12
+
13
+ BPMN_API_KEY=<%=it.bpmnsetting.BPMN_API_KEY%>
14
+
15
+
9
16
  OAUTH2_BASEURL=<%=it.keycloaksetting.OAUTH2_BASEURL%>
10
17
 
11
18
  OAUTH2_REALM=<%=it.keycloaksetting.OAUTH2_REALM%>
@@ -13,10 +13,10 @@ async function bootstrap() {
13
13
  in: 'header',name: 'x-org',type: 'apiKey',description: 'base 64 url encode. example: MS0xLTE',
14
14
  },'x-org',)
15
15
  .addOAuth2({
16
- name:'oauth2',in:'header',type:'oauth2',flows:{
16
+ type:'oauth2',flows:{
17
17
  implicit:{
18
18
  authorizationUrl: `${process.env.OAUTH2_CONFIGURL}/protocol/openid-connect/auth`,
19
- scopes:[],
19
+ scopes:{},
20
20
  }}},'oauth2')
21
21
  .addSecurityRequirements('x-org')
22
22
  .addSecurityRequirements('oauth2')
@@ -31,7 +31,7 @@ const router = useRouter()
31
31
  const route = useRoute()
32
32
  const filters = ref()
33
33
  defineShortcuts({
34
- 'ctrl_i': () => newData()
34
+ 'ctrl_enter': () => newData()
35
35
  })
36
36
  const refresh = () => {
37
37
  obj.list().then((res:any) => {
@@ -91,7 +91,7 @@ refresh();
91
91
 
92
92
  <template>
93
93
  <div class="simpleapp-crudsimple">
94
- <button class="bg-primary" @click="newData" v-tooltip="'Add new(ctrl+i)'" >New</button>
94
+ <button class="bg-primary" @click="newData" v-tooltip="'Add new(ctrl+enter)'" >New</button>
95
95
  <SimpleAppDatatable
96
96
  @row-dblclick="triggerEdit"
97
97
  v-model="recordlist"
@@ -5,17 +5,23 @@
5
5
  * last change 2023-09-09
6
6
  * author: Ks Tan
7
7
  */
8
+ // import Panel from 'primevue/panel';
9
+ // import ScrollPanel from 'primevue/scrollpanel';
10
+ import Dialog from 'primevue/dialog';
8
11
 
12
+ import {ref} from 'vue'
9
13
  const modelValue = defineModel()
10
14
  const isdebug = ref(useRuntimeConfig().public.DEBUGDATA)
15
+ const visible = ref(false)
11
16
  </script>
12
17
  <template>
13
18
  <div class="floatright" v-if="isdebug=='1'">
14
- <h3>data in json</h3>
15
- <pre>
16
- {{ modelValue }}
17
- </pre>
18
- </div>
19
+ <button @click="visible=true">Debug</button>
20
+ <Dialog v-model:visible="visible" modal header="Debug data" :style="{ width: '80vw' }">
21
+ <pre>{{ modelValue }}</pre>
22
+ </Dialog>
23
+ </div>
24
+
19
25
  </template>
20
26
  <style scoped>
21
27
  .floatright{
@@ -23,6 +29,6 @@ const isdebug = ref(useRuntimeConfig().public.DEBUGDATA)
23
29
  right: 0;
24
30
  background-color: antiquewhite;
25
31
  font-size: large;
26
- top: 0;
32
+ top: 20;
27
33
  }
28
34
  </style>
@@ -7,14 +7,29 @@
7
7
  */
8
8
 
9
9
  // import MegaMenu from 'primevue/megamenu';
10
- import Menubar from 'primevue/menubar';
11
- const route = useRoute()
12
- const menus = getMenus(route.params.xorg)
10
+ // import Menubar from 'primevue/menubar';
11
+ // const route = useRoute()
12
+ // const menus = getMenus(route.params.xorg)
13
+ const logout = async () => {
14
+ const { signOut } = useAuth();
15
+ const { data } = await <any>useFetch('/api/auth/logout');
16
+ const addPath = encodeURIComponent("/login");
17
+ signOut({ redirect: false });
18
+ window.location.href = data?.value?.path + addPath;
19
+ };
13
20
  </script>
14
21
  <template>
15
- <header>
22
+ <!-- <header> -->
16
23
  <!-- <MegaMenu :model="getMenus()" orientation="horizontal" /> -->
17
- <Menubar :model="menus">
18
- </Menubar>
19
- </header>
24
+ <div class="bg-white border-b-2 border-b-gray-300 h-10 flex">
25
+
26
+ <div class="flex-1">
27
+ <NuxtLink to="/"><i class="pi pi-home m-2"></i>Home</NuxtLink>
28
+ </div>
29
+ <div class="flex-1"></div>
30
+ <button class="text-right" @click="logout()">
31
+ <i class="pi pi-sign-out "></i>logout
32
+ </button>
33
+ </div>
34
+ <!-- </header> -->
20
35
  </template>
@@ -17,11 +17,9 @@ const getAutoComplete = (apiname: string): any => {
17
17
  isJsonMime: () => true,
18
18
  };
19
19
  const docsOpenapi: any = {
20
- 'category' : new o.CATApi(config),
21
- 'leadtype' : new o.LEADTApi(config),
22
- 'level' : new o.LVLApi(config),
23
- 'product' : new o.PRDApi(config),
24
- 'studentgroup' : new o.STGApi(config),
20
+ <% for(let i=0;i<it.length; i++){ %>
21
+ '<%=it[i].docname.toLowerCase()%>': new o.<%=it[i].doctype.toUpperCase()%>Api(config),
22
+ <%}%>
25
23
  };
26
24
  if (!docsOpenapi[apiname]) {
27
25
  console.error(
@@ -6,7 +6,13 @@
6
6
  */
7
7
 
8
8
  export const getMenus =()=>{
9
-
9
+ const logout = async () => {
10
+ const { signOut } = useAuth();
11
+ const { data } = await <any>useFetch('/api/auth/logout');
12
+ const addPath = encodeURIComponent("/login");
13
+ signOut({ redirect: false });
14
+ window.location.href = data?.value?.path + addPath;
15
+ };
10
16
  const route = useRoute();
11
17
  const xorg = route.params.xorg
12
18
  let data =[];
@@ -19,9 +25,13 @@ export const getMenus =()=>{
19
25
  {label: '<%=obj.docname.toLowerCase()%>', to:`/${xorg}/<%=obj.docname.toLowerCase()%>`},
20
26
  <%}%>
21
27
  ]},
28
+ {label: 'Signout',icon: 'pi pi-fw pi-home', command: () => logout()},
22
29
  ]
23
30
  }else{
24
- data= [{label: 'Home',icon: 'pi pi-fw pi-home', url:'/'},]
31
+ data= [
32
+ {label: 'Home',icon: 'pi pi-fw pi-home', url:'/'},
33
+ {label: 'Signout',icon: 'pi pi-fw pi-home', command: () => logout()},
34
+ ]
25
35
  }
26
36
  return data
27
37
  }
@@ -5,15 +5,16 @@
5
5
  * last change 2023-09-09
6
6
  * author: Ks Tan
7
7
  */
8
- </script>
8
+ const menus = getMenus();
9
+ </script>
9
10
  <template>
10
11
  <div>
11
- <h1>index page</h1>
12
- <ul>
13
- <li><NuxtLink :external="true" to="/MS0xLTE" >MS0xLTE (1-1-1)</NuxtLink></li>
14
- <li><NuxtLink :external="true" to="/Mi0yLTI" >Mi0yLTI (2-2-2)</NuxtLink></li>
15
- </ul>
16
-
12
+
13
+
14
+ <div class="desktop-shortcut-link">
15
+ <div v-for="menu in menus[1].items" class="">
16
+ <NuxtLink :external="true" :to="menu.to">{{ menu.label }}</NuxtLink>
17
+ </div>
18
+ </div>
17
19
  </div>
18
-
19
20
  </template>
@@ -5,15 +5,68 @@
5
5
  * last change 2023-09-09
6
6
  * author: Ks Tan
7
7
  */
8
- </script>
8
+ import { ref, Ref } from "vue";
9
+ import { TenantDoc } from "../simpleapp/simpleappdocs/TenantDoc";
10
+ // import OrderList from 'primevue/orderlist';
11
+ import Panel from "primevue/panel";
12
+
13
+ const { $event, $listen } = useNuxtApp();
14
+ const route = useRoute();
15
+ const doc = new TenantDoc("", $event, $listen);
16
+ type tenantDataType = {
17
+ tenantId: number;
18
+ tenantCode: string;
19
+ tenantName: string;
20
+ xorg: string;
21
+ };
22
+ const initialtenant: tenantDataType[] = [];
23
+ const tenantlist = ref(initialtenant);
24
+
25
+ doc
26
+ .getApi()
27
+ .getMyTenant()
28
+ .then((res: any) => {
29
+ for (let i = 0; i < res.data.length; i++) {
30
+ const x = res.data[i];
31
+ const tmp: tenantDataType = {
32
+ xorg: x.xOrg,
33
+ tenantId: x.tenantId,
34
+ tenantCode: x.tenantCode,
35
+ tenantName: x.tenantName,
36
+ };
37
+ tenantlist.value.push(tmp);
38
+ }
39
+ console.log(tenantlist.value);
40
+ });
41
+ // const mytenant = doc.get
42
+ </script>
9
43
  <template>
10
44
  <div>
11
- <h1>index page</h1>
12
- <ul>
13
- <li><NuxtLink :external="true" to="/MS0xLTE" >MS0xLTE (1-1-1)</NuxtLink></li>
14
- <li><NuxtLink :external="true" to="/Mi0yLTI" >Mi0yLTI (2-2-2)</NuxtLink></li>
15
- </ul>
16
-
45
+
46
+ <Panel header="Tenant List">
47
+ <div>
48
+ <NuxtLink
49
+ v-for="item in tenantlist"
50
+ :external="true"
51
+ :to="item.xorg"
52
+ class="tenant-link"
53
+ >
54
+ <div class="flex flex-wrap p-2 align-items-center gap-3">
55
+ <div class="flex-1 flex flex-column gap-2">
56
+ <span class="font-bold">{{ item.tenantName }}</span>
57
+ <div class="flex align-items-center gap-2">
58
+ <span>{{ item.xorg }}</span>
59
+ </div>
60
+ </div>
61
+ <span class="font-bold text-900">{{ item.tenantCode }}</span>
62
+ </div>
63
+ </NuxtLink>
64
+ </div>
65
+ </Panel>
17
66
  </div>
18
-
19
67
  </template>
68
+ <style scoped>
69
+ .p-panel {
70
+ @apply m-2;
71
+ }
72
+ </style>
@@ -30,6 +30,9 @@ import SimpleAppTextarea from '@simitgroup/simpleapp-vue-component/src/component
30
30
  import SimpleAppValue from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppValue.vue'
31
31
  import SimpleFieldContainer from '@simitgroup/simpleapp-vue-component/src/components/SimpleFieldContainer.vue'
32
32
  import SimpleAppDatatable from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppDatatable.vue'
33
+ import SimpleAppInputTable from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppInputTable.vue'
34
+ import SimpleAppDynamicInput from '@simitgroup/simpleapp-vue-component/src/components/SimpleAppDynamicInput.vue'
35
+
33
36
  import mitt from 'mitt'
34
37
  import ToastService from 'primevue/toastservice';
35
38
  import ConfirmationService from 'primevue/confirmationservice';
@@ -66,6 +69,10 @@ export default defineNuxtPlugin((nuxtApp) => {
66
69
  .component("SimpleAppTextarea",SimpleAppTextarea)
67
70
  .component("SimpleAppValue",SimpleAppValue)
68
71
  .component("SimpleFieldContainer",SimpleFieldContainer)
72
+ .component("SimpleAppDatatable",SimpleAppDatatable)
73
+ .component("SimpleAppDynamicInput",SimpleAppDynamicInput)
74
+ .component("SimpleAppInputTable",SimpleAppInputTable)
75
+
69
76
  //.component("Quill",Quill) // cause problem in ssr mode
70
77
  .use(ToastService)
71
78
  .use(ConfirmationService)
@@ -127,7 +127,8 @@ export default defineEventHandler(async (event) => {
127
127
  // console.log('#####################################')
128
128
 
129
129
  if (error.response?.status && error.response.status == '401') {
130
- return reject({ statusMessage: 'Unauthorized', statusCode: 401 });
130
+ //return reject({ statusMessage: 'Unauthorized', statusCode: 401 });
131
+ return sendRedirect(event, '/login', 401)
131
132
  // throw createError({ statusMessage: 'Unauthorized', statusCode: 401 })
132
133
  }
133
134
 
@@ -5,10 +5,18 @@
5
5
  button {
6
6
  @apply p-2 border-2
7
7
  }
8
-
8
+ .simpleapp-input-container,.simpleapp-input-container,.simpleapp-input-container .simpleapp-inputfield{
9
+ @apply flex flex-col
10
+ }
11
+ .simpleapp-input-container .p-chips ul{
12
+ width: 100%
13
+ }
9
14
  .input-error{
10
15
  @apply text-red-500
11
16
  }
17
+ .input-error input{
18
+ @apply border-red-600
19
+ }
12
20
  .simpleapp-tool-bar button{
13
21
  margin-right: 1rem;
14
22
  }
@@ -25,4 +33,17 @@ button {
25
33
  }
26
34
  .bg-warning{
27
35
  @apply bg-orange-600 text-white
36
+ }
37
+
38
+ .desktop-shortcut-link{
39
+ @apply m-2 m-2 p-2 space-x-2 rounded-sm text-center grid grid-cols-4 gap-4
40
+ }
41
+ .desktop-shortcut-link div{
42
+ @apply bg-teal-300 p-2
43
+ }
44
+ .desktop-shortcut-link div:hover{
45
+ @apply bg-teal-600 p-2
46
+ }
47
+ .tenant-link:hover div{
48
+ @apply bg-gray-300
28
49
  }
package/tsconfig.json CHANGED
@@ -13,5 +13,8 @@
13
13
  "noImplicitAny": false,
14
14
  "strictBindCallApply": false,
15
15
  "paths": {"@": ["./"]}
16
- }
16
+ },
17
+ "exclude": [
18
+ "node_modules" , "./dist" , "./tools"
19
+ ]
17
20
  }
@@ -1,115 +0,0 @@
1
- import { Injectable, Scope } from '@nestjs/common';
2
- import Base64URL from '@darkwolf/base64url';
3
- import * as jwt from 'jsonwebtoken'
4
-
5
-
6
-
7
-
8
-
9
- @Injectable({
10
- scope: Scope.REQUEST,
11
- })
12
- export class User {
13
- private static instance: User;
14
- protected uid: string = '';
15
- protected uname: string = '';
16
- protected email: string = '';
17
- protected fullname:string=''
18
- protected xOrg: string = '';
19
- protected tenantId: number = 0;
20
- protected orgId: number = 0;
21
- protected branchId: number = 0;
22
- protected accessrights:any = {}
23
- protected token:string = ''
24
- protected refreshtoken:string = ''
25
- constructor() {}
26
- public static getInstance(): User {
27
- if (!User.instance) {
28
- User.instance = new User();
29
- }
30
- return User.instance;
31
- }
32
- setUserToken = (tokenstr: string) => {
33
- const tokeninfo = jwt.decode(tokenstr)
34
- // realm_access: {
35
- // roles: [
36
- // 'default-roles-simitdeveloper',
37
- // 'offline_access',
38
- // 'uma_authorization'
39
- // ]
40
- // },
41
- // resource_access: { account: { roles: [Array] } },
42
- // scope: 'openid email profile',
43
- // sid: '53192f53-d4af-413b-b8d7-1e186419fe53',
44
- // email_verified: false,
45
- // name: 'kstan kstan',
46
- // preferred_username: 'kstan',
47
- // given_name: 'kstan',
48
- // family_name: 'kstan',
49
- // email: 'kstan@simitgroup.com'
50
-
51
- const u = User.getInstance()
52
- u.token = tokenstr
53
- u.uid = tokeninfo.sub;
54
- u.email = tokeninfo.email
55
- u.uname = tokeninfo.preferred_username
56
- u.fullname = tokeninfo.name
57
- u.accessrights = tokeninfo.resource_access
58
- };
59
- getInfo = () => {
60
- return User.getInstance();
61
- };
62
- getBranchFilter = () => {
63
- return {
64
- tenantId: User.getInstance().tenantId,
65
- orgId: User.getInstance().orgId,
66
- branchId: User.getInstance().branchId,
67
- };
68
- };
69
- getTenantFilter = () => {
70
- return { tenantId: User.getInstance().tenantId };
71
- };
72
- getOrgFilter = () => {
73
- return {
74
- tenantId: User.getInstance().tenantId,
75
- orgId: User.getInstance().orgId,
76
- };
77
- };
78
-
79
- getCreateFilter = () => {
80
- const u = User.getInstance();
81
- return {
82
- tenantId: u.tenantId,
83
- orgId: u.orgId,
84
- branchId: u.branchId,
85
- createdby: u.uid,
86
- updatedby: u.uid,
87
- created: new Date().getTime().toString(),
88
- updated: new Date().getTime().toString(),
89
- };
90
- };
91
- getUpdateFilter = () => {
92
- const u = User.getInstance();
93
- return {
94
- updatedby: u.uid,
95
- updated: new Date().getTime().toString(),
96
- };
97
- };
98
- setXorg = (xorg) => {
99
- try {
100
- const decodedText: string = Base64URL.decodeText(xorg);
101
- const arrXorg = decodedText.split('-');
102
-
103
- if (arrXorg.length == 3) {
104
- const u = User.getInstance();
105
- u.tenantId = Number(arrXorg[0]);
106
- u.orgId = Number(arrXorg[1]);
107
- u.branchId = Number(arrXorg[2]);
108
- } else {
109
- throw 'invalid x-org';
110
- }
111
- } catch (err) {
112
- throw err;
113
- }
114
- };
115
- }