Skip to content

Commit

Permalink
Redesign and simplify steps to create a new project (#1224)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Jonathan de Bruin <jonathandebruinos@gmail.com>
  • Loading branch information
terrymyc and J535D165 committed Jan 6, 2024
1 parent f1a9021 commit 3a615da
Show file tree
Hide file tree
Showing 50 changed files with 2,233 additions and 1,805 deletions.
2 changes: 1 addition & 1 deletion asreview/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def add_dataset(self, file_name):
if self.config["mode"] == PROJECT_MODE_EXPLORE and as_data.labels is None:
raise ValueError("Import partially or fully labeled dataset")

self.update_config(dataset_path=file_name)
self.update_config(dataset_path=file_name, name=file_name.rsplit(".", 1)[0])

with open_state(self.project_path, read_only=False) as state:
# save the record ids in the state file
Expand Down
28 changes: 7 additions & 21 deletions asreview/webapp/api/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import shutil
import subprocess
import tempfile
import time
from pathlib import Path
from urllib.request import urlretrieve
from uuid import uuid4
Expand All @@ -36,10 +37,6 @@
from werkzeug.exceptions import InternalServerError
from werkzeug.utils import secure_filename

from asreview.config import DEFAULT_BALANCE_STRATEGY
from asreview.config import DEFAULT_FEATURE_EXTRACTION
from asreview.config import DEFAULT_MODEL
from asreview.config import DEFAULT_QUERY_STRATEGY
from asreview.config import LABEL_NA
from asreview.config import PROJECT_MODE_EXPLORE
from asreview.config import PROJECT_MODE_SIMULATE
Expand Down Expand Up @@ -185,9 +182,8 @@ def api_init_project(): # noqa: F401
"""Initialize a new project"""

project_mode = request.form["mode"]
project_title = request.form["name"]
project_description = request.form["description"]
project_authors = request.form["authors"]
project_title = request.form["mode"] + "_" + time.strftime("%Y%m%d-%H%M%S")
# TODO{Terry}: retrieve author from the authenticated profile

# get a unique project id
project_id = uuid4().hex
Expand All @@ -200,8 +196,6 @@ def api_init_project(): # noqa: F401
project_id=project_id,
project_mode=project_mode,
project_name=project_title,
project_description=project_description,
project_authors=project_authors,
)

if current_app.config.get("LOGIN_DISABLED", False):
Expand Down Expand Up @@ -276,7 +270,6 @@ def api_update_project_info(project): # noqa: F401
"""Update project info"""

project.update_config(
mode=request.form["mode"],
name=request.form["name"],
description=request.form["description"],
authors=request.form["authors"],
Expand Down Expand Up @@ -888,12 +881,7 @@ def api_list_algorithms():
@login_required
@project_authorization
def api_get_algorithms(project): # noqa: F401
default_payload = {
"model": DEFAULT_MODEL,
"feature_extraction": DEFAULT_FEATURE_EXTRACTION,
"query_strategy": DEFAULT_QUERY_STRATEGY,
"balance_strategy": DEFAULT_BALANCE_STRATEGY,
}
"""Get the algorithms used in the project"""

# check if there were algorithms stored in the state file
try:
Expand All @@ -906,9 +894,9 @@ def api_get_algorithms(project): # noqa: F401
"balance_strategy": state.settings.balance_strategy,
}
else:
payload = default_payload
payload = None
except StateNotFoundError:
payload = default_payload
payload = None

return jsonify(payload)

Expand Down Expand Up @@ -1113,9 +1101,7 @@ def api_import_project():

try:
project = ASReviewProject.load(
request.files["file"],
asreview_path(),
safe_import=True
request.files["file"], asreview_path(), safe_import=True
)

