42
common/resources/client/workspace/requests/change-role.ts
Executable file
42
common/resources/client/workspace/requests/change-role.ts
Executable file
@@ -0,0 +1,42 @@
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {toast} from '../../ui/toast/toast';
|
||||
import {apiClient, queryClient} from '../../http/query-client';
|
||||
import {WorkspaceQueryKeys} from './workspace-query-keys';
|
||||
import {WorkspaceMember} from '../types/workspace-member';
|
||||
import {WorkspaceInvite} from '../types/workspace-invite';
|
||||
import {message} from '../../i18n/message';
|
||||
import {showHttpErrorToast} from '../../utils/http/show-http-error-toast';
|
||||
|
||||
interface Response extends BackendResponse {}
|
||||
|
||||
interface Props {
|
||||
workspaceId: number;
|
||||
member: WorkspaceMember | WorkspaceInvite;
|
||||
roleId: number;
|
||||
}
|
||||
|
||||
function ChangeRole({workspaceId, member, ...other}: Props): Promise<Response> {
|
||||
const modelType = member.model_type;
|
||||
const memberId =
|
||||
member.model_type === 'invite' ? member.id : member.member_id;
|
||||
return apiClient
|
||||
.post(
|
||||
`workspace/${workspaceId}/${modelType}/${memberId}/change-role`,
|
||||
other,
|
||||
)
|
||||
.then(r => r.data);
|
||||
}
|
||||
|
||||
export function useChangeRole() {
|
||||
return useMutation({
|
||||
mutationFn: (props: Props) => ChangeRole(props),
|
||||
onSuccess: (response, props) => {
|
||||
toast(message('Role changed'));
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: WorkspaceQueryKeys.workspaceWithMembers(props.workspaceId),
|
||||
});
|
||||
},
|
||||
onError: err => showHttpErrorToast(err),
|
||||
});
|
||||
}
|
||||
34
common/resources/client/workspace/requests/create-workspace.ts
Executable file
34
common/resources/client/workspace/requests/create-workspace.ts
Executable file
@@ -0,0 +1,34 @@
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {UseFormReturn} from 'react-hook-form';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {toast} from '../../ui/toast/toast';
|
||||
import {apiClient, queryClient} from '../../http/query-client';
|
||||
import {WorkspaceQueryKeys} from './workspace-query-keys';
|
||||
import {Workspace} from '../types/workspace';
|
||||
import {onFormQueryError} from '../../errors/on-form-query-error';
|
||||
import {message} from '../../i18n/message';
|
||||
|
||||
interface Response extends BackendResponse {
|
||||
workspace: Workspace;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export function useCreateWorkspace(form: UseFormReturn<Props>) {
|
||||
return useMutation({
|
||||
mutationFn: (props: Props) => createWorkspace(props),
|
||||
onSuccess: () => {
|
||||
toast(message('Created workspace'));
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: WorkspaceQueryKeys.fetchUserWorkspaces,
|
||||
});
|
||||
},
|
||||
onError: r => onFormQueryError(r, form),
|
||||
});
|
||||
}
|
||||
|
||||
function createWorkspace(props: Props): Promise<Response> {
|
||||
return apiClient.post('workspace', props).then(r => r.data);
|
||||
}
|
||||
36
common/resources/client/workspace/requests/delete-invite.ts
Executable file
36
common/resources/client/workspace/requests/delete-invite.ts
Executable file
@@ -0,0 +1,36 @@
|
||||
import axios from 'axios';
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {toast} from '../../ui/toast/toast';
|
||||
import {apiClient, queryClient} from '../../http/query-client';
|
||||
import {useUserNotifications} from '../../notifications/dialog/requests/user-notifications';
|
||||
import {message} from '../../i18n/message';
|
||||
import {showHttpErrorToast} from '../../utils/http/show-http-error-toast';
|
||||
|
||||
interface Response extends BackendResponse {}
|
||||
|
||||
interface Props {
|
||||
inviteId: string;
|
||||
}
|
||||
|
||||
function deleteInvite({inviteId}: Props): Promise<Response> {
|
||||
return apiClient.delete(`workspace/invite/${inviteId}`).then(r => r.data);
|
||||
}
|
||||
|
||||
export function useDeleteInvite() {
|
||||
return useMutation({
|
||||
mutationFn: (props: Props) => deleteInvite(props),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({queryKey: useUserNotifications.key});
|
||||
toast(message('Declined workspace invitation'));
|
||||
},
|
||||
onError: e => {
|
||||
if (axios.isAxiosError(e) && e.response && e.response.status === 404) {
|
||||
queryClient.invalidateQueries({queryKey: useUserNotifications.key});
|
||||
toast.danger(message('This invite is no longer valid'));
|
||||
} else {
|
||||
showHttpErrorToast(e);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
41
common/resources/client/workspace/requests/delete-workspace.ts
Executable file
41
common/resources/client/workspace/requests/delete-workspace.ts
Executable file
@@ -0,0 +1,41 @@
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {toast} from '../../ui/toast/toast';
|
||||
import {apiClient, queryClient} from '../../http/query-client';
|
||||
import {WorkspaceQueryKeys} from './workspace-query-keys';
|
||||
import {useActiveWorkspaceId} from '../active-workspace-id-context';
|
||||
import {PersonalWorkspace} from '../user-workspaces';
|
||||
import {message} from '../../i18n/message';
|
||||
import {showHttpErrorToast} from '../../utils/http/show-http-error-toast';
|
||||
|
||||
interface Response extends BackendResponse {}
|
||||
|
||||
export interface DeleteWorkspacePayload {
|
||||
id: number;
|
||||
}
|
||||
|
||||
function deleteWorkspace({id}: DeleteWorkspacePayload): Promise<Response> {
|
||||
return apiClient.delete(`workspace/${id}`).then(r => r.data);
|
||||
}
|
||||
|
||||
export function useDeleteWorkspace() {
|
||||
const {workspaceId, setWorkspaceId} = useActiveWorkspaceId();
|
||||
return useMutation({
|
||||
mutationFn: (props: DeleteWorkspacePayload) => deleteWorkspace(props),
|
||||
onSuccess: (r, payload) => {
|
||||
toast(message('Deleted workspace'));
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: WorkspaceQueryKeys.fetchUserWorkspaces,
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: WorkspaceQueryKeys.workspaceWithMembers(payload.id),
|
||||
});
|
||||
|
||||
// if user deleted workspace that is currently active, switch to personal workspace
|
||||
if (workspaceId === payload.id) {
|
||||
setWorkspaceId(PersonalWorkspace.id);
|
||||
}
|
||||
},
|
||||
onError: err => showHttpErrorToast(err),
|
||||
});
|
||||
}
|
||||
34
common/resources/client/workspace/requests/invite-members.ts
Executable file
34
common/resources/client/workspace/requests/invite-members.ts
Executable file
@@ -0,0 +1,34 @@
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {apiClient, queryClient} from '../../http/query-client';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {WorkspaceInvite} from '../types/workspace-invite';
|
||||
import {WorkspaceQueryKeys} from './workspace-query-keys';
|
||||
import {showHttpErrorToast} from '../../utils/http/show-http-error-toast';
|
||||
|
||||
interface Response extends BackendResponse {
|
||||
invites: WorkspaceInvite[];
|
||||
}
|
||||
|
||||
interface Props {
|
||||
workspaceId: number;
|
||||
emails: string[];
|
||||
roleId: number;
|
||||
}
|
||||
|
||||
function InviteMembers({workspaceId, ...other}: Props): Promise<Response> {
|
||||
return apiClient
|
||||
.post(`workspace/${workspaceId}/invite`, other)
|
||||
.then(r => r.data);
|
||||
}
|
||||
|
||||
export function useInviteMembers() {
|
||||
return useMutation({
|
||||
mutationFn: (props: Props) => InviteMembers(props),
|
||||
onSuccess: (response, props) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: WorkspaceQueryKeys.workspaceWithMembers(props.workspaceId),
|
||||
});
|
||||
},
|
||||
onError: err => showHttpErrorToast(err),
|
||||
});
|
||||
}
|
||||
46
common/resources/client/workspace/requests/join-workspace.ts
Executable file
46
common/resources/client/workspace/requests/join-workspace.ts
Executable file
@@ -0,0 +1,46 @@
|
||||
import axios from 'axios';
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {toast} from '../../ui/toast/toast';
|
||||
import {apiClient, queryClient} from '../../http/query-client';
|
||||
import {Workspace} from '../types/workspace';
|
||||
import {WorkspaceQueryKeys} from './workspace-query-keys';
|
||||
import {useActiveWorkspaceId} from '../active-workspace-id-context';
|
||||
import {useUserNotifications} from '../../notifications/dialog/requests/user-notifications';
|
||||
import {message} from '../../i18n/message';
|
||||
import {showHttpErrorToast} from '../../utils/http/show-http-error-toast';
|
||||
|
||||
interface Response extends BackendResponse {
|
||||
workspace: Workspace;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
inviteId: string;
|
||||
}
|
||||
|
||||
export function useJoinWorkspace() {
|
||||
const {setWorkspaceId} = useActiveWorkspaceId() || {};
|
||||
return useMutation({
|
||||
mutationFn: (props: Props) => joinWorkspace(props),
|
||||
onSuccess: response => {
|
||||
toast(message('Joined workspace'));
|
||||
setWorkspaceId(response.workspace.id);
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: WorkspaceQueryKeys.fetchUserWorkspaces,
|
||||
});
|
||||
queryClient.invalidateQueries({queryKey: useUserNotifications.key});
|
||||
},
|
||||
onError: e => {
|
||||
if (axios.isAxiosError(e) && e.response && e.response.status === 404) {
|
||||
queryClient.invalidateQueries({queryKey: useUserNotifications.key});
|
||||
toast.danger(message('This invite is no longer valid'));
|
||||
} else {
|
||||
showHttpErrorToast(e);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function joinWorkspace({inviteId}: Props): Promise<Response> {
|
||||
return apiClient.get(`workspace/join/${inviteId}`).then(r => r.data);
|
||||
}
|
||||
50
common/resources/client/workspace/requests/remove-member.ts
Executable file
50
common/resources/client/workspace/requests/remove-member.ts
Executable file
@@ -0,0 +1,50 @@
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {apiClient, queryClient} from '../../http/query-client';
|
||||
import {WorkspaceQueryKeys} from './workspace-query-keys';
|
||||
import {useAuth} from '../../auth/use-auth';
|
||||
import {useActiveWorkspaceId} from '../active-workspace-id-context';
|
||||
import {PersonalWorkspace} from '../user-workspaces';
|
||||
import {showHttpErrorToast} from '../../utils/http/show-http-error-toast';
|
||||
|
||||
interface Response extends BackendResponse {}
|
||||
|
||||
interface Props {
|
||||
workspaceId: number;
|
||||
memberId: number | string;
|
||||
memberType: 'invite' | 'member';
|
||||
}
|
||||
|
||||
function removeMember({
|
||||
workspaceId,
|
||||
memberId,
|
||||
memberType,
|
||||
}: Props): Promise<Response> {
|
||||
const endpoint =
|
||||
memberType === 'invite'
|
||||
? `workspace/invite/${memberId}`
|
||||
: `workspace/${workspaceId}/member/${memberId}`;
|
||||
return apiClient.delete(endpoint).then(r => r.data);
|
||||
}
|
||||
|
||||
export function useRemoveMember() {
|
||||
const {workspaceId, setWorkspaceId} = useActiveWorkspaceId();
|
||||
const {user} = useAuth();
|
||||
return useMutation({
|
||||
mutationFn: (props: Props) => removeMember(props),
|
||||
onSuccess: (response, props) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: WorkspaceQueryKeys.fetchUserWorkspaces,
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: WorkspaceQueryKeys.workspaceWithMembers(props.workspaceId),
|
||||
});
|
||||
|
||||
// if user left workspace that is currently active, switch to personal workspace
|
||||
if (props.memberId === user?.id && workspaceId === props.workspaceId) {
|
||||
setWorkspaceId(PersonalWorkspace.id);
|
||||
}
|
||||
},
|
||||
onError: err => showHttpErrorToast(err),
|
||||
});
|
||||
}
|
||||
35
common/resources/client/workspace/requests/resend-invite.ts
Executable file
35
common/resources/client/workspace/requests/resend-invite.ts
Executable file
@@ -0,0 +1,35 @@
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {WorkspaceInvite} from '../types/workspace-invite';
|
||||
import {toast} from '../../ui/toast/toast';
|
||||
import {apiClient} from '../../http/query-client';
|
||||
import {showHttpErrorToast} from '../../utils/http/show-http-error-toast';
|
||||
|
||||
interface Response extends BackendResponse {
|
||||
invite: WorkspaceInvite;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
workspaceId: number;
|
||||
inviteId: string;
|
||||
}
|
||||
|
||||
function ResendInvite({
|
||||
workspaceId,
|
||||
inviteId,
|
||||
...other
|
||||
}: Props): Promise<Response> {
|
||||
return apiClient
|
||||
.post(`workspace/${workspaceId}/${inviteId}/resend`, other)
|
||||
.then(r => r.data);
|
||||
}
|
||||
|
||||
export function useResendInvite() {
|
||||
return useMutation({
|
||||
mutationFn: (props: Props) => ResendInvite(props),
|
||||
onSuccess: () => {
|
||||
toast('Invite sent');
|
||||
},
|
||||
onError: err => showHttpErrorToast(err),
|
||||
});
|
||||
}
|
||||
48
common/resources/client/workspace/requests/update-workspace.ts
Executable file
48
common/resources/client/workspace/requests/update-workspace.ts
Executable file
@@ -0,0 +1,48 @@
|
||||
import {useMutation} from '@tanstack/react-query';
|
||||
import {UseFormReturn} from 'react-hook-form';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {toast} from '../../ui/toast/toast';
|
||||
import {apiClient, queryClient} from '../../http/query-client';
|
||||
import {WorkspaceQueryKeys} from './workspace-query-keys';
|
||||
import {Workspace} from '../types/workspace';
|
||||
import {onFormQueryError} from '../../errors/on-form-query-error';
|
||||
import {useDialogContext} from '../../ui/overlays/dialog/dialog-context';
|
||||
import {message} from '../../i18n/message';
|
||||
|
||||
interface Response extends BackendResponse {
|
||||
workspace: Workspace;
|
||||
}
|
||||
|
||||
export interface UpdateWorkspacePayload {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
function updateWorkspace({
|
||||
id,
|
||||
...props
|
||||
}: UpdateWorkspacePayload): Promise<Response> {
|
||||
return apiClient.put(`workspace/${id}`, props).then(r => r.data);
|
||||
}
|
||||
|
||||
export function useUpdateWorkspace(
|
||||
form: UseFormReturn<UpdateWorkspacePayload>,
|
||||
) {
|
||||
const {close} = useDialogContext();
|
||||
return useMutation({
|
||||
mutationFn: (props: UpdateWorkspacePayload) => updateWorkspace(props),
|
||||
onSuccess: response => {
|
||||
close();
|
||||
toast(message('Updated workspace'));
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: WorkspaceQueryKeys.fetchUserWorkspaces,
|
||||
});
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: WorkspaceQueryKeys.workspaceWithMembers(
|
||||
response.workspace.id,
|
||||
),
|
||||
});
|
||||
},
|
||||
onError: r => onFormQueryError(r, form),
|
||||
});
|
||||
}
|
||||
4
common/resources/client/workspace/requests/workspace-query-keys.ts
Executable file
4
common/resources/client/workspace/requests/workspace-query-keys.ts
Executable file
@@ -0,0 +1,4 @@
|
||||
export const WorkspaceQueryKeys = {
|
||||
fetchUserWorkspaces: ['user-workspaces'],
|
||||
workspaceWithMembers: (id: number) => ['workspace-with-members', id],
|
||||
};
|
||||
24
common/resources/client/workspace/requests/workspace-with-members.ts
Executable file
24
common/resources/client/workspace/requests/workspace-with-members.ts
Executable file
@@ -0,0 +1,24 @@
|
||||
import {useQuery} from '@tanstack/react-query';
|
||||
import {WorkspaceQueryKeys} from './workspace-query-keys';
|
||||
import {Workspace} from '../types/workspace';
|
||||
import {BackendResponse} from '../../http/backend-response/backend-response';
|
||||
import {apiClient} from '../../http/query-client';
|
||||
|
||||
export interface FetchWorkspaceWithMembersResponse extends BackendResponse {
|
||||
workspace: Workspace;
|
||||
}
|
||||
|
||||
function fetchWorkspaceWithMembers(
|
||||
workspaceId: number,
|
||||
): Promise<FetchWorkspaceWithMembersResponse> {
|
||||
return apiClient
|
||||
.get(`workspace/${workspaceId}`)
|
||||
.then(response => response.data);
|
||||
}
|
||||
|
||||
export function useWorkspaceWithMembers(workspaceId: number) {
|
||||
return useQuery({
|
||||
queryKey: WorkspaceQueryKeys.workspaceWithMembers(workspaceId),
|
||||
queryFn: () => fetchWorkspaceWithMembers(workspaceId),
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user