diff --git a/frontend/app/src/entities/branches/api/rebase-branch-from-api.ts b/frontend/app/src/entities/branches/api/rebase-branch-from-api.ts new file mode 100644 index 0000000000..d4635bdc53 --- /dev/null +++ b/frontend/app/src/entities/branches/api/rebase-branch-from-api.ts @@ -0,0 +1,44 @@ +import graphqlClient from "@/shared/api/graphql/graphqlClientApollo"; +import { gql } from "@apollo/client"; + +export const BRANCH_REBASE = gql` + mutation BRANCH_REBASE($name: String, $waitForCompletion: Boolean!) { + BranchRebase ( + wait_until_completion: $waitForCompletion + data: { + name: $name + } + ) { + ok + object { + id + name + description + origin_branch + branched_from + created_at + sync_with_git + is_default + has_schema_changes + } + task { + id + } + } + } +`; + +export type RebaseBranchFromApiParams = { + branchName: string; + waitForCompletion: boolean; +}; + +export const rebaseBranchFromApi = ({ + branchName, + waitForCompletion, +}: RebaseBranchFromApiParams) => { + return graphqlClient.mutate({ + mutation: BRANCH_REBASE, + variables: { name: branchName, waitForCompletion }, + }); +}; diff --git a/frontend/app/src/entities/branches/api/rebaseBranch.ts b/frontend/app/src/entities/branches/api/rebaseBranch.ts deleted file mode 100644 index 973edd273d..0000000000 --- a/frontend/app/src/entities/branches/api/rebaseBranch.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { gql } from "@apollo/client"; - -export const BRANCH_REBASE = gql` -mutation BRANCH_REBASE($name: String) { - BranchRebase ( - wait_until_completion: false - data: { - name: $name - } - ) { - ok - task { - id - } - } -} -`; diff --git a/frontend/app/src/entities/branches/domain/rebase-branch.ts b/frontend/app/src/entities/branches/domain/rebase-branch.ts new file mode 100644 index 0000000000..1a6aa03e01 --- /dev/null +++ b/frontend/app/src/entities/branches/domain/rebase-branch.ts @@ -0,0 +1,31 @@ +import { rebaseBranchFromApi } from "@/entities/branches/api/rebase-branch-from-api"; +import { Branch } from "@/shared/api/graphql/generated/graphql"; +import { useMutation } from "@tanstack/react-query"; + +export type RebaseBranchParams = { + branchName: string; + waitForCompletion?: boolean; +}; + +export type RebaseBranch = (params: RebaseBranchParams) => Promise<{ + branch: Branch; + relatedTaskId: string | null; +}>; + +export const rebaseBranch: RebaseBranch = async ({ + branchName, + waitForCompletion = true, +}: RebaseBranchParams) => { + const { data } = await rebaseBranchFromApi({ branchName, waitForCompletion }); + + return { + branch: data.BranchRebase.object, + relatedTaskId: data.BranchRebase.task?.id ?? null, + }; +}; + +export const useRebaseBranch = () => { + return useMutation({ + mutationFn: rebaseBranch, + }); +}; diff --git a/frontend/app/src/entities/branches/ui/branch-rebase-button.tsx b/frontend/app/src/entities/branches/ui/branch-rebase-button.tsx index d2b104f8c1..4db07f9f6e 100644 --- a/frontend/app/src/entities/branches/ui/branch-rebase-button.tsx +++ b/frontend/app/src/entities/branches/ui/branch-rebase-button.tsx @@ -1,15 +1,12 @@ import { TASK_OBJECT } from "@/config/constants"; import { useAuth } from "@/entities/authentication/ui/useAuth"; -import { BRANCH_REBASE } from "@/entities/branches/api/rebaseBranch"; +import { useRebaseBranch } from "@/entities/branches/domain/rebase-branch"; import { BRANCH_REBASE_WORKFLOW, TASK_ONGOING_STATES } from "@/entities/tasks/constants"; import { Branch } from "@/shared/api/graphql/generated/graphql"; -import graphqlClient from "@/shared/api/graphql/graphqlClientApollo"; import { Button } from "@/shared/components/buttons/button-primitive"; import { ALERT_TYPES, Alert } from "@/shared/components/ui/alert"; -import { datetimeAtom } from "@/shared/stores/time.atom"; import { useQuery } from "@apollo/client"; import { Icon } from "@iconify-icon/react"; -import { useAtomValue } from "jotai"; import { toast } from "react-toastify"; import { GET_BRANCH_ACTION_STATE } from "../api/getBranchActionState"; @@ -19,9 +16,9 @@ type BranchRebaseButtonProps = { export const BranchRebaseButton = ({ branch }: BranchRebaseButtonProps) => { const { isAuthenticated } = useAuth(); - const date = useAtomValue(datetimeAtom); + const rebaseBranchMutation = useRebaseBranch(); - const { loading, data } = useQuery(GET_BRANCH_ACTION_STATE, { + const { loading, data, refetch } = useQuery(GET_BRANCH_ACTION_STATE, { variables: { branch: branch.name, workflow: [BRANCH_REBASE_WORKFLOW], @@ -32,34 +29,36 @@ export const BranchRebaseButton = ({ branch }: BranchRebaseButtonProps) => { const taskData = data?.[TASK_OBJECT]; - const handleSubmit = async () => { - try { - await graphqlClient.mutate({ - mutation: BRANCH_REBASE, - variables: { - name: branch.name, + const handleRebase = () => { + rebaseBranchMutation.mutate( + { + branchName: branch.name, + waitForCompletion: false, + }, + { + onSuccess: async () => { + toast(, { + toastId: "alert-success", + }); + await refetch(); }, - context: { - branch: branch.name, - date, + onError: (error) => { + console.error("Error while rebasing branch: ", error); + toast( + + ); }, - }); - - toast(, { - toastId: "alert-success", - }); - } catch (error) { - console.error(error); - toast( - - ); - } + } + ); }; return ( - - + + Updated + + + +
-
+
+ -
+
{nodes.length ? ( nodes .filter(({ status }) => status !== "UNCHANGED") @@ -192,7 +124,7 @@ export const NodeDiff = ({ branchName, filters }: NodeDiffProps) => { ) : ( )} -
+
); diff --git a/frontend/app/src/entities/diff/ui/diff-rebase-button.tsx b/frontend/app/src/entities/diff/ui/diff-rebase-button.tsx new file mode 100644 index 0000000000..162551832a --- /dev/null +++ b/frontend/app/src/entities/diff/ui/diff-rebase-button.tsx @@ -0,0 +1,39 @@ +import { useRebaseBranch } from "@/entities/branches/domain/rebase-branch"; +import { useUpdateDiffMutation } from "@/entities/diff/domain/update-diff.mutation"; +import { Button, ButtonProps } from "@/shared/components/buttons/button-primitive"; +import { ALERT_TYPES, Alert } from "@/shared/components/ui/alert"; +import { toast } from "react-toastify"; + +export interface DiffRebaseButtonProps extends ButtonProps { + branchName: string; +} + +export function DiffRebaseButton({ branchName, ...props }: DiffRebaseButtonProps) { + const updateDiffMutation = useUpdateDiffMutation(); + const rebaseBranchMutation = useRebaseBranch(); + + const handleRebase = async () => { + try { + await rebaseBranchMutation.mutateAsync({ branchName }); + toast(); + await updateDiffMutation.mutateAsync(branchName); + } catch (error: unknown) { + if (error instanceof Error) { + toast(); + } + } + }; + + return ( + + ); +} diff --git a/frontend/app/src/entities/diff/ui/diff-refresh-button.tsx b/frontend/app/src/entities/diff/ui/diff-refresh-button.tsx index 36134e2ec5..c3ff5bfec2 100644 --- a/frontend/app/src/entities/diff/ui/diff-refresh-button.tsx +++ b/frontend/app/src/entities/diff/ui/diff-refresh-button.tsx @@ -1,7 +1,11 @@ -import { useUpdateDiffMutation } from "@/entities/diff/domain/update-diff.mutation"; +import { + UPDATE_DIFF_KEY, + useUpdateDiffMutation, +} from "@/entities/diff/domain/update-diff.mutation"; import { Button, ButtonProps } from "@/shared/components/buttons/button-primitive"; import { classNames } from "@/shared/utils/common"; import { Icon } from "@iconify-icon/react"; +import { useMutationState } from "@tanstack/react-query"; export interface DiffRefreshButtonProps extends Omit { branchName: string; @@ -9,6 +13,12 @@ export interface DiffRefreshButtonProps extends Omit { export function DiffRefreshButton({ branchName, ...props }: DiffRefreshButtonProps) { const updateDiffMutation = useUpdateDiffMutation(); + const allUpdatingDiffs = useMutationState({ + filters: { status: "pending", mutationKey: [UPDATE_DIFF_KEY] }, + select: (mutation) => mutation.state.variables, + }); + + const isLoading = allUpdatingDiffs.includes(branchName); return ( ); }