except Exception as err:
Expand Down
14 changes: 7 additions & 7 deletions asreview/webapp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion asreview/webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"react-share": "^4.4.0",
"react-swipeable-views": "^0.14.0",
"react-transition-group": "^4.4.1",
"react-truncate-markup": "^5.1.0",
"react-truncate-markup": "^5.1.2",
"react-youtube": "^9.0.1",
"semver": "^7.5.2",
"typeface-roboto": "0.0.75",
Expand Down
3 changes: 2 additions & 1 deletion asreview/webapp/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
.dialog-header {
align-items: center;
justify-content: space-between;
height: 64px;
}
.dialog-header-button {
align-items: center;
Expand All @@ -122,5 +123,5 @@
padding-left: 48px;
}
.dialog-header-button.right {
padding-right: 24px;
padding-right: 16px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export default function DashboardPageHeader(props) {
<Tooltip title="Import project">
<IconButton
disableRipple
onClick={props.toggleImportDialog}
onClick={props.toggleImportProject}
size={!props.mobileScreen ? "medium" : "small"}
>
<Avatar className={classes.headerButton}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -603,10 +603,7 @@ const ProjectTable = (props) => {
<Typography sx={{ color: "text.secondary", marginTop: "64px" }}>
Your projects will show up here
</Typography>
<Button
id="get-started"
onClick={props.toggleProjectSetup}
>
<Button id="get-started" onClick={props.toggleModePick}>
Get Started
</Button>
<img
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,25 @@ import {
NumberCard,
ProjectTable,
} from "../DashboardComponents";
import { useToggle } from "../../hooks/useToggle";
import { ActionsFeedbackBar } from "../../Components";
import { ProjectImportDialog } from "../../ProjectComponents";
import { SetupDialog } from "../../ProjectComponents/SetupComponents";
import { ImportProject } from "../../ProjectComponents";
import {
ModePickDialog,
SetupDialog,
} from "../../ProjectComponents/SetupComponents";
import {
AddPriorKnowledge,
ImportDataset,
} from "../../ProjectComponents/SetupComponents/DataComponents";

import { useToggle } from "../../hooks/useToggle";

const ProjectsOverview = (props) => {
const [onImportDialog, toggleImportDialog] = useToggle();
const [onAddPrior, toggleAddPrior] = useToggle();
const [onModePick, toggleModePick] = useToggle();
const [onImportDataset, toggleImportDataset] = useToggle();
const [onImportProject, toggleImportProject] = useToggle();

const [feedbackBar, setFeedbackBar] = React.useState({
open: false,
message: null,
Expand All @@ -29,7 +41,7 @@ const ProjectsOverview = (props) => {
<>
<DashboardPageHeader
mobileScreen={props.mobileScreen}
toggleImportDialog={toggleImportDialog}
toggleImportProject={toggleImportProject}
/>
<Box className="main-page-body-wrapper">
<Stack className="main-page-body" spacing={6}>
Expand All @@ -39,6 +51,7 @@ const ProjectsOverview = (props) => {
projectCheck={props.projectCheck}
setFeedbackBar={setFeedbackBar}
setProjectCheck={props.setProjectCheck}
toggleModePick={toggleModePick}
toggleProjectSetup={props.toggleProjectSetup}
toggleAcceptanceSetup={props.AcceptanceDialog}
/>
Expand All @@ -48,23 +61,44 @@ const ProjectsOverview = (props) => {
id="create-project"
className="main-page-fab"
color="primary"
onClick={props.toggleProjectSetup}
onClick={toggleModePick}
variant="extended"
>
<Add sx={{ mr: 1 }} />
Create
</Fab>
<ProjectImportDialog
<ModePickDialog
open={onModePick}
toggleModePick={toggleModePick}
toggleImportDataset={toggleImportDataset}
/>
<AddPriorKnowledge
open={onAddPrior}
mobileScreen={props.mobileScreen}
toggleAddPrior={toggleAddPrior}
/>
<ImportDataset
open={onImportDataset}
datasetAdded={false}
mobileScreen={props.mobileScreen}
toggleImportDataset={toggleImportDataset}
toggleProjectSetup={props.toggleProjectSetup}
/>
<ImportProject
mobileScreen={props.mobileScreen}
open={onImportDialog}
onClose={toggleImportDialog}
open={onImportProject}
toggleImportProject={toggleImportProject}
setFeedbackBar={setFeedbackBar}
/>
<SetupDialog
mobileScreen={props.mobileScreen}
onAddPrior={onAddPrior}
onImportDataset={onImportDataset}
open={props.onProjectSetup}
onClose={props.toggleProjectSetup}
setFeedbackBar={setFeedbackBar}
toggleAddPrior={toggleAddPrior}
toggleImportDataset={toggleImportDataset}
/>
<ActionsFeedbackBar
center
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Box,
Button,
Fade,
Grid,
IconButton,
Menu,
MenuItem,
Expand All @@ -16,7 +17,7 @@ import { styled } from "@mui/material/styles";
import { MoreVert } from "@mui/icons-material";
import LoadingButton from "@mui/lab/LoadingButton";

import { ProjectInfoForm, ProjectDeleteDialog } from "../../ProjectComponents";
import { ProjectInfo, ProjectDeleteDialog } from "../../ProjectComponents";
import { ActionsFeedbackBar } from "../../Components";
import { DataForm, ModelForm } from "../DetailsComponents";
import { TypographyH5Medium } from "../../StyledComponents/StyledTypography.js";
Expand Down Expand Up @@ -125,6 +126,10 @@ const DetailsPage = (props) => {
toggleDeleteDialog();
};

const isTitleValidated = () => {
return info.title.length > 0;
};

return (
<Root aria-label="details page">
<Fade in>
Expand Down Expand Up @@ -200,26 +205,26 @@ const DetailsPage = (props) => {

{/* Page body */}
<Box className="main-page-body-wrapper">
<Stack
className="main-page-body"
direction={!props.mobileScreen ? "row" : "column"}
spacing={3}
>
<ProjectInfoForm
info={info}
mobileScreen={props.mobileScreen}
setInfo={setInfo}
setDisableSaveButton={setDisableSaveButton}
setDisableUndoButton={setDisableUndoButton}
/>
<Stack
spacing={3}
sx={{ width: !props.mobileScreen ? "40%" : "100%" }}
>
<DataForm setHistoryFilterQuery={props.setHistoryFilterQuery} />
<ModelForm />
</Stack>
</Stack>
<Grid className="main-page-body" container spacing={3}>
<Grid item xs={12} sm={8}>
<ProjectInfo
info={info}
isTitleValidated={isTitleValidated()}
mobileScreen={props.mobileScreen}
setInfo={setInfo}
setDisableSaveButton={setDisableSaveButton}
setDisableUndoButton={setDisableUndoButton}
/>
</Grid>
<Grid item xs={12} sm={4}>
<Stack spacing={3}>
<DataForm
setHistoryFilterQuery={props.setHistoryFilterQuery}
/>
<ModelForm />
</Stack>
</Grid>
</Grid>
</Box>
</Box>
</Fade>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from "react";

import { Chip, Stack } from "@mui/material";

export default function LabelChip(props) {
const LabelChip = (props) => {
const handleClickRelevant = () => {
props.setLabel("relevant");
};
Expand Down Expand Up @@ -47,4 +48,6 @@ export default function LabelChip(props) {
/>
</Stack>
);
}
};

export default LabelChip;
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const LabeledRecord = (props) => {
},
);

// For use on History page ONLY
React.useEffect(() => {
setSubset(
props.filterQuery?.map((element) => {
Expand Down

0 comments on commit 3a615da

Please sign in to comment.