Skip to content

Commit 555a9df

Browse files
authored
Update species removal confirmation (#847)
* Also, fix useResizeObserver
1 parent 003ce56 commit 555a9df

6 files changed

Lines changed: 154 additions & 326 deletions

File tree

src/content/app/species/components/species-title-area/SpeciesTitleArea.scss

Lines changed: 80 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,61 +2,17 @@
22

33
$container-padding-right: 20px;
44

5-
@mixin narrow-grid {
6-
grid-template-areas:
7-
'icon species-name usage-toggle'
8-
'icon geneSearchWrapper remove';
9-
grid-template-columns: 60px 150px 1fr;
10-
padding: 20px $container-padding-right 12px 0;
11-
height: auto;
12-
13-
.speciesIcon {
14-
align-self: start;
15-
}
16-
17-
.speciesNameWrapper {
18-
min-height: 60px;
19-
display: flex;
20-
align-items: center;
21-
}
22-
23-
.speciesToggle {
24-
padding: 0;
25-
}
26-
27-
.remove {
28-
align-self: start;
29-
white-space: nowrap;
30-
}
31-
32-
.speciesRemove {
33-
white-space: normal;
34-
}
35-
36-
.geneSearchWrapper {
37-
margin: 0;
38-
}
39-
}
40-
415
.speciesTitleArea {
426
display: grid;
43-
grid-template-areas: 'icon species-name usage-toggle search remove';
7+
grid-template-areas:
8+
'icon species-name usage-toggle search remove'
9+
'. remove-message remove-message remove-message remove-message';
4410
grid-template-columns: 60px fit-content(60%) minmax(200px, 680px) auto 1fr;
11+
grid-template-rows: 80px auto;
4512
grid-column-gap: 20px;
4613
align-items: center;
47-
height: 90px;
4814
margin-left: 60px;
4915
padding-right: $container-padding-right;
50-
51-
@media (max-width: 999px) {
52-
@include narrow-grid;
53-
}
54-
55-
&Narrow {
56-
@media (max-width: 1199px) {
57-
@include narrow-grid;
58-
}
59-
}
6016
}
6117

6218
.speciesIcon {
@@ -85,6 +41,7 @@ $container-padding-right: 20px;
8541
}
8642

8743
.speciesToggle {
44+
grid-area: usage-toggle;
8845
padding-left: 25px;
8946
}
9047

@@ -94,11 +51,21 @@ $container-padding-right: 20px;
9451
white-space: nowrap;
9552
}
9653

97-
.search {
98-
grid-area: search;
54+
.disabledRemoveButton {
55+
background-color: $grey;
56+
color: $white;
57+
border: 1px solid $grey;
58+
cursor: default;
59+
}
60+
61+
.speciesRemoveMessage {
62+
grid-area: remove-message;
63+
justify-content: end;
64+
margin-bottom: 20px;
9965
}
10066

10167
.geneSearchWrapper {
68+
grid-area: search;
10269
color: $blue;
10370
cursor: pointer;
10471
display: inline-flex;
@@ -111,3 +78,66 @@ $container-padding-right: 20px;
11178
width: 13px;
11279
}
11380
}
81+
82+
.speciesTitleAreaCompact {
83+
grid-template-areas:
84+
'icon species-name usage-toggle remove'
85+
'. remove-message remove-message remove-message'
86+
'. search . .';
87+
grid-template-columns: 60px 150px auto 1fr;
88+
grid-template-rows: 80px auto auto;
89+
margin-bottom: 20px;
90+
91+
.speciesNameWrapper {
92+
grid-area: species-name;
93+
min-height: 60px;
94+
display: flex;
95+
align-items: center;
96+
}
97+
98+
.speciesToggle {
99+
grid-area: usage-toggle;
100+
padding: 0;
101+
}
102+
103+
.remove {
104+
grid-area: remove;
105+
align-self: start;
106+
white-space: nowrap;
107+
}
108+
109+
.speciesRemove {
110+
white-space: normal;
111+
}
112+
113+
.speciesRemoveMessage {
114+
grid-area: remove-message;
115+
justify-content: start;
116+
}
117+
118+
.geneSearchWrapper {
119+
grid-area: search;
120+
margin: 0;
121+
}
122+
}
123+
124+
.speciesTitleAreaMinimal {
125+
grid-template-areas:
126+
'icon species-name .'
127+
'. usage-toggle remove'
128+
'. remove-message remove-message'
129+
'. search .';
130+
grid-template-columns: 60px 150px 1fr;
131+
grid-template-rows: 80px 0px auto 40px;
132+
grid-row-gap: 10px;
133+
margin-bottom: 20px;
134+
135+
.speciesRemoveMessage {
136+
margin-top: 20px;
137+
justify-content: start;
138+
}
139+
140+
.speciesToggle {
141+
padding: 0;
142+
}
143+
}

src/content/app/species/components/species-title-area/SpeciesTitleArea.tsx

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,32 +14,51 @@
1414
* limitations under the License.
1515
*/
1616

17-
import React, { useEffect } from 'react';
17+
import React, { useEffect, useState, useRef } from 'react';
1818
import classNames from 'classnames';
19+
import { useNavigate } from 'react-router-dom';
1920

2021
import { useAppSelector, useAppDispatch } from 'src/store';
2122

