Unverified Commit 126e9eba authored by Jyothish's avatar Jyothish Committed by GitHub
Browse files

Replace download with new loading button (#500)

parent 3853e259
Pipeline #160144 passed with stages
in 5 minutes and 27 seconds
......@@ -68,28 +68,31 @@ export const setSearchText = createAction(
'species_selector/set_search_text'
)<string>();
export const updateSearch =
(text: string): ThunkAction<void, any, null, Action<string>> =>
(dispatch, getState: () => RootState) => {
const state = getState();
const selectedItem = getSelectedItem(state);
const previousText = getSearchText(state);
if (selectedItem) {
dispatch(clearSelectedSearchResult());
}
export const updateSearch = (
text: string
): ThunkAction<void, any, null, Action<string>> => (
dispatch,
getState: () => RootState
) => {
const state = getState();
const selectedItem = getSelectedItem(state);
const previousText = getSearchText(state);
if (selectedItem) {
dispatch(clearSelectedSearchResult());
}
const trimmedText = text.trim();
if (text.length < previousText.length) {
// user is deleting their input; clear search results
dispatch(clearSearchResults());
}
const trimmedText = text.trim();
if (text.length < previousText.length) {
// user is deleting their input; clear search results
dispatch(clearSearchResults());
}
if (trimmedText.length >= MINIMUM_SEARCH_LENGTH) {
dispatch(fetchSpeciesSearchResults.request(trimmedText));
}
if (trimmedText.length >= MINIMUM_SEARCH_LENGTH) {
dispatch(fetchSpeciesSearchResults.request(trimmedText));
}
dispatch(setSearchText(text));
};
dispatch(setSearchText(text));
};
export const fetchSpeciesSearchResults = createAsyncAction(
'species_selector/species_search_request',
......@@ -140,163 +143,175 @@ export const clearSelectedSearchResult = createAction(
// }
// };
export const ensureSpeciesIsCommitted =
(genomeId: string): ThunkAction<void, any, null, Action<string>> =>
async (dispatch, getState: () => RootState) => {
const state = getState();
const committedSpecies = getCommittedSpecies(state);
const genomeInfo = getGenomeInfoById(state, genomeId);
if (getCommittedSpeciesById(state, genomeId) || !genomeInfo) {
return;
export const ensureSpeciesIsCommitted = (
genomeId: string
): ThunkAction<void, any, null, Action<string>> => async (
dispatch,
getState: () => RootState
) => {
const state = getState();
const committedSpecies = getCommittedSpecies(state);
const genomeInfo = getGenomeInfoById(state, genomeId);
if (getCommittedSpeciesById(state, genomeId) || !genomeInfo) {
return;
}
const newCommittedSpecies = [
...committedSpecies,
{
...pickBy(genomeInfo, (value, key) => {
return key !== 'example_objects';
}),
isEnabled: true
}
] as CommittedItem[];
dispatch(updateCommittedSpecies(newCommittedSpecies));
speciesSelectorStorageService.saveSelectedSpecies(newCommittedSpecies);
};
export const ensureSpeciesIsEnabled = (
genomeId: string
): ThunkAction<void, any, null, Action<string>> => (
dispatch,
getState: () => RootState
) => {
const state = getState();
const currentSpecies = getCommittedSpeciesById(state, genomeId);
if (!currentSpecies || currentSpecies.isEnabled) {
return;
}
dispatch(toggleSpeciesUseAndSave(genomeId));
};
export const fetchPopularSpecies = (): ThunkAction<
void,
any,
null,
Action<string>
> => async (dispatch) => {
try {
dispatch(fetchPopularSpeciesAsyncActions.request());
const url = '/api/genomesearch/popular_genomes';
const response = await apiService.fetch(url);
dispatch(
fetchPopularSpeciesAsyncActions.success({
popularSpecies: response.popular_species
})
);
} catch (error) {
dispatch(fetchPopularSpeciesAsyncActions.failure(error));
}
};
const newCommittedSpecies = [
...committedSpecies,
{
...pickBy(genomeInfo, (value, key) => {
return key !== 'example_objects';
}),
isEnabled: true
}
] as CommittedItem[];
dispatch(updateCommittedSpecies(newCommittedSpecies));
speciesSelectorStorageService.saveSelectedSpecies(newCommittedSpecies);
};
export const ensureSpeciesIsEnabled =
(genomeId: string): ThunkAction<void, any, null, Action<string>> =>
(dispatch, getState: () => RootState) => {
const state = getState();
const currentSpecies = getCommittedSpeciesById(state, genomeId);
if (!currentSpecies || currentSpecies.isEnabled) {
return;
}
dispatch(toggleSpeciesUseAndSave(genomeId));
};
export const fetchPopularSpecies =
(): ThunkAction<void, any, null, Action<string>> => async (dispatch) => {
try {
dispatch(fetchPopularSpeciesAsyncActions.request());
const url = '/api/genomesearch/popular_genomes';
const response = await apiService.fetch(url);
dispatch(
fetchPopularSpeciesAsyncActions.success({
popularSpecies: response.popular_species
})
);
} catch (error) {
dispatch(fetchPopularSpeciesAsyncActions.failure(error));
}
};
export const handleSelectedSpecies =
(
item: SearchMatch | PopularSpecies
): ThunkAction<void, any, null, Action<string>> =>
(dispatch) => {
dispatch(setSelectedSpecies(item));
export const handleSelectedSpecies = (
item: SearchMatch | PopularSpecies
): ThunkAction<void, any, null, Action<string>> => (dispatch) => {
dispatch(setSelectedSpecies(item));
// TODO: fetch strains when they are ready
// dispatch(fetchStrains(genome_id));
};
// TODO: fetch strains when they are ready
// dispatch(fetchStrains(genome_id));
};
export const updateCommittedSpecies = createAction(
'species_selector/update_committed_species'
)<CommittedItem[]>();
export const commitSelectedSpeciesAndSave =
(): ThunkAction<void, any, null, Action<string>> => (dispatch, getState) => {
const committedSpecies = getCommittedSpecies(getState());
const selectedItem = getSelectedItem(getState());
if (!selectedItem) {
return;
}
const newCommittedSpecies = [
...committedSpecies,
buildCommittedItem(selectedItem)
];
const speciesName = getSpeciesAnalyticsName(selectedItem);
analyticsTracking.setSpeciesDimension(selectedItem.genome_id);
analyticsTracking.trackEvent({
category: categories.ADD_SPECIES,
label: speciesName,
action: 'select'
});
dispatch(updateCommittedSpecies(newCommittedSpecies));
dispatch(clearSelectedSearchResult());
speciesSelectorStorageService.saveSelectedSpecies(newCommittedSpecies);
};
export const toggleSpeciesUseAndSave =
(genomeId: string): ThunkAction<void, any, null, Action<string>> =>
(dispatch, getState) => {
const state = getState();
const committedSpecies = getCommittedSpecies(state);
const currentSpecies = getCommittedSpeciesById(state, genomeId);
if (!currentSpecies) {
return; // should never happen
}
const speciesNameForAnalytics = getSpeciesAnalyticsName(currentSpecies);
const updatedStatus = currentSpecies.isEnabled ? 'do_not_use' : 'use';
const updatedCommittedSpecies = committedSpecies.map((item) => {
return item.genome_id === genomeId
? {
...item,
isEnabled: !item.isEnabled
}
: item;
});
export const commitSelectedSpeciesAndSave = (): ThunkAction<
void,
any,
null,
Action<string>
> => (dispatch, getState) => {
const committedSpecies = getCommittedSpecies(getState());
const selectedItem = getSelectedItem(getState());
if (!selectedItem) {
return;
}
const newCommittedSpecies = [
...committedSpecies,
buildCommittedItem(selectedItem)
];
const speciesName = getSpeciesAnalyticsName(selectedItem);
analyticsTracking.setSpeciesDimension(selectedItem.genome_id);
analyticsTracking.trackEvent({
category: categories.ADD_SPECIES,
label: speciesName,
action: 'select'
});
dispatch(updateCommittedSpecies(newCommittedSpecies));
dispatch(clearSelectedSearchResult());
speciesSelectorStorageService.saveSelectedSpecies(newCommittedSpecies);
};
export const toggleSpeciesUseAndSave = (
genomeId: string
): ThunkAction<void, any, null, Action<string>> => (dispatch, getState) => {
const state = getState();
const committedSpecies = getCommittedSpecies(state);
const currentSpecies = getCommittedSpeciesById(state, genomeId);
if (!currentSpecies) {
return; // should never happen
}
const speciesNameForAnalytics = getSpeciesAnalyticsName(currentSpecies);
const updatedStatus = currentSpecies.isEnabled ? 'do_not_use' : 'use';
const updatedCommittedSpecies = committedSpecies.map((item) => {
return item.genome_id === genomeId
? {
...item,
isEnabled: !item.isEnabled
}
: item;
});
analyticsTracking.trackEvent({
category: categories.SELECTED_SPECIES,
label: speciesNameForAnalytics,
action: updatedStatus
});
dispatch(updateCommittedSpecies(updatedCommittedSpecies));
speciesSelectorStorageService.saveSelectedSpecies(updatedCommittedSpecies);
};
export const deleteSpeciesAndSave = (
genomeId: string
): ThunkAction<void, any, null, Action<string>> => (dispatch, getState) => {
const committedSpecies = getCommittedSpecies(getState());
const deletedSpecies = find(
committedSpecies,
({ genome_id }) => genome_id === genomeId
);
if (deletedSpecies) {
const deletedSpeciesName = getSpeciesAnalyticsName(deletedSpecies);
analyticsTracking.setSpeciesDimension(deletedSpecies.genome_id);
analyticsTracking.trackEvent({
category: categories.SELECTED_SPECIES,
label: speciesNameForAnalytics,
action: updatedStatus
label: deletedSpeciesName,
action: 'unselect'
});
dispatch(updateCommittedSpecies(updatedCommittedSpecies));
speciesSelectorStorageService.saveSelectedSpecies(updatedCommittedSpecies);
};
export const deleteSpeciesAndSave =
(genomeId: string): ThunkAction<void, any, null, Action<string>> =>
(dispatch, getState) => {
const committedSpecies = getCommittedSpecies(getState());
const deletedSpecies = find(
committedSpecies,
({ genome_id }) => genome_id === genomeId
);
if (deletedSpecies) {
const deletedSpeciesName = getSpeciesAnalyticsName(deletedSpecies);
analyticsTracking.setSpeciesDimension(deletedSpecies.genome_id);
analyticsTracking.trackEvent({
category: categories.SELECTED_SPECIES,
label: deletedSpeciesName,
action: 'unselect'
});
}
const updatedCommittedSpecies = committedSpecies.filter(
({ genome_id }) => genome_id !== genomeId
);
dispatch(updateCommittedSpecies(updatedCommittedSpecies));
dispatch(deleteSpeciesInGenomeBrowser(genomeId));
dispatch(deleteSpeciesInEntityViewer(genomeId));
speciesSelectorStorageService.saveSelectedSpecies(updatedCommittedSpecies);
};
}
const updatedCommittedSpecies = committedSpecies.filter(
({ genome_id }) => genome_id !== genomeId
);
dispatch(updateCommittedSpecies(updatedCommittedSpecies));
dispatch(deleteSpeciesInGenomeBrowser(genomeId));
dispatch(deleteSpeciesInEntityViewer(genomeId));
speciesSelectorStorageService.saveSelectedSpecies(updatedCommittedSpecies);
};
......@@ -47,18 +47,14 @@ export const fetchSpeciesSearchResultsEpic: Epic<Action, Action, RootState> = (
// but forget the previous query every time user clears search results
(action1, action2) =>
action1.type === action2.type &&
(
action1 as PayloadAction<
(action1 as PayloadAction<
'species_selector/species_search_request',
string
>).payload ===
(action2 as PayloadAction<
'species_selector/species_search_request',
string
>
).payload ===
(
action2 as PayloadAction<
'species_selector/species_search_request',
string
>
).payload
>).payload
),
filter(
isActionOf(speciesSelectorActions.fetchSpeciesSearchResults.request)
......
......@@ -16,16 +16,16 @@
import React from 'react';
import { PrimaryButton } from 'src/shared/components/button/Button';
import LoadingButton from '../../loading-button';
type Props = {
isDisabled?: boolean;
className?: string;
onClick: () => void;
onClick: () => Promise<unknown>;
};
const InstantDownloadButton = (props: Props) => {
return <PrimaryButton {...props}>Download</PrimaryButton>;
return <LoadingButton {...props}>Download</LoadingButton>;
};
export default InstantDownloadButton;
......@@ -46,11 +46,6 @@
}
}
.downloadButtonDisabled {
border-color: $dark-grey;
color: $dark-grey;
}
.container {
position: relative;
......@@ -68,7 +63,7 @@
}
}
button {
.downloadButton {
margin: 35px 20px 0 0;
float: right;
}
......
......@@ -19,7 +19,10 @@ import intersection from 'lodash/intersection';
import classNames from 'classnames';
import { fetchForGene } from '../instant-download-fetch/fetchForGene';
import { filterTranscriptOptions } from '../instant-download-transcript/InstantDownloadTranscript';
import {
filterTranscriptOptions,
defaultTranscriptOptions
} from '../instant-download-transcript/InstantDownloadTranscript';
import Checkbox from 'src/shared/components/checkbox/Checkbox';
import InstantDownloadButton from '../instant-download-button/InstantDownloadButton';
......@@ -100,7 +103,12 @@ const InstantDownloadGene = (props: Props) => {
setIsGeneSequenceSelected(!isGeneSequenceSelected);
};
const onSubmit = () => {
const resetCheckboxes = () => {
setIsGeneSequenceSelected(false);
setTranscriptOptions(defaultTranscriptOptions);
};
const onSubmit = async () => {
const payload = {
genomeId,
geneId,
......@@ -110,7 +118,11 @@ const InstantDownloadGene = (props: Props) => {
}
};
fetchForGene(payload);
try {
await fetchForGene(payload);
} finally {
resetCheckboxes();
}
};
const themeClass =
......@@ -135,11 +147,12 @@ const InstantDownloadGene = (props: Props) => {
theme={props.theme}
onChange={onTranscriptOptionChange}
/>
<InstantDownloadButton
className={isButtonDisabled ? styles.downloadButtonDisabled : undefined}
isDisabled={isButtonDisabled}
onClick={onSubmit}
/>
<div className={styles.downloadButton}>
<InstantDownloadButton
isDisabled={isButtonDisabled}
onClick={onSubmit}
/>
</div>
</div>
);
};
......
......@@ -8,7 +8,3 @@
margin-right: 20px;
max-width: inherit;
}
.downloadButtonDisabled {
color: $medium-dark-grey;
}
......@@ -50,7 +50,12 @@ const InstantDownloadProtein = (props: InstantDownloadProteinProps) => {
setProteinSeqSelected(!isProteinSeqSelected);
const onCdsCheckboxChange = () => setCdsSeqSelected(!isCdsSeqSelected);
const onSubmit = () => {
const resetCheckboxes = () => {
setProteinSeqSelected(false);
setCdsSeqSelected(false);
};
const onSubmit = async () => {
const payload = {
genomeId,
transcriptId,
......@@ -60,7 +65,11 @@ const InstantDownloadProtein = (props: InstantDownloadProteinProps) => {
}
};
fetchForProtein(payload);
try {
await fetchForProtein(payload);
} finally {
resetCheckboxes();
}
};
const isDownloadDisabled = () => !isProteinSeqSelected && !isCdsSeqSelected;
......@@ -80,9 +89,6 @@ const InstantDownloadProtein = (props: InstantDownloadProteinProps) => {
onChange={onCdsCheckboxChange}
/>
<InstantDownloadButton
className={
isDownloadDisabled() ? styles.downloadButtonDisabled : undefined
}
isDisabled={isDownloadDisabled()}
onClick={onSubmit}
/>
......
......@@ -49,14 +49,14 @@
}
}
.downloadButtonDisabled {
border-color: $dark-grey;
color: $dark-grey;
.downloadButton {
text-align: right;
}
.layout {
display: grid;
font-size: 13px;
align-items: start;
&Horizontal {
grid-template-columns: 1fr 1fr;
......
......@@ -79,7 +79,7 @@ export const transcriptOptionsOrder: TranscriptOption[] = [
'cds'