@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.
Files changed (87) hide show
  1. package/README.md +4 -0
  2. package/dist/CommonRoutes.d.ts +7 -0
  3. package/dist/UcsdPlugin.d.ts +9 -0
  4. package/dist/assets/dark_bg.webp +0 -0
  5. package/dist/assets/light_dock_bg.jpg +0 -0
  6. package/dist/assets/settings.icns +0 -0
  7. package/dist/assets/settings.png +0 -0
  8. package/dist/assets/ucsd-its-frontend.css +1 -0
  9. package/dist/assets/ucsd_logo.png +0 -0
  10. package/dist/assets/ucsd_logo_white.png +0 -0
  11. package/dist/cli.cjs +73 -0
  12. package/dist/components/TileButton.vue.d.ts +113 -0
  13. package/dist/components/authorization/Login.vue.d.ts +2 -0
  14. package/dist/components/authorization/LoginSuccess.vue.d.ts +2 -0
  15. package/dist/components/authorization/Logout.vue.d.ts +2 -0
  16. package/dist/components/authorization/Unauthorized.vue.d.ts +2 -0
  17. package/dist/components/commons/ChangeHistory.vue.d.ts +54 -0
  18. package/dist/components/commons/ProgressDialog.vue.d.ts +2 -0
  19. package/dist/composables/auditLog.d.ts +25 -0
  20. package/dist/composables/layout.d.ts +19 -0
  21. package/dist/composables/utils/ucsdAppUtils.d.ts +15 -0
  22. package/dist/index.d.ts +31 -0
  23. package/dist/layouts/AppLayout.vue.d.ts +2 -0
  24. package/dist/layouts/DefaultLayout.vue.d.ts +20 -0
  25. package/dist/layouts/FixedLayout.vue.d.ts +20 -0
  26. package/dist/layouts/FloatingLayout.vue.d.ts +2 -0
  27. package/dist/layouts/UcsdFooter.vue.d.ts +2 -0
  28. package/dist/layouts/UcsdHeader.vue.d.ts +23 -0
  29. package/dist/layouts/UserPanel.vue.d.ts +2 -0
  30. package/dist/layouts/menu/FloatMenu.vue.d.ts +2 -0
  31. package/dist/layouts/menu/RailMenu.vue.d.ts +24 -0
  32. package/dist/layouts/menu/TopMenu.vue.d.ts +12 -0
  33. package/dist/main.css +63 -0
  34. package/dist/stores/its-app.d.ts +336 -0
  35. package/dist/stores/its-audit.d.ts +184 -0
  36. package/dist/stores/its-auth.d.ts +169 -0
  37. package/dist/templates/.env +9 -0
  38. package/dist/templates/App.vue +17 -0
  39. package/dist/templates/config/ucsd.config.ts +105 -0
  40. package/dist/templates/index.html +17 -0
  41. package/dist/templates/main.ts +6 -0
  42. package/dist/templates/pages/DashBoard.vue +29 -0
  43. package/dist/templates/pages/Home.vue +20 -0
  44. package/dist/templates/pages/admin/AdminPage.vue +19 -0
  45. package/dist/templates/pages/customer/CustomerHome.vue +19 -0
  46. package/dist/templates/pages/customer/CustomerSearch.vue +21 -0
  47. package/dist/templates/pages/customer/SimpleForm.vue +299 -0
  48. package/dist/templates/pages/invoices/InvoiceHome.vue +19 -0
  49. package/dist/templates/plugins/index.ts +43 -0
  50. package/dist/templates/plugins/vuetify.ts +9 -0
  51. package/dist/templates/router/index.ts +17 -0
  52. package/dist/templates/router/routes.ts +49 -0
  53. package/dist/templates/stores/app.ts +74 -0
  54. package/dist/templates/stores/index.ts +9 -0
  55. package/dist/templates/styles/README.md +3 -0
  56. package/dist/templates/styles/settings.scss +10 -0
  57. package/dist/templates/vite.config.ts +75 -0
  58. package/dist/types/ApiError.d.ts +6 -0
  59. package/dist/types/LoginUser.d.ts +12 -0
  60. package/dist/types/TileRecord.d.ts +41 -0
  61. package/dist/types/UcsdConfig.d.ts +29 -0
  62. package/dist/types/audit.d.ts +57 -0
  63. package/dist/ucsd-its-frontend.js +13251 -0
  64. package/dist/ucsd-its-frontend.umd.cjs +345 -0
  65. package/dist/vite.svg +1 -0
  66. package/package.json +109 -0
  67. package/src/lib/templates/.env +9 -0
  68. package/src/lib/templates/App.vue +17 -0
  69. package/src/lib/templates/config/ucsd.config.ts +105 -0
  70. package/src/lib/templates/index.html +17 -0
  71. package/src/lib/templates/main.ts +6 -0
  72. package/src/lib/templates/pages/DashBoard.vue +29 -0
  73. package/src/lib/templates/pages/Home.vue +20 -0
  74. package/src/lib/templates/pages/admin/AdminPage.vue +19 -0
  75. package/src/lib/templates/pages/customer/CustomerHome.vue +19 -0
  76. package/src/lib/templates/pages/customer/CustomerSearch.vue +21 -0
  77. package/src/lib/templates/pages/customer/SimpleForm.vue +299 -0
  78. package/src/lib/templates/pages/invoices/InvoiceHome.vue +19 -0
  79. package/src/lib/templates/plugins/index.ts +43 -0
  80. package/src/lib/templates/plugins/vuetify.ts +9 -0
  81. package/src/lib/templates/router/index.ts +17 -0
  82. package/src/lib/templates/router/routes.ts +49 -0
  83. package/src/lib/templates/stores/app.ts +74 -0
  84. package/src/lib/templates/stores/index.ts +9 -0
  85. package/src/lib/templates/styles/README.md +3 -0
  86. package/src/lib/templates/styles/settings.scss +10 -0
  87. package/src/lib/templates/vite.config.ts +75 -0
