Skip to content
Open
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
46 changes: 46 additions & 0 deletions client/src/components/TakeActionAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*!
* Copyright 2025 - Swiss Data Science Center (SDSC)
* A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
* Eidgenössische Technische Hochschule Zürich (ETHZ).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import cx from "classnames";
import { Alert } from "reactstrap";

interface TakeActionAlertProps {
children: React.ReactNode;
"data-cy"?: string;
icon?: React.ReactNode;
className?: string;
}
export default function TakeActionAlert({
children,
icon,
...props
}: TakeActionAlertProps) {
return (
<Alert
color="take-action"
isOpen
data-cy={props["data-cy"]}
className={cx(props.className, "overflow-y-auto")}
>
<div className={cx("d-flex", "gap-3")}>
{icon && <div>{icon}</div>}
<div className={cx("my-auto", "w-100")}>{children}</div>
</div>
</Alert>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import {
Row,
} from "reactstrap";

import RepositoryGitLabWarnBadge from "~/features/legacy/RepositoryGitLabWarnBadge";

import { useLoginUrl } from "../../../../authentication/useLoginUrl.hook";
import {
ErrorAlert,
Expand Down Expand Up @@ -508,6 +510,11 @@ export function RepositoryItem({
</>
)}
</Row>
<Row>
<Col data-cy="repo-gitlab-warning">
<RepositoryGitLabWarnBadge project={project} />
</Col>
</Row>
</ListGroupItem>
{!readonly && (
<RepositoryView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { ProjectImageView } from "../ProjectPageContent/ProjectInformation/Proje

import ProjectAutostartRedirectBanner from "./ProjectAutostartRedirectBanner";
import ProjectCopyBanner from "./ProjectCopyBanner";
import ProjectGitLabWarnBanner from "../../legacy/ProjectGitLabWarnBanner";
import ProjectTemplateInfoBanner from "./ProjectTemplateInfoBanner";

interface ProjectPageHeaderProps {
Expand Down Expand Up @@ -75,6 +76,11 @@ export default function ProjectPageHeader({ project }: ProjectPageHeaderProps) {
</Col>
</Col>
</Row>
<Row>
<Col>
<ProjectGitLabWarnBanner project={project} />
</Col>
</Row>
<Row>
<Col>
{project.is_template && <ProjectCopyBanner project={project} />}
Expand Down
30 changes: 30 additions & 0 deletions client/src/features/legacy/InternalGitLabWarnBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*!
* Copyright 2025 - Swiss Data Science Center (SDSC)
* A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
* Eidgenössische Technische Hochschule Zürich (ETHZ).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import cx from "classnames";
import { EmojiDizzyFill } from "react-bootstrap-icons";
import { Badge } from "reactstrap";

export default function InternalGitLabReferenceWarnBadge() {
return (
<Badge pill color="take-action">
<EmojiDizzyFill className={cx("bi", "me-1")} />
Migration needed
</Badge>
);
}
101 changes: 101 additions & 0 deletions client/src/features/legacy/ProjectGitLabWarnBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*!
* Copyright 2025 - Swiss Data Science Center (SDSC)
* A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
* Eidgenössische Technische Hochschule Zürich (ETHZ).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
import cx from "classnames";
import { EmojiDizzy } from "react-bootstrap-icons";

import { ExternalLink } from "~/components/ExternalLinks";
import TakeActionAlert from "~/components/TakeActionAlert";
import PermissionsGuard from "~/features/permissionsV2/PermissionsGuard";
import type { Project } from "~/features/projectsV2/api/projectV2.api";
import useProjectPermissions from "~/features/ProjectPageV2/utils/useProjectPermissions.hook";
import { useGetProjectsByProjectIdSessionLaunchersQuery } from "~/features/sessionsV2/api/sessionLaunchersV2.api";
import { useGetUserQueryState } from "~/features/usersV2/api/users.api";

import {
DEFAULT_INTERNAL_GITLAB_HOSTS,
doesProjectReferenceRenkulabGitLab,
} from "./legacy.utils";

function ProjectEditorWarnBanner() {
return (
<>
<TakeActionAlert className="p-2" icon={null}>
<div className={cx("d-flex", "align-items-start", "px-4", "py-2")}>
<div>
<h5>
<EmojiDizzy className={cx("bi", "me-3")} />
</h5>
</div>
<div>
<h5>You must take action to avoid losing access to your data.</h5>
<p>
<b>Resources in this project will be removed</b> unless you
migrate them before the RenkuLab GitLab shut down in{" "}
<b>January 2026</b>.
</p>
<div>
<ExternalLink
className="text-take-action"
color="light"
data-cy="help-save-work-button"
role="button"
showLinkIcon={true}
url="https://renku.notion.site/How-to-migrate-out-of-RenkuLab-GitLab-2700df2efafc80c2b442c3ad981d86fc"
>
Help me save my work
</ExternalLink>
</div>
</div>
</div>
</TakeActionAlert>
</>
);
}

export default function ProjectGitLabWarnBanner({
project,
}: {
project: Project;
}) {
const { data: currentUser } = useGetUserQueryState();
const userPermissions = useProjectPermissions({ projectId: project.id });
// There is no way to determine these hosts dynamically
const {
data: launchers,
error: launchersError,
isLoading: isLoadingLaunchers,
} = useGetProjectsByProjectIdSessionLaunchersQuery({ projectId: project.id });
if (currentUser == null) return null;
if (isLoadingLaunchers || launchersError || launchers == null) return null;
if (
!doesProjectReferenceRenkulabGitLab(
project.repositories,
launchers,
DEFAULT_INTERNAL_GITLAB_HOSTS
)
)
return null;
return (
<PermissionsGuard
disabled={null}
enabled={<ProjectEditorWarnBanner />}
requestedPermission="write"
userPermissions={userPermissions}
/>
);
}
63 changes: 63 additions & 0 deletions client/src/features/legacy/RepositoryGitLabWarnBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*!
* Copyright 2025 - Swiss Data Science Center (SDSC)
* A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
* Eidgenössische Technische Hochschule Zürich (ETHZ).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import PermissionsGuard from "~/features/permissionsV2/PermissionsGuard";
import useProjectPermissions from "~/features/ProjectPageV2/utils/useProjectPermissions.hook";
import type { Project } from "~/features/projectsV2/api/projectV2.api";

import InternalGitLabReferenceWarnBadge from "./InternalGitLabWarnBadge";
import {
DEFAULT_INTERNAL_GITLAB_HOSTS,
doesProjectReferenceRenkulabGitLab,
} from "./legacy.utils";

interface RepositoryGitLabWarnBadgeProps {
project: Project;
}

function RepositoryGitLabWarnBadgeForProject({
project,
}: RepositoryGitLabWarnBadgeProps) {
const userPermissions = useProjectPermissions({
projectId: project.id,
});

return (
<PermissionsGuard
disabled={null}
enabled={<InternalGitLabReferenceWarnBadge />}
requestedPermission="write"
userPermissions={userPermissions}
/>
);
}

export default function RepositoryGitLabWarnBadge({
project,
}: RepositoryGitLabWarnBadgeProps) {
if (
!doesProjectReferenceRenkulabGitLab(
project.repositories,
[],
DEFAULT_INTERNAL_GITLAB_HOSTS
)
)
return null;

return <RepositoryGitLabWarnBadgeForProject project={project} />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*!
* Copyright 2025 - Swiss Data Science Center (SDSC)
* A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
* Eidgenössische Technische Hochschule Zürich (ETHZ).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import PermissionsGuard from "~/features/permissionsV2/PermissionsGuard";
import useProjectPermissions from "~/features/ProjectPageV2/utils/useProjectPermissions.hook";
import { SessionLauncher } from "~/features/sessionsV2/api/sessionLaunchersV2.api";

import InternalGitLabReferenceWarnBadge from "./InternalGitLabWarnBadge";
import {
DEFAULT_INTERNAL_GITLAB_HOSTS,
doesProjectReferenceRenkulabGitLab,
} from "./legacy.utils";

type SessionEnvironmentGitLabWarningBadgeForLauncherProps = {
[K in keyof SessionEnvironmentGitLabWarningBadgeProps]-?: NonNullable<
SessionEnvironmentGitLabWarningBadgeProps[K]
>;
};
function SessionEnvironmentGitLabWarningBadgeForLauncher({
launcher,
}: SessionEnvironmentGitLabWarningBadgeForLauncherProps) {
const userPermissions = useProjectPermissions({
projectId: launcher.project_id,
});

return (
<PermissionsGuard
disabled={null}
enabled={<InternalGitLabReferenceWarnBadge />}
requestedPermission="write"
userPermissions={userPermissions}
/>
);
}

interface SessionEnvironmentGitLabWarningBadgeProps {
launcher: SessionLauncher | null | undefined;
}

export default function SessionEnvironmentGitLabWarningBadge({
launcher,
}: SessionEnvironmentGitLabWarningBadgeProps) {
if (!launcher) return null;
if (
!doesProjectReferenceRenkulabGitLab(
undefined,
[launcher],
DEFAULT_INTERNAL_GITLAB_HOSTS
)
)
return null;
return (
<SessionEnvironmentGitLabWarningBadgeForLauncher launcher={launcher} />
);
}
Loading
Loading