@simitgroup/simpleapp-generator 1.0.59 → 1.0.60
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/dist/buildinschemas/branch.d.ts.map +1 -1
- package/dist/buildinschemas/branch.js +1 -0
- package/dist/buildinschemas/branch.js.map +1 -1
- package/dist/buildinschemas/organization.d.ts.map +1 -1
- package/dist/buildinschemas/organization.js +1 -0
- package/dist/buildinschemas/organization.js.map +1 -1
- package/dist/buildinschemas/permission.js +1 -1
- package/dist/buildinschemas/permission.js.map +1 -1
- package/dist/buildinschemas/user.d.ts.map +1 -1
- package/dist/buildinschemas/user.js +4 -1
- package/dist/buildinschemas/user.js.map +1 -1
- package/dist/framework.js +1 -1
- package/dist/framework.js.map +1 -1
- package/dist/generate.js +6 -1
- package/dist/generate.js.map +1 -1
- package/dist/type.d.ts +1 -0
- package/dist/type.d.ts.map +1 -1
- package/docs/jsonschema.md +1 -0
- package/package.json +1 -1
- package/src/buildinschemas/branch.ts +1 -0
- package/src/buildinschemas/organization.ts +1 -0
- package/src/buildinschemas/permission.ts +1 -1
- package/src/buildinschemas/user.ts +4 -1
- package/src/framework.ts +1 -1
- package/src/generate.ts +6 -1
- package/src/type.ts +1 -0
- package/templates/basic/nest/controller.ts.eta +5 -3
- package/templates/basic/nest/model.ts.eta +32 -7
- package/templates/basic/nuxt/pages.crud.vue.eta +59 -163
- package/templates/basic/nuxt/pages.index.vue.eta +225 -0
- package/templates/nest/.env._eta +1 -0
- package/templates/nest/src/simpleapp/generate/commons/exceptions/SimpleAppExceptionFilter.ts.eta +1 -1
- package/templates/nest/src/simpleapp/generate/commons/roles/roles.group.ts.eta +1 -1
- package/templates/nest/src/simpleapp/generate/commons/user.context.ts.eta +127 -22
- package/templates/nest/src/simpleapp/generate/processors/simpleapp.processor.ts.eta +1 -1
- package/templates/nest/src/simpleapp/profile/profile.controller.ts.eta +25 -2
- package/templates/nest/src/simpleapp/profile/profile.service.ts.eta +20 -2
- package/templates/nest/src/simpleapp/services/branch.service.ts.eta +41 -40
- package/templates/nest/src/simpleapp/services/user.service.ts.eta +10 -9
- package/templates/nuxt/app.vue.eta +2 -1
- package/templates/nuxt/assets/css/style.css._eta +3 -12
- package/templates/nuxt/assets/primevue/passthrough.ts._eta +24 -20
- package/templates/nuxt/components/ButtonCreateTenant.vue.eta +30 -23
- package/templates/nuxt/components/ButtonHome.vue.eta +15 -2
- package/templates/nuxt/components/ButtonMenuPicker.vue.eta +5 -20
- package/templates/nuxt/components/ButtonPermissionInfo.vue.eta +5 -7
- package/templates/nuxt/components/ButtonProfile.vue.eta +42 -25
- package/templates/nuxt/components/CrudSimple.vue.eta +1 -1
- package/templates/nuxt/components/EventDecision.vue.eta +115 -0
- package/templates/nuxt/components/EventNotification.vue.eta +157 -0
- package/templates/nuxt/components/HeaderBar.vue.eta +2 -2
- package/templates/nuxt/components/Invitation.vue.eta +3 -3
- package/templates/nuxt/components/SelectBranch.vue.eta +5 -2
- package/templates/nuxt/components/SimpleAppDatatable.vue.eta +151 -5
- package/templates/nuxt/components/TenantPicker.vue.eta +75 -0
- package/templates/nuxt/components/UserProfileListItem.vue.eta +65 -0
- package/templates/nuxt/components/renderers/BooleanRender.vue.eta +7 -0
- package/templates/nuxt/components/renderers/DateRender.vue.eta +6 -0
- package/templates/nuxt/components/renderers/ForeignKeyRender.vue.eta +10 -0
- package/templates/nuxt/components/renderers/MoneyRender.vue.eta +7 -0
- package/templates/nuxt/components/renderers/MultiTextRender.vue.eta +11 -0
- package/templates/nuxt/composables/getDocument.generate.ts.eta +4 -0
- package/templates/nuxt/composables/getMenus.generate.ts.eta +35 -31
- package/templates/nuxt/composables/getUserStore.generate.ts.eta +6 -1
- package/templates/nuxt/composables/goTo.generate.ts.eta +15 -0
- package/templates/nuxt/composables/notifications.generate.ts.eta +21 -0
- package/templates/nuxt/composables/stringHelper.generate.ts.eta +11 -1
- package/templates/nuxt/error.vue._eta +20 -5
- package/templates/nuxt/layouts/documentlist.vue.eta +166 -0
- package/templates/nuxt/middleware/30.acl.global.ts.eta +4 -1
- package/templates/nuxt/pages/[xorg]/organization/index.vue.eta +4 -4
- package/templates/nuxt/pages/[xorg]/profile.vue.eta +6 -0
- package/templates/nuxt/pages/[xorg]/user/[id].vue.eta +6 -0
- package/templates/nuxt/pages/[xorg]/user/index.vue.eta +211 -377
- package/templates/nuxt/pages/[xorg]/user.vue.eta +197 -0
- package/templates/nuxt/pages/index.vue._eta +101 -0
- package/templates/nuxt/pages/profile.vue.eta +94 -0
- package/templates/nuxt/plugins/10.simpleapp-event.ts.eta +4 -4
- package/templates/nuxt/plugins/20.simpleapp-userstore.ts.eta +11 -10
- package/templates/nuxt/simpleapp/generate/clients/SimpleAppClient.ts.eta +69 -17
- package/templates/nuxt/simpleapp/generate/commons/documents.ts.eta +6 -3
- package/templates/nuxt/tailwind.config.ts._eta +10 -0
- package/templates/nuxt/types/documentlist.ts.eta +9 -0
- package/templates/nuxt/types/events.ts.eta +20 -0
- package/templates/nuxt/types/index.ts.eta +6 -79
- package/templates/nuxt/types/notifications.ts.eta +16 -0
- package/templates/nuxt/types/others.ts.eta +42 -0
- package/templates/nuxt/types/user.ts.eta +44 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/templates/nest/src/simpleapp/generate/models/perm.model.ts.eta +0 -52
- package/templates/nest/src/simpleapp/generate/models/tenant.model.ts.eta +0 -43
- package/templates/nest/src/simpleapp/generate/models/user.model.ts.eta +0 -56
- package/templates/nuxt/components/EventMonitor.vue.eta +0 -85
- package/templates/nuxt/pages/[xorg]/tenant/index.vue.eta +0 -89
- package/templates/nuxt/pages/index.vue.eta +0 -116
- package/templates/nuxt/simpleapp/generate/commons/events.ts.eta +0 -11
|
@@ -1,7 +1,36 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<DataTable v-bind="$attrs"
|
|
1
|
+
<!-- <template>
|
|
2
|
+
<DataTable v-bind="$attrs"
|
|
3
|
+
stripedRows
|
|
4
|
+
dataKey="_id"
|
|
5
|
+
:pt="{
|
|
6
|
+
bodyRow:{class:'bg-blue-200'},
|
|
7
|
+
wrapper:{class:'bg-red-100'},
|
|
8
|
+
|
|
9
|
+
root:{class:'bg-green-100'},
|
|
10
|
+
header:{class:'bg-blue-600'},
|
|
11
|
+
pagebutton:{class:'bg-red-800'},
|
|
12
|
+
|
|
13
|
+
tfoot:{class:'bg-red-800 boder round m-4 gap-4'},
|
|
14
|
+
}"
|
|
15
|
+
|
|
16
|
+
:value="valueModel"
|
|
17
|
+
:filters="filters"
|
|
18
|
+
:paginator="true" :rows="20"
|
|
19
|
+
:rowsPerPageOptions="[20,40,60,100]"
|
|
20
|
+
filterDisplay="row"
|
|
21
|
+
>
|
|
22
|
+
|
|
3
23
|
<template #empty> <div class="text-center">No record found.</div> </template>
|
|
4
|
-
<template #header><slot name="header"
|
|
24
|
+
<template #header><slot name="header">
|
|
25
|
+
<div class="flex flex-wrap gap-2 align-items-center justify-content-between">
|
|
26
|
+
<h4 class="m-0 flex-1">Records</h4>
|
|
27
|
+
<span class="p-input-icon-left">
|
|
28
|
+
<i class="pi pi-search" />
|
|
29
|
+
<InputText v-model="filters['global'].value" placeholder="Search..." />
|
|
30
|
+
</span>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
</slot></template>
|
|
5
34
|
<Column v-for="(col,index) in columns" :field="col" :header="camelCaseToWords(col)"></Column>
|
|
6
35
|
<slot >
|
|
7
36
|
|
|
@@ -9,11 +38,128 @@
|
|
|
9
38
|
</DataTable>
|
|
10
39
|
</template>
|
|
11
40
|
<script setup lang="ts">
|
|
41
|
+
import { FilterMatchMode } from 'primevue/api';
|
|
12
42
|
import DataTable from 'primevue/datatable';
|
|
13
43
|
import Column from 'primevue/column';
|
|
14
44
|
import {camelCaseToWords} from './helper'
|
|
15
|
-
const props = defineProps<{columns:string[]}>()
|
|
45
|
+
const props = defineProps<{columns:string[]|string[][]}>()
|
|
16
46
|
const valueModel = defineModel<Object[]>()
|
|
47
|
+
const filters = ref({
|
|
48
|
+
'global': {value: null, matchMode: FilterMatchMode.CONTAINS},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
</script> -->
|
|
52
|
+
<template>
|
|
53
|
+
<DataTable v-bind="$attrs"
|
|
54
|
+
stripedRows
|
|
55
|
+
dataKey="_id"
|
|
56
|
+
:showGridlines="true"
|
|
57
|
+
:pt="{
|
|
58
|
+
// header:{ class:'border bg-gray-100'},
|
|
59
|
+
headerRow:{ class:'border bg-gray-200'},
|
|
60
|
+
}"
|
|
61
|
+
:value="value"
|
|
62
|
+
:filters="filters"
|
|
63
|
+
:paginator="true" :rows="20"
|
|
64
|
+
:rowsPerPageOptions="[20,40,60,100]"
|
|
65
|
+
>
|
|
66
|
+
<!-- header -->
|
|
67
|
+
<template #header>
|
|
68
|
+
<div class=" flex flex-row w-full text-right justify-content-end">
|
|
69
|
+
<div class="flex-1">
|
|
70
|
+
<slot name="toolbar"></slot>
|
|
71
|
+
</div>
|
|
72
|
+
<div class="flex-1">
|
|
73
|
+
<slot name="title">
|
|
74
|
+
<h1 class="text text-2xl pt-2 text-center">{{ title }}</h1>
|
|
75
|
+
</slot>
|
|
76
|
+
|
|
77
|
+
</div>
|
|
78
|
+
<span class="p-input-icon-left flex-1">
|
|
79
|
+
<i class="pi pi-search mt-4 ml-2 text-gray-400 absolute" />
|
|
80
|
+
<InputText type ="search" v-model="filters['global'].value" class="text-right" placeholder="Keyword Search" />
|
|
81
|
+
</span>
|
|
82
|
+
</div>
|
|
83
|
+
</template>
|
|
84
|
+
<!-- no data found -->
|
|
85
|
+
<template #empty>
|
|
86
|
+
<div class="text-center ">
|
|
87
|
+
<div class="text-3xl text-gray-400 pi pi-exclamation-circle"></div>
|
|
88
|
+
<div class="text-3xl text-gray-400">no data found</div>
|
|
89
|
+
|
|
90
|
+
</div>
|
|
91
|
+
</template>
|
|
92
|
+
|
|
93
|
+
<Column v-for="(col,index) in columns" :field="typeof col == 'string' ? col : col.field">
|
|
94
|
+
<template v-if="typeof col == 'string'" #header>
|
|
95
|
+
<p >{{ col }}</p>
|
|
96
|
+
</template>
|
|
97
|
+
<template v-else-if="typeof col =='object'" #header>
|
|
98
|
+
<span>{{ col.title }} </span>
|
|
99
|
+
</template>
|
|
100
|
+
<template v-else #header>
|
|
101
|
+
<span class="text-danger-600">unknown</span>
|
|
102
|
+
</template>
|
|
103
|
+
|
|
104
|
+
<template v-if="typeof col == 'string'" #body="{index,data}">
|
|
105
|
+
<p >{{ data[col] }}</p>
|
|
106
|
+
</template>
|
|
107
|
+
<template v-else-if="typeof col =='object'" #body="{index,data}">
|
|
108
|
+
<div v-if="col.component && col.field=='*'">
|
|
109
|
+
<component :is="col.component" :value="data" :fields="col.moreFields" :class="col.cssClass" :setting="col.componentSetting"></component>
|
|
110
|
+
</div>
|
|
111
|
+
<div v-else-if="col.component && col.field!='*'">
|
|
112
|
+
<component :is="col.component" v-model="data[col.field]" :moreFields="col.moreFields" :class="col.cssClass" :setting="col.componentSetting" ></component>
|
|
113
|
+
</div>
|
|
114
|
+
<div v-else class="flex flex-col">
|
|
115
|
+
<div :class="col.class">{{ data[col.field] }}</div>
|
|
116
|
+
<div v-for="(f,findex) in col.moreFields" class="flex flex-col">
|
|
117
|
+
<!-- additional field define as string -->
|
|
118
|
+
<div v-if="typeof f == 'string'" :class="'text-gray-400 text-sm' + f.cssClass??'' ">{{ data[f] }}</div>
|
|
119
|
+
<!-- additional field define as object -->
|
|
120
|
+
<div v-else>
|
|
121
|
+
<div v-if="f.component && f.field=='*'">
|
|
122
|
+
<component :is="f.component" :value="data" :class="f.cssClass" :setting="f.componentSetting"></component>
|
|
123
|
+
</div>
|
|
124
|
+
<div v-else-if="f.component && f.field!='*'">
|
|
125
|
+
<component :is="f.component" v-model="data[f.field]" :class="f.cssClass" :setting="f.componentSetting" ></component>
|
|
126
|
+
</div>
|
|
127
|
+
<div v-else>
|
|
128
|
+
<div :class="f.cssClass">{{ data[f.field] }}</div>
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
</div>
|
|
134
|
+
</div>
|
|
135
|
+
</template>
|
|
136
|
+
<template v-else #body>
|
|
137
|
+
<span class="text-danger-600">unknown col {{ col }}</span>
|
|
138
|
+
</template>
|
|
139
|
+
</Column>
|
|
140
|
+
<slot>
|
|
141
|
+
|
|
142
|
+
</slot>
|
|
143
|
+
</Datatable>
|
|
144
|
+
</template>
|
|
145
|
+
<script setup lang="ts">
|
|
146
|
+
import {SearchBody,CellSetting} from '~/types'
|
|
147
|
+
import { FilterMatchMode } from 'primevue/api';
|
|
148
|
+
import DataTable from 'primevue/datatable';
|
|
149
|
+
import Column from 'primevue/column';
|
|
150
|
+
|
|
151
|
+
const props = defineProps<{
|
|
152
|
+
value:any[]
|
|
153
|
+
columns: CellSetting[]
|
|
154
|
+
title:string
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
}>()
|
|
158
|
+
|
|
159
|
+
const filters = ref({
|
|
160
|
+
'global': {value: null, matchMode: FilterMatchMode.CONTAINS},
|
|
161
|
+
});
|
|
162
|
+
|
|
17
163
|
|
|
164
|
+
</script>
|
|
18
165
|
|
|
19
|
-
</script>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<card>
|
|
3
|
+
<template #header>
|
|
4
|
+
<h1 class="font font-bold text text-gray-700">{{ tenant.tenantName }}</h1>
|
|
5
|
+
</template>
|
|
6
|
+
<template #content>
|
|
7
|
+
|
|
8
|
+
<ul >
|
|
9
|
+
<li v-for="o in orglist">
|
|
10
|
+
<h1>{{ o.orgName }}</h1>
|
|
11
|
+
<ul role="list" class="divide-y divide-gray-100 rounded-md border border-gray-200">
|
|
12
|
+
<li v-for="b in branchlist" class="flex items-center justify-between py-4 pl-4 pr-5 text-sm leading-6">
|
|
13
|
+
<NuxtLink :href="`/${b.xOrg }`" v-if="o.orgId==b.orgId" :external="true" class="hover:bg-primary-100">
|
|
14
|
+
<div class="flex w-full flex-1 items-center ">
|
|
15
|
+
<!-- <i class="pi pi-sitemap"></i> -->
|
|
16
|
+
<p class="flex-1 flex-shrink-0 font-bold text-primary-600 ">
|
|
17
|
+
{{ b.branchCode }}
|
|
18
|
+
</p>
|
|
19
|
+
<p class=" text-right min-w-0 flex-1 gap-2">
|
|
20
|
+
<span href="#" class="font-medium text-gray-600 ">{{ b.group }}</span>
|
|
21
|
+
</p>
|
|
22
|
+
</div>
|
|
23
|
+
<div class=" flex-shrink-0">
|
|
24
|
+
|
|
25
|
+
<span class=" font-medium text-gray-400">{{useRuntimeConfig().public.APP_URL}}/{{b.xOrg }}</span>
|
|
26
|
+
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
</NuxtLink>
|
|
30
|
+
</li>
|
|
31
|
+
</ul>
|
|
32
|
+
|
|
33
|
+
</li>
|
|
34
|
+
</ul>
|
|
35
|
+
|
|
36
|
+
<!-- <ul>
|
|
37
|
+
<li v-for="b in branches" class="border border-b-1">
|
|
38
|
+
<NuxtLink :href="`/${b.xOrg }`" :external="true">
|
|
39
|
+
|
|
40
|
+
<div class="flex flex-col">
|
|
41
|
+
<div class="flex">
|
|
42
|
+
<p class="flex-1">{{b.branch.branchCode}}</p>
|
|
43
|
+
<p class="flex-1 text-right">{{b.group }}</p>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
<p class="text-gray-500">{{useRuntimeConfig().public.APP_URL}}/{{b.xOrg }}</p>
|
|
48
|
+
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
</NuxtLink>
|
|
52
|
+
</li>
|
|
53
|
+
</ul> -->
|
|
54
|
+
</template>
|
|
55
|
+
</card>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<script setup lang="ts">
|
|
59
|
+
import _ from 'lodash'
|
|
60
|
+
const props = defineProps<{
|
|
61
|
+
tenant:any
|
|
62
|
+
}>()
|
|
63
|
+
const branchlist = computed(()=>props.tenant.permissions)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
const orglist = computed(()=>_.uniqBy(branchlist.value,'orgId')
|
|
67
|
+
.map((item:any)=>({ orgId:item.orgId,orgCode:item.orgCode,orgName:item.orgName}) ) )
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
onMounted(()=>{
|
|
72
|
+
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
</script>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- <ul role="list" class="divide-y divide-gray-100">
|
|
3
|
+
<li v-for="person in people" :key="person.email" class="flex justify-between gap-x-6 py-5"> -->
|
|
4
|
+
<div class="flex justify-between gap-x-6 py-5 cursor-pointer">
|
|
5
|
+
<div class="flex min-w-0 gap-x-4">
|
|
6
|
+
<img class="h-12 w-12 flex-none rounded-full bg-gray-50" :src="`${getAvatarLink(data.email,32)}`" alt="" />
|
|
7
|
+
<div class="min-w-0 flex-auto">
|
|
8
|
+
<p class="text-sm font-semibold leading-6 text-gray-900">{{ data.fullname }}</p>
|
|
9
|
+
<p class="mt-1 truncate text-xs leading-5 text-gray-500">{{ data.email }}</p>
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
12
|
+
<div class="hidden shrink-0 sm:flex sm:flex-col sm:items-end">
|
|
13
|
+
|
|
14
|
+
<div v-if="isOnline" class="mt-1 flex items-center gap-x-1.5">
|
|
15
|
+
<div class="flex-none rounded-full bg-emerald-500/20 p-1">
|
|
16
|
+
<div class="h-1.5 w-1.5 rounded-full bg-emerald-500" />
|
|
17
|
+
</div>
|
|
18
|
+
<p class="text-xs leading-5 text-gray-500">Online</p>
|
|
19
|
+
</div>
|
|
20
|
+
<p v-else class="mt-1 text-xs leading-5 text-gray-500">
|
|
21
|
+
<span v-if="datedifferent.get('years')>0">{{ datedifferent.get('years') }} year(s)</span>
|
|
22
|
+
<span v-if="datedifferent.get('months')>0">{{ datedifferent.get('months') }} month(s)</span>
|
|
23
|
+
<span v-if="datedifferent.get('days')>0">{{ datedifferent.get('days') }} day(s)</span>
|
|
24
|
+
<span v-if="datedifferent.get('hours')>0">{{ datedifferent.get('hours') }} Hour(s)</span>
|
|
25
|
+
<span v-if="datedifferent.get('minutes')>0">{{ datedifferent.get('minutes') }} min(s)</span>
|
|
26
|
+
</p>
|
|
27
|
+
<p class="text-sm text-right leading-6 text-gray-400 w-[120px] truncate ...">
|
|
28
|
+
{{ data.description }}
|
|
29
|
+
</p>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<script setup lang="ts">
|
|
36
|
+
import {computed} from 'vue'
|
|
37
|
+
import moment from 'moment'
|
|
38
|
+
const props = defineProps<{
|
|
39
|
+
data:any
|
|
40
|
+
}>()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
const datedifferent = computed(()=>{
|
|
45
|
+
const data = moment.duration(differentTime.value)
|
|
46
|
+
return data
|
|
47
|
+
})
|
|
48
|
+
const differentTime = computed(()=>{
|
|
49
|
+
const lasttime = new Date(props.data.lastActivity).getTime()
|
|
50
|
+
const current = new Date().getTime()
|
|
51
|
+
const result = current - lasttime
|
|
52
|
+
return result
|
|
53
|
+
})
|
|
54
|
+
const isOnline = computed(()=>{
|
|
55
|
+
if(props.data.lastActivity) {
|
|
56
|
+
const diffminutes = differentTime.value/ 1000/60
|
|
57
|
+
return diffminutes < 1
|
|
58
|
+
}else{
|
|
59
|
+
return false
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
</script>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<NuxtLink :to="getDocumentUrl(setting.collection,modelValue ? modelValue['_id']:'')" class="text-primary-700 hover:text-primary-500">
|
|
3
|
+
{{modelValue?.label}}
|
|
4
|
+
</NuxtLink>
|
|
5
|
+
</template>
|
|
6
|
+
<script setup lang="ts">
|
|
7
|
+
const modelValue = defineModel()
|
|
8
|
+
|
|
9
|
+
const props = defineProps<{setting:any}>()
|
|
10
|
+
</script>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
<template>
|
|
3
|
+
<p v-for="(f,index) in fields" >
|
|
4
|
+
<span v-if="index==0">{{ value[f] }}</span>
|
|
5
|
+
<span v-else class="text-gray-400 text-sm">{{ value[f] }}</span>
|
|
6
|
+
</p>
|
|
7
|
+
</template>
|
|
8
|
+
<script lang="ts" setup>
|
|
9
|
+
const props = defineProps(['value','fields'])
|
|
10
|
+
|
|
11
|
+
</script>
|
|
@@ -6,48 +6,52 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import _ from 'lodash'
|
|
8
8
|
import {MenuData} from '~/types'
|
|
9
|
-
import {
|
|
9
|
+
import {getAllDocuments} from '../simpleapp/generate/commons/documents'
|
|
10
10
|
export const getDocTypes = ()=>{
|
|
11
|
-
return
|
|
11
|
+
return getAllDocuments().filter(item=>item.page!='')
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const getPublicResource = (xorg:string) : MenuData[] => {
|
|
15
|
+
// const xorg = getUserStore().getCurrentXorg()
|
|
16
|
+
const menus:MenuData[] = [
|
|
17
|
+
{label: 'Home',icon: 'pi pi-fw pi-home', url:`/${xorg}`},
|
|
18
|
+
{label: "Profile", url:`/profile`, isolationType:'none', icon:''},
|
|
19
|
+
{label: "Profile", url:`/${xorg}/profile`, isolationType:'none', icon:''},
|
|
20
|
+
{label: 'Signout',icon: 'pi pi-fw pi-home', command: () => logout()},
|
|
21
|
+
{label: 'Signin',icon: 'pi pi-fw pi-home', 'url':'/login'},
|
|
22
|
+
]
|
|
23
|
+
return menus
|
|
12
24
|
}
|
|
13
25
|
export const getMenus =() :MenuData[]=>{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const xorg =
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let allmenus =
|
|
26
|
+
// const logout = async () => {
|
|
27
|
+
// const { signOut } = useAuth();
|
|
28
|
+
// const { data } = await <any>useFetch('/api/auth/logout');
|
|
29
|
+
// const addPath = encodeURIComponent("/login");
|
|
30
|
+
// signOut({ redirect: false });
|
|
31
|
+
// window.location.href = data?.value?.path + addPath;
|
|
32
|
+
// };
|
|
33
|
+
|
|
34
|
+
// const route = useRoute();
|
|
35
|
+
const xorg = getUserStore().getCurrentXorg()
|
|
36
|
+
// let data:MenuData[] =[];
|
|
37
|
+
// //sss
|
|
38
|
+
let allmenus = getAllDocuments().filter(item=>item.page!='')
|
|
27
39
|
|
|
28
|
-
const roles =
|
|
40
|
+
const roles = getUserProfile().roles
|
|
29
41
|
let allowmenus=[]
|
|
30
42
|
for(let i=0; i< allmenus.length;i++){
|
|
31
43
|
const keyword = allmenus[i].docName
|
|
32
44
|
// if(m.label)
|
|
33
45
|
|
|
34
|
-
if(
|
|
46
|
+
if(getUserStore().haveAccess(keyword)){
|
|
35
47
|
const m:MenuData = {label: keyword, url:`/${xorg}/${keyword}`, isolationType:allmenus[i].isolationType}
|
|
36
48
|
allowmenus.push(m)
|
|
37
49
|
}
|
|
38
50
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
]
|
|
46
|
-
}else{
|
|
47
|
-
data= [
|
|
48
|
-
{label: 'Home',icon: 'pi pi-fw pi-home', url:'/'},
|
|
49
|
-
{label: 'Signout',icon: 'pi pi-fw pi-home', command: () => logout()},
|
|
50
|
-
]
|
|
51
|
-
}
|
|
52
|
-
return data
|
|
51
|
+
// data = publicMenus()
|
|
52
|
+
// if(xorg){
|
|
53
|
+
// data.push({label: 'Cruds',icon: 'pi pi-fw pi-pencil',items:allowmenus})
|
|
54
|
+
// }
|
|
55
|
+
// console.log('data',data)
|
|
56
|
+
return allowmenus
|
|
53
57
|
}
|
|
@@ -10,7 +10,12 @@ export const reloadUserStore = async () =>{
|
|
|
10
10
|
export const getUserProfile = () =>{
|
|
11
11
|
return getUserStore().getUserInfo()
|
|
12
12
|
}
|
|
13
|
-
|
|
13
|
+
export const getCurrentXorg = () =>{
|
|
14
|
+
return getUserStore().getCurrentXorg()
|
|
15
|
+
}
|
|
16
|
+
export const getPageBaseUrl = (resourcename:string) =>{
|
|
17
|
+
return `/${getCurrentXorg()}/${resourcename}`;
|
|
18
|
+
}
|
|
14
19
|
/**
|
|
15
20
|
* verify current user can perform specific action base on backend RBAC
|
|
16
21
|
* @param resource:string upper case first letter document name
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export const getDocumentUrl = (document:string,id?:string,querystr?:string)=>{
|
|
2
|
+
let path = `/${getCurrentXorg()}/${document}`
|
|
3
|
+
if(id){
|
|
4
|
+
path = path + '/'+id
|
|
5
|
+
}
|
|
6
|
+
if(querystr){
|
|
7
|
+
path=path+'?'+querystr
|
|
8
|
+
}
|
|
9
|
+
return path
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export const goTo = (document:string,id?:string,querystr?:string)=>{
|
|
14
|
+
navigateTo(getDocumentUrl(document,id,querystr))
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {NotificationStatus} from '~/types'
|
|
2
|
+
export const getStatusColor = (status:NotificationStatus) => {
|
|
3
|
+
console.log("get status color",status)
|
|
4
|
+
switch(status){
|
|
5
|
+
case NotificationStatus.error:
|
|
6
|
+
return 'bg bg-danger-600 text-white';
|
|
7
|
+
break;
|
|
8
|
+
case NotificationStatus.warn:
|
|
9
|
+
return 'bg bg-warning-600 text-white';
|
|
10
|
+
break;
|
|
11
|
+
case NotificationStatus.info:
|
|
12
|
+
return 'bg bg-secondary-600 text-white';
|
|
13
|
+
break;
|
|
14
|
+
case NotificationStatus.success:
|
|
15
|
+
default:
|
|
16
|
+
return 'bg bg-primary-600 text-white';
|
|
17
|
+
break;
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
import {Md5} from 'ts-md5'
|
|
1
2
|
export const camelCaseToWords = (s: string) =>{
|
|
2
3
|
const result = s.replace(/([A-Z])/g, ' $1');
|
|
3
4
|
return result.charAt(0).toUpperCase() + result.slice(1);
|
|
4
5
|
}
|
|
5
|
-
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export const md5=(s:string)=> new Md5().appendStr(s).end()
|
|
9
|
+
|
|
10
|
+
export const getAvatarLink = (email:string, size:number):string=>{
|
|
11
|
+
return `https://api.simbiz.cloud/cloudapi/avatar/${md5(email)}?size=${size}`
|
|
12
|
+
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const toLocalDate = (dateiso8601:string)=> new Date(String(dateiso8601)).toLocaleDateString()
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<div class="flex items-center justify-center py-12 bg bg-gray-500">
|
|
3
|
+
<div class="bg-white border rounded-md flex items-center justify-center mx-4 md:w-2/3">
|
|
4
|
+
<div class="flex flex-col items-center py-16">
|
|
5
|
+
|
|
6
|
+
<div class="flex flex-row">
|
|
7
|
+
<div class="w w-40">
|
|
8
|
+
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-13.59 -13.59 480.17 480.17" xml:space="preserve" fill="#000000" stroke="#000000" stroke-width="0.00452986"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <g> <g> <g> <path style="fill:#010002;" d="M0,0v452.986h452.986V0H0z M403.223,24.655c8.132,0,14.668,6.558,14.668,14.625 c0,8.111-6.536,14.711-14.668,14.711c-8.089,0-14.668-6.601-14.668-14.711C388.576,31.234,395.134,24.655,403.223,24.655z M352.035,24.655c8.046,0,14.647,6.558,14.647,14.625c0,8.111-6.601,14.711-14.647,14.711c-8.132,0-14.668-6.601-14.668-14.711 C337.389,31.234,343.903,24.655,352.035,24.655z M417.955,418.624H35.053V85.701h382.903V418.624z"></path> <path style="fill:#010002;" d="M226.493,398.952c80.394,0,145.495-65.101,145.495-145.43s-65.101-145.495-145.495-145.495 c-80.373,0-145.516,65.165-145.516,145.495C80.977,333.873,146.12,398.952,226.493,398.952z M142.044,198.516l29.444-29.444 l55.005,55.027l54.984-55.027l29.379,29.444L255.894,253.5l54.984,54.941l-29.423,29.444l-54.962-54.962l-55.005,54.984 l-29.444-29.444l54.984-54.941L142.044,198.516z"></path> </g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> </g> </g></svg>
|
|
9
|
+
</div>
|
|
10
|
+
<div>
|
|
11
|
+
<h1 class="px-4 pt-2 pb-4 text-left text-5xl font-bold leading-10 text-gray-800">OOPS!</h1>
|
|
12
|
+
<p class="px-4 mt mb-4 text-4xl text-left font font-bold">{{error.statusCode}} Error</p>
|
|
13
|
+
<p class="px-4 pb-10 text-base leading-none text-left text-gray-400">{{error.message}}</p>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
7
22
|
</template>
|
|
8
23
|
<script setup lang="ts">
|
|
9
24
|
|