@titus-system/syncdesk 0.3.1 → 0.5.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 +29 -0
- package/README.md +34 -1
- package/package.json +1 -1
- package/src/auth/hooks/useAuth.ts +78 -0
- package/src/auth/types/auth.ts +28 -2
- package/src/health/hooks/useHealth.ts +14 -5
- package/src/index.ts +1 -0
- package/src/live_chat/hooks/useLiveChat.ts +31 -10
- package/src/permissions/hooks/usePermissions.ts +64 -9
- package/src/roles/hooks/useRoles.ts +73 -9
- package/src/ticket/hooks/useTickets.ts +89 -0
- package/src/ticket/index.ts +2 -0
- package/src/ticket/types/ticket.ts +88 -0
- package/src/users/hooks/useUsers.ts +11 -7
- package/src/users/index.ts +0 -6
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
5
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
### Deprecated
|
|
14
|
+
|
|
15
|
+
### Removed
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
### Security
|
|
20
|
+
|
|
21
|
+
### Dev Notes
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# 0.5.0 - 2026-04-04
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- Get a specific client's conversations.
|
package/README.md
CHANGED
|
@@ -14,6 +14,8 @@ npm install @titus-system/syncdesk
|
|
|
14
14
|
|
|
15
15
|
### Install locally
|
|
16
16
|
|
|
17
|
+
Alternatively, you can install locally bypassing the npm registry.
|
|
18
|
+
|
|
17
19
|
```sh
|
|
18
20
|
npm run build
|
|
19
21
|
npm pack
|
|
@@ -25,13 +27,44 @@ It creates a compressed tarball file in your folder. You can install it in your
|
|
|
25
27
|
npm install /path/to/your/library-1.0.0.tgz
|
|
26
28
|
```
|
|
27
29
|
|
|
30
|
+
### Configure your project to use the library
|
|
31
|
+
|
|
32
|
+
This lib requires some configuration to work properly, such as the API base URL.
|
|
33
|
+
To do so, you should call the `configLibrary` function in your project, passing the necessary configuration options. For example:
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { configLibrary } from "@titus-system/syncdesk";
|
|
37
|
+
configureLibrary({
|
|
38
|
+
baseURL: 'http://localhost:8000/api', // should not be hardcoded, but in a .env file or similar
|
|
39
|
+
|
|
40
|
+
getAccessToken: () => localStorage.getItem('access_token'),
|
|
41
|
+
getRefreshToken: () => localStorage.getItem('refresh_token'),
|
|
42
|
+
|
|
43
|
+
onTokensRefreshed: (newAccess: string, newRefresh: string) => {
|
|
44
|
+
localStorage.setItem('access_token', newAccess)
|
|
45
|
+
localStorage.setItem('refresh_token', newRefresh)
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
onUnauthorized: () => {
|
|
49
|
+
localStorage.removeItem('access_token')
|
|
50
|
+
localStorage.removeItem('refresh_token')
|
|
51
|
+
window.location.href = '/login'
|
|
52
|
+
|
|
53
|
+
// // Mobile-specific logic to clear secure storage and navigate
|
|
54
|
+
// await SecureStore.deleteItemAsync('access_token')
|
|
55
|
+
// router.replace('/login')
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
28
60
|
## Publish new version to npm registry
|
|
29
61
|
|
|
30
62
|
```sh
|
|
31
63
|
# You may have to login to npm registry first with `npm login`
|
|
32
64
|
npm login
|
|
33
65
|
|
|
34
|
-
npm run build
|
|
66
|
+
npm run build
|
|
67
|
+
npm publish --access public
|
|
35
68
|
```
|
|
36
69
|
|
|
37
70
|
---
|
package/package.json
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
2
2
|
import { apiClient, ApiResponse } from "../../api";
|
|
3
3
|
import {
|
|
4
|
+
AdminRegisterUserRequest,
|
|
5
|
+
ChangePasswordRequest,
|
|
6
|
+
ForgotPasswordRequest,
|
|
7
|
+
ForgotPasswordResponse,
|
|
4
8
|
LoginResponse,
|
|
5
9
|
RegisterUserRequest,
|
|
10
|
+
ResetPasswordRequest,
|
|
6
11
|
UserCreatedResponse,
|
|
7
12
|
UserLoginRequest,
|
|
8
13
|
UserWithRoles,
|
|
9
14
|
} from "../types/auth";
|
|
15
|
+
import { User } from "../../users/types/user";
|
|
10
16
|
|
|
11
17
|
const PATH = "auth";
|
|
12
18
|
|
|
13
19
|
/**
|
|
14
20
|
* Get the currently authenticated user's profile.
|
|
21
|
+
* @returns {UseQueryResult<UserWithRoles, Error>} The query result.
|
|
15
22
|
*/
|
|
16
23
|
export const useGetMe = () => {
|
|
17
24
|
return useQuery({
|
|
@@ -32,6 +39,8 @@ export const useGetMe = () => {
|
|
|
32
39
|
* Log in a user.
|
|
33
40
|
*
|
|
34
41
|
* Refresh tokens are handled automatically using Interceptors.
|
|
42
|
+
* @param {UserLoginRequest} credentials The user login credentials.
|
|
43
|
+
* @returns {UseMutationResult<LoginResponse, Error, UserLoginRequest>} The mutation result.
|
|
35
44
|
*/
|
|
36
45
|
export const useLogin = () => {
|
|
37
46
|
const queryClient = useQueryClient();
|
|
@@ -55,6 +64,8 @@ export const useLogin = () => {
|
|
|
55
64
|
|
|
56
65
|
/**
|
|
57
66
|
* Register a new user.
|
|
67
|
+
* @param {RegisterUserRequest} userData The user registration details.
|
|
68
|
+
* @returns {UseMutationResult<UserCreatedResponse, Error, RegisterUserRequest>} The mutation result.
|
|
58
69
|
*/
|
|
59
70
|
export const useRegister = () => {
|
|
60
71
|
const queryClient = useQueryClient();
|
|
@@ -78,6 +89,7 @@ export const useRegister = () => {
|
|
|
78
89
|
|
|
79
90
|
/**
|
|
80
91
|
* Log out the current user.
|
|
92
|
+
* @returns {UseMutationResult<void, Error, void>} The mutation result.
|
|
81
93
|
*/
|
|
82
94
|
export const useLogout = () => {
|
|
83
95
|
const queryClient = useQueryClient();
|
|
@@ -93,3 +105,69 @@ export const useLogout = () => {
|
|
|
93
105
|
},
|
|
94
106
|
});
|
|
95
107
|
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Register a new user as admin.
|
|
111
|
+
* @param {AdminRegisterUserRequest} userData The admin user registration details.
|
|
112
|
+
* @returns {UseMutationResult<User, Error, AdminRegisterUserRequest>} The mutation result.
|
|
113
|
+
*/
|
|
114
|
+
export const useAdminRegister = () => {
|
|
115
|
+
const queryClient = useQueryClient();
|
|
116
|
+
|
|
117
|
+
return useMutation({
|
|
118
|
+
mutationFn: async (userData: AdminRegisterUserRequest): Promise<User> => {
|
|
119
|
+
const response = await apiClient.post<ApiResponse<User>>(
|
|
120
|
+
`${PATH}/admin/register`,
|
|
121
|
+
userData,
|
|
122
|
+
);
|
|
123
|
+
return response.data.data;
|
|
124
|
+
},
|
|
125
|
+
onSuccess: () => {
|
|
126
|
+
queryClient.invalidateQueries({ queryKey: ["users"] });
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Change the current user's password.
|
|
133
|
+
* @param {ChangePasswordRequest} data The password change request details.
|
|
134
|
+
* @returns {UseMutationResult<void, Error, ChangePasswordRequest>} The mutation result.
|
|
135
|
+
*/
|
|
136
|
+
export const useChangePassword = () => {
|
|
137
|
+
return useMutation({
|
|
138
|
+
mutationFn: async (data: ChangePasswordRequest): Promise<void> => {
|
|
139
|
+
await apiClient.post(`${PATH}/change-password`, data);
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Request a password reset.
|
|
146
|
+
* @param {ForgotPasswordRequest} data The forgot password request details.
|
|
147
|
+
* @returns {UseMutationResult<ForgotPasswordResponse, Error, ForgotPasswordRequest>} The mutation result.
|
|
148
|
+
*/
|
|
149
|
+
export const useForgotPassword = () => {
|
|
150
|
+
return useMutation({
|
|
151
|
+
mutationFn: async (
|
|
152
|
+
data: ForgotPasswordRequest,
|
|
153
|
+
): Promise<ForgotPasswordResponse> => {
|
|
154
|
+
const response = await apiClient.post<
|
|
155
|
+
ApiResponse<ForgotPasswordResponse>
|
|
156
|
+
>(`${PATH}/forgot-password`, data);
|
|
157
|
+
return response.data.data;
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Reset the current user's password using a valid reset token.
|
|
164
|
+
* @param {ResetPasswordRequest} data The reset password request details.
|
|
165
|
+
* @returns {UseMutationResult<void, Error, ResetPasswordRequest>} The mutation result.
|
|
166
|
+
*/
|
|
167
|
+
export const useResetPassword = () => {
|
|
168
|
+
return useMutation({
|
|
169
|
+
mutationFn: async (data: ResetPasswordRequest): Promise<void> => {
|
|
170
|
+
await apiClient.post(`${PATH}/reset-password`, data);
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
};
|
package/src/auth/types/auth.ts
CHANGED
|
@@ -3,6 +3,8 @@ export type OAuthProvider = "local" | "google" | "microsoft";
|
|
|
3
3
|
export interface LoginResponse {
|
|
4
4
|
access_token: string;
|
|
5
5
|
refresh_token: string;
|
|
6
|
+
must_change_password?: boolean;
|
|
7
|
+
must_accept_terms?: boolean;
|
|
6
8
|
}
|
|
7
9
|
|
|
8
10
|
export interface UserCreatedResponse {
|
|
@@ -20,11 +22,35 @@ export interface UserLoginRequest {
|
|
|
20
22
|
|
|
21
23
|
export interface RegisterUserRequest {
|
|
22
24
|
email: string;
|
|
23
|
-
name
|
|
24
|
-
username
|
|
25
|
+
name?: string;
|
|
26
|
+
username?: string;
|
|
25
27
|
password: string;
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
export interface AdminRegisterUserRequest {
|
|
31
|
+
email: string;
|
|
32
|
+
name?: string | null;
|
|
33
|
+
role_ids?: number[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ChangePasswordRequest {
|
|
37
|
+
current_password: string;
|
|
38
|
+
new_password: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface ForgotPasswordRequest {
|
|
42
|
+
email: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface ResetPasswordRequest {
|
|
46
|
+
token: string;
|
|
47
|
+
new_password: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ForgotPasswordResponse {
|
|
51
|
+
message: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
28
54
|
// I am making a safe assumption for your /me route based on "user_with_roles"
|
|
29
55
|
export interface UserWithRoles {
|
|
30
56
|
id: string;
|
|
@@ -6,14 +6,19 @@ import type {
|
|
|
6
6
|
ReadyResponse,
|
|
7
7
|
} from "../types/health";
|
|
8
8
|
|
|
9
|
+
const PATH = "";
|
|
10
|
+
|
|
9
11
|
/**
|
|
10
12
|
* Ping the server to check for basic connectivity.
|
|
13
|
+
* @returns {UseQueryResult<PingResponse, Error>} The result.
|
|
11
14
|
*/
|
|
12
15
|
export const usePing = () => {
|
|
13
16
|
return useQuery({
|
|
14
17
|
queryKey: ["health", "ping"],
|
|
15
18
|
queryFn: async (): Promise<PingResponse> => {
|
|
16
|
-
const response = await apiClient.get<ApiResponse<PingResponse>>(
|
|
19
|
+
const response = await apiClient.get<ApiResponse<PingResponse>>(
|
|
20
|
+
`${PATH}/ping`,
|
|
21
|
+
);
|
|
17
22
|
return response.data.data;
|
|
18
23
|
},
|
|
19
24
|
});
|
|
@@ -21,13 +26,15 @@ export const usePing = () => {
|
|
|
21
26
|
|
|
22
27
|
/**
|
|
23
28
|
* Check the detailed health of the server and its dependencies (e.g. databases).
|
|
29
|
+
* @returns {UseQueryResult<HealthResponse, Error>} The result.
|
|
24
30
|
*/
|
|
25
31
|
export const useHealth = () => {
|
|
26
32
|
return useQuery({
|
|
27
33
|
queryKey: ["health", "status"],
|
|
28
34
|
queryFn: async (): Promise<HealthResponse> => {
|
|
29
|
-
const response =
|
|
30
|
-
|
|
35
|
+
const response = await apiClient.get<ApiResponse<HealthResponse>>(
|
|
36
|
+
`${PATH}/health`,
|
|
37
|
+
);
|
|
31
38
|
return response.data.data;
|
|
32
39
|
},
|
|
33
40
|
});
|
|
@@ -35,13 +42,15 @@ export const useHealth = () => {
|
|
|
35
42
|
|
|
36
43
|
/**
|
|
37
44
|
* Check if the server is ready to accept traffic.
|
|
45
|
+
* @returns {UseQueryResult<ReadyResponse, Error>} The result.
|
|
38
46
|
*/
|
|
39
47
|
export const useReady = () => {
|
|
40
48
|
return useQuery({
|
|
41
49
|
queryKey: ["health", "ready"],
|
|
42
50
|
queryFn: async (): Promise<ReadyResponse> => {
|
|
43
|
-
const response =
|
|
44
|
-
|
|
51
|
+
const response = await apiClient.get<ApiResponse<ReadyResponse>>(
|
|
52
|
+
`${PATH}/ready`,
|
|
53
|
+
);
|
|
45
54
|
return response.data.data;
|
|
46
55
|
},
|
|
47
56
|
});
|
package/src/index.ts
CHANGED
|
@@ -9,8 +9,9 @@ import {
|
|
|
9
9
|
const PATH = "/conversations";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* Get all conversations
|
|
13
|
-
* @param ticket_id
|
|
12
|
+
* Get all conversations of a ticket.
|
|
13
|
+
* @param {string} ticket_id ticket_id parameter.
|
|
14
|
+
* @returns {UseQueryResult<Conversation[]>} The query result.
|
|
14
15
|
*/
|
|
15
16
|
export const useGetConversations = (ticket_id: string) => {
|
|
16
17
|
return useQuery({
|
|
@@ -26,10 +27,29 @@ export const useGetConversations = (ticket_id: string) => {
|
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
|
-
* Get
|
|
30
|
-
* @param
|
|
31
|
-
* @
|
|
32
|
-
|
|
30
|
+
* Get a specific client's conversations.
|
|
31
|
+
* @param {string} client_id client_id parameter.
|
|
32
|
+
* @returns {UseQueryResult<Conversation[]>} The query result.
|
|
33
|
+
*/
|
|
34
|
+
export const useGetClientConversations = (client_id: string) => {
|
|
35
|
+
return useQuery({
|
|
36
|
+
queryKey: ["conversations", "client", client_id],
|
|
37
|
+
queryFn: async (): Promise<Conversation[]> => {
|
|
38
|
+
const response = await apiClient.get<ApiResponse<Conversation[]>>(
|
|
39
|
+
`${PATH}/client/${client_id}`,
|
|
40
|
+
);
|
|
41
|
+
return response.data.data;
|
|
42
|
+
},
|
|
43
|
+
enabled: !!client_id,
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get ticket messages with pagination.
|
|
49
|
+
* @param {string} ticket_id ticket_id parameter.
|
|
50
|
+
* @param {number} page page parameter.
|
|
51
|
+
* @param {number} limit limit parameter.
|
|
52
|
+
* @returns {UseQueryResult<PaginatedMessages>} The query result.
|
|
33
53
|
*/
|
|
34
54
|
export const useGetPaginatedMessages = (
|
|
35
55
|
ticket_id: string,
|
|
@@ -56,7 +76,9 @@ export const useGetPaginatedMessages = (
|
|
|
56
76
|
};
|
|
57
77
|
|
|
58
78
|
/**
|
|
59
|
-
* Create a new conversation
|
|
79
|
+
* Create a new conversation.
|
|
80
|
+
* @param {CreateConversationDTO} dto The conversation creation details.
|
|
81
|
+
* @returns {UseMutationResult<Conversation, Error, CreateConversationDTO>} The mutation result.
|
|
60
82
|
*/
|
|
61
83
|
export const useCreateConversation = () => {
|
|
62
84
|
const queryClient = useQueryClient();
|
|
@@ -79,6 +101,8 @@ export const useCreateConversation = () => {
|
|
|
79
101
|
|
|
80
102
|
/**
|
|
81
103
|
* Assign an agent to a conversation.
|
|
104
|
+
* @param {{ chat_id: string; agent_id: string }} params The chat ID and agent ID payload.
|
|
105
|
+
* @returns {UseMutationResult<void, Error, { chat_id: string; agent_id: string }>} The mutation result.
|
|
82
106
|
*/
|
|
83
107
|
export const useSetConversationAgent = () => {
|
|
84
108
|
const queryClient = useQueryClient();
|
|
@@ -93,9 +117,6 @@ export const useSetConversationAgent = () => {
|
|
|
93
117
|
}): Promise<void> => {
|
|
94
118
|
await apiClient.patch(`${PATH}/${chat_id}/set-agent/${agent_id}`);
|
|
95
119
|
},
|
|
96
|
-
// We invalidate the ticket conversations here.
|
|
97
|
-
// To do so effectively, you may need the ticket_id, but the mutation only receives the chat_id.
|
|
98
|
-
// If ticket list invalidation is required, invalidate the whole 'conversations' key.
|
|
99
120
|
onSuccess: () => {
|
|
100
121
|
queryClient.invalidateQueries({ queryKey: ["conversations"] });
|
|
101
122
|
},
|
|
@@ -9,23 +9,35 @@ import type {
|
|
|
9
9
|
AddPermissionRolesDTO,
|
|
10
10
|
} from "../types/permission";
|
|
11
11
|
|
|
12
|
+
const PATH = "/permissions";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* List all permissions.
|
|
16
|
+
* @returns {UseQueryResult<Permission[]>} The query result.
|
|
17
|
+
*/
|
|
12
18
|
export function usePermissions() {
|
|
13
19
|
return useQuery<Permission[]>({
|
|
14
20
|
queryKey: ["permissions"],
|
|
15
21
|
queryFn: async () => {
|
|
16
|
-
const response =
|
|
17
|
-
|
|
22
|
+
const response = await apiClient.get<ApiResponse<Permission[]>>(
|
|
23
|
+
`${PATH}/`,
|
|
24
|
+
);
|
|
18
25
|
return response.data.data;
|
|
19
26
|
},
|
|
20
27
|
});
|
|
21
28
|
}
|
|
22
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Get a permission by ID.
|
|
32
|
+
* @param {number} id id parameter.
|
|
33
|
+
* @returns {UseQueryResult<Permission>} The query result.
|
|
34
|
+
*/
|
|
23
35
|
export function usePermission(id: number) {
|
|
24
36
|
return useQuery<Permission>({
|
|
25
37
|
queryKey: ["permissions", id],
|
|
26
38
|
queryFn: async () => {
|
|
27
39
|
const response = await apiClient.get<ApiResponse<Permission>>(
|
|
28
|
-
|
|
40
|
+
`${PATH}/${id}`,
|
|
29
41
|
);
|
|
30
42
|
return response.data.data;
|
|
31
43
|
},
|
|
@@ -33,12 +45,17 @@ export function usePermission(id: number) {
|
|
|
33
45
|
});
|
|
34
46
|
}
|
|
35
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Create a new permission.
|
|
50
|
+
* @param {CreatePermissionDTO} dto DTO containing details.
|
|
51
|
+
* @returns {UseMutationResult<Permission, Error, CreatePermissionDTO>} The mutation result.
|
|
52
|
+
*/
|
|
36
53
|
export function useCreatePermission() {
|
|
37
54
|
const queryClient = useQueryClient();
|
|
38
55
|
return useMutation<Permission, Error, CreatePermissionDTO>({
|
|
39
56
|
mutationFn: async (dto) => {
|
|
40
57
|
const response = await apiClient.post<ApiResponse<Permission>>(
|
|
41
|
-
|
|
58
|
+
`${PATH}/`,
|
|
42
59
|
dto,
|
|
43
60
|
);
|
|
44
61
|
return response.data.data;
|
|
@@ -49,6 +66,14 @@ export function useCreatePermission() {
|
|
|
49
66
|
});
|
|
50
67
|
}
|
|
51
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Replace a permission by ID.
|
|
71
|
+
* @param {number} id ID.
|
|
72
|
+
* @param {ReplacePermissionDTO} dto DTO containing details.
|
|
73
|
+
* @returns {UseMutationResult<Permission,
|
|
74
|
+
Error,
|
|
75
|
+
{ id: number; dto: ReplacePermissionDTO }>} The mutation result.
|
|
76
|
+
*/
|
|
52
77
|
export function useReplacePermission() {
|
|
53
78
|
const queryClient = useQueryClient();
|
|
54
79
|
return useMutation<
|
|
@@ -58,7 +83,7 @@ export function useReplacePermission() {
|
|
|
58
83
|
>({
|
|
59
84
|
mutationFn: async ({ id, dto }) => {
|
|
60
85
|
const response = await apiClient.put<ApiResponse<Permission>>(
|
|
61
|
-
|
|
86
|
+
`${PATH}/${id}`,
|
|
62
87
|
dto,
|
|
63
88
|
);
|
|
64
89
|
return response.data.data;
|
|
@@ -70,6 +95,14 @@ export function useReplacePermission() {
|
|
|
70
95
|
});
|
|
71
96
|
}
|
|
72
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Update a permission by ID.
|
|
100
|
+
* @param {number} id ID.
|
|
101
|
+
* @param {UpdatePermissionDTO} dto DTO containing details.
|
|
102
|
+
* @returns {UseMutationResult<Permission,
|
|
103
|
+
Error,
|
|
104
|
+
{ id: number; dto: UpdatePermissionDTO }>} The mutation result.
|
|
105
|
+
*/
|
|
73
106
|
export function useUpdatePermission() {
|
|
74
107
|
const queryClient = useQueryClient();
|
|
75
108
|
return useMutation<
|
|
@@ -79,7 +112,7 @@ export function useUpdatePermission() {
|
|
|
79
112
|
>({
|
|
80
113
|
mutationFn: async ({ id, dto }) => {
|
|
81
114
|
const response = await apiClient.patch<ApiResponse<Permission>>(
|
|
82
|
-
|
|
115
|
+
`${PATH}/${id}`,
|
|
83
116
|
dto,
|
|
84
117
|
);
|
|
85
118
|
return response.data.data;
|
|
@@ -91,12 +124,17 @@ export function useUpdatePermission() {
|
|
|
91
124
|
});
|
|
92
125
|
}
|
|
93
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Delete a permission by ID.
|
|
129
|
+
* @param {number} dto DTO containing details.
|
|
130
|
+
* @returns {UseMutationResult<Permission, Error, number>} The mutation result.
|
|
131
|
+
*/
|
|
94
132
|
export function useDeletePermission() {
|
|
95
133
|
const queryClient = useQueryClient();
|
|
96
134
|
return useMutation<Permission, Error, number>({
|
|
97
135
|
mutationFn: async (id) => {
|
|
98
136
|
const response = await apiClient.delete<ApiResponse<Permission>>(
|
|
99
|
-
|
|
137
|
+
`${PATH}/${id}`,
|
|
100
138
|
);
|
|
101
139
|
return response.data.data;
|
|
102
140
|
},
|
|
@@ -107,12 +145,21 @@ export function useDeletePermission() {
|
|
|
107
145
|
});
|
|
108
146
|
}
|
|
109
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Get permission with associated roles.
|
|
150
|
+
*
|
|
151
|
+
* All roles that have this permission will be included in the
|
|
152
|
+
* response under a `roles` field.
|
|
153
|
+
*
|
|
154
|
+
* @param {number} id id parameter.
|
|
155
|
+
* @returns {UseQueryResult<Permission>} The query result.
|
|
156
|
+
*/
|
|
110
157
|
export function usePermissionRoles(id: number) {
|
|
111
158
|
return useQuery<Permission>({
|
|
112
159
|
queryKey: ["permissions", id, "roles"],
|
|
113
160
|
queryFn: async () => {
|
|
114
161
|
const response = await apiClient.get<ApiResponse<Permission>>(
|
|
115
|
-
|
|
162
|
+
`${PATH}/${id}/roles`,
|
|
116
163
|
);
|
|
117
164
|
return response.data.data;
|
|
118
165
|
},
|
|
@@ -120,6 +167,14 @@ export function usePermissionRoles(id: number) {
|
|
|
120
167
|
});
|
|
121
168
|
}
|
|
122
169
|
|
|
170
|
+
/**
|
|
171
|
+
* Add a permission to a list of roles.
|
|
172
|
+
* @param {number} id ID.
|
|
173
|
+
* @param {AddPermissionRolesDTO} dto DTO containing details.
|
|
174
|
+
* @returns {UseMutationResult<Permission,
|
|
175
|
+
Error,
|
|
176
|
+
{ id: number; dto: AddPermissionRolesDTO }>} The mutation result.
|
|
177
|
+
*/
|
|
123
178
|
export function useAddPermissionRoles() {
|
|
124
179
|
const queryClient = useQueryClient();
|
|
125
180
|
return useMutation<
|
|
@@ -129,7 +184,7 @@ export function useAddPermissionRoles() {
|
|
|
129
184
|
>({
|
|
130
185
|
mutationFn: async ({ id, dto }) => {
|
|
131
186
|
const response = await apiClient.post<ApiResponse<Permission>>(
|
|
132
|
-
|
|
187
|
+
`${PATH}/${id}/roles`,
|
|
133
188
|
dto,
|
|
134
189
|
);
|
|
135
190
|
return response.data.data;
|
|
@@ -1,33 +1,55 @@
|
|
|
1
1
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
|
2
2
|
import { apiClient, ApiResponse } from "../../api";
|
|
3
|
-
import type {
|
|
3
|
+
import type {
|
|
4
|
+
Role,
|
|
5
|
+
CreateRoleDTO,
|
|
6
|
+
ReplaceRoleDTO,
|
|
7
|
+
UpdateRoleDTO,
|
|
8
|
+
AddRolePermissionsDTO,
|
|
9
|
+
} from "../types/role";
|
|
4
10
|
|
|
11
|
+
const PATH = "/roles";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* List all roles.
|
|
15
|
+
* @returns {UseQueryResult<Role[]>} The query result.
|
|
16
|
+
*/
|
|
5
17
|
export function useRoles() {
|
|
6
18
|
return useQuery<Role[]>({
|
|
7
19
|
queryKey: ["roles"],
|
|
8
20
|
queryFn: async () => {
|
|
9
|
-
const response = await apiClient.get<ApiResponse<Role[]>>(
|
|
21
|
+
const response = await apiClient.get<ApiResponse<Role[]>>(`${PATH}/`);
|
|
10
22
|
return response.data.data;
|
|
11
23
|
},
|
|
12
24
|
});
|
|
13
25
|
}
|
|
14
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Get a role by ID.
|
|
29
|
+
* @param {number} id id parameter.
|
|
30
|
+
* @returns {UseQueryResult<Role>} The query result.
|
|
31
|
+
*/
|
|
15
32
|
export function useRole(id: number) {
|
|
16
33
|
return useQuery<Role>({
|
|
17
34
|
queryKey: ["roles", id],
|
|
18
35
|
queryFn: async () => {
|
|
19
|
-
const response = await apiClient.get<ApiResponse<Role>>(
|
|
36
|
+
const response = await apiClient.get<ApiResponse<Role>>(`${PATH}/${id}`);
|
|
20
37
|
return response.data.data;
|
|
21
38
|
},
|
|
22
39
|
enabled: !!id,
|
|
23
40
|
});
|
|
24
41
|
}
|
|
25
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Create a new role.
|
|
45
|
+
* @param {CreateRoleDTO} dto DTO containing details.
|
|
46
|
+
* @returns {UseMutationResult<Role, Error, CreateRoleDTO>} The mutation result.
|
|
47
|
+
*/
|
|
26
48
|
export function useCreateRole() {
|
|
27
49
|
const queryClient = useQueryClient();
|
|
28
50
|
return useMutation<Role, Error, CreateRoleDTO>({
|
|
29
51
|
mutationFn: async (dto) => {
|
|
30
|
-
const response = await apiClient.post<ApiResponse<Role>>(
|
|
52
|
+
const response = await apiClient.post<ApiResponse<Role>>(`${PATH}/`, dto);
|
|
31
53
|
return response.data.data;
|
|
32
54
|
},
|
|
33
55
|
onSuccess: () => {
|
|
@@ -36,11 +58,20 @@ export function useCreateRole() {
|
|
|
36
58
|
});
|
|
37
59
|
}
|
|
38
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Replace a role by ID.
|
|
63
|
+
* @param {number} id ID.
|
|
64
|
+
* @param {ReplaceRoleDTO} dto DTO containing details.
|
|
65
|
+
* @returns {UseMutationResult<Role, Error, { id: number; dto: ReplaceRoleDTO }>} The mutation result.
|
|
66
|
+
*/
|
|
39
67
|
export function useReplaceRole() {
|
|
40
68
|
const queryClient = useQueryClient();
|
|
41
69
|
return useMutation<Role, Error, { id: number; dto: ReplaceRoleDTO }>({
|
|
42
70
|
mutationFn: async ({ id, dto }) => {
|
|
43
|
-
const response = await apiClient.put<ApiResponse<Role>>(
|
|
71
|
+
const response = await apiClient.put<ApiResponse<Role>>(
|
|
72
|
+
`${PATH}/${id}`,
|
|
73
|
+
dto,
|
|
74
|
+
);
|
|
44
75
|
return response.data.data;
|
|
45
76
|
},
|
|
46
77
|
onSuccess: (_, { id }) => {
|
|
@@ -50,11 +81,20 @@ export function useReplaceRole() {
|
|
|
50
81
|
});
|
|
51
82
|
}
|
|
52
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Update a role by ID.
|
|
86
|
+
* @param {number} id ID.
|
|
87
|
+
* @param {UpdateRoleDTO} dto DTO containing details.
|
|
88
|
+
* @returns {UseMutationResult<Role, Error, { id: number; dto: UpdateRoleDTO }>} The mutation result.
|
|
89
|
+
*/
|
|
53
90
|
export function useUpdateRole() {
|
|
54
91
|
const queryClient = useQueryClient();
|
|
55
92
|
return useMutation<Role, Error, { id: number; dto: UpdateRoleDTO }>({
|
|
56
93
|
mutationFn: async ({ id, dto }) => {
|
|
57
|
-
const response = await apiClient.patch<ApiResponse<Role>>(
|
|
94
|
+
const response = await apiClient.patch<ApiResponse<Role>>(
|
|
95
|
+
`${PATH}/${id}`,
|
|
96
|
+
dto,
|
|
97
|
+
);
|
|
58
98
|
return response.data.data;
|
|
59
99
|
},
|
|
60
100
|
onSuccess: (_, { id }) => {
|
|
@@ -64,11 +104,18 @@ export function useUpdateRole() {
|
|
|
64
104
|
});
|
|
65
105
|
}
|
|
66
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Delete a role by ID.
|
|
109
|
+
* @param {number} dto DTO containing details.
|
|
110
|
+
* @returns {UseMutationResult<Role, Error, number>} The mutation result.
|
|
111
|
+
*/
|
|
67
112
|
export function useDeleteRole() {
|
|
68
113
|
const queryClient = useQueryClient();
|
|
69
114
|
return useMutation<Role, Error, number>({
|
|
70
115
|
mutationFn: async (id) => {
|
|
71
|
-
const response = await apiClient.delete<ApiResponse<Role>>(
|
|
116
|
+
const response = await apiClient.delete<ApiResponse<Role>>(
|
|
117
|
+
`${PATH}/${id}`,
|
|
118
|
+
);
|
|
72
119
|
return response.data.data;
|
|
73
120
|
},
|
|
74
121
|
onSuccess: (_, id) => {
|
|
@@ -78,22 +125,39 @@ export function useDeleteRole() {
|
|
|
78
125
|
});
|
|
79
126
|
}
|
|
80
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Get the permissions for a role by ID.
|
|
130
|
+
* @param {number} id id parameter.
|
|
131
|
+
* @returns {UseQueryResult<Role>} The query result.
|
|
132
|
+
*/
|
|
81
133
|
export function useRolePermissions(id: number) {
|
|
82
134
|
return useQuery<Role>({
|
|
83
135
|
queryKey: ["roles", id, "permissions"],
|
|
84
136
|
queryFn: async () => {
|
|
85
|
-
const response = await apiClient.get<ApiResponse<Role>>(
|
|
137
|
+
const response = await apiClient.get<ApiResponse<Role>>(
|
|
138
|
+
`${PATH}/${id}/permissions`,
|
|
139
|
+
);
|
|
86
140
|
return response.data.data;
|
|
87
141
|
},
|
|
88
142
|
enabled: !!id,
|
|
89
143
|
});
|
|
90
144
|
}
|
|
91
145
|
|
|
146
|
+
/**
|
|
147
|
+
* Add permissions to a role.
|
|
148
|
+
*
|
|
149
|
+
* @param {number} id ID.
|
|
150
|
+
* @param {AddRolePermissionsDTO} dto DTO containing details.
|
|
151
|
+
* @returns {UseMutationResult<Role, Error, { id: number; dto: AddRolePermissionsDTO }>} The mutation result.
|
|
152
|
+
*/
|
|
92
153
|
export function useAddRolePermissions() {
|
|
93
154
|
const queryClient = useQueryClient();
|
|
94
155
|
return useMutation<Role, Error, { id: number; dto: AddRolePermissionsDTO }>({
|
|
95
156
|
mutationFn: async ({ id, dto }) => {
|
|
96
|
-
const response = await apiClient.post<ApiResponse<Role>>(
|
|
157
|
+
const response = await apiClient.post<ApiResponse<Role>>(
|
|
158
|
+
`${PATH}/${id}/permissions`,
|
|
159
|
+
dto,
|
|
160
|
+
);
|
|
97
161
|
return response.data.data;
|
|
98
162
|
},
|
|
99
163
|
onSuccess: (_, { id }) => {
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
2
|
+
import { apiClient, ApiResponse } from "../../api";
|
|
3
|
+
import {
|
|
4
|
+
CreateTicketRequest,
|
|
5
|
+
CreateTicketResponse,
|
|
6
|
+
TicketResponse,
|
|
7
|
+
TicketSearchFilters,
|
|
8
|
+
UpdateTicketStatusRequest,
|
|
9
|
+
UpdateTicketStatusResponse,
|
|
10
|
+
} from "../types/ticket";
|
|
11
|
+
|
|
12
|
+
const PATH = "/tickets";
|
|
13
|
+
|
|
14
|
+
// Query keys
|
|
15
|
+
export const TICKET_KEYS = {
|
|
16
|
+
all: ["tickets"] as const,
|
|
17
|
+
list: (filters: TicketSearchFilters) =>
|
|
18
|
+
[...TICKET_KEYS.all, "list", filters] as const,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get all tickets.
|
|
23
|
+
* @param {TicketSearchFilters} filters filters parameter.
|
|
24
|
+
* @returns {UseQueryResult<TicketResponse[]>} The query result.
|
|
25
|
+
*/
|
|
26
|
+
export const useTickets = (filters: TicketSearchFilters = {}) => {
|
|
27
|
+
return useQuery({
|
|
28
|
+
queryKey: TICKET_KEYS.list(filters),
|
|
29
|
+
queryFn: async (): Promise<TicketResponse[]> => {
|
|
30
|
+
const response = await apiClient.get<ApiResponse<TicketResponse[]>>(
|
|
31
|
+
`${PATH}/`,
|
|
32
|
+
{ params: filters },
|
|
33
|
+
);
|
|
34
|
+
return response.data.data;
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Create a new ticket.
|
|
41
|
+
* @param {CreateTicketRequest} payload The ticket creation details.
|
|
42
|
+
* @returns {UseMutationResult<CreateTicketResponse, Error, CreateTicketRequest>} The mutation result.
|
|
43
|
+
*/
|
|
44
|
+
export const useCreateTicket = () => {
|
|
45
|
+
const queryClient = useQueryClient();
|
|
46
|
+
|
|
47
|
+
return useMutation({
|
|
48
|
+
mutationFn: async (
|
|
49
|
+
payload: CreateTicketRequest,
|
|
50
|
+
): Promise<CreateTicketResponse> => {
|
|
51
|
+
const response = await apiClient.post<ApiResponse<CreateTicketResponse>>(
|
|
52
|
+
`${PATH}/`,
|
|
53
|
+
payload,
|
|
54
|
+
);
|
|
55
|
+
return response.data.data;
|
|
56
|
+
},
|
|
57
|
+
onSuccess: () => {
|
|
58
|
+
// Invalidate tickets list queries on success
|
|
59
|
+
queryClient.invalidateQueries({ queryKey: TICKET_KEYS.all });
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Update a ticket's status.
|
|
66
|
+
* @param {{ ticketId: string; payload: UpdateTicketStatusRequest }} params The ticket ID and status update payload.
|
|
67
|
+
* @returns {UseMutationResult<UpdateTicketStatusResponse, Error, { ticketId: string; payload: UpdateTicketStatusRequest }>} The mutation result.
|
|
68
|
+
*/
|
|
69
|
+
export const useUpdateTicketStatus = () => {
|
|
70
|
+
const queryClient = useQueryClient();
|
|
71
|
+
|
|
72
|
+
return useMutation({
|
|
73
|
+
mutationFn: async ({
|
|
74
|
+
ticketId,
|
|
75
|
+
payload,
|
|
76
|
+
}: {
|
|
77
|
+
ticketId: string;
|
|
78
|
+
payload: UpdateTicketStatusRequest;
|
|
79
|
+
}): Promise<UpdateTicketStatusResponse> => {
|
|
80
|
+
const response = await apiClient.patch<
|
|
81
|
+
ApiResponse<UpdateTicketStatusResponse>
|
|
82
|
+
>(`${PATH}/${ticketId}/status`, payload);
|
|
83
|
+
return response.data.data;
|
|
84
|
+
},
|
|
85
|
+
onSuccess: () => {
|
|
86
|
+
queryClient.invalidateQueries({ queryKey: TICKET_KEYS.all });
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export type TicketType = "issue" | "access" | "new_feature";
|
|
2
|
+
export type TicketCriticality = "high" | "medium" | "low";
|
|
3
|
+
export type TicketStatus =
|
|
4
|
+
| "open"
|
|
5
|
+
| "in_progress"
|
|
6
|
+
| "waiting_for_provider"
|
|
7
|
+
| "waiting_for_validation"
|
|
8
|
+
| "finished";
|
|
9
|
+
|
|
10
|
+
export interface CreateTicketRequest {
|
|
11
|
+
triage_id: string; // PydanticObjectId as string
|
|
12
|
+
type: TicketType;
|
|
13
|
+
criticality: TicketCriticality;
|
|
14
|
+
product: string;
|
|
15
|
+
description: string;
|
|
16
|
+
chat_ids: string[]; // List of PydanticObjectId as string
|
|
17
|
+
client_id: string; // UUID as string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CreateTicketResponse {
|
|
21
|
+
id: string;
|
|
22
|
+
status: TicketStatus;
|
|
23
|
+
creation_date: string; // ISO datetime
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface TicketSearchFilters {
|
|
27
|
+
ticket_id?: string;
|
|
28
|
+
client_id?: string;
|
|
29
|
+
triage_id?: string;
|
|
30
|
+
status?: TicketStatus;
|
|
31
|
+
criticality?: TicketCriticality;
|
|
32
|
+
type?: TicketType;
|
|
33
|
+
product?: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface TicketCompanyResponse {
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface TicketClientResponse {
|
|
42
|
+
id: string;
|
|
43
|
+
name: string;
|
|
44
|
+
email: string;
|
|
45
|
+
company: TicketCompanyResponse;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface TicketHistoryResponse {
|
|
49
|
+
agent_id: string;
|
|
50
|
+
name: string;
|
|
51
|
+
level: string;
|
|
52
|
+
assignment_date: string;
|
|
53
|
+
exit_date: string;
|
|
54
|
+
transfer_reason: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface TicketCommentResponse {
|
|
58
|
+
comment_id: string;
|
|
59
|
+
author: string;
|
|
60
|
+
text: string;
|
|
61
|
+
date: string;
|
|
62
|
+
internal: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface TicketResponse {
|
|
66
|
+
id: string;
|
|
67
|
+
triage_id: string;
|
|
68
|
+
type: TicketType;
|
|
69
|
+
criticality: TicketCriticality;
|
|
70
|
+
product: string;
|
|
71
|
+
status: TicketStatus;
|
|
72
|
+
creation_date: string;
|
|
73
|
+
description: string;
|
|
74
|
+
chat_ids: string[];
|
|
75
|
+
agent_history: TicketHistoryResponse[];
|
|
76
|
+
client: TicketClientResponse;
|
|
77
|
+
comments: TicketCommentResponse[];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface UpdateTicketStatusRequest {
|
|
81
|
+
status: TicketStatus;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface UpdateTicketStatusResponse {
|
|
85
|
+
id: string;
|
|
86
|
+
previous_status: TicketStatus;
|
|
87
|
+
current_status: TicketStatus;
|
|
88
|
+
}
|
|
@@ -12,7 +12,7 @@ const PATH = "/users";
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Get all users.
|
|
15
|
-
* @returns
|
|
15
|
+
* @returns {UseQueryResult<User[]>} The query result.
|
|
16
16
|
*/
|
|
17
17
|
export const useGetUsers = () => {
|
|
18
18
|
return useQuery({
|
|
@@ -28,8 +28,8 @@ export const useGetUsers = () => {
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Get one user.
|
|
31
|
-
* @param id
|
|
32
|
-
* @returns
|
|
31
|
+
* @param {string} id id parameter.
|
|
32
|
+
* @returns {UseQueryResult<User>} The query result.
|
|
33
33
|
*/
|
|
34
34
|
export const useGetUser = (id: string) => {
|
|
35
35
|
return useQuery({
|
|
@@ -44,7 +44,8 @@ export const useGetUser = (id: string) => {
|
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
46
|
* Create a user.
|
|
47
|
-
* @
|
|
47
|
+
* @param {CreateUserDTO} user The user creation details.
|
|
48
|
+
* @returns {UseMutationResult<User, Error, CreateUserDTO>} The mutation result.
|
|
48
49
|
*/
|
|
49
50
|
export const useCreateUser = () => {
|
|
50
51
|
const queryClient = useQueryClient();
|
|
@@ -63,7 +64,8 @@ export const useCreateUser = () => {
|
|
|
63
64
|
|
|
64
65
|
/**
|
|
65
66
|
* Replace an entire user.
|
|
66
|
-
* @
|
|
67
|
+
* @param {{ id: string; data: ReplaceUserDTO }} params The ID and user replacement data.
|
|
68
|
+
* @returns {UseMutationResult<User, Error, { id: string; data: ReplaceUserDTO }>} The mutation result.
|
|
67
69
|
*/
|
|
68
70
|
export const useUpdateUser = () => {
|
|
69
71
|
const queryClient = useQueryClient();
|
|
@@ -91,7 +93,8 @@ export const useUpdateUser = () => {
|
|
|
91
93
|
|
|
92
94
|
/**
|
|
93
95
|
* Update specific fields of a user.
|
|
94
|
-
* @
|
|
96
|
+
* @param {{ id: string; data: UpdateUserDTO }} params The ID and user update data.
|
|
97
|
+
* @returns {UseMutationResult<User, Error, { id: string; data: UpdateUserDTO }>} The mutation result.
|
|
95
98
|
*/
|
|
96
99
|
export const usePatchUser = () => {
|
|
97
100
|
const queryClient = useQueryClient();
|
|
@@ -119,7 +122,8 @@ export const usePatchUser = () => {
|
|
|
119
122
|
|
|
120
123
|
/**
|
|
121
124
|
* Add roles to a user.
|
|
122
|
-
* @
|
|
125
|
+
* @param {{ id: string; data: AddUserRolesDTO }} params The ID and user roles data.
|
|
126
|
+
* @returns {UseMutationResult<User, Error, { id: string; data: AddUserRolesDTO }>} The mutation result.
|
|
123
127
|
*/
|
|
124
128
|
export const useAddUserRoles = () => {
|
|
125
129
|
const queryClient = useQueryClient();
|
package/src/users/index.ts
CHANGED
|
@@ -14,9 +14,3 @@ export type {
|
|
|
14
14
|
ReplaceUserDTO,
|
|
15
15
|
AddUserRolesDTO,
|
|
16
16
|
} from "./types/user";
|
|
17
|
-
|
|
18
|
-
// # syncdesk-api/app/api/api_router
|
|
19
|
-
// - /auth/ -- /app/domains/auth/routers/auth_router
|
|
20
|
-
// | `/api/users/` | User management (CRUD) |
|
|
21
|
-
// | `/api/roles/` | Role management (CRUD) |
|
|
22
|
-
// | `/api/permissions/` | Permission management (CRUD) |
|