Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 0 additions & 32 deletions client/src/components/buttons/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import {
ArrowRight,
ChevronDown,
ThreeDotsVertical,

Check warning on line 30 in client/src/components/buttons/Button.tsx

View workflow job for this annotation

GitHub Actions / test-client

'ThreeDotsVertical' is defined but never used
} from "react-bootstrap-icons";
import { Link } from "react-router";
import {
Expand Down Expand Up @@ -163,38 +163,6 @@
);
}

export function SingleButtonWithMenu({
children,
className,
color,
direction,
disabled,
id,
size,
}: Omit<ButtonWithMenuV2Props, "default" | "preventPropagation">) {
return (
<UncontrolledDropdown
className={className}
color={color ?? "primary"}
direction={direction ?? "down"}
disabled={disabled}
id={id}
size={size ?? "md"}
>
<DropdownToggle
caret={false}
data-bs-toggle="dropdown"
color={color ?? "primary"}
data-cy="button-with-menu-dropdown"
disabled={disabled}
>
<ThreeDotsVertical />
</DropdownToggle>
<DropdownMenu end>{children}</DropdownMenu>
</UncontrolledDropdown>
);
}

/*
* underline Link with icon
*/
Expand Down
1 change: 1 addition & 0 deletions client/src/components/entities/entities.types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export type EntityTypes =
| "code-repository"
| "data-connector"
| "project"
| "session-launcher";
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import cx from "classnames";
import {
Database,
FileCode,
Folder,
PlayCircle,
QuestionCircle,
} from "react-bootstrap-icons";
Expand Down Expand Up @@ -31,6 +32,8 @@ export default function OffcanvasHeaderWithType({
<PlayCircle className="me-1" />
) : entityType === "code-repository" ? (
<FileCode className="me-1" />
) : entityType === "project" ? (
<Folder className="me-1" />
) : (
<QuestionCircle className="me-1" />
);
Expand All @@ -43,7 +46,9 @@ export default function OffcanvasHeaderWithType({
? "Session launcher"
: entityType === "code-repository"
? "Code repository"
: "Unknown";
: entityType === "project"
? "Project"
: "Unknown";

return (
<div>
Expand Down
75 changes: 75 additions & 0 deletions client/src/features/ProjectPageV2/ProjectOffcanvas.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// interface DataConnectorViewProps {
// dataConnector: DataConnectorRead;
// dataConnectorLink?: DataConnectorToProjectLink;
// lastDeposit?: Deposit;
// showView: boolean;
// toggleView: () => void;
// toggleEdit: (initialStep?: number) => void;
// dataConnectorPotentiallyInaccessible?: boolean;
// }

import cx from "classnames";
import { generatePath } from "react-router";
import { Offcanvas, OffcanvasBody } from "reactstrap";

import OffcanvasHeaderWithType from "~/components/offcanvas/OffcanvasHeaderWithType";
import OffcanvasTopButtons from "~/components/offcanvas/OffcanvasTopButtons";
import { ABSOLUTE_ROUTES } from "~/routing/routes.constants";
import { Project } from "../projectsV2/api/projectV2.api";
import ProjectInformation from "./ProjectPageContent/ProjectInformation/ProjectInformation";
import ProjectCopyBanner from "./ProjectPageHeader/ProjectCopyBanner";
import ProjectTemplateInfoBanner from "./ProjectPageHeader/ProjectTemplateInfoBanner";

interface ProjectInformationProps {
isOffcanvasOpen: boolean;
project: Project;
toggleOffcanvas: () => void;
}
export default function ProjectOffcanvas({
isOffcanvasOpen,
project,
toggleOffcanvas,
}: ProjectInformationProps) {
const fullPageLink = generatePath(ABSOLUTE_ROUTES.v2.projects.show.root, {
namespace: project.namespace,
slug: project.slug,
});

return (
<Offcanvas
toggle={toggleOffcanvas}
isOpen={isOffcanvasOpen}
direction="end"
backdrop={true}
>
<OffcanvasBody data-cy="project-offcanvas-view">
<OffcanvasTopButtons
entityType="project"
fullPageLink={fullPageLink}
toggleView={toggleOffcanvas}
/>

<div className={cx("d-flex", "flex-column", "gap-3")}>
<OffcanvasHeaderWithType
entityType="project"
title={project.name}
></OffcanvasHeaderWithType>

{project.description && (
<p className="mb-0" data-cy="project-description">
{project.description}
</p>
)}
{project.is_template && (
<>
<ProjectTemplateInfoBanner project={project} />
<ProjectCopyBanner project={project} />
</>
)}

<ProjectInformation project={project} />
</div>
</OffcanvasBody>
</Offcanvas>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

import KeywordBadge from "~/components/keywords/KeywordBadge";
import KeywordContainer from "~/components/keywords/KeywordContainer";
import { useProject } from "~/routes/projects/root";

Check warning on line 36 in client/src/features/ProjectPageV2/ProjectPageContent/ProjectInformation/ProjectInformation.tsx

View workflow job for this annotation

GitHub Actions / test-client

'useProject' is defined but never used
import { UnderlineArrowLink } from "../../../../components/buttons/Button";
import { Loader } from "../../../../components/Loader";
import { TimeCaption } from "../../../../components/TimeCaption";
Expand Down Expand Up @@ -105,13 +105,13 @@
}

interface ProjectInformationProps {
output?: "plain" | "card";
headerTag?: "h2" | "h3" | "h4";
project: Project;
}
export default function ProjectInformation({
output = "plain",
headerTag = "h2",
project,
}: ProjectInformationProps) {
const { project } = useProject();

const permissions = useProjectPermissions({ projectId: project.id });

const { data: members } = useGetProjectsByProjectIdMembersQuery({
Expand Down Expand Up @@ -208,29 +208,28 @@
<ProjectCopyTemplateInformationBox project={project} />
</div>
);
return output === "plain" ? (
information
) : (

const Header = headerTag;
return (
<Card data-cy="project-info-card">
<CardHeader>
<div
className={cx(
"align-items-center",
"d-flex",
"justify-content-between",
)}
>
<h2 className="m-0">
<InfoCircle className={cx("me-1", "bi")} />
Info
</h2>
<CardHeader
className={cx(
"align-items-center",
"d-flex",
"justify-content-between",
)}
tag="div"
>
<Header className="m-0">
<InfoCircle className={cx("me-1", "bi")} />
Info
</Header>

<div>
<ProjectInformationButton
userPermissions={permissions}
project={project}
/>
</div>
<div>
<ProjectInformationButton
userPermissions={permissions}
project={project}
/>
</div>
</CardHeader>
<CardBody>{information}</CardBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@
* limitations under the License.
*/

import cx from "classnames";
import { useCallback, useState } from "react";
import { DropdownItem } from "reactstrap";
import { useCallback, useRef, useState } from "react";
import { Button, UncontrolledTooltip } from "reactstrap";

import { useGetUserQueryState } from "~/features/usersV2/api/users.api";
import { SingleButtonWithMenu } from "../../../../components/buttons/Button";
import BootstrapCopyIcon from "../../../../components/icons/BootstrapCopyIcon";
import type { Project } from "../../../projectsV2/api/projectV2.api";
import ProjectCopyModal from "../../ProjectPageHeader/ProjectCopyModal";
Expand All @@ -38,27 +36,29 @@ export default function ProjectInformationButton({
const toggleCopyModal = useCallback(() => {
setCopyModalOpen((open) => !open);
}, []);
const ref = useRef(null);

const isUserLoggedIn = !!currentUser?.isLoggedIn;
if (!isUserLoggedIn) return null;
return (
<>
<SingleButtonWithMenu color="outline-primary" size="sm">
<DropdownItem
data-cy="project-copy-menu-item"
onClick={toggleCopyModal}
>
<BootstrapCopyIcon className={cx("bi")} />
<span className={cx("ms-2")}>Copy project</span>
</DropdownItem>
</SingleButtonWithMenu>
{
<ProjectCopyModal
currentUser={currentUser}
isOpen={isCopyModalOpen}
project={project}
toggle={toggleCopyModal}
/>
}
</>
<div ref={ref}>
<Button
color="outline-primary"
data-cy="project-copy-button"
onClick={toggleCopyModal}
size="sm"
>
<BootstrapCopyIcon />
</Button>
<UncontrolledTooltip target={ref} trigger="hover">
Copy project
</UncontrolledTooltip>
<ProjectCopyModal
currentUser={currentUser}
isOpen={isCopyModalOpen}
project={project}
toggle={toggleCopyModal}
/>
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
* limitations under the License
*/

import { useState } from "react";
import { Col, Row } from "reactstrap";

import { useProject } from "~/routes/projects/root";
import SessionsV2 from "../../sessionsV2/SessionsV2";
import ProjectOffcanvas from "../ProjectOffcanvas";
import { CodeRepositoriesDisplay } from "./CodeRepositories/RepositoriesBox";
import ProjectDataConnectorsBox from "./DataConnectors/ProjectDataConnectorsBox";
import Documentation from "./Documentation/Documentation";
Expand All @@ -28,6 +30,8 @@ import ProjectInformation from "./ProjectInformation/ProjectInformation";
export default function ProjectOverviewPage() {
const { project } = useProject();

const [isOffcanvasOpen, setIsOffcanvasOpen] = useState(true);

return (
<Row className="g-4">
<Col xs={12} md={8} xl={9}>
Expand All @@ -48,9 +52,14 @@ export default function ProjectOverviewPage() {
</Col>
<Col xs={12} md={4} xl={3}>
<div className="mb-3">
<ProjectInformation output="card" />
<ProjectInformation project={project} />
</div>
</Col>
<ProjectOffcanvas
isOffcanvasOpen={isOffcanvasOpen}
project={project}
toggleOffcanvas={() => setIsOffcanvasOpen(!isOffcanvasOpen)}
/>
</Row>
);
}
Loading