Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cursor issue with oql editor and improve styling and behavior #2976

Merged
merged 1 commit into from
Jan 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/pages/studyView/studyPageHeader/rightPanel/RightPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@ export default class RightPanel extends React.Component<IRightPanelProps, {}> {
return (
<div className="studyViewSummaryHeader">
<div className={styles.rightPanel}>
<div className={"small"}>
<OQLTextArea
inputGeneQuery={this.props.store.geneQueryStr}
validateInputGeneQuery={false}
callback={this.updateSelectedGenes}
location={GeneBoxType.STUDY_VIEW_PAGE}
/>
</div>
<button
disabled={this.isQueryButtonDisabled}
className={classnames(
Expand Down
4 changes: 0 additions & 4 deletions src/pages/studyView/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,6 @@ $selectHeightInner: $selectHeight - 2px;
width: 100%;
}

#geneBoxValidationStatus > div {
max-width: 280px;
}

#wideGeneBoxValidationStatus > div {
max-width: 555px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('GeneSymbolValidator', () => {
},
geneQuery: 'TP53',
skipGeneValidation: false,
replaceGene: ()=>{},
updateGeneQuery: () => null,
} as IGeneSymbolValidatorProps;
wrapper = mount(<GeneSymbolValidator {...props} />);
Expand Down
17 changes: 2 additions & 15 deletions src/shared/components/GeneSelectionBox/GeneSymbolValidator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface IGeneSymbolValidatorProps {
oql: OQL
) => void;
wrap?: boolean;
replaceGene:(oldSymbol: string, newSymbol: string)=>void;
}

export type GeneValidationResult = {
Expand Down Expand Up @@ -194,24 +195,10 @@ export default class GeneSymbolValidator extends React.Component<
}
errorMessageOnly={this.props.errorMessageOnly}
wrapTheContent={this.props.wrap}
replaceGene={this.replaceGene}
replaceGene={this.props.replaceGene}
>
{this.props.children}
</GeneSymbolValidatorMessage>
);
}

