Skip to content

Commit

Permalink
Merge pull request #118 from MetaCell/SCKAN-85-c
Browse files Browse the repository at this point in the history
SKCAN-85 feat: implement changes to the autosave
  • Loading branch information
ddelpiano authored May 4, 2023
2 parents d051c54 + 0b13f89 commit 5f2c693
Show file tree
Hide file tree
Showing 14 changed files with 86 additions and 52 deletions.
1 change: 1 addition & 0 deletions frontend/src/Pages/SentenceDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ const SentencesDetails = () => {
disabled={disabled}
format="small"
setter={setSentence}
enableAutoSave={true}
/>
</Grid>

Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/DistillationTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const DistillationTab = ({ statement, setStatement, refreshStatement, disabled }
statement_id: statement.id,
knowledge_statement: statement.knowledge_statement,
}}
enableAutoSave={true}
uiFields={[
"sex_id",
"apinatomy_model",
Expand Down
53 changes: 48 additions & 5 deletions frontend/src/components/Forms/FormBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ export const FormBase = (props: any) => {
templates,
submitButtonProps,
className = false,
showErrorList
showErrorList,
submitOnChangeFields = [],
submitOnBlurFields = []
} = props;
const [localData, setLocalData] = useState<any>(data);
const [isSaving, setIsSaving] = useState<boolean>(false);
Expand All @@ -40,6 +42,8 @@ export const FormBase = (props: any) => {
const [customSchema, setCustomSchema] = useState<any>(schema);
const [customUiSchema, setCustomUiSchema] = useState<any>(uiSchema);

const timer = useRef<any>(null)

const submitButtonRef = useRef<any>(null);
const removeProp = (obj: any, prop: string) => {
const { [prop]: removedProp, ...newObj } = obj;
Expand Down Expand Up @@ -68,6 +72,27 @@ export const FormBase = (props: any) => {
}
}, [data]);

const startTimer = () => timer.current = setTimeout(()=>{
if(enableAutoSave){
onSave()
}
},EDIT_DEBOUNCE)

const stopTimer = () =>{
clearTimeout(timer.current)
}

const resetTimer = () =>{
stopTimer()
startTimer()
}


useEffect(() => {
return () => stopTimer()
}, [])


const onError = (errors: any) => {
log("errors");
log(errors);
Expand Down Expand Up @@ -105,19 +130,35 @@ export const FormBase = (props: any) => {
});
};

const handleUpdate = async (event: IChangeEvent) => {
const handleUpdate = async (event: IChangeEvent, id: any) => {
const formData = { ...event.formData, ...extraData };
if(submitOnBlurFields.some((field:string)=> id.includes(field))){
resetTimer()
}
if(submitOnChangeFields.some((field:string)=> id.includes(field))){
return onSave()
}
setLocalData(formData);
if (formIsValid && !formIsValid(formData)) {
setIsSubmitButtonDisabled(true);
} else {
setIsSubmitButtonDisabled(false);
if (enableAutoSave) {
return triggerAutoSave();
}
}
};

const handleBlur = async (id: string) => {
if(submitOnBlurFields.some((field:string)=> id.includes(field))){
stopTimer()
return onSave()
}
}

const handleFocus = (id: string) => {
if(submitOnBlurFields.some((field:string)=> id.includes(field))){
startTimer()
}
}

return (
<>
{(!data || isSaving) && (
Expand All @@ -135,6 +176,8 @@ export const FormBase = (props: any) => {
onChange={handleUpdate}
onSubmit={handleSubmit}
onError={onError}
onBlur={handleBlur}
onFocus={handleFocus}
widgets={widgets}
className={className}
templates={templates}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Forms/SentenceAddForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ const SentenceAddForm = (props: any) => {
schema={customSchema}
uiSchema={customUiSchema}
uiFields={uiFields}
enableAutoSave={true}
enableAutoSave={false}
formIsValid={format === "create" && formIsValid}
disableSubmitButton={setDisabled}
submitButtonProps={submitButtonProps}
Expand Down
6 changes: 2 additions & 4 deletions frontend/src/components/Forms/SentenceForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,12 @@ const SentenceForm = (props: any) => {
schema={customSchema}
uiSchema={customUiSchema}
uiFields={uiFields}
enableAutoSave={true}
enableAutoSave={false}
children={true}
submitOnBlurFields={['title']}
{...props}
/>
<Box mt={2}>
{/* <Typography color={vars.labelColor} fontWeight={500} mb={1}>
PMID (PubMed identifier)
</Typography> */}
{
linkedChip({id: data?.pmid, uri: data?.pmid_uri, label: "PMID"})
}
Expand Down
16 changes: 9 additions & 7 deletions frontend/src/components/Forms/StatementForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react";
import React from "react";
import { FormBase } from "./FormBase";
import { jsonSchemas } from "../../services/JsonSchema";
import statementService from "../../services/StatementService";
Expand All @@ -10,6 +10,7 @@ import AnatomicalEntitiesField from "../AnatomicalEntitiesField";
import { sexes } from '../../services/SexService';
import { phenotypes } from '../../services/PhenotypeService';


const StatementForm = (props: any) => {
const { uiFields, statement, setter, format } = props;
const { schema, uiSchema } = jsonSchemas.getConnectivityStatementSchema();
Expand Down Expand Up @@ -37,7 +38,7 @@ const StatementForm = (props: any) => {
copiedUISchema.projection= {
"ui:widget": "radio",
"ui:options": {
classNames: 'col-xs-12 col-md-6'
classNames: 'col-xs-12 col-md-6',
}
}

Expand Down Expand Up @@ -67,7 +68,7 @@ const StatementForm = (props: any) => {
placeholder: "Select Phenotype",
data: phenotypes.getPhenotypes().map((row: any) => ({ label: row.name, value: row.id })),
},
value: statement?.phenotype_id ?? ""
value: statement?.phenotype_id ?? "",
}

copiedUISchema.knowledge_statement = {
Expand All @@ -76,7 +77,6 @@ const StatementForm = (props: any) => {
label: "Knowledge Statement",
placeholder: "Enter Knowledge Statement",
rows: 4,
hasDebouncedOnChange: true,
value: statement?.knowledge_statement ?? "",
},
};
Expand Down Expand Up @@ -127,7 +127,7 @@ const StatementForm = (props: any) => {
label: "Additional Information",
placeholder: "Enter additional information on the knowledge statement",
multiline: true,
rows: 4
rows: 4,
},
value: statement?.additional_information ?? "",
};
Expand All @@ -146,17 +146,19 @@ const StatementForm = (props: any) => {

return (
<FormBase
{...props}
data={statement}
service={statementService}
schema={copiedSchema}
uiSchema={copiedUISchema}
uiFields={uiFields}
enableAutoSave={true}
enableAutoSave={false}
children={true}
widgets={widgets}
templates={templates}
showErrorList={false}
submitOnBlurFields={['knowledge_statement', 'additional_information', 'apinatomy_model']}
submitOnChangeFields={['phenotype_id', 'sex_id', 'laterality', 'circuit_type', 'projection', 'destination_type', 'path_type']}
{...props}
/>
);
};
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/components/ProofingTab/PathsBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ const PathsBuilder = (props: any) => {
setter={refreshStatement}
extraData={{ sentence_id: statement.sentence.id }}
uiFields={["origin_id"]}
enableAutoSave={false}
submitOnChangeFields={['origin_id']}
/>
</Grid>
</Grid>
Expand All @@ -68,6 +70,8 @@ const PathsBuilder = (props: any) => {
extraData={{ sentence_id: statement.sentence.id }}
uiFields={["path"]}
className="vias"
enableAutoSave={false}
submitOnChangeFields={['path']}
/>
</Box>
<Box height={24} width={2} bgcolor='#D0D5DD' ml='34px'/>
Expand All @@ -84,6 +88,8 @@ const PathsBuilder = (props: any) => {
extraData={{ sentence_id: statement.sentence.id }}
uiFields={["destination_id", "destination_type"]}
className="inLineForm"
enableAutoSave={false}
submitOnChangeFields={["destination_id", "destination_type"]}
/>
</TableRow>
</TableBody>
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/components/ProofingTab/ProofingTab.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import { ConnectivityStatement } from "../../apiclient/backend";
import { Grid, Typography, Box, Stack, Divider, Paper } from "@mui/material";
import StatementChart from "./StatementChart";
import StatementWithProvenances from "../StatementWithProvenances";
Expand All @@ -9,7 +8,7 @@ import { useTheme } from "@mui/system";
import PathsBuilder from "./PathsBuilder";

const ProofingTab = (props: any) => {
const { statement } = props;
const { statement, refreshStatement, setStatement } = props;
const theme = useTheme();
const sectionStyle = useSectionStyle(theme);

Expand Down Expand Up @@ -42,7 +41,7 @@ const ProofingTab = (props: any) => {
textAlign: "center",
}}
>
<StatementWithProvenances statement={statement} />
<StatementWithProvenances statement={statement} refreshStatement={refreshStatement} setStatement={setStatement}/>
</Box>
</Paper>
</Grid>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/StatementWithProvenances.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const StatementWithProvenances = ({ statement, background = "#fff", refreshState
uiFields={["knowledge_statement"]}
className='ks'
disabled={disabled}
enableAutoSave={true}
/>

<ProvenancesForm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const StatementDetailsAccordion = (props: any) => {
statement={statement}
format="small"
setter={setter}
enableAutoSave={true}
extraData={{
sentence_id: sentence.id,
knowledge_statement: statement.knowledge_statement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const TriageStatementSection = (props: any) => {
extraData={{ sentence_id: sentence.id }}
uiFields={["knowledge_statement"]}
className='ks'
enableAutoSave={true}
/>

<ProvenancesForm
Expand Down
35 changes: 5 additions & 30 deletions frontend/src/components/Widgets/CustomTextArea.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import * as React from "react";
import TextField from "@mui/material/TextField";
import FormControl from "@mui/material/FormControl";
import {useDebouncedCallback} from "use-debounce";
import {EDIT_DEBOUNCE} from "../../settings";
import { styled } from "@mui/material";

const StyledInput = styled(TextField)(({ theme }) => ({
Expand All @@ -22,46 +20,23 @@ const StyledInput = styled(TextField)(({ theme }) => ({
}));


export default function TextArea({value, placeholder, required, disabled, onChange, options: { rows, hasDebouncedOnChange } }: any) {
export default function TextArea({ id, value, placeholder, required, disabled, onChange, onBlur, onFocus, options: { rows } }: any) {

const [inputValue, setInputValue] = React.useState(value)

const debouncedChangeHandler = useDebouncedCallback(
(event) => onChange(event.target.value),
EDIT_DEBOUNCE
);

const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement|HTMLInputElement>) => {
const inputValue = e.target.value;
setInputValue(inputValue);
debouncedChangeHandler(e);
};

React.useEffect(()=>setInputValue(value), [value])

return (
<FormControl variant="standard">
{hasDebouncedOnChange
? <StyledInput defaultValue={value}
multiline
rows={rows}
placeholder={placeholder}
fullWidth
required={required}
disabled={disabled}
value={inputValue}
onChange={handleChange}/>
:<StyledInput
<StyledInput
value={value?value:''}
multiline
rows={rows}
placeholder={placeholder}
fullWidth
required={required}
onChange={(e)=>onChange(e.target.value)}
onBlur={(e)=>onBlur(id,e.target.value)}
onFocus={(e)=>onFocus(id,e.target.value)}
disabled={disabled}
/>
}

</FormControl>
);
}
8 changes: 7 additions & 1 deletion frontend/src/components/Widgets/CustomTextField.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from "react";
import TextField from "@mui/material/TextField";
import InputLabel from "@mui/material/InputLabel";
import FormControl from "@mui/material/FormControl";
import { styled } from "@mui/material";
import Typography from "@mui/material/Typography";
Expand All @@ -16,12 +15,17 @@ const StyledInput = styled(TextField)(({ theme }) => ({
}));

export default function CustomTextField({
id,
value,
placeholder,
disabled,
onChange,
onBlur,
onFocus,
options: { label, multiline, rows },
}: any) {


return (
<FormControl variant="standard">
<Typography variant="h6" fontWeight={500} marginBottom={2} color={vars.titleFontColor}>
Expand All @@ -36,6 +40,8 @@ export default function CustomTextField({
rows={rows}
value={value ? value : ''}
disabled={disabled}
onBlur={(e=>onBlur(id,e.target.value))}
onFocus={(e=>onFocus(id,e.target.value))}
/>
</FormControl>
);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/settings.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const EDIT_DEBOUNCE = 1500 // 1.5 seconds
export const EDIT_DEBOUNCE = 120000 // 120 seconds
export const SEARCH_DEBOUNCE = 300 // 0.3 seconds
export const ROWS_PER_PAGE = 10 //number of records displayed at sentence and statement list

0 comments on commit 5f2c693

Please sign in to comment.