diff --git a/portals-ui/sites/ngs-portal/src/pages/home/components/pipeline-card.tsx b/portals-ui/sites/ngs-portal/src/pages/home/components/pipeline-card.tsx
index dfa5a30ff1..9e271294df 100644
--- a/portals-ui/sites/ngs-portal/src/pages/home/components/pipeline-card.tsx
+++ b/portals-ui/sites/ngs-portal/src/pages/home/components/pipeline-card.tsx
@@ -2,13 +2,15 @@ import { Badge, FlexRow, Button, RichTextView } from '@epam/uui';
import ContentPersonFillIcon from '@epam/assets/icons/content-person-fill.svg?react';
import cn from 'classnames';
import { Link } from 'react-router-dom';
-import type { Pipeline } from '@cloud-pipeline/core';
+import { noop, type Pipeline } from '@cloud-pipeline/core';
import type { CommonProps } from '@cloud-pipeline/components';
import HighlightedText from '../../../shared/highlight-text';
import { NgsUserCard } from '../../../widgets/ngs-user-card';
import './style.css';
import { useMemo } from 'react';
import { NgsTag } from '../../../widgets/ngs-tag';
+import { useUuiContext } from '@epam/uui-core';
+import { PipelineToProjectModal } from '../../../widgets/modals';
type Props = CommonProps & {
pipeline: Pipeline;
@@ -78,6 +80,7 @@ export const PipelineCard = ({
style,
mode = 'standard',
}: Props) => {
+ const { uuiModals } = useUuiContext();
const { id, name, owner, data = {}, description } = pipeline;
const tags = useMemo(
() =>
@@ -87,6 +90,13 @@ export const PipelineCard = ({
[data],
);
+ const openAddPipelineModal = () => {
+ uuiModals
+ .show((props) => )
+ .then(noop)
+ .catch(noop);
+ };
+
const filteredTag = useMemo(() => tags.filter(filterTag), [tags]);
return (
null}
+ onClick={openAddPipelineModal}
/>
)}
diff --git a/portals-ui/sites/ngs-portal/src/pages/home/components/projects-list.tsx b/portals-ui/sites/ngs-portal/src/pages/home/components/projects-list.tsx
index 9f314872ac..1abfb0a3ae 100644
--- a/portals-ui/sites/ngs-portal/src/pages/home/components/projects-list.tsx
+++ b/portals-ui/sites/ngs-portal/src/pages/home/components/projects-list.tsx
@@ -20,23 +20,19 @@ type Props = {
export const ProjectsList = memo(
({ projects, mode = 'standard', filters }: Props) => {
- const { uuiModals} = useUuiContext();
- const {pipelines} = usePipelinesState();
+ const { uuiModals } = useUuiContext();
+ const { pipelines } = usePipelinesState();
const getRandomPipeline = () =>
pipelines?.[Math.floor(Math.random() * pipelines.length)];
useEffect(() => {
- loadPipelines()
- .then(() => {
- })
- .catch(() => {
- });
+ loadPipelines().then(noop).catch(noop);
}, []);
const renderItem = (item: Project, search: string, i: number) => (
@@ -53,7 +49,7 @@ export const ProjectsList = memo(
className="max-h-full list-container overflow-auto"
title={
}
diff --git a/portals-ui/sites/ngs-portal/src/widgets/modals/index.ts b/portals-ui/sites/ngs-portal/src/widgets/modals/index.ts
index e8ad03fdec..48464d97c3 100644
--- a/portals-ui/sites/ngs-portal/src/widgets/modals/index.ts
+++ b/portals-ui/sites/ngs-portal/src/widgets/modals/index.ts
@@ -1 +1,2 @@
export { CreateProjectModal } from './create-project-modal';
+export { PipelineToProjectModal } from './pipeline-to-project-modal';
diff --git a/portals-ui/sites/ngs-portal/src/widgets/modals/pipeline-to-project-modal/index.tsx b/portals-ui/sites/ngs-portal/src/widgets/modals/pipeline-to-project-modal/index.tsx
new file mode 100644
index 0000000000..2c2804f548
--- /dev/null
+++ b/portals-ui/sites/ngs-portal/src/widgets/modals/pipeline-to-project-modal/index.tsx
@@ -0,0 +1,107 @@
+import { noop } from '@cloud-pipeline/core';
+import {
+ ModalHeader,
+ ModalFooter,
+ Button,
+ ModalBlocker,
+ ModalWindow,
+ LabeledInput,
+ PickerInput,
+ SuccessNotification,
+ ErrorNotification,
+} from '@epam/uui';
+import { useArrayDataSource, useUuiContext, type IModal } from '@epam/uui-core';
+import { useEffect, useState } from 'react';
+import CircleLoaderIcon from '@epam/assets/icons/loaders/circle-loader.svg?react';
+import { loadProjects } from '../../../state/projects/load-projects';
+import { useProjectsState } from '../../../state/projects/hooks';
+
+export const PipelineToProjectModal = (props: IModal) => {
+ const { projects } = useProjectsState();
+ const [selectedProjectId, setSelectedProjectId] = useState();
+ useEffect(() => {
+ loadProjects()
+ .then(() => {})
+ .catch(() => {});
+ }, []);
+ const { uuiNotifications } = useUuiContext();
+ const [pending, setPending] = useState(false);
+ const [spin, setSpin] = useState(false);
+ const dataSource = useArrayDataSource(
+ {
+ items: projects,
+ },
+ [],
+ );
+ const onOk = () => {
+ if (pending || !selectedProjectId) {
+ return;
+ }
+ setPending(true);
+ setSpin(true);
+ const selected = projects?.find(({ id }) => id === selectedProjectId);
+ try {
+ uuiNotifications
+ .show((props) => (
+
+ Successfully added to {selected?.name ?? 'project'}.
+
+ ))
+ .then(noop)
+ .catch(noop);
+ props.success('');
+ } catch (error) {
+ uuiNotifications
+ .show((props) => (
+
+ Failed to add to {selected?.name ?? 'project'}.
+
+ {error instanceof Error ? error.message : String(error)}
+
+
+ ))
+ .then(noop)
+ .catch(noop);
+ } finally {
+ setPending(false);
+ setSpin(false);
+ }
+ };
+ return (
+
+
+ props.abort()} />
+
+
Select datastorage:}
+ labelPosition="left">
+
+
+
+
+
+
+
+ );
+};