Skip to content

Commit 78df036

Browse files
authored
feat(aggregations): confirm when deleting pipeline COMPASS-4137 (#3915)
1 parent 0ef9e52 commit 78df036

File tree

11 files changed

+475
-270
lines changed

11 files changed

+475
-270
lines changed

packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-header/index.spec.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ describe('PipelineHeader', function () {
2222
isOpenPipelineVisible
2323
isSavedPipelineVisible={false}
2424
isOptionsVisible
25-
namespace="test.pineapple"
26-
savedPipelines={[]}
2725
showRunButton
2826
showExportButton
2927
showExplainButton

packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-header/index.tsx

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { connect } from 'react-redux';
1313
import PipelineStages from './pipeline-stages';
1414
import PipelineActions from './pipeline-actions';
1515
import { setShowSavedPipelines } from '../../../modules/saved-pipeline';
16-
import { SavedPipelines } from '../../saved-pipelines/saved-pipelines';
16+
import SavedPipelines from '../../saved-pipelines/saved-pipelines';
1717
import type { RootState } from '../../../modules';
1818

1919
const containerStyles = css({
@@ -63,19 +63,16 @@ const savedAggregationsPopoverStyles = css({
6363

6464
type PipelineHeaderProps = {
6565
isOptionsVisible: boolean;
66-
namespace: string;
6766
showRunButton: boolean;
6867
showExportButton: boolean;
6968
showExplainButton: boolean;
7069
onToggleSavedPipelines: (show: boolean) => void;
7170
onToggleOptions: () => void;
7271
isOpenPipelineVisible: boolean;
7372
isSavedPipelineVisible: boolean;
74-
savedPipelines: { id: string; name: string }[];
7573
};
7674

7775
export const PipelineHeader: React.FunctionComponent<PipelineHeaderProps> = ({
78-
namespace,
7976
showRunButton,
8077
showExportButton,
8178
showExplainButton,
@@ -84,10 +81,12 @@ export const PipelineHeader: React.FunctionComponent<PipelineHeaderProps> = ({
8481
isOptionsVisible,
8582
isOpenPipelineVisible,
8683
isSavedPipelineVisible,
87-
savedPipelines,
8884
}) => {
8985
const containedElements = useMemo(() => {
90-
return ['[data-id="open-pipeline-confirmation-modal"]']
86+
return [
87+
'[data-id="open-pipeline-confirmation-modal"]',
88+
'[data-id="delete-pipeline-confirmation-modal"]',
89+
]
9190
}, [])
9291

9392
return (
@@ -99,7 +98,10 @@ export const PipelineHeader: React.FunctionComponent<PipelineHeaderProps> = ({
9998
// To prevent popover from closing when confirmation modal is shown
10099
containedElements={containedElements}
101100
trigger={({ onClick, ref, children }) => (
102-
<div className={pipelineTextAndOpenStyles}>
101+
<div
102+
data-testid="saved-pipelines-popover"
103+
className={pipelineTextAndOpenStyles}
104+
>
103105
<Body weight="medium">Pipeline</Body>
104106
<button
105107
data-testid="pipeline-toolbar-open-pipelines-button"
@@ -120,10 +122,7 @@ export const PipelineHeader: React.FunctionComponent<PipelineHeaderProps> = ({
120122
open={isSavedPipelineVisible}
121123
setOpen={onToggleSavedPipelines}
122124
>
123-
<SavedPipelines
124-
namespace={namespace}
125-
savedPipelines={savedPipelines}
126-
/>
125+
<SavedPipelines />
127126
</InteractivePopover>
128127
)}
129128
<div className={pipelineStagesStyles}>
@@ -147,10 +146,6 @@ export default connect(
147146
return {
148147
isOpenPipelineVisible: !state.editViewName && !state.isAtlasDeployed,
149148
isSavedPipelineVisible: state.savedPipeline.isListVisible,
150-
// TODO: this component should not be the one connected to the saved
151-
// pipelines state as it's not the one using it
152-
namespace: state.namespace,
153-
savedPipelines: state.savedPipeline.pipelines
154149
};
155150
},
156151
{

packages/compass-aggregations/src/components/saved-pipelines/saved-pipeline-card.spec.jsx

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 37 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,22 @@
1-
import React, { useCallback, useState } from 'react';
2-
import { createLoggerAndTelemetry } from '@mongodb-js/compass-logging';
3-
import { connect } from 'react-redux';
4-
import { deletePipeline, openPipelineById } from '../../modules/saved-pipeline';
1+
import React from 'react';
52
import {
63
Body,
74
Button,
8-
ConfirmationModal,
95
css,
106
cx,
117
Icon,
128
KeylineCard,
139
spacing
1410
} from '@mongodb-js/compass-components';
15-
import type { RootState } from '../../modules';
16-
import {
17-
type EditorViewType,
18-
mapPipelineModeToEditorViewType,
19-
} from '../../modules/pipeline-builder/builder-helpers';
20-
21-
const { track } = createLoggerAndTelemetry('COMPASS-AGGREGATIONS-UI');
2211

2312
type SavePipelineCardProps = {
2413
id: string;
2514
name: string;
26-
editor_view_type: EditorViewType;
27-
onOpenPipelineConfirm: (id: string) => void;
28-
onDeletePipeline: (id: string) => void;
15+
onOpenPipeline: () => void;
16+
onDeletePipeline: () => void;
2917
};
3018

31-
const cardOuter = css({
19+
const containerStyles = css({
3220
margin: spacing[2]
3321
});
3422

@@ -54,95 +42,43 @@ const button = css({
5442
flex: 'none'
5543
});
5644

57-
const SavePipelineCard: React.FunctionComponent<SavePipelineCardProps> = ({
45+
export const SavePipelineCard: React.FunctionComponent<SavePipelineCardProps> = ({
5846
id,
5947
name,
60-
editor_view_type,
61-
onOpenPipelineConfirm,
48+
onOpenPipeline,
6249
onDeletePipeline
6350
}) => {
64-
const [showConfirmModal, setShowConfirmModal] = useState(false);
65-
66-
const onDelete = useCallback(() => {
67-
track('Aggregation Deleted', {
68-
id,
69-
editor_view_type,
70-
screen: 'aggregations',
71-
});
72-
onDeletePipeline(id);
73-
}, [id, editor_view_type, onDeletePipeline]);
74-
75-
const onOpenConfirm = useCallback(() => {
76-
track('Aggregation Opened', {
77-
id,
78-
editor_view_type,
79-
screen: 'aggregations',
80-
});
81-
setShowConfirmModal(false);
82-
onOpenPipelineConfirm(id);
83-
}, [id, editor_view_type, onOpenPipelineConfirm]);
84-
8551
return (
86-
<>
87-
<ConfirmationModal
88-
data-id="open-pipeline-confirmation-modal"
89-
title="Are you sure you want to open this pipeline?"
90-
open={showConfirmModal}
91-
onConfirm={() => {
92-
onOpenConfirm();
93-
}}
94-
onCancel={() => {
95-
setShowConfirmModal(false);
96-
}}
97-
buttonText="Open Pipeline"
98-
trackingId="restore_pipeline_modal"
99-
data-testid="restore-pipeline-modal"
52+
<div className={containerStyles}>
53+
<KeylineCard
54+
className={card}
55+
data-testid="saved-pipeline-card"
56+
data-pipeline-object-id={id}
57+
data-pipeline-object-name={name}
10058
>
101-
Opening this project will abandon <b>unsaved</b> changes to the current
102-
pipeline you are building.
103-
</ConfirmationModal>
104-
<div className={cardOuter}>
105-
<KeylineCard
106-
className={card}
107-
data-testid="saved-pipeline-card"
108-
data-pipeline-object-id={id}
109-
>
110-
<Body as="div" data-testid="saved-pipeline-card-name">
111-
{name}
112-
</Body>
113-
<div className={cx(controls, 'controls')}>
114-
<Button
115-
className={button}
116-
size="xsmall"
117-
onClick={() => {
118-
setShowConfirmModal(true);
119-
}}
120-
>
121-
Open
122-
</Button>
123-
<Button
124-
className={button}
125-
size="xsmall"
126-
onClick={onDelete}
127-
aria-label="Delete"
128-
>
129-
<Icon size="small" glyph="Trash"></Icon>
130-
</Button>
131-
</div>
132-
</KeylineCard>
133-
</div>
134-
</>
59+
<Body as="div" data-testid="saved-pipeline-card-name">
60+
{name}
61+
</Body>
62+
<div className={cx(controls, 'controls')}>
63+
<Button
64+
className={button}
65+
size="xsmall"
66+
onClick={onOpenPipeline}
67+
data-testid="saved-pipeline-card-open-action"
68+
>
69+
Open
70+
</Button>
71+
<Button
72+
className={button}
73+
size="xsmall"
74+
onClick={onDeletePipeline}
75+
aria-label="Delete"
76+
data-testid="saved-pipeline-card-delete-action"
77+
>
78+
<Icon size="small" glyph="Trash"></Icon>
79+
</Button>
80+
</div>
81+
</KeylineCard>
82+
</div>
13583
);
136-
};
137-
138-
export default connect(
139-
(state: RootState) => ({
140-
editor_view_type: mapPipelineModeToEditorViewType(
141-
state.pipelineBuilder.pipelineMode
142-
),
143-
}),
144-
{
145-
onOpenPipelineConfirm: openPipelineById,
146-
onDeletePipeline: deletePipeline,
147-
}
148-
)(SavePipelineCard);
84+
};
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React from 'react';
2+
import { ConfirmationModal } from '@mongodb-js/compass-components';
3+
4+
export const OpenPipelineConfirmationModal: React.FunctionComponent<{
5+
isOpen: boolean;
6+
onCancel: () => void;
7+
onConfirm: () => void;
8+
}> = ({ isOpen, onCancel, onConfirm }) => {
9+
return (
10+
<ConfirmationModal
11+
data-id="open-pipeline-confirmation-modal"
12+
title="Are you sure you want to open this pipeline?"
13+
open={isOpen}
14+
onConfirm={onConfirm}
15+
onCancel={onCancel}
16+
buttonText="Open Pipeline"
17+
trackingId="restore_pipeline_modal"
18+
data-testid="restore-pipeline-modal"
19+
>
20+
Opening this project will abandon <b>unsaved</b> changes to the current
21+
pipeline you are building.
22+
</ConfirmationModal>
23+
);
24+
};
25+
26+
export const DeletePipelineConfirmationModal: React.FunctionComponent<{
27+
isOpen: boolean;
28+
onCancel: () => void;
29+
onConfirm: () => void;
30+
}> = ({ isOpen, onCancel, onConfirm }) => {
31+
return (
32+
<ConfirmationModal
33+
data-id="delete-pipeline-confirmation-modal"
34+
title="Are you sure you want to delete this pipeline?"
35+
open={isOpen}
36+
onConfirm={onConfirm}
37+
onCancel={onCancel}
38+
buttonText="Delete Pipeline"
39+
trackingId="delete_pipeline_modal"
40+
data-testid="delete-pipeline-modal"
41+
>
42+
Deleting this pipeline will remove it from your saved pipelines.
43+
</ConfirmationModal>
44+
);
45+
};
46+
47+

0 commit comments

Comments
 (0)