Skip to content

Commit

Permalink
[INNO] ARC-2714 - Adding modals for backfill page (#2598)
Browse files Browse the repository at this point in the history
* - Modal added for backfilling and disconnecting subscription

* - Fixing eslint in a test case

* - WIP - backfill modal

* - WIP - backfill modal

* - WIP - backfill modal

* - Using the corrected datepicker

* - Fixing the delete subscription endpoint

* - Test cases added
- TODO updated

* - Fixing test cases
  • Loading branch information
krazziekay authored Dec 8, 2023
1 parent c6020bb commit a5ebf21
Show file tree
Hide file tree
Showing 10 changed files with 445 additions and 19 deletions.
2 changes: 2 additions & 0 deletions spa/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
"@atlaskit/avatar": "^21.3.9",
"@atlaskit/badge": "^15.1.14",
"@atlaskit/button": "^16.8.0",
"@atlaskit/checkbox": "^13.0.1",
"@atlaskit/css-reset": "^6.5.2",
"@atlaskit/dropdown-menu": "^12.1.8",
"@atlaskit/datetime-picker": "^13.0.3",
"@atlaskit/dynamic-table": "^14.11.5",
"@atlaskit/form": "^8.11.8",
"@atlaskit/heading": "^1.3.7",
Expand Down
2 changes: 1 addition & 1 deletion spa/src/common/Wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const wrapperStyle = css`
`;
const wrapperCenterStyle = css`
margin: 0 auto;
max-width: 800px;
max-width: 580px;
height: calc(100vh - ${navHeight * 2}px);
display: flex;
flex-direction: column;
Expand Down
59 changes: 50 additions & 9 deletions spa/src/pages/Connections/GHCloudConnections/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
/** @jsxImportSource @emotion/react */
import { useState } from "react";
import { DynamicTableStateless } from "@atlaskit/dynamic-table";
import {
head,
getGHSubscriptionsRows,
} from "../../../utils/dynamicTableHelper";
import { GhCloudSubscriptions } from "../../../rest-interfaces";
import { BackfillPageModalTypes, GhCloudSubscriptions } from "../../../rest-interfaces";
import { Box, xcss } from "@atlaskit/primitives";
import { SuccessfulConnection } from "rest-interfaces";
import DisconnectSubscriptionModal from "../Modals/DisconnectSubscriptionModal";
import RestartBackfillModal from "../Modals/RestartBackfillModal";
import { ModalTransition } from "@atlaskit/modal-dialog";

const containerStyles = xcss({
display: "flex",
Expand All @@ -15,18 +20,54 @@ const containerStyles = xcss({
type GitHubCloudConnectionsProps = {
ghCloudSubscriptions: GhCloudSubscriptions;
};

const GitHubCloudConnections = ({
ghCloudSubscriptions,
}: GitHubCloudConnectionsProps) => {
const [isModalOpened, setIsModalOpened] = useState(false);
const [subscriptionForModal, setSubscriptionForModal] = useState<SuccessfulConnection | undefined>(undefined);
const [selectedModal, setSelectedModal] = useState<BackfillPageModalTypes>("BACKFILL");

const openedModal = () => {
switch (selectedModal) {
case "BACKFILL":
return (<RestartBackfillModal
subscription={subscriptionForModal as SuccessfulConnection}
setIsModalOpened={setIsModalOpened}
/>);
case "DISCONNECT_SUBSCRIPTION":
return <DisconnectSubscriptionModal
subscription={subscriptionForModal as SuccessfulConnection}
setIsModalOpened={setIsModalOpened}
/>;
// TODO: Create modals for GHE later
case "DISCONNECT_SERVER":
case "DISCONNECT_SERVER_APP":
default:
return <></>;
}
};

return (
<Box xcss={containerStyles}>
<DynamicTableStateless
head={head}
rows={getGHSubscriptionsRows(ghCloudSubscriptions.successfulCloudConnections)}
rowsPerPage={5}
page={1}
/>
</Box>
<>
<Box xcss={containerStyles}>
<DynamicTableStateless
head={head}
rows={getGHSubscriptionsRows(
ghCloudSubscriptions.successfulCloudConnections,
{ setIsModalOpened, setSubscriptionForModal, setSelectedModal }
)}
rowsPerPage={5}
page={1}
/>
</Box>

<ModalTransition>
{
isModalOpened && subscriptionForModal && openedModal()
}
</ModalTransition>
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import { BrowserRouter } from "react-router-dom";
import userEvent from "@testing-library/user-event";
import DisconnectSubscriptionModal from "./DisconnectSubscriptionModal";

const sampleSubscription = {
app_slug: "string",
syncWarning: "warning",
id: 1,
account: {
login: "sample",
id: 1,
avatar_url: "string",
},
repository_selection: "string",
app_id: 1,
target_id: 1,
target_type: "string",
created_at: "string",
updated_at: "string",
syncStatus: "string",
totalNumberOfRepos: 2,
numberOfSyncedRepos: 2,
jiraHost: "https://test-jira.atlassian.net",
isGlobalInstall: true,
backfillSince: null,
subscriptionId: 1,
html_url: "html_url"
};
const isModalOpened = jest.fn();

test("Disconnect subscription Modal", async () => {
render(
<BrowserRouter>
<DisconnectSubscriptionModal subscription={sampleSubscription} setIsModalOpened={isModalOpened} />
</BrowserRouter>
);

expect(screen.getByText("Disconnect sample?")).toBeInTheDocument();
const text = screen.getByTestId("disconnect-content");
expect(text.textContent).toBe("Are you sure you want to disconnect your organization sample? This means that you will have to redo the backfill of historical data if you ever want to reconnect");

await userEvent.click(screen.getByText("Cancel"));
expect(isModalOpened).toBeCalled();
});
44 changes: 44 additions & 0 deletions spa/src/pages/Connections/Modals/DisconnectSubscriptionModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Modal, { ModalBody, ModalFooter, ModalHeader, ModalTitle } from "@atlaskit/modal-dialog";
import Button from "@atlaskit/button";
import { SuccessfulConnection } from "../../../../../src/rest-interfaces";

/**
* NOTE: While testing in dev mode, please disable the React.StrictMode first,
* otherwise this modal won't show up.
*/
const DisconnectSubscriptionModal = ({ subscription, setIsModalOpened }: {
subscription: SuccessfulConnection,
setIsModalOpened: (x: boolean) => void
}) => {
const disconnect = () => {
// TODO: API call to disconnect this subscription
console.log("Disconnect", subscription.account.login);
setIsModalOpened(false);
};

return (
<>
<Modal onClose={() => setIsModalOpened(false)}>
<ModalHeader>
<ModalTitle appearance="warning">
<>Disconnect {subscription.account.login}?</>
</ModalTitle>
</ModalHeader>
<ModalBody>
<p data-testid="disconnect-content">
Are you sure you want to disconnect your organization <b>{subscription.account.login}</b>?
This means that you will have to redo the backfill of historical data if you ever want to reconnect
</p>
</ModalBody>
<ModalFooter>
<Button appearance="subtle" onClick={() => setIsModalOpened(false)}>Cancel</Button>
<Button appearance="danger" onClick={disconnect}>
Disconnect
</Button>
</ModalFooter>
</Modal>
</>
);
};

export default DisconnectSubscriptionModal;
46 changes: 46 additions & 0 deletions spa/src/pages/Connections/Modals/RestartBackfillModal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import { BrowserRouter } from "react-router-dom";
import userEvent from "@testing-library/user-event";
import RestartBackfillModal from "./RestartBackfillModal";

const sampleSubscription = {
app_slug: "string",
syncWarning: "warning",
id: 1,
account: {
login: "sample",
id: 1,
avatar_url: "string",
},
repository_selection: "string",
app_id: 1,
target_id: 1,
target_type: "string",
created_at: "string",
updated_at: "string",
syncStatus: "string",
totalNumberOfRepos: 2,
numberOfSyncedRepos: 2,
jiraHost: "https://test-jira.atlassian.net",
isGlobalInstall: true,
backfillSince: null,
subscriptionId: 1,
html_url: "html_url"
};
const isModalOpened = jest.fn();

test("Restart backfill Modal", async () => {
render(
<BrowserRouter>
<RestartBackfillModal subscription={sampleSubscription} setIsModalOpened={isModalOpened} />
</BrowserRouter>
);

expect(screen.getByText("Backfill your data")).toBeInTheDocument();
// expect(screen.queryByTestId("backfill-datepicker")).toBeInTheDocument();
expect(screen.getByRole("checkbox", {name: "Restart the backfill from today to this date"})).toBeInTheDocument();

await userEvent.click(screen.getByText("Cancel"));
expect(isModalOpened).toBeCalled();
});
81 changes: 81 additions & 0 deletions spa/src/pages/Connections/Modals/RestartBackfillModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { useEffect, useState } from "react";
import Modal, { ModalBody, ModalFooter, ModalHeader, ModalTitle } from "@atlaskit/modal-dialog";
import Button from "@atlaskit/button";
import { SuccessfulConnection } from "../../../../../src/rest-interfaces";
import { Checkbox } from "@atlaskit/checkbox";
import { Label } from "@atlaskit/form";
import { DatePicker } from "@atlaskit/datetime-picker";

/**
* NOTE: While testing in dev mode, please disable the React.StrictMode first,
* otherwise this modal won't show up.
*/
const RestartBackfillModal = ({ subscription, setIsModalOpened }: {
subscription: SuccessfulConnection,
setIsModalOpened: (x: boolean) => void
}) => {
const [restartFromDateCheck, setRestartFromDateCheck] = useState(false);
const [backfillDate, setBackfillDate] = useState("");

/**
* TODO: Remove this later once the issue within datepicker is identified and fixed
* Thread: https://atlassian.slack.com/archives/CFJ9DU39U/p1701912243843529
*
* The datepicker jumps around when rendered inside a modal,
* Until that is fixed, adding a short disable for the datepicker,
* which is then enabled to avoid having the jumpy effect.
*/
const [isDisabled, setIsDisabled] = useState(true);
useEffect(() => {
setTimeout(() => setIsDisabled(false), 10);
}, []);

const backfill = () => {
// TODO: API call to disconnect this subscription
console.log("Backfill for", subscription.account.login, restartFromDateCheck, backfillDate);
setIsModalOpened(false);
};

return (
<>
<Modal onClose={() => setIsModalOpened(false)}>
<ModalHeader>
<ModalTitle>Backfill your data</ModalTitle>
</ModalHeader>
<ModalBody>
<p>
Backfilling data can take a long time, so we’ll only backfill your data from the last 6 months.
If you want to backfill more data, choose a date below. Branches will be backfilled regardless of their age.
</p>
<p>
<Label htmlFor="backfill-date-picker">Choose date</Label>
<DatePicker
testId="backfill-datepicker"
selectProps={{
inputId: "backfill-date-picker",
}}
placeholder="Select date"
isDisabled={isDisabled} // TODO: remove this later
onChange={setBackfillDate}
/>
</p>
<p>
<Checkbox
onChange={() => setRestartFromDateCheck(!restartFromDateCheck)}
label={`Restart the backfill from today to this date`}
name="restart-from-selected-date"
/>
</p>
</ModalBody>
<ModalFooter>
<Button appearance="subtle" onClick={() => setIsModalOpened(false)}>Cancel</Button>
<Button appearance="danger" onClick={backfill}>
Backfill data
</Button>
</ModalFooter>
</Modal>
</>
);
};

export default RestartBackfillModal;
29 changes: 27 additions & 2 deletions spa/src/utils/dynamicTableHelper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Avatar from "@atlaskit/avatar";
import Badge from "@atlaskit/badge";
import { token } from "@atlaskit/tokens";
import Lozenge from "@atlaskit/lozenge";
import { SuccessfulConnection } from "../rest-interfaces";
import { BackfillPageModalTypes, SuccessfulConnection } from "../rest-interfaces";
import { ThemeAppearance } from "@atlaskit/lozenge/dist/types/Lozenge";
import { css } from "@emotion/react";
import EditIcon from "@atlaskit/icon/glyph/edit";
Expand All @@ -17,6 +17,12 @@ type Row = {
cells: { key: string | number; content: React.JSX.Element | string | number }[];
};

type ConnectionsActionsCallback = {
setIsModalOpened: (x: boolean) => void;
setSubscriptionForModal: (sub: SuccessfulConnection) => void;
setSelectedModal: (x: BackfillPageModalTypes) => void;
};

const rowWrapperStyle = css`
display: flex;
align-items: center;
Expand Down Expand Up @@ -82,7 +88,8 @@ const createHead = (withWidth: boolean) => {
export const head = createHead(true);

export const getGHSubscriptionsRows = (
SuccessfulConnections: SuccessfulConnection[]
SuccessfulConnections: SuccessfulConnection[],
callbacks?: ConnectionsActionsCallback
): Row[] => {
if (!SuccessfulConnections) {
return [];
Expand Down Expand Up @@ -194,6 +201,24 @@ export const getGHSubscriptionsRows = (
>
Configure
</DropdownItem>
<DropdownItem
onClick={() => {
callbacks?.setIsModalOpened(true);
callbacks?.setSubscriptionForModal(cloudConnection);
callbacks?.setSelectedModal("BACKFILL");
}}
>
Backfill
</DropdownItem>
<DropdownItem
onClick={() => {
callbacks?.setIsModalOpened(true);
callbacks?.setSubscriptionForModal(cloudConnection);
callbacks?.setSelectedModal("DISCONNECT_SUBSCRIPTION");
}}
>
Disconnect
</DropdownItem>
</DropdownItemGroup>
</DropdownMenu>
</div>
Expand Down
Loading

0 comments on commit a5ebf21

Please sign in to comment.