@autobind
@action
private replaceGene(oldSymbol: string, newSymbol: string) {
let updatedQuery = normalizeQuery(
this.props.geneQuery
.toUpperCase()
.replace(
new RegExp(`\\b${oldSymbol.toUpperCase()}\\b`, 'g'),
() => newSymbol.toUpperCase()
)
);
this.props.updateGeneQuery(updatedQuery);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { GeneReplacement } from 'shared/components/query/QueryStore';
import ReactSelect from 'react-select1';
import classNames from 'classnames';
import * as _ from 'lodash';
import {DropdownButton, MenuItem} from "react-bootstrap";

export type GeneSymbolValidatorMessageProps = {
errorMessageOnly?: boolean;
Expand Down Expand Up @@ -67,15 +68,21 @@ const RenderSuggestion = function(props: RenderSuggestionProps) {
<div className={styles.suggestionBubble} title={title}>
<FontAwesome className={styles.icon} name="question" />
<span className={styles.multiChoiceLabel}>{props.alias}</span>
<span>{': '}</span>
<ReactSelect
placeholder="select a symbol"
options={options}
onChange={(option: any) =>
option && props.replaceGene(props.alias, option.value)
<span>{':'}&nbsp;</span>
<DropdownButton
bsStyle={title.toLowerCase()}
bsSize="xsmall"
title="Select symbol"
id={`geneReplace_${props.alias}`}
>
{
options.map((item, i)=>{
return <MenuItem onClick={()=>{ props.replaceGene(props.alias, item.value) }} eventKey={i+1}>{item.label}</MenuItem>
})
}
autosize
/>
</DropdownButton>


</div>
);
};
Expand Down Expand Up @@ -131,14 +138,15 @@ const GeneSymbolValidatorMessageChild = (
<span>Invalid gene symbols.</span>
</div>

{props.genes.suggestions.map((suggestion, index) => (
{
props.genes.suggestions.map((suggestion, index) =>
<RenderSuggestion
key={index}
genes={suggestion.genes}
alias={suggestion.alias}
replaceGene={props.replaceGene}
/>
))}
/>)
}
</div>
);
}
Expand Down Expand Up @@ -213,7 +221,7 @@ class GeneSymbolValidatorMessage extends React.Component<

return (
<div id="geneBoxValidationStatus">
<GeneSymbolValidatorMessageChild {...this.props} />
<GeneSymbolValidatorMessageChild replaceGene={this.props.replaceGene} {...this.props} />
</div>
);
}
Expand Down
49 changes: 38 additions & 11 deletions src/shared/components/GeneSelectionBox/OQLTextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from 'mobx';
import { Gene } from 'shared/api/generated/CBioPortalAPI';
import { SingleGeneQuery } from 'shared/lib/oql/oql-parser';
import { GeneReplacement, Focus } from 'shared/components/query/QueryStore';
import {GeneReplacement, Focus, normalizeQuery} from 'shared/components/query/QueryStore';
import {
getEmptyGeneValidationResult,
getFocusOutText,
Expand All @@ -22,6 +22,7 @@ import GeneSymbolValidator, {
GeneValidationResult,
} from './GeneSymbolValidator';
import autobind from 'autobind-decorator';
import bind from "bind-decorator";

export interface IGeneSelectionBoxProps {
focus?: Focus;
Expand Down Expand Up @@ -208,8 +209,7 @@ export default class OQLTextArea extends React.Component<
oql: OQL
) {
this.geneQueryIsValid = validQuery;
// no matter whether the query is valid, we need to sync queryToBeValidated with geneQuery
this.geneQuery = this.queryToBeValidated;

if (this.props.callback) {
this.props.callback(oql, validationResult, this.geneQuery);
}
Expand All @@ -235,38 +235,65 @@ export default class OQLTextArea extends React.Component<
: 'Click gene symbols below or enter here';
}

@bind onChange(event:any){
this.currentTextAreaValue = event.currentTarget.value;
this.geneQuery = this.currentTextAreaValue;
this.updateQueryToBeValidateDebounce();
}

@bind onFocus(){
this.isFocused = true;
}

@bind onBlur(){
this.isFocused = false;
}

@bind replaceGene(oldSymbol: string, newSymbol: string) {
let updatedQuery = normalizeQuery(
this.getTextAreaValue()
.toUpperCase()
.replace(
new RegExp(`\\b${oldSymbol.toUpperCase()}\\b`, 'g'),
() => newSymbol.toUpperCase()
)
);
this.updateGeneQuery(updatedQuery);
}

render() {
return (
<div className={styles.genesSelection}>

<textarea
ref={this.textAreaRef}
onFocus={() => (this.isFocused = true)}
onBlur={() => (this.isFocused = false)}
className={classnames(...this.textAreaClasses)}
ref={this.textAreaRef as any}
onFocus={this.onFocus}
onBlur={this.onBlur}
className={classnames(this.textAreaClasses)}
rows={5}
cols={80}
placeholder={this.promptText}
title={this.promptText}
defaultValue={this.getTextAreaValue()}
onChange={event => {
this.currentTextAreaValue = event.currentTarget.value;
this.updateQueryToBeValidateDebounce();
}}
onChange={this.onChange}
data-test="geneSet"
/>

<div className={classnames({ [styles.minWidthContainer]: (this.props.location === GeneBoxType.DEFAULT) })}>
<GeneSymbolValidator
focus={this.props.focus}
geneQuery={this.queryToBeValidated}
skipGeneValidation={this.skipGenesValidation}
updateGeneQuery={this.updateGeneQuery}
afterValidation={this.afterGeneSymbolValidation}
replaceGene={this.replaceGene}
errorMessageOnly={
this.props.location === GeneBoxType.STUDY_VIEW_PAGE
}
>
{this.props.children}
</GeneSymbolValidator>
</div>
</div>
);
}
Expand Down
30 changes: 20 additions & 10 deletions src/shared/components/GeneSelectionBox/styles.module.scss
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
.validationBubbleBase {
margin: 0px 5px 3px 0;
padding: 2px 5px;
border-radius: $border-radius-base;
}

.minWidthContainer {
min-height:25px;
}

.genesSelection {
textarea.default {
width: 555px;
resize: vertical;
border-radius: 2px;
}
textarea.oncoprintHeatmap {
width: 100%;
resize: vertical;
border-radius: 2px;
}
textarea{
border-radius: $border-radius-base;
padding: 5px;
border: 1px solid #d3d3d3;
&.empty {
}
border-color: $borderColor;
}

textarea.studyView {
width: 200px;
//box-sizing: content-box;
height: 30px;
//color: darkgrey;
border-radius: $border-radius-base;
outline-offset: -2px;
font-size:12px;
Expand All @@ -39,13 +47,18 @@
cursor: default;
display: flex;
align-items: center;
padding-top: 5px;
padding-top: 1px;
flex-wrap:wrap;
&.nowrap {
white-space: nowrap;
flex-wrap:nowrap;
width:200px;
}

button {
line-height:1 !important;
}

span.icon {
text-align: center;
margin-right: 4px;
Expand All @@ -65,9 +78,7 @@
color: #fff;
display: flex;
align-items: center;
margin: 2px 2px 2px 0;
padding: 5px 10px;
border-radius: 2px;
@extend .validationBubbleBase;
span.icon {
color: #fff;
line-height: 17px;
Expand All @@ -87,8 +98,7 @@
cursor: pointer;
display: flex;
align-items: center;
margin: 2px;
padding: 5px 10px;
@extend .validationBubbleBase;
background-color: $lightGrey;
border-radius: 2px;
&:hover {
Expand Down
4 changes: 1 addition & 3 deletions src/shared/components/flexbox/styles.module.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.padded.column {
> * {
flex-shrink: 0;
margin-top: 8px;
}
> *:nth-child(1) {
Expand All @@ -9,10 +8,9 @@
}
.padded.row {
> * {
flex-shrink: 0;
margin-left: 8px;
}
> *:nth-child(1) {
margin-left: 0;
}
}
}
7 changes: 1 addition & 6 deletions src/shared/components/query/GeneSetSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export default class GeneSetSelector extends QueryStoreComponent<{}, {}> {

render() {
return (
<FlexRow padded overflow className={styles.GeneSetSelector}>
<FlexRow overflow padded className={styles.GeneSetSelector}>
<SectionHeader
className="sectionLabel"
secondaryComponent={
Expand All @@ -133,11 +133,6 @@ export default class GeneSetSelector extends QueryStoreComponent<{}, {}> {
<i className={'fa fa-external-link'} />
</a>
}
promises={[
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't want to show loader anymore. it's pointless and distracting to typing user

this.store.mutSigForSingleStudy,
this.store.gisticForSingleStudy,
this.store.genes,
]}
>
Enter Genes:
</SectionHeader>
Expand Down
Loading