@diasro/ucsd-its-frontend 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/CommonRoutes.d.ts +7 -0
- package/dist/UcsdPlugin.d.ts +9 -0
- package/dist/assets/dark_bg.webp +0 -0
- package/dist/assets/light_dock_bg.jpg +0 -0
- package/dist/assets/settings.icns +0 -0
- package/dist/assets/settings.png +0 -0
- package/dist/assets/ucsd-its-frontend.css +1 -0
- package/dist/assets/ucsd_logo.png +0 -0
- package/dist/assets/ucsd_logo_white.png +0 -0
- package/dist/cli.cjs +73 -0
- package/dist/components/TileButton.vue.d.ts +113 -0
- package/dist/components/authorization/Login.vue.d.ts +2 -0
- package/dist/components/authorization/LoginSuccess.vue.d.ts +2 -0
- package/dist/components/authorization/Logout.vue.d.ts +2 -0
- package/dist/components/authorization/Unauthorized.vue.d.ts +2 -0
- package/dist/components/commons/ChangeHistory.vue.d.ts +54 -0
- package/dist/components/commons/ProgressDialog.vue.d.ts +2 -0
- package/dist/composables/auditLog.d.ts +25 -0
- package/dist/composables/layout.d.ts +19 -0
- package/dist/composables/utils/ucsdAppUtils.d.ts +15 -0
- package/dist/index.d.ts +31 -0
- package/dist/layouts/AppLayout.vue.d.ts +2 -0
- package/dist/layouts/DefaultLayout.vue.d.ts +20 -0
- package/dist/layouts/FixedLayout.vue.d.ts +20 -0
- package/dist/layouts/FloatingLayout.vue.d.ts +2 -0
- package/dist/layouts/UcsdFooter.vue.d.ts +2 -0
- package/dist/layouts/UcsdHeader.vue.d.ts +23 -0
- package/dist/layouts/UserPanel.vue.d.ts +2 -0
- package/dist/layouts/menu/FloatMenu.vue.d.ts +2 -0
- package/dist/layouts/menu/RailMenu.vue.d.ts +24 -0
- package/dist/layouts/menu/TopMenu.vue.d.ts +12 -0
- package/dist/main.css +63 -0
- package/dist/stores/its-app.d.ts +336 -0
- package/dist/stores/its-audit.d.ts +184 -0
- package/dist/stores/its-auth.d.ts +169 -0
- package/dist/templates/.env +9 -0
- package/dist/templates/App.vue +17 -0
- package/dist/templates/config/ucsd.config.ts +105 -0
- package/dist/templates/index.html +17 -0
- package/dist/templates/main.ts +6 -0
- package/dist/templates/pages/DashBoard.vue +29 -0
- package/dist/templates/pages/Home.vue +20 -0
- package/dist/templates/pages/admin/AdminPage.vue +19 -0
- package/dist/templates/pages/customer/CustomerHome.vue +19 -0
- package/dist/templates/pages/customer/CustomerSearch.vue +21 -0
- package/dist/templates/pages/customer/SimpleForm.vue +299 -0
- package/dist/templates/pages/invoices/InvoiceHome.vue +19 -0
- package/dist/templates/plugins/index.ts +43 -0
- package/dist/templates/plugins/vuetify.ts +9 -0
- package/dist/templates/router/index.ts +17 -0
- package/dist/templates/router/routes.ts +49 -0
- package/dist/templates/stores/app.ts +74 -0
- package/dist/templates/stores/index.ts +9 -0
- package/dist/templates/styles/README.md +3 -0
- package/dist/templates/styles/settings.scss +10 -0
- package/dist/templates/vite.config.ts +75 -0
- package/dist/types/ApiError.d.ts +6 -0
- package/dist/types/LoginUser.d.ts +12 -0
- package/dist/types/TileRecord.d.ts +41 -0
- package/dist/types/UcsdConfig.d.ts +29 -0
- package/dist/types/audit.d.ts +57 -0
- package/dist/ucsd-its-frontend.js +13251 -0
- package/dist/ucsd-its-frontend.umd.cjs +345 -0
- package/dist/vite.svg +1 -0
- package/package.json +109 -0
- package/src/lib/templates/.env +9 -0
- package/src/lib/templates/App.vue +17 -0
- package/src/lib/templates/config/ucsd.config.ts +105 -0
- package/src/lib/templates/index.html +17 -0
- package/src/lib/templates/main.ts +6 -0
- package/src/lib/templates/pages/DashBoard.vue +29 -0
- package/src/lib/templates/pages/Home.vue +20 -0
- package/src/lib/templates/pages/admin/AdminPage.vue +19 -0
- package/src/lib/templates/pages/customer/CustomerHome.vue +19 -0
- package/src/lib/templates/pages/customer/CustomerSearch.vue +21 -0
- package/src/lib/templates/pages/customer/SimpleForm.vue +299 -0
- package/src/lib/templates/pages/invoices/InvoiceHome.vue +19 -0
- package/src/lib/templates/plugins/index.ts +43 -0
- package/src/lib/templates/plugins/vuetify.ts +9 -0
- package/src/lib/templates/router/index.ts +17 -0
- package/src/lib/templates/router/routes.ts +49 -0
- package/src/lib/templates/stores/app.ts +74 -0
- package/src/lib/templates/stores/index.ts +9 -0
- package/src/lib/templates/styles/README.md +3 -0
- package/src/lib/templates/styles/settings.scss +10 -0
- package/src/lib/templates/vite.config.ts +75 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import {onMounted, ref, useTemplateRef} from "vue";
|
|
3
|
+
import {useAuditLog} from "ucsd-its-frontend";
|
|
4
|
+
import {useAppStore} from "../../stores/app";
|
|
5
|
+
import {Audit} from "ucsd-its-frontend";
|
|
6
|
+
import {useToast} from 'vue-toast-notification';
|
|
7
|
+
import {useTheme} from "vuetify";
|
|
8
|
+
import {useUcsdAppUtils} from "ucsd-its-frontend";
|
|
9
|
+
import 'vue-toast-notification/dist/theme-bootstrap.css';
|
|
10
|
+
import {ChangeHistory} from "ucsd-its-frontend";
|
|
11
|
+
import {useItsAppStore} from "ucsd-its-frontend";
|
|
12
|
+
import {AuditTimeLine} from "ucsd-its-frontend";
|
|
13
|
+
import {useItsAuthStore} from "ucsd-its-frontend";
|
|
14
|
+
|
|
15
|
+
const auditLog = useAuditLog()
|
|
16
|
+
const appStore = useAppStore()
|
|
17
|
+
const $toast = useToast()
|
|
18
|
+
const theme = useTheme()
|
|
19
|
+
const appUtils = useUcsdAppUtils()
|
|
20
|
+
const itsAppStore = useItsAppStore()
|
|
21
|
+
const itsAuthStore = useItsAuthStore()
|
|
22
|
+
|
|
23
|
+
interface SimpleFormData {
|
|
24
|
+
id: number,
|
|
25
|
+
name: string,
|
|
26
|
+
item: string | null,
|
|
27
|
+
paid: boolean,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let auditTimeLine = [] as AuditTimeLine[]
|
|
31
|
+
const loadingTimeLine = ref(true)
|
|
32
|
+
const formDataList = ref([] as SimpleFormData[]);
|
|
33
|
+
const formData = ref({} as SimpleFormData)
|
|
34
|
+
const items = ref(['Item 1', 'Item 2', 'Item 3', 'Item 4'])
|
|
35
|
+
const loading = ref(false)
|
|
36
|
+
const formRef = useTemplateRef('form')
|
|
37
|
+
const nameRules = [
|
|
38
|
+
(v: any) => !!v || 'Name is required',
|
|
39
|
+
(v: any) => (v && v.length <= 10) || 'Name must be 10 characters or less',
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
const showAuditTimeline = () => {
|
|
43
|
+
loadingTimeLine.value = true;
|
|
44
|
+
let detailKey = 'simple-form-' + formData.value.id;
|
|
45
|
+
const audits = itsAppStore.getAuditQueue(detailKey);
|
|
46
|
+
auditTimeLine = auditLog.mapAuditToTimeLine(audits);
|
|
47
|
+
loadingTimeLine.value = false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const userAudit = () => {
|
|
51
|
+
loadingTimeLine.value = true;
|
|
52
|
+
const audits = itsAppStore.getAuditQueue(undefined, itsAuthStore.getUserEmail());
|
|
53
|
+
auditTimeLine = auditLog.mapAuditToTimeLine(audits);
|
|
54
|
+
loadingTimeLine.value = false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
onMounted(() => {
|
|
58
|
+
//You can await here if data is loaded via API
|
|
59
|
+
itsAppStore.resetAuditQueue()
|
|
60
|
+
auditLog.trackChanges(formData.value, false)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const updateExample = () => {
|
|
64
|
+
const auditRecord: Audit = appStore.getAuditRecord(); //Audit application source identifier
|
|
65
|
+
auditRecord.event = 'Existing Record Updated';
|
|
66
|
+
auditRecord.eventIcon = 'mdi-account-edit-outline'; //Change the icon based on description
|
|
67
|
+
auditLog.commitChanges(formData.value, auditRecord, 'simple-form-' + formData.value.id, 'update', []);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const newExample = () => {
|
|
71
|
+
const auditRecord: Audit = appStore.getAuditRecord(); //Audit application source identifier
|
|
72
|
+
auditRecord.event = 'New Record created';
|
|
73
|
+
auditRecord.eventIcon = 'mdi-account-plus-outline'; //Change the icon based on description
|
|
74
|
+
auditRecord.eventColor = 'success'
|
|
75
|
+
auditLog.commitChanges(formData.value, auditRecord, 'simple-form-' + formData.value.id, 'new', ['id', 'name']);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const deleteExample = () => {
|
|
79
|
+
const auditRecord: Audit = appStore.getAuditRecord(); //Audit application source identifier
|
|
80
|
+
auditRecord.event = 'Record deleted';
|
|
81
|
+
auditRecord.eventIcon = 'mdi-account-minus-outline'; //Change the icon based on description
|
|
82
|
+
auditRecord.eventColor = 'error'
|
|
83
|
+
auditLog.commitChanges(formData.value, auditRecord, 'simple-form-' + formData.value.id, 'delete', []);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const addRecord = () => {
|
|
87
|
+
const data = appUtils.deepClone(formData.value) as SimpleFormData;
|
|
88
|
+
data.id = formDataList.value.length + 1;
|
|
89
|
+
data.paid = !(data.paid === null || !data.paid);
|
|
90
|
+
formData.value.id = data.id;
|
|
91
|
+
formDataList.value.push(data)
|
|
92
|
+
newExample();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const updateRecord = () => {
|
|
96
|
+
const data = appUtils.deepClone(formData.value) as SimpleFormData;
|
|
97
|
+
formDataList.value.forEach((item, index) => {
|
|
98
|
+
if (item.id === data.id) {
|
|
99
|
+
formDataList.value[index] = data;
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
updateExample();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const deleteRecord = () => {
|
|
106
|
+
formDataList.value = formDataList.value.filter(item => item.id !== formData.value.id)
|
|
107
|
+
deleteExample();
|
|
108
|
+
formData.value = {
|
|
109
|
+
id: 0,
|
|
110
|
+
name: '',
|
|
111
|
+
item: null,
|
|
112
|
+
paid: false,
|
|
113
|
+
}
|
|
114
|
+
resetValidation();
|
|
115
|
+
$toast.success('Record deleted successfully')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
const validate = async () => {
|
|
120
|
+
// @ts-ignore
|
|
121
|
+
const {valid} = await formRef.value?.validate()
|
|
122
|
+
if (valid) {
|
|
123
|
+
loading.value = true;
|
|
124
|
+
await appStore.simulateAxiosCall({message: 'Success'}, 1000, false).then(response => {
|
|
125
|
+
if (formData.value.id > 0) {
|
|
126
|
+
updateRecord()
|
|
127
|
+
} else {
|
|
128
|
+
addRecord()
|
|
129
|
+
}
|
|
130
|
+
$toast.success('Data saved successfully', {position: 'top-right'})
|
|
131
|
+
}).catch(error => {
|
|
132
|
+
$toast.error('Failed to save data ' + error.message, {position: 'top-right'})
|
|
133
|
+
})
|
|
134
|
+
loading.value = false;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const reset = () => {
|
|
139
|
+
// @ts-ignore
|
|
140
|
+
formRef.value?.reset()
|
|
141
|
+
formData.value = {
|
|
142
|
+
id: 0,
|
|
143
|
+
name: '',
|
|
144
|
+
item: null,
|
|
145
|
+
paid: false,
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
const resetValidation = () => {
|
|
151
|
+
// @ts-ignore
|
|
152
|
+
formRef.value?.resetValidation()
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
</script>
|
|
157
|
+
|
|
158
|
+
<template>
|
|
159
|
+
<v-container>
|
|
160
|
+
<v-row justify="center" class="ma-2">
|
|
161
|
+
<v-col cols="auto">
|
|
162
|
+
<v-card class="rounded-xl pa-4"
|
|
163
|
+
:class="`bg-grey-${theme.current.value.dark ? 'darken' : 'lighten'}-4`">
|
|
164
|
+
<v-card-title>
|
|
165
|
+
<v-row>
|
|
166
|
+
<v-col cols="2">
|
|
167
|
+
<v-btn class="text-none" variant="plain" size="large" prepend-icon="mdi-history"
|
|
168
|
+
@click.stop="showAuditTimeline">
|
|
169
|
+
<change-history :loading-history="loadingTimeLine" :audit-time-line="auditTimeLine"/>
|
|
170
|
+
</v-btn>
|
|
171
|
+
</v-col>
|
|
172
|
+
<v-col cols="8"><h3 class="text-center">Simple Form</h3></v-col>
|
|
173
|
+
<v-col cols="2" class="text-right text-body-1">
|
|
174
|
+
ID: {{ formData.id }}
|
|
175
|
+
</v-col>
|
|
176
|
+
</v-row>
|
|
177
|
+
</v-card-title>
|
|
178
|
+
<v-card-item>
|
|
179
|
+
<v-form ref="form">
|
|
180
|
+
<v-text-field
|
|
181
|
+
v-model="formData.name"
|
|
182
|
+
:counter="10"
|
|
183
|
+
label="Name"
|
|
184
|
+
required
|
|
185
|
+
:rules="nameRules"
|
|
186
|
+
/>
|
|
187
|
+
|
|
188
|
+
<v-select
|
|
189
|
+
v-model="formData.item"
|
|
190
|
+
:items="items"
|
|
191
|
+
label="Item"
|
|
192
|
+
required
|
|
193
|
+
:rules="[v => !!v || 'Item is required']"
|
|
194
|
+
/>
|
|
195
|
+
|
|
196
|
+
<v-checkbox
|
|
197
|
+
hide-details
|
|
198
|
+
v-model="formData.paid"
|
|
199
|
+
label="Paid?"
|
|
200
|
+
/>
|
|
201
|
+
|
|
202
|
+
<v-progress-linear
|
|
203
|
+
v-if="loading"
|
|
204
|
+
class="mb-4"
|
|
205
|
+
color="light-green-darken-4"
|
|
206
|
+
height="10"
|
|
207
|
+
indeterminate
|
|
208
|
+
striped
|
|
209
|
+
></v-progress-linear>
|
|
210
|
+
|
|
211
|
+
<div class="d-flex flex-column mx-auto" style="width: 70%">
|
|
212
|
+
<v-btn
|
|
213
|
+
block
|
|
214
|
+
class="mt-4"
|
|
215
|
+
color="success"
|
|
216
|
+
@click="validate"
|
|
217
|
+
>
|
|
218
|
+
Validate and Save
|
|
219
|
+
</v-btn>
|
|
220
|
+
|
|
221
|
+
<v-btn
|
|
222
|
+
block
|
|
223
|
+
class="mt-4"
|
|
224
|
+
color="error"
|
|
225
|
+
@click="reset"
|
|
226
|
+
>
|
|
227
|
+
Reset Form
|
|
228
|
+
</v-btn>
|
|
229
|
+
|
|
230
|
+
<v-btn
|
|
231
|
+
block
|
|
232
|
+
class="mt-4"
|
|
233
|
+
color="success"
|
|
234
|
+
@click="reset"
|
|
235
|
+
>
|
|
236
|
+
New Record
|
|
237
|
+
</v-btn>
|
|
238
|
+
|
|
239
|
+
<v-btn v-if="formData.id > 0"
|
|
240
|
+
block
|
|
241
|
+
class="mt-4"
|
|
242
|
+
color="secondary"
|
|
243
|
+
@click="deleteRecord"
|
|
244
|
+
>
|
|
245
|
+
Delete
|
|
246
|
+
</v-btn>
|
|
247
|
+
<v-btn class="mt-4" color="secondary" prepend-icon="mdi-history" @click.stop="userAudit" block> User
|
|
248
|
+
Audit
|
|
249
|
+
<change-history :loading-history="loadingTimeLine" :audit-time-line="auditTimeLine"/>
|
|
250
|
+
</v-btn>
|
|
251
|
+
</div>
|
|
252
|
+
|
|
253
|
+
</v-form>
|
|
254
|
+
</v-card-item>
|
|
255
|
+
</v-card>
|
|
256
|
+
</v-col>
|
|
257
|
+
<v-col cols="auto">
|
|
258
|
+
<v-table
|
|
259
|
+
class="mt-10"
|
|
260
|
+
height="300px"
|
|
261
|
+
fixed-header
|
|
262
|
+
>
|
|
263
|
+
<thead>
|
|
264
|
+
<tr>
|
|
265
|
+
<th class="text-left">
|
|
266
|
+
ID
|
|
267
|
+
</th>
|
|
268
|
+
<th class="text-left">
|
|
269
|
+
Name
|
|
270
|
+
</th>
|
|
271
|
+
<th class="text-left">
|
|
272
|
+
Item
|
|
273
|
+
</th>
|
|
274
|
+
<th class="text-left">
|
|
275
|
+
Paid
|
|
276
|
+
</th>
|
|
277
|
+
</tr>
|
|
278
|
+
</thead>
|
|
279
|
+
<tbody>
|
|
280
|
+
<tr
|
|
281
|
+
v-for="item in formDataList"
|
|
282
|
+
:key="item.id"
|
|
283
|
+
class="cursor-pointer"
|
|
284
|
+
@click="formData = item"
|
|
285
|
+
>
|
|
286
|
+
<td>{{ item.id }}</td>
|
|
287
|
+
<td>{{ item.name }}</td>
|
|
288
|
+
<td>{{ item.item }}</td>
|
|
289
|
+
<td>{{ item.paid }}</td>
|
|
290
|
+
</tr>
|
|
291
|
+
</tbody>
|
|
292
|
+
</v-table>
|
|
293
|
+
</v-col>
|
|
294
|
+
</v-row>
|
|
295
|
+
</v-container>
|
|
296
|
+
</template>
|
|
297
|
+
<style scoped>
|
|
298
|
+
|
|
299
|
+
</style>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row justify="center" class="ma-2">
|
|
3
|
+
<v-col cols="auto">
|
|
4
|
+
<v-card class="pa-2"
|
|
5
|
+
variant="outlined"
|
|
6
|
+
flat
|
|
7
|
+
>
|
|
8
|
+
<v-card-title class="text-center">Invoice Home Page</v-card-title>
|
|
9
|
+
<v-card-text> Remove this welcome card and add your own content.</v-card-text>
|
|
10
|
+
</v-card>
|
|
11
|
+
</v-col>
|
|
12
|
+
</v-row>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<style scoped>
|
|
16
|
+
|
|
17
|
+
</style>
|
|
18
|
+
<script setup lang="ts">
|
|
19
|
+
</script>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {Button, Tree} from 'primevue'
|
|
2
|
+
import vuetify from './vuetify'
|
|
3
|
+
import pinia from '../stores'
|
|
4
|
+
import router from '../router'
|
|
5
|
+
import PrimeVue from 'primevue/config'
|
|
6
|
+
import 'primeicons/primeicons.css'
|
|
7
|
+
import Aura from '@primevue/themes/aura'
|
|
8
|
+
import 'ucsd-its-frontend/style.css'
|
|
9
|
+
|
|
10
|
+
import type {App} from 'vue'
|
|
11
|
+
import {UcsdPlugin} from "ucsd-its-frontend";
|
|
12
|
+
import {ucsdAppConfig} from "../config/ucsd.config";
|
|
13
|
+
|
|
14
|
+
import {library} from '@fortawesome/fontawesome-svg-core'
|
|
15
|
+
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome'
|
|
16
|
+
import {fas} from '@fortawesome/free-solid-svg-icons'
|
|
17
|
+
import {far} from '@fortawesome/free-regular-svg-icons'
|
|
18
|
+
import ToastPlugin from 'vue-toast-notification';
|
|
19
|
+
|
|
20
|
+
import 'vue-toast-notification/dist/theme-bootstrap.css';
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
export function registerPlugins(app: App) {
|
|
24
|
+
library.add(fas) // Include needed solid icons
|
|
25
|
+
library.add(far) // Include needed regular icons
|
|
26
|
+
app
|
|
27
|
+
.use(vuetify)
|
|
28
|
+
.use(router)
|
|
29
|
+
.use(pinia)
|
|
30
|
+
.use(PrimeVue, {
|
|
31
|
+
theme: {
|
|
32
|
+
preset: Aura,
|
|
33
|
+
options: {
|
|
34
|
+
darkModeSelector: '.my-app-dark',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
})
|
|
38
|
+
.use(ToastPlugin)
|
|
39
|
+
.use(UcsdPlugin, {ucsdAppConfig})
|
|
40
|
+
.component('Button', Button)
|
|
41
|
+
.component('Tree', Tree)
|
|
42
|
+
.component('font-awesome-icon', FontAwesomeIcon)
|
|
43
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import routes from "./routes";
|
|
2
|
+
import {createRouter, createWebHistory} from "vue-router";
|
|
3
|
+
import {CommonRoutes, registerGlobalGuards} from "ucsd-its-frontend";
|
|
4
|
+
|
|
5
|
+
const router = createRouter({
|
|
6
|
+
history: createWebHistory(import.meta.env.BASE_URL),
|
|
7
|
+
routes
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
//Client app begin
|
|
11
|
+
CommonRoutes.forEach((route) => {
|
|
12
|
+
router.addRoute(route);
|
|
13
|
+
});
|
|
14
|
+
registerGlobalGuards(router);
|
|
15
|
+
//Client app end
|
|
16
|
+
|
|
17
|
+
export default router
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type {RouteRecordRaw} from "vue-router";
|
|
2
|
+
|
|
3
|
+
const routes: Array<RouteRecordRaw> = [
|
|
4
|
+
{
|
|
5
|
+
path: '/admin',
|
|
6
|
+
name: 'Admin',
|
|
7
|
+
component: () => import( '../pages/admin/AdminPage.vue'),
|
|
8
|
+
meta: { requiresAuth: true, roles: ['admin'] }
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
path: '/',
|
|
12
|
+
name: 'Home',
|
|
13
|
+
component: () => import( '../pages/Home.vue'),
|
|
14
|
+
meta: { /* pageHeader and pageSubHeader is optional */
|
|
15
|
+
pageHeader: 'Main Header'
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
path: '/dashboard',
|
|
20
|
+
name: 'Dashboard',
|
|
21
|
+
component: () => import( '../pages/DashBoard.vue'),
|
|
22
|
+
meta: { requiresAuth: true }
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
path: '/customer/home',
|
|
26
|
+
name: 'CustomerHome',
|
|
27
|
+
component: () => import( '../pages/customer/CustomerHome.vue'),
|
|
28
|
+
meta: { requiresAuth: true }
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
path: '/customer/search',
|
|
32
|
+
name: 'CustomerSearch',
|
|
33
|
+
component: () => import( '../pages/customer/CustomerSearch.vue'),
|
|
34
|
+
meta: { requiresAuth: true }
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
path: '/customer/create',
|
|
38
|
+
name: 'CustomerCreate',
|
|
39
|
+
component: () => import( '../pages/customer/SimpleForm.vue'),
|
|
40
|
+
meta: { requiresAuth: true }
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
path: '/invoices/home',
|
|
44
|
+
name: 'InvoiceHome',
|
|
45
|
+
component: () => import( '../pages/invoices/InvoiceHome.vue'),
|
|
46
|
+
meta: { requiresAuth: true }
|
|
47
|
+
}
|
|
48
|
+
];
|
|
49
|
+
export default routes;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import {defineStore} from 'pinia'
|
|
2
|
+
import {ref} from 'vue'
|
|
3
|
+
import type {Audit, AuditDetail} from "ucsd-its-frontend";
|
|
4
|
+
import {useUcsdAppUtils} from "ucsd-its-frontend";
|
|
5
|
+
import axios from "axios";
|
|
6
|
+
import {useItsAuthStore} from "ucsd-its-frontend";
|
|
7
|
+
import type {LoginUser} from "ucsd-its-frontend";
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export const useAppStore = defineStore('app', () => {
|
|
11
|
+
const appUtils = useUcsdAppUtils();
|
|
12
|
+
const authStore = useItsAuthStore();
|
|
13
|
+
const invoiceCount = ref('10');
|
|
14
|
+
|
|
15
|
+
const initializeStore = () => {
|
|
16
|
+
console.log('Initializing store')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const fetchRoles = async () : Promise<{user:LoginUser,path:string}> => {
|
|
20
|
+
try {
|
|
21
|
+
const response = await axios.get(import.meta.env.VITE_USER_ROLES_API_URL, {
|
|
22
|
+
headers: {
|
|
23
|
+
Authorization: `Bearer ${authStore.decryptedToken()}`
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
const apiData = response.data[0];
|
|
27
|
+
const loginUser = {
|
|
28
|
+
id: apiData.PERSON_ID,
|
|
29
|
+
email: apiData.EMAIL_ADDRESS,
|
|
30
|
+
firstName: '',
|
|
31
|
+
lastName: '',
|
|
32
|
+
roles: apiData.OFC_ROLES.split(','),
|
|
33
|
+
departmentName: apiData.DEPARTMENT_NAME,
|
|
34
|
+
businessUnitName: apiData.BUSINESS_UNIT_NAME,
|
|
35
|
+
system18Id: apiData.SYSTEM18_ID
|
|
36
|
+
} as LoginUser
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
resolve({user: loginUser,path:'/'})
|
|
39
|
+
})
|
|
40
|
+
} catch (error) {
|
|
41
|
+
throw error
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const auditRecord = { // default audit record. Change this based on your domain
|
|
46
|
+
auditId: 0,
|
|
47
|
+
event: 'Update',
|
|
48
|
+
eventIcon: '',
|
|
49
|
+
nameSpace: 'edu.ucsd.its.fis.ciperb',
|
|
50
|
+
auditConstituent : {
|
|
51
|
+
constituentCode: 'Financial Information Systems',
|
|
52
|
+
},
|
|
53
|
+
details: [
|
|
54
|
+
{
|
|
55
|
+
detailKey: "0",
|
|
56
|
+
detailValue: '',
|
|
57
|
+
} as AuditDetail
|
|
58
|
+
]
|
|
59
|
+
} as Audit;
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
const getAuditRecord = () : Audit => {
|
|
63
|
+
return <Audit>appUtils.deepClone(auditRecord)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
invoiceCount,
|
|
69
|
+
getAuditRecord,
|
|
70
|
+
initializeStore,
|
|
71
|
+
fetchRoles
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
})
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import {defineConfig, loadEnv} from 'vite'
|
|
2
|
+
import vuetify, {transformAssetUrls} from "vite-plugin-vuetify";
|
|
3
|
+
import dts from "vite-plugin-dts";
|
|
4
|
+
import Vue from "@vitejs/plugin-vue";
|
|
5
|
+
import Vuetify from "vite-plugin-vuetify";
|
|
6
|
+
import path from 'path';
|
|
7
|
+
|
|
8
|
+
export default defineConfig(({command, mode}) => {
|
|
9
|
+
const env = loadEnv(mode, process.cwd(), '')
|
|
10
|
+
const VITE_BASE_URL = env.VITE_BASE_URL || '';
|
|
11
|
+
console.log('Asset URL: ' + VITE_BASE_URL);
|
|
12
|
+
console.log('Mode:' + mode)
|
|
13
|
+
console.log('Command:' + command)
|
|
14
|
+
if (command === 'serve') {
|
|
15
|
+
return { // dev specific config
|
|
16
|
+
server: {
|
|
17
|
+
proxy: {
|
|
18
|
+
'/api': {
|
|
19
|
+
target: 'http://localhost:8080',
|
|
20
|
+
changeOrigin: true,
|
|
21
|
+
rewrite: (path) => {
|
|
22
|
+
const newPath = path.replace(/^\//, '');
|
|
23
|
+
console.log("Rewritten API URL: ", newPath);
|
|
24
|
+
return newPath;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
resolve: {
|
|
30
|
+
alias: {
|
|
31
|
+
'@': path.resolve(__dirname, './src'),
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
plugins: [
|
|
35
|
+
Vue({
|
|
36
|
+
template: { transformAssetUrls: transformAssetUrls },
|
|
37
|
+
}),
|
|
38
|
+
Vuetify({
|
|
39
|
+
autoImport: true,
|
|
40
|
+
styles: {
|
|
41
|
+
configFile: 'src/styles/settings.scss',
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
],
|
|
45
|
+
}
|
|
46
|
+
} else { // command === 'build'
|
|
47
|
+
return {
|
|
48
|
+
plugins: [ Vue({
|
|
49
|
+
isProduction: true,
|
|
50
|
+
template: { transformAssetUrls },
|
|
51
|
+
features: { propsDestructure : true}
|
|
52
|
+
}
|
|
53
|
+
), vuetify({ styles: 'none' }),
|
|
54
|
+
dts({exclude: ['node_modules','dist','.storybook']})],
|
|
55
|
+
resolve: {
|
|
56
|
+
alias: {
|
|
57
|
+
'@': path.resolve(__dirname, './src'),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
build: {
|
|
61
|
+
assetsInlineLimit: 0, // Prevent inlining images as Base64
|
|
62
|
+
minify: true,
|
|
63
|
+
emptyOutDir: true,
|
|
64
|
+
target: 'esnext',
|
|
65
|
+
modulePreload: {polyfill: false},
|
|
66
|
+
rollupOptions: {
|
|
67
|
+
output: {
|
|
68
|
+
assetFileNames: 'assets/[name].[hash][extname]'
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
base: `${VITE_BASE_URL}`
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
})
|