Skip to content

Commit

Permalink
rebase query
Browse files Browse the repository at this point in the history
  • Loading branch information
bilalabbad committed Feb 5, 2025
1 parent 4d84edf commit e086d34
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 131 deletions.
44 changes: 44 additions & 0 deletions frontend/app/src/entities/branches/api/rebase-branch-from-api.ts
Original file line number Diff line number Diff line change
@@ -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 },
});
};
17 changes: 0 additions & 17 deletions frontend/app/src/entities/branches/api/rebaseBranch.ts

This file was deleted.

31 changes: 31 additions & 0 deletions frontend/app/src/entities/branches/domain/rebase-branch.ts
Original file line number Diff line number Diff line change
@@ -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,
});
};
53 changes: 26 additions & 27 deletions frontend/app/src/entities/branches/ui/branch-rebase-button.tsx
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -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],
Expand All @@ -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(<Alert type={ALERT_TYPES.SUCCESS} message="Branch rebase requested!" />, {
toastId: "alert-success",
});
await refetch();
},
context: {
branch: branch.name,
date,
onError: (error) => {
console.error("Error while rebasing branch: ", error);
toast(
<Alert
type={ALERT_TYPES.ERROR}
message={"An error occurred while merging the branch"}
/>
);
},
});

toast(<Alert type={ALERT_TYPES.SUCCESS} message={"Branch merge requested!"} />, {
toastId: "alert-success",
});
} catch (error) {
console.error(error);
toast(
<Alert type={ALERT_TYPES.ERROR} message={"An error occurred while merging the branch"} />
);
}
}
);
};