@@ -0,0 +1,9 @@
1
+ VITE_APP_VERSION=1.0.0
2
+ VITE_APP_TITLE='UCSD Vue App'
3
+ VITE_DEFAULT_HEADER='My Application Header'
4
+ VITE_DEFAULT_SUB_HEADER='My Sub Header'
5
+ VITE_CLIENT_ID='From API manager'
6
+ VITE_CLIENT_SECRET='From API manager'
7
+ VITE_AUTH_URL='https://api-qa.ucsd.edu/oauth2/authorize'
8
+ VITE_ACCESS_TOKEN_URL='https://api-qa.ucsd.edu/oauth2/token'
9
+ VITE_USER_ROLES_API_URL='https://api-qa.ucsd.edu:8243/OFC-PPM-Data-DEV5/v1/login-user'
@@ -0,0 +1,17 @@
1
+ <script setup lang="ts">
2
+ import {AppLayout} from "ucsd-its-frontend";
3
+ import {useItsAppStore} from "ucsd-its-frontend";
4
+ import {ProgressDialog} from "ucsd-its-frontend";
5
+ const itsAppStore = useItsAppStore();
6
+ </script>
7
+
8
+ <template>
9
+ <v-app id="app" :theme="itsAppStore.currentTheme">
10
+ <ProgressDialog />
11
+ <AppLayout />
12
+ </v-app>
13
+ </template>
14
+
15
+ <style scoped>
16
+
17
+ </style>
@@ -0,0 +1,105 @@
1
+ import type {TileRecord} from "ucsd-its-frontend";
2
+ import {useAppStore} from "../stores/app";
3
+ import type {UcsdConfig} from "ucsd-its-frontend";
4
+ /**
5
+ * Configuration object for the UCSD Application.
6
+ *
7
+ * Provides details related to the application layout, menus, themes, and default settings.
8
+ * Supports nested menu structures and dynamic behaviors.
9
+ *
10
+ * @type {object}
11
+ * @property {string} defaultLayout - The default layout type for the application. Possible values include 'Floating' or other layout types defined in the application.
12
+ * @property {string} defaultPageHdr - The default page header text for the application.
13
+ * @property {string} defaultSubHdr - The default sub-header text for the application.
14
+ * @property {string} defaultTheme - The default theme for the application, e.g., 'dark'.
15
+ * @property {TileRecord} rootMenu - The root-level menu configuration, containing metadata such as label, value, icon, etc.
16
+ * @property {Array.<TileRecord>} menus - A list of menu items and their hierarchies. Each menu item can have nested children, actions, links, icons, and dynamic behaviors.
17
+ */
18
+ export const ucsdAppConfig : UcsdConfig = {
19
+ defaultLayout: 'Fixed',
20
+ defaultPageHdr: 'Main Title',
21
+ defaultSubHdr: 'Sub Title',
22
+ initCallback : () => useAppStore().initializeStore(),
23
+ loginCallback: () => useAppStore().fetchRoles(),
24
+ defaultTheme: 'dark',
25
+ rootMenu : {
26
+ label: 'Home',
27
+ key : '0-0',
28
+ icon : 'mdi-home',
29
+ disabled: false,
30
+ buttonColor: 'purple',
31
+ link: '/',
32
+ active: true,
33
+ children: []
34
+ } as TileRecord,
35
+ menus: [
36
+ {
37
+ label: 'Customer',
38
+ key : '0-1',
39
+ icon : 'mdi-account',
40
+ disabled: false,
41
+ buttonColor: 'purple',
42
+ link: '/customer/home',
43
+ active: false,
44
+ children: [
45
+ {
46
+ label: 'Search Customer',
47
+ key : '0-1-0',
48
+ icon : 'mdi-magnify',
49
+ disabled: false,
50
+ buttonColor: 'purple',
51
+ link: '/customer/search',
52
+ active: false,
53
+ },
54
+ {
55
+ label: 'Manage Customer',
56
+ key : '0-1-1',
57
+ icon : 'mdi-folder-account-outline',
58
+ disabled: false,
59
+ buttonColor: 'purple',
60
+ active: false,
61
+ children : [
62
+ {
63
+ label: 'Create Customer',
64
+ key : '0-1-1-0',
65
+ icon : 'mdi-account-plus',
66
+ disabled: false,
67
+ buttonColor: 'purple',
68
+ link: '/customer/create',
69
+ active: false,
70
+ }
71
+ ]
72
+ }
73
+ ]
74
+ },
75
+ {
76
+ label: 'Invoices',
77
+ key : '0-2',
78
+ icon : 'mdi-text-box',
79
+ disabled: false,
80
+ buttonColor: 'purple',
81
+ link: '/invoices/home',
82
+ badgeContent: () => {return useAppStore().invoiceCount},
83
+ active: false,
84
+ },
85
+ {
86
+ label: 'Admin',
87
+ key : '0-3',
88
+ icon : 'mdi-shield-account',
89
+ disabled: false,
90
+ buttonColor: 'purple',
91
+ link: '/admin',
92
+ active: false,
93
+ },
94
+ {
95
+ label: 'Help',
96
+ key : '0-4',
97
+ icon: 'mdi-help',
98
+ buttonColor: 'purple',
99
+ disabled: false,
100
+ link: 'https://blink.ucsd.edu/finance/billing/get-started/training/ciperb/index.html',
101
+ active: false,
102
+ }
103
+ ] as Array<TileRecord>
104
+ }
105
+
@@ -0,0 +1,17 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vue-toast-notification@3.1.3/dist/theme-bootstrap.min.css">
8
+ <link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
9
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify@3.7.6/dist/vuetify.min.css">
10
+ <style data-primevue-style-id="dock-variables">:root{--p-dock-background:rgba(255,255,255,0.1);--p-dock-border-color:rgba(255,255,255,0.2);--p-dock-padding:0.5rem;--p-dock-border-radius:var(--p-border-radius-xl);--p-dock-item-border-radius:var(--p-content-border-radius);--p-dock-item-padding:0.5rem;--p-dock-item-size:3rem;--p-dock-item-focus-ring-width:var(--p-focus-ring-width);--p-dock-item-focus-ring-style:var(--p-focus-ring-style);--p-dock-item-focus-ring-color:var(--p-focus-ring-color);--p-dock-item-focus-ring-offset:var(--p-focus-ring-offset);--p-dock-item-focus-ring-shadow:var(--p-focus-ring-shadow);}</style>
11
+ <title>I am client</title>
12
+ </head>
13
+ <body>
14
+ <div id="app"></div>
15
+ <script type="module" src="/src/main.ts"></script>
16
+ </body>
17
+ </html>
@@ -0,0 +1,6 @@
1
+ import { createApp } from 'vue'
2
+ import App from './App.vue'
3
+ import {registerPlugins} from "./plugins";
4
+ const app = createApp(App)
5
+ registerPlugins(app)
6
+ app.mount('#app')
@@ -0,0 +1,29 @@
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">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-col cols="auto">
13
+ <v-card class="pa-2"
14
+ variant="elevated"
15
+ flat
16
+ >
17
+ <v-card-title class="text-center">Dashboard</v-card-title>
18
+ <v-card-text> Remove this welcome card and add your own content.</v-card-text>
19
+ <v-card-actions><v-btn variant="elevated" color="info">Submit</v-btn></v-card-actions>
20
+ </v-card>
21
+ </v-col>
22
+ </v-row>
23
+ </template>
24
+
25
+ <style scoped>
26
+
27
+ </style>
28
+ <script setup lang="ts">
29
+ </script>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <v-row justify="center" class="ma-2">
3
+ <v-col cols="auto">
4
+ <v-card class="pa-2"
5
+ variant="elevated"
6
+ flat
7
+ >
8
+ <v-card-title class="text-center">Home Page</v-card-title>
9
+ <v-card-text> Remove this welcome card and add your own content.</v-card-text>
10
+ <v-card-actions><v-btn variant="elevated" color="info">Submit</v-btn></v-card-actions>
11
+ </v-card>
12
+ </v-col>
13
+ </v-row>
14
+ </template>
15
+
16
+ <style scoped>
17
+
18
+ </style>
19
+ <script setup lang="ts">
20
+ </script>
@@ -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">Admin page</v-card-title>
9
+ <v-card-text>Protected by role</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,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">Customer 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,21 @@
1
+ <template>
2
+ <v-container fluid>
3
+ <v-row justify="center" class="ma-2">
4
+ <v-col cols="auto">
5
+ <v-card class="pa-2"
6
+ variant="outlined"
7
+ flat
8
+ >
9
+ <v-card-title class="text-center">Customer Search Page</v-card-title>
10
+ <v-card-text> Remove this welcome card and add your own content.</v-card-text>
11
+ </v-card>
12
+ </v-col>
13
+ </v-row>
14
+ </v-container>
15
+ </template>
16
+
17
+ <style scoped>
18
+
19
+ </style>
20
+ <script setup lang="ts">
21
+ </script>
@@ -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,9 @@
1
+ import '@mdi/font/css/materialdesignicons.css'
2
+ import '@fortawesome/fontawesome-free/css/all.css'
3
+ import 'vuetify/styles/main.css'
4
+ import { createVuetify } from 'vuetify'
5
+ export default createVuetify({
6
+ theme: {
7
+ defaultTheme: 'dark',
8
+ }
9
+ })
@@ -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