Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
ensembl-web
ensembl-client
Commits
126e9eba
Unverified
Commit
126e9eba
authored
May 28, 2021
by
Jyothish
Committed by
GitHub
May 28, 2021
Browse files
Replace download with new loading button (#500)
parent
3853e259
Pipeline
#160144
passed with stages
in 5 minutes and 27 seconds
Changes
10
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
247 additions
and
215 deletions
+247
-215
src/ensembl/src/content/app/species-selector/state/speciesSelectorActions.ts
...tent/app/species-selector/state/speciesSelectorActions.ts
+182
-167
src/ensembl/src/content/app/species-selector/state/speciesSelectorEpics.ts
...ontent/app/species-selector/state/speciesSelectorEpics.ts
+6
-10
src/ensembl/src/shared/components/instant-download/instant-download-button/InstantDownloadButton.tsx
...ownload/instant-download-button/InstantDownloadButton.tsx
+3
-3
src/ensembl/src/shared/components/instant-download/instant-download-gene/InstantDownloadGene.scss
...t-download/instant-download-gene/InstantDownloadGene.scss
+1
-6
src/ensembl/src/shared/components/instant-download/instant-download-gene/InstantDownloadGene.tsx
...nt-download/instant-download-gene/InstantDownloadGene.tsx
+21
-8
src/ensembl/src/shared/components/instant-download/instant-download-protein/InstantDownloadProtein.scss
...load/instant-download-protein/InstantDownloadProtein.scss
+0
-4
src/ensembl/src/shared/components/instant-download/instant-download-protein/InstantDownloadProtein.tsx
...nload/instant-download-protein/InstantDownloadProtein.tsx
+11
-5
src/ensembl/src/shared/components/instant-download/instant-download-transcript/InstantDownloadTranscript.scss
...nstant-download-transcript/InstantDownloadTranscript.scss
+4
-4
src/ensembl/src/shared/components/instant-download/instant-download-transcript/InstantDownloadTranscript.tsx
...instant-download-transcript/InstantDownloadTranscript.tsx
+18
-8
src/ensembl/src/shared/components/loading-button/LoadingButton.tsx
...bl/src/shared/components/loading-button/LoadingButton.tsx
+1
-0
No files found.
src/ensembl/src/content/app/species-selector/state/speciesSelectorActions.ts
View file @
126e9eba
...
...
@@ -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
:
s
peciesName
ForAnalytics
,
action
:
updatedStatus
label
:
deletedS
peciesName
,
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
);
};
src/ensembl/src/content/app/species-selector/state/speciesSelectorEpics.ts
View file @
126e9eba
...
...
@@ -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
)
...
...
src/ensembl/src/shared/components/instant-download/instant-download-button/InstantDownloadButton.tsx
View file @
126e9eba
...
...
@@ -16,16 +16,16 @@
import
React
from
'
react
'
;
import
{
Primary
Button
}
from
'
src/shared/components/button/B
utton
'
;
import
Loading
Button
from
'
../../loading-b
utton
'
;
type
Props
=
{
isDisabled
?:
boolean
;
className
?:
string
;
onClick
:
()
=>
void
;
onClick
:
()
=>
Promise
<
unknown
>
;
};
const
InstantDownloadButton
=
(
props
:
Props
)
=>
{
return
<
Primary
Button
{
...
props
}
>
Download
</
Primary
Button
>;
return
<
Loading
Button
{
...
props
}
>
Download
</
Loading
Button
>;
};
export
default
InstantDownloadButton
;
src/ensembl/src/shared/components/instant-download/instant-download-gene/InstantDownloadGene.scss
View file @
126e9eba
...
...
@@ -46,11 +46,6 @@
}
}
.downloadButtonDisabled
{
border-color
:
$dark-grey
;
color
:
$dark-grey
;
}
.container
{
position
:
relative
;
...
...
@@ -68,7 +63,7 @@
}
}
b
utton
{
.downloadB
utton
{
margin
:
35px
20px
0
0
;
float
:
right
;
}
...
...
src/ensembl/src/shared/components/instant-download/instant-download-gene/InstantDownloadGene.tsx
View file @
126e9eba
...
...
@@ -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
>
);
};
...
...
src/ensembl/src/shared/components/instant-download/instant-download-protein/InstantDownloadProtein.scss
View file @
126e9eba
...
...
@@ -8,7 +8,3 @@
margin-right
:
20px
;
max-width
:
inherit
;
}
.downloadButtonDisabled
{
color
:
$medium-dark-grey
;
}
src/ensembl/src/shared/components/instant-download/instant-download-protein/InstantDownloadProtein.tsx
View file @
126e9eba
...
...
@@ -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
}
/>
...
...
src/ensembl/src/shared/components/instant-download/instant-download-transcript/InstantDownloadTranscript.scss
View file @
126e9eba
...
...
@@ -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
;
...
...
src/ensembl/src/shared/components/instant-download/instant-download-transcript/InstantDownloadTranscript.tsx
View file @
126e9eba
...
...
@@ -79,7 +79,7 @@ export const transcriptOptionsOrder: TranscriptOption[] = [
'
cds
'
];