@autobusal/admin-api-consumers 1.2.1 → 1.3.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/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
- const { data, isLoading, isFetching, refetch } = useGetApiConsumers(getParams(searchParams, ['page', 'sort', 'order', 'q']));
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
- <Link to={ `${ url }/receivables` }>
87
- <Button type="button" size="medium" subtype="secondary" noMargin text={ t('admin_api_consumers.receivables.title', { ns: 'common' }) } />
88
- </Link>
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,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.3.0 (2026-08-29)
4
+
5
+ - Editors offer Save & Close alongside Save & Stay, so correcting a record no longer bounces you back to its list every time (opt-in per page, editing only).
6
+
7
+ ## 1.2.2 (2026-08-28)
8
+
9
+ - 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.
10
+
3
11
  ## 1.2.1
4
12
 
5
13
  ### Fixed
package/Manage.tsx CHANGED
@@ -42,7 +42,7 @@ const Manage = ({ url, t }: Props): JSX.Element => {
42
42
  return <Box />;
43
43
  }
44
44
 
45
- const onSave = (formData: Record<string, any>): void => {
45
+ const onSave = (formData: Record<string, any>, stay?: boolean): void => {
46
46
  Update(formData, {
47
47
  onSuccess: (response) => {
48
48
  success(t('admin_api_consumers.manage.messages.saved', { ns: 'common' }));
@@ -55,7 +55,9 @@ const Manage = ({ url, t }: Props): JSX.Element => {
55
55
  return;
56
56
  }
57
57
 
58
- navigate(url);
58
+ if (!stay) {
59
+ navigate(url);
60
+ }
59
61
  }
60
62
  });
61
63
  };
@@ -164,7 +166,7 @@ const Manage = ({ url, t }: Props): JSX.Element => {
164
166
  pending={ isPendingSave || isPendingDelete }
165
167
  t={ t }
166
168
  actions={
167
- id > 0 ? ['save', 'delete'] : ['save']
169
+ id > 0 ? ['save', 'save_stay', 'delete'] : ['save']
168
170
  }
169
171
  onSave={ onSave }
170
172
  onDelete={ onDelete }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autobusal/admin-api-consumers",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "author": "Ferjolt Ozuni",
5
5
  "type": "module",
6
6
  "main": "index.ts"
package/services.ts CHANGED
@@ -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'],
package/types.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { ComissionData } from '@autobusal/providers/types/users';
2
2
 
3
3
  export interface ApiConsumerData {
4
+ api_requested_at?: (string | null)
4
5
  id: number
5
6
  company: string
6
7
  operators: (number | string)[]