return (
<Button
disabled={!isAuthenticated || loading || branch.is_default || taskData?.count > 0}
onClick={handleSubmit}
onClick={handleRebase}
variant={"outline"}
className="flex items-center gap-2"
>
Expand Down
3 changes: 3 additions & 0 deletions frontend/app/src/entities/diff/domain/update-diff.mutation.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { updateDiff } from "@/entities/diff/domain/update-diff";
import { useMutation } from "@tanstack/react-query";

export const UPDATE_DIFF_KEY = "update-diff";

export function useUpdateDiffMutation() {
return useMutation({
mutationKey: [UPDATE_DIFF_KEY],
mutationFn: (branchName: string) => updateDiff(branchName),
});
}
94 changes: 13 additions & 81 deletions frontend/app/src/entities/diff/node-diff/index.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
import { PROPOSED_CHANGES_OBJECT_THREAD_OBJECT } from "@/config/constants";
import { QSP } from "@/config/qsp";
import { BRANCH_REBASE } from "@/entities/branches/api/rebaseBranch";
import { useUpdateDiffMutation } from "@/entities/diff/domain/update-diff.mutation";
import { DIFF_STATUS, DiffNode as DiffNodeType } from "@/entities/diff/node-diff/types";
import { DiffComputing } from "@/entities/diff/ui/diff-computing";
import { DiffEmpty } from "@/entities/diff/ui/diff-empty";
import { DiffNoFound } from "@/entities/diff/ui/diff-no-found";
import { DiffRebaseButton } from "@/entities/diff/ui/diff-rebase-button";
import { DiffRefreshButton } from "@/entities/diff/ui/diff-refresh-button";
import DiffTree from "@/entities/diff/ui/diff-tree";
import { getProposedChangesDiffTree } from "@/entities/proposed-changes/api/getProposedChangesDiffTree";
import { proposedChangedState } from "@/entities/proposed-changes/stores/proposedChanges.atom";
import { schemaState } from "@/entities/schema/stores/schema.atom";
import graphqlClient from "@/shared/api/graphql/graphqlClientApollo";
import useQuery from "@/shared/api/graphql/useQuery";
import { Button } from "@/shared/components/buttons/button-primitive";
import { DateDisplay } from "@/shared/components/display/date-display";
import ErrorScreen from "@/shared/components/errors/error-screen";
import LoadingScreen from "@/shared/components/loading-screen";
import { ALERT_TYPES, Alert } from "@/shared/components/ui/alert";
import { datetimeAtom } from "@/shared/stores/time.atom";
import { NetworkStatus } from "@apollo/client";
import { useAtomValue } from "jotai";
import { createContext, useState } from "react";
import { toast } from "react-toastify";
import { createContext } from "react";
import { StringParam, useQueryParam } from "use-query-params";
import { DiffFilter, ProposedChangeDiffFilter } from "../../proposed-changes/ui/diff-filter";
import { DiffNode } from "./node";
Expand Down Expand Up @@ -52,15 +46,11 @@ const buildFilters = (filters: DiffFilter, qsp?: string | null) => {

export const NodeDiff = ({ branchName, filters }: NodeDiffProps) => {
const [qspStatus] = useQueryParam(QSP.STATUS, StringParam);
const date = useAtomValue(datetimeAtom);
const proposedChangesDetails = useAtomValue(proposedChangedState);
const nodeSchemas = useAtomValue(schemaState);
const [isLoadingUpdate, setIsLoadingUpdate] = useState(false);

const branch = proposedChangesDetails?.source_branch?.value || branchName; // Used in proposed changes view and branch view

const updateDiffMutation = useUpdateDiffMutation();

const schemaData = nodeSchemas.find((s) => s.kind === PROPOSED_CHANGES_OBJECT_THREAD_OBJECT);

// Get filters merged with status filter
Expand All @@ -78,47 +68,6 @@ export const NodeDiff = ({ branchName, filters }: NodeDiffProps) => {
return <ErrorScreen message={error?.message} className="max-w-lg m-auto" />;
}

const handleRefresh = async () => {
setIsLoadingUpdate(true);
try {
await updateDiffMutation.mutateAsync(branch);

await graphqlClient.refetchQueries({
include: ["GET_PROPOSED_CHANGES_DIFF_TREE", "GET_PROPOSED_CHANGES_DIFF_SUMMARY"],
});

toast(<Alert type={ALERT_TYPES.SUCCESS} message="Diff updated!" />);
} catch (error: any) {
toast(<Alert type={ALERT_TYPES.SUCCESS} message={error?.message} />);
}
setIsLoadingUpdate(false);
};

const handleRebase = async () => {
setIsLoadingUpdate(true);

try {
await graphqlClient.mutate({
mutation: BRANCH_REBASE,
variables: {
name: branch,
},
context: {
branch: branchName,
date,
},
});

toast(<Alert type={ALERT_TYPES.SUCCESS} message="Branch rebased!" />);

await handleRefresh();
} catch (error: any) {
toast(<Alert type={ALERT_TYPES.ERROR} message={error?.message} />);
}

setIsLoadingUpdate(false);
};

const diffTreeData = (data || previousData)?.DiffTree;

// When a proposed change is created, there is also a job that compute the diff that is triggered.
Expand Down Expand Up @@ -146,38 +95,21 @@ export const NodeDiff = ({ branchName, filters }: NodeDiffProps) => {

return (
<div className="h-full overflow-hidden flex flex-col">
<div className="flex items-center p-2 bg-custom-white border-b">
<header className="flex items-center px-4 py-2 border-b gap-2">
<ProposedChangeDiffFilter branch={branch} filters={filters} />

<div className="flex flex-1 items-center gap-2 justify-end pr-2">
{isLoadingUpdate && <LoadingScreen size={22} hideText />}

<div className="flex items-center">
<div className="flex items-center text-xs mr-2">
<span className="mr-1">Updated</span>
<DateDisplay date={diffTreeData?.to_time} />
</div>

<DiffRefreshButton size="sm" variant="primary" branchName={branch} />
</div>

<Button
size="sm"
variant="primary-outline"
onClick={handleRebase}
disabled={isLoadingUpdate}
>
Rebase
</Button>
</div>
</div>
<span className="text-xs inline-flex gap-1 ml-auto">
Updated <DateDisplay date={diffTreeData?.to_time} />
</span>
<DiffRefreshButton size="sm" variant="primary" branchName={branch} />
<DiffRebaseButton branchName={branch} />
</header>

<div className="flex-grow grid grid-cols-4 overflow-hidden">
<div className="p-4 col-span-1 overflow-auto border-r">
<nav className="p-4 col-span-1 overflow-auto border-r">
<DiffTree nodes={nodes} className="w-full" />
</div>
</nav>

<div className="space-y-4 p-4 col-start-2 col-end-5 overflow-auto bg-stone-100">
<main className="space-y-4 p-4 col-start-2 col-end-5 overflow-auto bg-stone-100">
{nodes.length ? (
nodes
.filter(({ status }) => status !== "UNCHANGED")
Expand All @@ -192,7 +124,7 @@ export const NodeDiff = ({ branchName, filters }: NodeDiffProps) => {
) : (
<DiffNoFound diffStatus={qspStatus as string} />
)}
</div>
</main>
</div>
</div>
);
Expand Down
39 changes: 39 additions & 0 deletions frontend/app/src/entities/diff/ui/diff-rebase-button.tsx
Original file line number Diff line number Diff line change
@@ -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(<Alert type={ALERT_TYPES.SUCCESS} message="Branch rebased!" />);
await updateDiffMutation.mutateAsync(branchName);
} catch (error: unknown) {
if (error instanceof Error) {
toast(<Alert type={ALERT_TYPES.ERROR} message={error.message} />);
}
}
};

return (
<Button
size="sm"
variant="primary-outline"
onClick={handleRebase}
isLoading={rebaseBranchMutation.isPending}
disabled={rebaseBranchMutation.isPending}
{...props}
>
Rebase
</Button>
);
}
Loading

0 comments on commit e086d34

Please sign in to comment.