23+
import * as urlFor from 'src/shared/helpers/urlHelper';
2224
import { getDisplayName } from 'src/shared/components/selected-species/selectedSpeciesHelpers';
25+
26+
import useSpeciesAnalytics from 'src/content/app/species/hooks/useSpeciesAnalytics';
27+
import useResizeObserver from 'src/shared/hooks/useResizeObserver';
28+
29+
import { SecondaryButton } from 'src/shared/components/button/Button';
30+
import DeletionConfirmation from 'src/shared/components/deletion-confirmation/DeletionConfirmation';
31+
2332
import SearchIcon from 'static/icons/icon_search.svg';
2433

25-
import { isSpeciesSidebarOpen as getSidebarStatus } from 'src/content/app/species/state/sidebar/speciesSidebarSelectors';
2634
import { getCommittedSpeciesById } from 'src/content/app/species-selector/state/speciesSelectorSelectors';
2735
import { getActiveGenomeId } from 'src/content/app/species/state/general/speciesGeneralSelectors';
2836
import { getPopularSpecies } from 'src/content/app/species-selector/state/speciesSelectorSelectors';
37+
2938
import {
3039
SpeciesSidebarModalView,
3140
updateSpeciesSidebarModalForGenome
3241
} from 'src/content/app/species/state/sidebar/speciesSidebarSlice';
33-
34-
import { fetchPopularSpecies } from 'src/content/app/species-selector/state/speciesSelectorSlice';
42+
import {
43+
fetchPopularSpecies,
44+
deleteSpeciesAndSave
45+
} from 'src/content/app/species-selector/state/speciesSelectorSlice';
3546

3647
import SpeciesUsageToggle from './species-usage-toggle/SpeciesUsageToggle';
37-
import SpeciesRemove from './species-remove/SpeciesRemove';
3848

3949
import { RootState } from 'src/store';
4050

4151
import styles from './SpeciesTitleArea.scss';
4252

53+
const MEDIUM_WIDTH = 720;
54+
const SMALL_WIDTH = 560;
55+
56+
enum Display {
57+
FULL = 'full',
58+
COMPACT = 'compact',
59+
MINIMAL = 'minimal'
60+
}
61+
4362
const useSpecies = () => {
4463
const activeGenomeId = useAppSelector(getActiveGenomeId);
4564
const popularSpecies = useAppSelector(getPopularSpecies);
@@ -68,12 +87,31 @@ const useSpecies = () => {
6887

6988
const SpeciesTitleArea = () => {
7089
const activeGenomeId = useAppSelector(getActiveGenomeId);
71-
const isSidebarOpen = useAppSelector(getSidebarStatus);
7290
const dispatch = useAppDispatch();
91+
const navigate = useNavigate();
7392
const { species, iconUrl } = useSpecies() || {};
93+
const [isRemoving, setIsRemoving] = useState(false);
94+
const [display, setDisplay] = useState(Display.FULL);
95+
const { trackDeletedSpecies } = useSpeciesAnalytics();
96+
97+
const containerRef = useRef<HTMLDivElement>(null);
98+
const { width: containerWidth } = useResizeObserver({ ref: containerRef });
99+
100+
// TODO:
101+
// Remove the useEffect below when all of our target browsers support CSS container queries
102+
useEffect(() => {
103+
if (containerWidth < SMALL_WIDTH) {
104+
display !== Display.MINIMAL && setDisplay(Display.MINIMAL);
105+
} else if (containerWidth < MEDIUM_WIDTH) {
106+
display !== Display.COMPACT && setDisplay(Display.COMPACT);
107+
} else {
108+
display !== Display.FULL && setDisplay(Display.FULL);
109+
}
110+
}, [containerWidth]);
74111

75112
const blockClasses = classNames(styles.speciesTitleArea, {
76-
[styles.speciesTitleAreaNarrow]: isSidebarOpen
113+
[styles.speciesTitleAreaMinimal]: display === Display.MINIMAL,
114+
[styles.speciesTitleAreaCompact]: display === Display.COMPACT
77115
});
78116

79117
if (!activeGenomeId) {
@@ -89,8 +127,18 @@ const SpeciesTitleArea = () => {
89127
);
90128
};
91129

130+
const toggleRemovalDialog = () => {
131+
setIsRemoving(!isRemoving);
132+
};
133+
134+
const onRemove = () => {
135+
dispatch(deleteSpeciesAndSave(activeGenomeId));
136+
species && trackDeletedSpecies(species);
137+
navigate(urlFor.speciesSelector());
138+
};
139+
92140
return species && iconUrl ? (
93-
<div className={blockClasses}>
141+
<div className={blockClasses} ref={containerRef}>
94142
<div className={styles.speciesIcon}>
95143
<img src={iconUrl} />
96144
</div>
@@ -106,8 +154,24 @@ const SpeciesTitleArea = () => {
106154
<SearchIcon />
107155
</div>
108156
<div className={styles.speciesRemove}>
109-
<SpeciesRemove />
157+
<SecondaryButton
158+
onClick={toggleRemovalDialog}
159+
isDisabled={isRemoving}
160+
className={classNames({ [styles.disabledRemoveButton]: isRemoving })}
161+
>
162+
Remove species
163+
</SecondaryButton>
110164
</div>
165+
{isRemoving && (
166+
<DeletionConfirmation
167+
warningText="If you remove this species, any views you have configured will be lost — do you wish to continue?"
168+
confirmText="Remove"
169+
cancelText="Do not remove"
170+
className={styles.speciesRemoveMessage}
171+
onCancel={toggleRemovalDialog}
172+
onConfirm={onRemove}
173+
/>
174+
)}
111175
</div>
112176
) : (
113177
<div className={blockClasses} />

src/content/app/species/components/species-title-area/species-remove/SpeciesRemove.scss

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)