@autobusal/admin-api-consumers 1.2.0 → 1.2.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/Browse.tsx +74 -7
- package/CHANGELOG.md +10 -0
- package/TokenManager.tsx +1 -1
- package/package.json +1 -1
- package/services.ts +55 -16
- package/types.ts +1 -0
package/Browse.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { Link, useSearchParams } from 'react-router-dom';
|
|
|
3
3
|
import { Meta, Table, Row, Button } from '@autobusal/common';
|
|
4
4
|
import { usePage, useBreadcrumbs } from '@autobusal/hooks';
|
|
5
5
|
import { DisplayStatus, getParams, success } from '@autobusal/utilities';
|
|
6
|
-
import { useGetApiConsumers, useDeleteApiConsumer } from './services';
|
|
6
|
+
import { useGetApiConsumers, useDeleteApiConsumer, useDeclineApiRequest } from './services';
|
|
7
7
|
|
|
8
8
|
interface Props {
|
|
9
9
|
url: string
|
|
@@ -17,10 +17,32 @@ const Browse = ({ url, t }: Props): JSX.Element => {
|
|
|
17
17
|
|
|
18
18
|
useBreadcrumbs(t('admin_api_consumers.browse.title', { ns: 'common' }));
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
/*
|
|
21
|
+
* Edited: Claude - Date: 2026-08-28
|
|
22
|
+
*
|
|
23
|
+
* ?type=requests flips this screen to the P8 self-serve queue: agents
|
|
24
|
+
* who asked for partner API access and await a ruling. Approving one is
|
|
25
|
+
* the ordinary manage screen on the same row - review, save, and the
|
|
26
|
+
* save sets the consumer flag - so the only new verb here is Decline.
|
|
27
|
+
*/
|
|
28
|
+
const requests = searchParams.get('type') === 'requests';
|
|
29
|
+
|
|
30
|
+
const { data, isLoading, isFetching, refetch } = useGetApiConsumers(getParams(searchParams, ['page', 'sort', 'order', 'q', 'type']));
|
|
21
31
|
|
|
22
32
|
const { mutate: Delete } = useDeleteApiConsumer();
|
|
23
33
|
|
|
34
|
+
const { mutate: Decline } = useDeclineApiRequest();
|
|
35
|
+
|
|
36
|
+
const onDecline = (id: number): void => {
|
|
37
|
+
Decline(id, {
|
|
38
|
+
onSuccess: () => {
|
|
39
|
+
success(t('admin_api_consumers.requests.declined', { ns: 'common' }));
|
|
40
|
+
|
|
41
|
+
refetch();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
24
46
|
const onDelete = (id: number): void => {
|
|
25
47
|
Delete(id, {
|
|
26
48
|
onSuccess: () => {
|
|
@@ -35,7 +57,21 @@ const Browse = ({ url, t }: Props): JSX.Element => {
|
|
|
35
57
|
<Row
|
|
36
58
|
key={ item.id }
|
|
37
59
|
id={ item.id }
|
|
38
|
-
data={ [
|
|
60
|
+
data={ requests ? [
|
|
61
|
+
item.company,
|
|
62
|
+
item.user.email,
|
|
63
|
+
item.api_requested_at ? String(item.api_requested_at).slice(0, 10) : '-',
|
|
64
|
+
DisplayStatus(item.user.status, t),
|
|
65
|
+
<Button
|
|
66
|
+
key="decline"
|
|
67
|
+
type="button"
|
|
68
|
+
size="small"
|
|
69
|
+
subtype="secondary"
|
|
70
|
+
noMargin
|
|
71
|
+
text={ t('admin_api_consumers.requests.decline', { ns: 'common' }) }
|
|
72
|
+
onClick={ () => onDecline(item.id) }
|
|
73
|
+
/>
|
|
74
|
+
] : [
|
|
39
75
|
item.company,
|
|
40
76
|
item.user.email,
|
|
41
77
|
item.operators.includes('all') ? t('admin_api_consumers.browse.all_operators', { ns: 'common' }) : String(item.operators.length),
|
|
@@ -51,7 +87,24 @@ const Browse = ({ url, t }: Props): JSX.Element => {
|
|
|
51
87
|
|
|
52
88
|
<Table
|
|
53
89
|
url={ url }
|
|
54
|
-
columns={ [{
|
|
90
|
+
columns={ requests ? [{
|
|
91
|
+
name: t('admin_api_consumers.browse.company', { ns: 'common' }),
|
|
92
|
+
width: 28,
|
|
93
|
+
slug: 'company',
|
|
94
|
+
type: 'az'
|
|
95
|
+
}, {
|
|
96
|
+
name: t('admin_api_consumers.browse.email', { ns: 'common' }),
|
|
97
|
+
width: 28
|
|
98
|
+
}, {
|
|
99
|
+
name: t('admin_api_consumers.requests.requested', { ns: 'common' }),
|
|
100
|
+
width: 16
|
|
101
|
+
}, {
|
|
102
|
+
name: t('admin_api_consumers.browse.status', { ns: 'common' }),
|
|
103
|
+
width: 14
|
|
104
|
+
}, {
|
|
105
|
+
name: '',
|
|
106
|
+
width: 14
|
|
107
|
+
}] : [{
|
|
55
108
|
name: t('admin_api_consumers.browse.company', { ns: 'common' }),
|
|
56
109
|
width: 25,
|
|
57
110
|
slug: 'company',
|
|
@@ -83,9 +136,23 @@ const Browse = ({ url, t }: Props): JSX.Element => {
|
|
|
83
136
|
'create', 'search', 'extra', 'view', 'delete'
|
|
84
137
|
] }
|
|
85
138
|
extra={
|
|
86
|
-
|
|
87
|
-
<
|
|
88
|
-
|
|
139
|
+
<>
|
|
140
|
+
<Link to={ requests ? url : `${ url }?type=requests` }>
|
|
141
|
+
<Button
|
|
142
|
+
type="button"
|
|
143
|
+
size="medium"
|
|
144
|
+
subtype="secondary"
|
|
145
|
+
noMargin
|
|
146
|
+
text={ requests
|
|
147
|
+
? t('admin_api_consumers.requests.back', { ns: 'common' })
|
|
148
|
+
: t('admin_api_consumers.requests.title', { ns: 'common' }) }
|
|
149
|
+
/>
|
|
150
|
+
</Link>
|
|
151
|
+
|
|
152
|
+
<Link to={ `${ url }/receivables` }>
|
|
153
|
+
<Button type="button" size="medium" subtype="secondary" noMargin text={ t('admin_api_consumers.receivables.title', { ns: 'common' }) } />
|
|
154
|
+
</Link>
|
|
155
|
+
</>
|
|
89
156
|
}
|
|
90
157
|
handlers={ {
|
|
91
158
|
delete: onDelete
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.2 (2026-08-28)
|
|
4
|
+
|
|
5
|
+
- Requests view (?type=requests): the P8 self-serve queue - agents awaiting a partner-API ruling, with Decline per row; approving stays the ordinary manage/save flow. Toggle button beside Receivables.
|
|
6
|
+
|
|
7
|
+
## 1.2.1
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **The token panel updates without a reload** - toggle/revoke/regenerate invalidate the consumer they changed. The button also reads "Generate Token" while no token exists. (Audit ADM-04f.)
|
|
12
|
+
|
|
3
13
|
## 1.2.0
|
|
4
14
|
|
|
5
15
|
### Added
|
package/TokenManager.tsx
CHANGED
|
@@ -78,7 +78,7 @@ const TokenManager = ({ id, hasToken, enabled, t }: Props): JSX.Element => {
|
|
|
78
78
|
subtype="secondary"
|
|
79
79
|
noMargin
|
|
80
80
|
loading={ isPendingRegenerate }
|
|
81
|
-
text={ <><FiRefreshCw /> { t('admin_api_consumers.token.regenerate', { ns: 'common' }) }</> }
|
|
81
|
+
text={ <><FiRefreshCw /> { t(hasToken ? 'admin_api_consumers.token.regenerate' : 'admin_api_consumers.token.generate', { ns: 'common' }) }</> }
|
|
82
82
|
onClick={ onRegenerate }
|
|
83
83
|
/>
|
|
84
84
|
|
package/package.json
CHANGED
package/services.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { UseMutationResult, UseQueryResult, UseSuspenseQueryResult, useMutation, useQuery, useSuspenseQuery } from '@tanstack/react-query';
|
|
1
|
+
import { UseMutationResult, UseQueryResult, UseSuspenseQueryResult, useMutation, useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query';
|
|
2
2
|
import { apiClient } from '@autobusal/providers';
|
|
3
3
|
import { PaginationData } from '@autobusal/providers/types/pagination';
|
|
4
4
|
import { TableParamsData } from '@autobusal/providers/types/other';
|
|
@@ -91,6 +91,23 @@ export const usePostApiConsumer = (id: number): UseMutationResult<{ api_token: s
|
|
|
91
91
|
})
|
|
92
92
|
);
|
|
93
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Decline a pending P8 access request - clears the ask, grants nothing.
|
|
96
|
+
* Edited: Claude - Date: 2026-08-28
|
|
97
|
+
*/
|
|
98
|
+
export const useDeclineApiRequest = (): UseMutationResult<void, Error, number, unknown> => (
|
|
99
|
+
useMutation({
|
|
100
|
+
mutationKey: ['admin-api-consumers-decline'],
|
|
101
|
+
mutationFn: async (id: number) => (
|
|
102
|
+
await apiClient
|
|
103
|
+
.post('/api/api_consumers/admin/decline', { id })
|
|
104
|
+
.then(response => (
|
|
105
|
+
response.data
|
|
106
|
+
))
|
|
107
|
+
)
|
|
108
|
+
})
|
|
109
|
+
);
|
|
110
|
+
|
|
94
111
|
export const useDeleteApiConsumer = (): UseMutationResult<void, Error, number, unknown> => (
|
|
95
112
|
useMutation({
|
|
96
113
|
mutationKey: ['admin-api-consumers-delete'],
|
|
@@ -106,8 +123,17 @@ export const useDeleteApiConsumer = (): UseMutationResult<void, Error, number, u
|
|
|
106
123
|
})
|
|
107
124
|
);
|
|
108
125
|
|
|
109
|
-
|
|
110
|
-
|
|
126
|
+
/*
|
|
127
|
+
* Claude - 2026-08-22 (audit finding ADM-04f): the token panel only showed
|
|
128
|
+
* a toggle/revoke/regenerate's effect after a full page reload - an admin
|
|
129
|
+
* could reasonably believe Revoke had failed. Each mutation now
|
|
130
|
+
* invalidates the consumer it changed, so the panel redraws from the
|
|
131
|
+
* server's answer immediately.
|
|
132
|
+
*/
|
|
133
|
+
export const useToggleApiConsumer = (): UseMutationResult<void, Error, { id: number, api: number }, unknown> => {
|
|
134
|
+
const client = useQueryClient();
|
|
135
|
+
|
|
136
|
+
return useMutation({
|
|
111
137
|
mutationKey: ['admin-api-consumers-toggle'],
|
|
112
138
|
mutationFn: async ({ id, api }: { id: number, api: number }) => (
|
|
113
139
|
await apiClient
|
|
@@ -115,12 +141,17 @@ export const useToggleApiConsumer = (): UseMutationResult<void, Error, { id: num
|
|
|
115
141
|
.then(response => (
|
|
116
142
|
response.data
|
|
117
143
|
))
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
);
|
|
144
|
+
),
|
|
145
|
+
onSuccess: (_, { id }): void => {
|
|
146
|
+
client.invalidateQueries({ queryKey: ['admin-api-consumers-manage', { id }] });
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
};
|
|
121
150
|
|
|
122
|
-
export const useRevokeApiConsumerToken = (): UseMutationResult<void, Error, number, unknown> =>
|
|
123
|
-
|
|
151
|
+
export const useRevokeApiConsumerToken = (): UseMutationResult<void, Error, number, unknown> => {
|
|
152
|
+
const client = useQueryClient();
|
|
153
|
+
|
|
154
|
+
return useMutation({
|
|
124
155
|
mutationKey: ['admin-api-consumers-revoke'],
|
|
125
156
|
mutationFn: async (id: number) => (
|
|
126
157
|
await apiClient
|
|
@@ -128,12 +159,17 @@ export const useRevokeApiConsumerToken = (): UseMutationResult<void, Error, numb
|
|
|
128
159
|
.then(response => (
|
|
129
160
|
response.data
|
|
130
161
|
))
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
);
|
|
162
|
+
),
|
|
163
|
+
onSuccess: (_, id): void => {
|
|
164
|
+
client.invalidateQueries({ queryKey: ['admin-api-consumers-manage', { id }] });
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
};
|
|
134
168
|
|
|
135
|
-
export const useRegenerateApiConsumerToken = (): UseMutationResult<{ api_token: string }, Error, number, unknown> =>
|
|
136
|
-
|
|
169
|
+
export const useRegenerateApiConsumerToken = (): UseMutationResult<{ api_token: string }, Error, number, unknown> => {
|
|
170
|
+
const client = useQueryClient();
|
|
171
|
+
|
|
172
|
+
return useMutation({
|
|
137
173
|
mutationKey: ['admin-api-consumers-regenerate'],
|
|
138
174
|
mutationFn: async (id: number) => (
|
|
139
175
|
await apiClient
|
|
@@ -141,9 +177,12 @@ export const useRegenerateApiConsumerToken = (): UseMutationResult<{ api_token:
|
|
|
141
177
|
.then(response => (
|
|
142
178
|
response.data
|
|
143
179
|
))
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
);
|
|
180
|
+
),
|
|
181
|
+
onSuccess: (_, id): void => {
|
|
182
|
+
client.invalidateQueries({ queryKey: ['admin-api-consumers-manage', { id }] });
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
};
|
|
147
186
|
|
|
148
187
|
// Edited: Ferjolt Ozuni - Date: 2026-07-27
|
|
149
188
|
// Package 3 - API partner receivables reports + settlements
|