@nuxt-customer-portal/timesheets 0.8.9 → 0.10.0
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/CHANGELOG.md +35 -0
- package/app/components/TimesheetsAdminApprovals.vue +1 -1
- package/app/components/TimesheetsClientSettingsPanel.vue +2 -2
- package/app/components/TimesheetsReviewRequests.vue +12 -5
- package/app/composables/useTimesheets.ts +71 -50
- package/app/composables/useTimesheetsAdminList.ts +1 -1
- package/app/pages/timesheets/client.vue +4 -3
- package/app/pages/timesheets/index.vue +9 -6
- package/app/pages/timesheets/suppliers.vue +4 -3
- package/app/plugins/timesheets-feature.ts +1 -1
- package/package.json +5 -5
- package/portal.manifest.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @nuxt-customer-portal/timesheets
|
|
2
2
|
|
|
3
|
+
## 0.10.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [2e267be]
|
|
8
|
+
- Updated dependencies [f115496]
|
|
9
|
+
- Updated dependencies [1235d0f]
|
|
10
|
+
- Updated dependencies [d25ff2e]
|
|
11
|
+
- Updated dependencies [1235d0f]
|
|
12
|
+
- @nuxt-customer-portal/organizations@0.10.0
|
|
13
|
+
- @nuxt-customer-portal/core@0.10.0
|
|
14
|
+
- @nuxt-customer-portal/ui@0.10.0
|
|
15
|
+
- @nuxt-customer-portal/clients@0.10.0
|
|
16
|
+
|
|
17
|
+
## 0.9.1
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Avoid generated API route type-inference limits when refreshing timesheet navigation capabilities in hosts with many routes. Release verification no longer forces Nuxt modules to use an older incompatible Nuxt Kit version.
|
|
22
|
+
- @nuxt-customer-portal/clients@0.9.1
|
|
23
|
+
- @nuxt-customer-portal/core@0.9.1
|
|
24
|
+
- @nuxt-customer-portal/organizations@0.9.1
|
|
25
|
+
- @nuxt-customer-portal/ui@0.9.1
|
|
26
|
+
|
|
27
|
+
## 0.9.0
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- Updated dependencies [936f0a2]
|
|
32
|
+
- Updated dependencies [6696fd0]
|
|
33
|
+
- @nuxt-customer-portal/core@0.9.0
|
|
34
|
+
- @nuxt-customer-portal/ui@0.9.0
|
|
35
|
+
- @nuxt-customer-portal/clients@0.9.0
|
|
36
|
+
- @nuxt-customer-portal/organizations@0.9.0
|
|
37
|
+
|
|
3
38
|
## 0.8.9
|
|
4
39
|
|
|
5
40
|
### Patch Changes
|
|
@@ -137,7 +137,7 @@ const requestApproval = async (submissionId: string, clientOrganizationId: strin
|
|
|
137
137
|
}
|
|
138
138
|
busy.value = true
|
|
139
139
|
try {
|
|
140
|
-
await $fetch(`/api/timesheets/submissions/${submissionId}/request-client-approval`, {
|
|
140
|
+
await $fetch<unknown, string>(`/api/timesheets/submissions/${submissionId}/request-client-approval`, {
|
|
141
141
|
method: 'POST',
|
|
142
142
|
body: { clientOrganizationId, message: requestState.message }
|
|
143
143
|
})
|
|
@@ -15,7 +15,7 @@ const schema = z.object({
|
|
|
15
15
|
accessMode: z.enum(['DISABLED', 'VIEW', 'REVIEW']),
|
|
16
16
|
reviewInterval: z.enum(['WEEKLY', 'TWO_WEEKLY', 'MONTHLY'])
|
|
17
17
|
})
|
|
18
|
-
const { data } = await useFetch<ClientTimesheetSettingsDto>(
|
|
18
|
+
const { data } = await useFetch<ClientTimesheetSettingsDto, import('#app').NuxtError<unknown>, string>(
|
|
19
19
|
`/api/timesheets/admin/client-settings/${props.client.organizationId}`
|
|
20
20
|
)
|
|
21
21
|
if (data.value) {
|
|
@@ -24,7 +24,7 @@ if (data.value) {
|
|
|
24
24
|
const save = async () => {
|
|
25
25
|
busy.value = true
|
|
26
26
|
try {
|
|
27
|
-
data.value = await $fetch<ClientTimesheetSettingsDto>(
|
|
27
|
+
data.value = await $fetch<ClientTimesheetSettingsDto, string>(
|
|
28
28
|
`/api/timesheets/admin/client-settings/${props.client.organizationId}`,
|
|
29
29
|
{
|
|
30
30
|
method: 'PUT',
|
|
@@ -8,7 +8,11 @@ const route = useRoute()
|
|
|
8
8
|
const toast = useToast()
|
|
9
9
|
const prefix = 'features.timesheets.reviewPeriods.'
|
|
10
10
|
const endpoint = computed(() => `/api/timesheets/${props.clientSide ? 'client' : 'admin'}/review-requests`)
|
|
11
|
-
const {
|
|
11
|
+
const {
|
|
12
|
+
data: requests,
|
|
13
|
+
error,
|
|
14
|
+
refresh
|
|
15
|
+
} = await useFetch<ClientReviewRequestDto[], import('#app').NuxtError<unknown>, string>(endpoint)
|
|
12
16
|
const month = ref(new Date().toLocaleDateString('sv-SE', { timeZone: 'Europe/Amsterdam' }).slice(0, 7))
|
|
13
17
|
const search = ref('')
|
|
14
18
|
const status = ref(typeof route.query.status === 'string' ? route.query.status : 'ALL')
|
|
@@ -19,7 +23,10 @@ const busy = ref(false)
|
|
|
19
23
|
const affectedRequests = ref<Array<{ id: string; clientName: string; startsOn: string; endsOn: string }>>([])
|
|
20
24
|
const loadPeriods = async () => {
|
|
21
25
|
if (!props.clientSide) {
|
|
22
|
-
const result = await $fetch
|
|
26
|
+
const result = await $fetch<{ periods: ClientReviewPeriodDto[]; startsOn: string }, string>(
|
|
27
|
+
'/api/timesheets/admin/review-periods',
|
|
28
|
+
{ query: { month: month.value } }
|
|
29
|
+
)
|
|
23
30
|
periods.value = result.periods
|
|
24
31
|
startsOn.value = result.startsOn
|
|
25
32
|
}
|
|
@@ -61,7 +68,7 @@ const submit = async () => {
|
|
|
61
68
|
busy.value = true
|
|
62
69
|
try {
|
|
63
70
|
if (action.value === 'SEND' && selectedPeriod.value) {
|
|
64
|
-
await $fetch('/api/timesheets/admin/review-requests', {
|
|
71
|
+
await $fetch<unknown, string>('/api/timesheets/admin/review-requests', {
|
|
65
72
|
method: 'POST',
|
|
66
73
|
body: { ...selectedPeriod.value, message: state.comment }
|
|
67
74
|
})
|
|
@@ -70,7 +77,7 @@ const submit = async () => {
|
|
|
70
77
|
action.value === 'WITHDRAW'
|
|
71
78
|
? `/api/timesheets/admin/review-requests/${selected.value.id}/withdraw`
|
|
72
79
|
: `/api/timesheets/client/review-requests/${selected.value.id}`
|
|
73
|
-
await $fetch(url, {
|
|
80
|
+
await $fetch<unknown, string>(url, {
|
|
74
81
|
method: 'POST',
|
|
75
82
|
body: { version: selected.value.version, action: action.value, comment: state.comment }
|
|
76
83
|
})
|
|
@@ -89,7 +96,7 @@ const submit = async () => {
|
|
|
89
96
|
const reopen = async (submissionId: string) => {
|
|
90
97
|
busy.value = true
|
|
91
98
|
try {
|
|
92
|
-
await $fetch(`/api/timesheets/admin/review-submissions/${submissionId}/reopen`, { method: 'POST' })
|
|
99
|
+
await $fetch<unknown, string>(`/api/timesheets/admin/review-submissions/${submissionId}/reopen`, { method: 'POST' })
|
|
93
100
|
affectedRequests.value = []
|
|
94
101
|
await Promise.all([refresh(), loadPeriods()])
|
|
95
102
|
toast.add({ title: t(prefix + 'reopened'), color: 'success' })
|
|
@@ -44,7 +44,7 @@ export interface OrganizationTimesheetCapabilities {
|
|
|
44
44
|
|
|
45
45
|
export const useTimesheets = () => {
|
|
46
46
|
const approvalEmailContext = (submissionId: string, clientOrganizationId?: string) =>
|
|
47
|
-
$fetch<import('@nuxt-customer-portal/timesheets/shared/types/timesheet').ApprovalEmailContextDto>(
|
|
47
|
+
$fetch<import('@nuxt-customer-portal/timesheets/shared/types/timesheet').ApprovalEmailContextDto, string>(
|
|
48
48
|
`/api/timesheets/submissions/${submissionId}/approval-email`,
|
|
49
49
|
{ query: { clientOrganizationId } }
|
|
50
50
|
)
|
|
@@ -54,7 +54,7 @@ export const useTimesheets = () => {
|
|
|
54
54
|
typeof import('@nuxt-customer-portal/timesheets/shared/approval-email').approvalEmailResendSchema
|
|
55
55
|
>
|
|
56
56
|
) =>
|
|
57
|
-
$fetch<{ sent: number; failed: number; sending: number }>(
|
|
57
|
+
$fetch<{ sent: number; failed: number; sending: number }, string>(
|
|
58
58
|
`/api/timesheets/submissions/${submissionId}/approval-email`,
|
|
59
59
|
{ method: 'POST', body: input }
|
|
60
60
|
)
|
|
@@ -66,17 +66,18 @@ export const useTimesheets = () => {
|
|
|
66
66
|
clearNuxtData('timesheets-dashboard')
|
|
67
67
|
await refreshNuxtData('timesheets-dashboard')
|
|
68
68
|
}
|
|
69
|
-
const bootstrap = (week?: string) =>
|
|
70
|
-
|
|
69
|
+
const bootstrap = (week?: string) =>
|
|
70
|
+
$fetch<TimesheetBootstrapDto, string>('/api/timesheets/bootstrap', { query: { week } })
|
|
71
|
+
const dashboard = () => $fetch<TimesheetsDashboardDto, string>('/api/timesheets/dashboard')
|
|
71
72
|
const internalApprovalQueue = (contextOnly = false) =>
|
|
72
|
-
$fetch<InternalApprovalQueueDto>('/api/timesheets/internal-approvals', { query: { contextOnly } })
|
|
73
|
+
$fetch<InternalApprovalQueueDto, string>('/api/timesheets/internal-approvals', { query: { contextOnly } })
|
|
73
74
|
const internalApprovalConfiguration = () =>
|
|
74
|
-
$fetch<InternalApprovalConfigurationDto>('/api/timesheets/admin/internal-approvals')
|
|
75
|
+
$fetch<InternalApprovalConfigurationDto, string>('/api/timesheets/admin/internal-approvals')
|
|
75
76
|
const updateInternalApprovalWorkspace = (enabled: boolean) =>
|
|
76
|
-
$fetch('/api/timesheets/admin/internal-approvals', { method: 'PATCH', body: { enabled } })
|
|
77
|
+
$fetch<unknown, string>('/api/timesheets/admin/internal-approvals', { method: 'PATCH', body: { enabled } })
|
|
77
78
|
const updateInternalApprovalMember = (userId: string, input: { required: boolean; approverUserIds: string[] }) =>
|
|
78
|
-
$fetch(`/api/timesheets/admin/internal-approvals/${userId}`, { method: 'PUT', body: input })
|
|
79
|
-
const setupStatus = () => $fetch<TimesheetsSetupStatusDto>('/api/timesheets/setup-status')
|
|
79
|
+
$fetch<unknown, string>(`/api/timesheets/admin/internal-approvals/${userId}`, { method: 'PUT', body: input })
|
|
80
|
+
const setupStatus = () => $fetch<TimesheetsSetupStatusDto, string>('/api/timesheets/setup-status')
|
|
80
81
|
|
|
81
82
|
const createEntry = (input: {
|
|
82
83
|
projectId: string
|
|
@@ -84,7 +85,7 @@ export const useTimesheets = () => {
|
|
|
84
85
|
entryDate: string
|
|
85
86
|
durationMinutes: number
|
|
86
87
|
note?: string | null
|
|
87
|
-
}) => $fetch<TimeEntryDto>('/api/timesheets/entries', { method: 'POST', body: input })
|
|
88
|
+
}) => $fetch<TimeEntryDto, string>('/api/timesheets/entries', { method: 'POST', body: input })
|
|
88
89
|
|
|
89
90
|
const updateEntry = (
|
|
90
91
|
id: string,
|
|
@@ -95,79 +96,99 @@ export const useTimesheets = () => {
|
|
|
95
96
|
durationMinutes: number
|
|
96
97
|
note: string | null
|
|
97
98
|
}>
|
|
98
|
-
) => $fetch<TimeEntryDto>(`/api/timesheets/entries/${id}`, { method: 'PATCH', body: input })
|
|
99
|
+
) => $fetch<TimeEntryDto, string>(`/api/timesheets/entries/${id}`, { method: 'PATCH', body: input })
|
|
99
100
|
|
|
100
|
-
const deleteEntry = (id: string) =>
|
|
101
|
+
const deleteEntry = (id: string) =>
|
|
102
|
+
$fetch<unknown, string>(`/api/timesheets/entries/${id}`, { method: 'DELETE' as never })
|
|
101
103
|
|
|
102
104
|
const startTimer = (input: { projectId: string; activityTypeId: string; entryDate: string; note?: string | null }) =>
|
|
103
|
-
$fetch<TimeEntryDto>('/api/timesheets/timer', { method: 'POST', body: input })
|
|
105
|
+
$fetch<TimeEntryDto, string>('/api/timesheets/timer', { method: 'POST', body: input })
|
|
104
106
|
|
|
105
|
-
const stopTimer = () => $fetch<TimeEntryDto>('/api/timesheets/timer', { method: 'DELETE' as never })
|
|
107
|
+
const stopTimer = () => $fetch<TimeEntryDto, string>('/api/timesheets/timer', { method: 'DELETE' as never })
|
|
106
108
|
|
|
107
109
|
const submitWeek = (id: string, cutoffDate: string, comment?: string) =>
|
|
108
|
-
$fetch(`/api/timesheets/weeks/${id}/submissions`, {
|
|
110
|
+
$fetch<unknown, string>(`/api/timesheets/weeks/${id}/submissions`, {
|
|
111
|
+
method: 'POST',
|
|
112
|
+
body: { cutoffDate, comment }
|
|
113
|
+
})
|
|
109
114
|
const replyClientSubmission = (id: string, clientOrganizationId: string, expectedVersion: number, reply?: string) =>
|
|
110
|
-
$fetch(`/api/timesheets/submissions/${id}/client-reply`, {
|
|
115
|
+
$fetch<unknown, string>(`/api/timesheets/submissions/${id}/client-reply`, {
|
|
111
116
|
method: 'POST',
|
|
112
117
|
body: { clientOrganizationId, expectedVersion, reply }
|
|
113
118
|
})
|
|
114
119
|
const resubmitSubmission = (id: string, reply?: string) =>
|
|
115
|
-
$fetch(`/api/timesheets/submissions/${id}/resubmit`, { method: 'POST', body: { reply } })
|
|
120
|
+
$fetch<unknown, string>(`/api/timesheets/submissions/${id}/resubmit`, { method: 'POST', body: { reply } })
|
|
116
121
|
|
|
117
122
|
const adminBootstrap = (section?: string) =>
|
|
118
|
-
$fetch<TimesheetsAdminBootstrap>('/api/timesheets/admin/bootstrap', {
|
|
123
|
+
$fetch<TimesheetsAdminBootstrap, string>('/api/timesheets/admin/bootstrap', {
|
|
124
|
+
query: section ? { section } : undefined
|
|
125
|
+
})
|
|
119
126
|
const createClient = (
|
|
120
127
|
input: { mode: 'link'; organizationId: string } | { mode: 'create'; name: string; slug: string }
|
|
121
|
-
) => $fetch('/api/timesheets/admin/clients', { method: 'POST', body: input })
|
|
128
|
+
) => $fetch<unknown, string>('/api/timesheets/admin/clients', { method: 'POST', body: input })
|
|
122
129
|
const getClientDeletionEligibility = (id: string) =>
|
|
123
|
-
$fetch<{ clientId: string; clientName: string; canDelete: boolean }>(
|
|
130
|
+
$fetch<{ clientId: string; clientName: string; canDelete: boolean }, string>(
|
|
131
|
+
`/api/timesheets/admin/clients/${id}/deletion`
|
|
132
|
+
)
|
|
124
133
|
const deleteClient = (id: string, clientName: string) =>
|
|
125
|
-
$fetch(`/api/timesheets/admin/clients/${id}`, {
|
|
134
|
+
$fetch<unknown, string>(`/api/timesheets/admin/clients/${id}`, {
|
|
126
135
|
method: 'DELETE' as never,
|
|
127
136
|
body: { clientName }
|
|
128
137
|
})
|
|
129
138
|
const updateClientAccess = (id: string, accessMode: ClientAccessMode) =>
|
|
130
|
-
$fetch(`/api/timesheets/admin/clients/${id}`, { method: 'PATCH', body: { accessMode } })
|
|
139
|
+
$fetch<unknown, string>(`/api/timesheets/admin/clients/${id}`, { method: 'PATCH', body: { accessMode } })
|
|
131
140
|
const getOrganizationTimesheetCapabilities = (organizationId: string) =>
|
|
132
|
-
$fetch<OrganizationTimesheetCapabilities>(
|
|
141
|
+
$fetch<OrganizationTimesheetCapabilities, string>(
|
|
142
|
+
`/api/timesheets/admin/organization-capabilities/${organizationId}`
|
|
143
|
+
)
|
|
133
144
|
const updateOrganizationTimesheetCapabilities = (organizationId: string, input: { workspaceEnabled: boolean }) =>
|
|
134
|
-
$fetch(`/api/timesheets/admin/organization-capabilities/${organizationId}`, {
|
|
135
|
-
|
|
145
|
+
$fetch<unknown, string>(`/api/timesheets/admin/organization-capabilities/${organizationId}`, {
|
|
146
|
+
method: 'PATCH',
|
|
147
|
+
body: input
|
|
148
|
+
})
|
|
149
|
+
const clientWorkspaces = () => $fetch<ClientWorkspaceDto[], string>('/api/timesheets/client/workspaces')
|
|
136
150
|
const clientApprovalMembers = () =>
|
|
137
|
-
$fetch<Array<{ id: string; name: string }
|
|
151
|
+
$fetch<Array<{ id: string; name: string }>, string>('/api/timesheets/client/approval-members')
|
|
138
152
|
const clientApprovalSuppliers = () =>
|
|
139
|
-
$fetch<ClientApprovalSupplierOptionDto[]>('/api/timesheets/client/approval-suppliers')
|
|
153
|
+
$fetch<ClientApprovalSupplierOptionDto[], string>('/api/timesheets/client/approval-suppliers')
|
|
140
154
|
const clientSupplierOptions = () =>
|
|
141
|
-
$fetch<ClientApprovalSupplierOptionDto[]>('/api/timesheets/client/supplier-options')
|
|
142
|
-
const clientReviewerSuppliers = () =>
|
|
155
|
+
$fetch<ClientApprovalSupplierOptionDto[], string>('/api/timesheets/client/supplier-options')
|
|
156
|
+
const clientReviewerSuppliers = () =>
|
|
157
|
+
$fetch<ClientReviewerSupplierDto[], string>('/api/timesheets/client/reviewer-suppliers')
|
|
143
158
|
const clientTimesheets = (workspaceClientId: string) =>
|
|
144
|
-
$fetch<ClientTimesheetsDto>(`/api/timesheets/client/${workspaceClientId}`)
|
|
159
|
+
$fetch<ClientTimesheetsDto, string>(`/api/timesheets/client/${workspaceClientId}`)
|
|
145
160
|
const reviewClientSlice = async (
|
|
146
161
|
workspaceClientId: string,
|
|
147
162
|
submissionId: string,
|
|
148
163
|
input: { action: 'APPROVE' | 'DISPUTE'; expectedVersion: number; comment?: string | null }
|
|
149
164
|
) => {
|
|
150
|
-
const result = await $fetch(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
165
|
+
const result = await $fetch<unknown, string>(
|
|
166
|
+
`/api/timesheets/client/${workspaceClientId}/reviews/${submissionId}`,
|
|
167
|
+
{
|
|
168
|
+
method: 'POST',
|
|
169
|
+
body: input
|
|
170
|
+
}
|
|
171
|
+
)
|
|
154
172
|
await refreshApprovalState()
|
|
155
173
|
return result
|
|
156
174
|
}
|
|
157
175
|
const clientReviewers = (workspaceClientId: string) =>
|
|
158
|
-
$fetch<ClientReviewerDto[]>(`/api/timesheets/client/${workspaceClientId}/reviewers`)
|
|
176
|
+
$fetch<ClientReviewerDto[], string>(`/api/timesheets/client/${workspaceClientId}/reviewers`)
|
|
159
177
|
const setClientReviewer = (workspaceClientId: string, userId: string, assigned: boolean) =>
|
|
160
|
-
$fetch(`/api/timesheets/client/${workspaceClientId}/reviewers`, {
|
|
178
|
+
$fetch<unknown, string>(`/api/timesheets/client/${workspaceClientId}/reviewers`, {
|
|
179
|
+
method: 'PUT',
|
|
180
|
+
body: { userId, assigned }
|
|
181
|
+
})
|
|
161
182
|
const createActivity = (input: { name: string; billable: boolean }) =>
|
|
162
|
-
$fetch('/api/timesheets/admin/activities', { method: 'POST', body: input })
|
|
183
|
+
$fetch<unknown, string>('/api/timesheets/admin/activities', { method: 'POST', body: input })
|
|
163
184
|
const updateActivity = (id: string, input: Partial<{ name: string; billable: boolean; active: boolean }>) =>
|
|
164
|
-
$fetch(`/api/timesheets/admin/activities/${id}`, { method: 'PATCH', body: input })
|
|
185
|
+
$fetch<unknown, string>(`/api/timesheets/admin/activities/${id}`, { method: 'PATCH', body: input })
|
|
165
186
|
const getActivityDeletionEligibility = (id: string) =>
|
|
166
|
-
$fetch<{ activityId: string; activityName: string; canDelete: boolean }>(
|
|
187
|
+
$fetch<{ activityId: string; activityName: string; canDelete: boolean }, string>(
|
|
167
188
|
`/api/timesheets/admin/activities/${id}/deletion`
|
|
168
189
|
)
|
|
169
190
|
const deleteActivity = (id: string, activityName: string) =>
|
|
170
|
-
$fetch(`/api/timesheets/admin/activities/${id}`, {
|
|
191
|
+
$fetch<unknown, string>(`/api/timesheets/admin/activities/${id}`, {
|
|
171
192
|
method: 'DELETE' as never,
|
|
172
193
|
body: { activityName }
|
|
173
194
|
})
|
|
@@ -178,32 +199,32 @@ export const useTimesheets = () => {
|
|
|
178
199
|
budgetMinutes?: number | null
|
|
179
200
|
budgetMinor?: number | null
|
|
180
201
|
activityTypeIds: string[]
|
|
181
|
-
}) => $fetch<{ id: string }>('/api/timesheets/admin/projects', { method: 'POST', body: input })
|
|
182
|
-
const getProject = (id: string) => $fetch<ProjectDto>(`/api/timesheets/admin/projects/${id}`)
|
|
202
|
+
}) => $fetch<{ id: string }, string>('/api/timesheets/admin/projects', { method: 'POST', body: input })
|
|
203
|
+
const getProject = (id: string) => $fetch<ProjectDto, string>(`/api/timesheets/admin/projects/${id}`)
|
|
183
204
|
const updateProject = (id: string, input: Record<string, unknown>) =>
|
|
184
|
-
$fetch(`/api/timesheets/admin/projects/${id}`, { method: 'PATCH', body: input })
|
|
205
|
+
$fetch<unknown, string>(`/api/timesheets/admin/projects/${id}`, { method: 'PATCH', body: input })
|
|
185
206
|
const getProjectDeletionEligibility = (id: string) =>
|
|
186
|
-
$fetch<{ projectId: string; projectName: string; canDelete: boolean }>(
|
|
207
|
+
$fetch<{ projectId: string; projectName: string; canDelete: boolean }, string>(
|
|
187
208
|
`/api/timesheets/admin/projects/${id}/deletion`
|
|
188
209
|
)
|
|
189
210
|
const deleteProject = (id: string, projectName: string) =>
|
|
190
|
-
$fetch(`/api/timesheets/admin/projects/${id}`, {
|
|
211
|
+
$fetch<unknown, string>(`/api/timesheets/admin/projects/${id}`, {
|
|
191
212
|
method: 'DELETE' as never,
|
|
192
213
|
body: { projectName }
|
|
193
214
|
})
|
|
194
215
|
const setTeamTariff = (userId: string, hourlyRateMinor: number) =>
|
|
195
|
-
$fetch('/api/timesheets/admin/tariffs', {
|
|
216
|
+
$fetch<unknown, string>('/api/timesheets/admin/tariffs', {
|
|
196
217
|
method: 'PUT',
|
|
197
218
|
body: { userId, hourlyRateMinor }
|
|
198
219
|
})
|
|
199
220
|
const updateTeamMemberSettings = (
|
|
200
221
|
userId: string,
|
|
201
222
|
input: { canEnterTime: boolean; defaultHourlyRateMinor: number | null }
|
|
202
|
-
) => $fetch(`/api/timesheets/admin/team/${userId}`, { method: 'PUT', body: input })
|
|
223
|
+
) => $fetch<unknown, string>(`/api/timesheets/admin/team/${userId}`, { method: 'PUT', body: input })
|
|
203
224
|
const updateSettings = (input: { currency?: string; timezone?: string; timerRoundingMinutes?: number }) =>
|
|
204
|
-
$fetch('/api/timesheets/admin/settings', { method: 'PATCH', body: input })
|
|
225
|
+
$fetch<unknown, string>('/api/timesheets/admin/settings', { method: 'PATCH', body: input })
|
|
205
226
|
const reviewSubmission = async (id: string, action: 'APPROVE' | 'REJECT' | 'REOPEN', comment?: string | null) => {
|
|
206
|
-
const result = await $fetch(`/api/timesheets/internal-approvals/${id}`, {
|
|
227
|
+
const result = await $fetch<unknown, string>(`/api/timesheets/internal-approvals/${id}`, {
|
|
207
228
|
method: 'POST',
|
|
208
229
|
body: { action, comment }
|
|
209
230
|
})
|
|
@@ -211,7 +232,7 @@ export const useTimesheets = () => {
|
|
|
211
232
|
return result
|
|
212
233
|
}
|
|
213
234
|
const getReport = (query: Record<string, string | undefined>) =>
|
|
214
|
-
$fetch<TimesheetReportDto>('/api/timesheets/admin/report', { query })
|
|
235
|
+
$fetch<TimesheetReportDto, string>('/api/timesheets/admin/report', { query })
|
|
215
236
|
|
|
216
237
|
return {
|
|
217
238
|
approvalEmailContext,
|
|
@@ -30,7 +30,7 @@ export const useTimesheetsAdminList = <Item>(options: {
|
|
|
30
30
|
pageSize,
|
|
31
31
|
getKey: (item) => (item as { id: string }).id,
|
|
32
32
|
fetchPage: ({ filters: query, page, pageSize, signal }) =>
|
|
33
|
-
$fetch<TimesheetsListResponse<Item
|
|
33
|
+
$fetch<TimesheetsListResponse<Item>, string>(options.endpoint, { query: { ...query, page, pageSize }, signal })
|
|
34
34
|
})
|
|
35
35
|
const query = () => ({
|
|
36
36
|
...(search.value.trim() ? { search: search.value.trim() } : {}),
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
const capabilities = await $fetch<
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const capabilities = await $fetch<
|
|
3
|
+
{ canAccessApprovals: boolean; canEnterTime: boolean; canViewSupplierTime: boolean },
|
|
4
|
+
string
|
|
5
|
+
>('/api/timesheets/capabilities')
|
|
5
6
|
const destination = capabilities.canAccessApprovals
|
|
6
7
|
? '/timesheets/approvals'
|
|
7
8
|
: capabilities.canEnterTime
|
|
@@ -10,12 +10,15 @@ defineOptions({ name: 'TimesheetsWorkbenchPage' })
|
|
|
10
10
|
|
|
11
11
|
definePageMeta({
|
|
12
12
|
middleware: async () => {
|
|
13
|
-
const capabilities = await $fetch<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
const capabilities = await $fetch<
|
|
14
|
+
{
|
|
15
|
+
canEnterTime: boolean
|
|
16
|
+
canReviewClientTimesheets: boolean
|
|
17
|
+
canApproveInternalTimesheets: boolean
|
|
18
|
+
canViewSupplierTime: boolean
|
|
19
|
+
},
|
|
20
|
+
string
|
|
21
|
+
>('/api/timesheets/capabilities')
|
|
19
22
|
if (capabilities.canEnterTime) {
|
|
20
23
|
return
|
|
21
24
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
const { t } = useI18n()
|
|
3
|
-
const capabilities = await $fetch<
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
const capabilities = await $fetch<
|
|
4
|
+
{ canAccessApprovals: boolean; canEnterTime: boolean; canViewSupplierTime: boolean },
|
|
5
|
+
string
|
|
6
|
+
>('/api/timesheets/capabilities')
|
|
6
7
|
|
|
7
8
|
if (!capabilities.canViewSupplierTime) {
|
|
8
9
|
await navigateTo(
|
|
@@ -101,7 +101,7 @@ export default defineNuxtPlugin(() => {
|
|
|
101
101
|
register(empty)
|
|
102
102
|
const refreshCapabilities = async () => {
|
|
103
103
|
try {
|
|
104
|
-
register(await $fetch<TimesheetCapabilitiesDto>('/api/timesheets/capabilities'))
|
|
104
|
+
register(await $fetch<TimesheetCapabilitiesDto, string>('/api/timesheets/capabilities'))
|
|
105
105
|
} catch {
|
|
106
106
|
register(empty)
|
|
107
107
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuxt-customer-portal/timesheets",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"homepage": "https://nuxt-customer-portal.com",
|
|
6
6
|
"repository": {
|
|
@@ -45,10 +45,10 @@
|
|
|
45
45
|
"pg": "^8.22.0",
|
|
46
46
|
"resend": "^6.18.1",
|
|
47
47
|
"zod": "^4.4.3",
|
|
48
|
-
"@nuxt-customer-portal/core": "^0.
|
|
49
|
-
"@nuxt-customer-portal/
|
|
50
|
-
"@nuxt-customer-portal/ui": "^0.
|
|
51
|
-
"@nuxt-customer-portal/
|
|
48
|
+
"@nuxt-customer-portal/core": "^0.10.0",
|
|
49
|
+
"@nuxt-customer-portal/clients": "^0.10.0",
|
|
50
|
+
"@nuxt-customer-portal/ui": "^0.10.0",
|
|
51
|
+
"@nuxt-customer-portal/organizations": "^0.10.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"nuxt": "^4.5.1",
|