Skip to content

Commit

Permalink
wip: Updated text throughout entire dataset organization workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
JacobiClark committed Jan 29, 2025
1 parent e7a337e commit 0d0ac5b
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,13 @@ const EntityDataSelectorPage = ({
{entityType === "source-derivative-folders-and-files" ? (
<Stack>
<Text>
<b>Source data</b> is raw, unaltered data such as ...
<b>Source data</b> is raw, unaltered data from an experiment such as recorded neural
signals or unprocessed microscope images.
</Text>
<Text>
<b>Derivative data</b> processed or transformed data such as ...
<b>Derivative data</b> is data that has been processed or transformed data such as ...
</Text>
<Text>Annotate your data as source or derivative in the interface below.</Text>
<Text>If you have source or derivative data, annotate it in the interface below.</Text>
</Stack>
) : (
<Stack>
Expand Down
13 changes: 7 additions & 6 deletions src/renderer/src/components/pages/EntitySelector/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,19 +108,20 @@ const EntitySelectorPage = ({
<GuidedModePage pageHeader={pageName}>
<GuidedModeSection>
<Text>
Every {entityTypeStringSingular} that data was extracted from must be given a unique ID.{" "}
{upperCaseFirstLetter(entityTypeStringSingular)} IDs can be added via the three following
methods:
Every {entityTypeStringSingular} in your dataset must be assigned a unique{" "}
{entityTypeStringSingular} ID. {upperCaseFirstLetter(entityTypeStringSingular)} IDs can be
added via the two following methods:
</Text>

<Text>
<b>1. Manual Entry:</b> Enter {entityTypeStringSingular} IDs manually in the interface
below.
<b>1. Manual Entry (Recommended if less than 10 {entityTypeStringPlural}):</b> Enter{" "}
{entityTypeStringSingular} IDs manually by typing them out individually.
</Text>

<Text>
<b>2. Spreadsheet Entry (Recommended for more than 10 {entityTypeStringPlural}):</b>{" "}
Generate a spreadsheet template to input {entityTypeStringSingular} IDs in bulk.
Generate a spreadsheet template to input {entityTypeStringSingular} IDs into and then
import them in bulk.
</Text>
{/*
<Text>
Expand Down
108 changes: 64 additions & 44 deletions src/renderer/src/components/shared/DatasetContentSelector/index.jsx
Original file line number Diff line number Diff line change
@@ -1,87 +1,107 @@
import { Card, Stack, Text, Group } from "@mantine/core";
import { Card, Stack, Text, Group, Tooltip } from "@mantine/core";
import { IconCheck } from "@tabler/icons-react";
import FullWidthContainer from "../../containers/FullWidthContainer";
import useGlobalStore from "../../../stores/globalStore";
import { toggleComponent } from "../../../stores/slices/datasetContentSelectorSlice";
import { toggleEntitySelection } from "../../../stores/slices/datasetContentSelectorSlice";

const upperCaseFirstLetter = (string) => string.charAt(0).toUpperCase() + string.slice(1);

const DatasetContentSelector = () => {
const selectedComponents = useGlobalStore((state) => state.selectedComponents);
const selectedEntities = useGlobalStore((state) => state.selectedEntities);

const options = [
const contentOptions = [
{
value: "subjects",
label: "Subjects",
description:
"Individual entities, such as humans, animals, or other organisms, that participated in the study.",
"Individual entities, such as humans, animals, or other biological specimens, from which data was collected during the study.",
},
{
value: "samples",
label: "Samples",
description:
"Biological or chemical specimens collected from subjects for further analysis or experimentation.",
"Biological specimens, such as tissue, blood, or fluid, collected from subjects for analysis or experimentation.",
dependsOn: "subjects",
},
{
value: "sites",
label: "Sites",
description:
"Specific locations in the body, environment, or experimental setup where data or samples were collected. Conditionally required if data were gathered from multiple distinct locations or experimental setups for the same subject or sample.",
"Multiple distinct anatomical or geographical locations where data was collected from subjects during the study.",
dependsOn: "subjects",
},
{
value: "performances",
label: "Performances",
description:
"Multiple distinct performances of one type of experimental protocol on the same subject or same sample (i.e. multiple visits, runs, sessions, or execution).",
"Multiple distinct performances of the same experimental protocol on the same subject or sample (e.g., multiple visits, runs, sessions, or executions).",
dependsOn: "subjects",
},
{
value: "code",
label: "Code",
description:
"Scripts, computational models, analysis pipelines, or other code/tools used in the study.",
"Scripts, computational models, analysis pipelines, or other code/tools used during the study for data processing or analysis.",
},
];

const toggleSelection = (value) => {
toggleComponent(value);
const handleEntitySelection = (value) => {
const isSelected = selectedEntities.includes(value);

// Deselect dependent entities if the value is deselected
if (isSelected) {
contentOptions.forEach((option) => {
if (option.dependsOn === value && selectedEntities.includes(option.value)) {
toggleEntitySelection(option.value);
}
});
}

// Toggle the selection of the current entity
toggleEntitySelection(value);
};

return (
<FullWidthContainer>
<Stack spacing="md">
{options.map((option) => {
const isDisabled = option.dependsOn && !selectedComponents.includes(option.dependsOn);
const isSelected = selectedComponents.includes(option.value);
{contentOptions.map((option) => {
const isDisabled = option.dependsOn && !selectedEntities.includes(option.dependsOn);
const isSelected = selectedEntities.includes(option.value) && !isDisabled;

return (
<Card
<Tooltip
key={option.value}
withBorder
shadow="sm"
padding="lg"
style={{
opacity: isDisabled ? 0.6 : 1,
cursor: isDisabled ? "not-allowed" : "pointer",
backgroundColor: isSelected ? "#e8f5e9" : "white", // Light green for selected
borderColor: isSelected ? "var(--color-light-green)" : "#e0e0e0",
borderWidth: isSelected ? 2 : 1,
borderStyle: "solid",
}}
onClick={() => {
if (!isDisabled) {
toggleSelection(option.value);
}
}}
label={
isDisabled
? `Requires ${upperCaseFirstLetter(option.dependsOn)} to be selected`
: isSelected
? `${upperCaseFirstLetter(option.value)} is selected`
: ""
}
disabled={!isDisabled && !isSelected}
>
<Group position="apart" align="flex-start">
<Text weight={500} size="lg">
{option.label}
<Card
withBorder
shadow="sm"
padding="lg"
style={{
opacity: isDisabled ? 0.6 : 1,
cursor: isDisabled ? "not-allowed" : "pointer",
backgroundColor: isSelected ? "#e8f5e9" : "white",
borderColor: isSelected ? "var(--color-light-green)" : "#e0e0e0",
borderWidth: isSelected ? 2 : 1,
borderStyle: "solid",
}}
onClick={() => {
if (!isDisabled) handleEntitySelection(option.value);
}}
>
<Group position="apart" align="flex-start">
<Text fw={700} size="lg">
{upperCaseFirstLetter(option.value)}
</Text>
{isSelected && <IconCheck size={18} color="var(--color-light-green)" />}
</Group>
<Text size="sm" mt="xs">
{option.description}
</Text>
</Group>
<Text c="dimmed" size="sm" mt="xs">
{option.description}
</Text>
</Card>
</Card>
</Tooltip>
);
})}
</Stack>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,7 @@ const DatasetTreeViewRenderer = ({ folderActions, fileActions, allowStructureEdi
datasetEntityObj: state.datasetEntityObj,
}));

console.log("datasetEntityObj: ", datasetEntityObj);

const [inputSearchFilter, setInputSearchFilter] = useState(datasetStructureSearchFilter);
console.log("inputSearchFilter::", inputSearchFilter);
const [debouncedSearchFilter] = useDebouncedValue(inputSearchFilter, 300); // 300ms debounce

useEffect(() => {
Expand Down
30 changes: 22 additions & 8 deletions src/renderer/src/scripts/guided-mode/guided-curate-dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -1168,6 +1168,25 @@ const savePageChanges = async (pageBeingLeftID) => {
}

if (pageBeingLeftID === "guided-prepare-dataset-structure-tab") {
const selectedEntities = useGlobalStore.getState()["selectedEntities"];
console.log("selectedEntities", selectedEntities);
if (selectedEntities.length === 0) {
errorArray.push({
type: "notyf",
message: "Please select at least one entity to continue",
});
throw errorArray;
}

/* ********************
if (selectedEntities.length === 0) {
errorArray.push({
type: "notyf",
message: "Please select at least one entity to continue",
});
throw errorArray;
}

const buttonDatasetContainsSubjects = document.getElementById(
"guided-button-dataset-contains-subjects"
);
Expand Down Expand Up @@ -1296,6 +1315,8 @@ const savePageChanges = async (pageBeingLeftID) => {
guidedSkipPage("guided-code-folder-tab");
guidedSkipPage("guided-add-code-metadata-tab");
}

*********************** */
}

if (pageBeingLeftID === "guided-subjects-addition-tab") {
Expand Down Expand Up @@ -1482,17 +1503,10 @@ const savePageChanges = async (pageBeingLeftID) => {
}

if (pageBeingLeftID === "guided-code-folder-tab") {
const codeFolder = window.datasetStructureJSONObj["folders"]["code"];
if (folderIsEmpty(codeFolder)) {
errorArray.push({
type: "notyf",
message: "Please add code used to generate your dataset",
});
throw errorArray;
}
}

if (pageBeingLeftID === "guided-protocol-folder-tab") {
guidedUnSkipPage("guided-code-folder-tab");
}

if (pageBeingLeftID === "guided-docs-folder-tab") {
Expand Down
72 changes: 45 additions & 27 deletions src/renderer/src/sections/guided_mode/guided_curate_dataset.html
Original file line number Diff line number Diff line change
Expand Up @@ -719,9 +719,7 @@ <h1 class="text-sub-step-title">Before getting started</h1>
>
<h1 class="text-sub-step-title">Describe the content of your dataset</h1>
<div class="guided--section">
<p class="help-text">
Select all dataset entities relevant to your study based on the data you collected.
</p>
<p class="help-text">Select the types of entities that are included in your dataset.</p>
</div>
<div data-component-type="dataset-content-selector" class="guided--section"></div>
</div>
Expand Down Expand Up @@ -1111,13 +1109,13 @@ <h2 class="text-sub-step-title mb-3 step-before-spreadsheet-path-declared">
<div class="guided--section">
<h1 class="text-sub-step-title">Import Your Data</h1>
<p class="help-text w-100">
Import all of the experimental data collected during your study using the interface
below.
Use the interface below to import all the experimental data you collected during your
study.
</p>
<p class="help-text">
<b>Note:</b> If your data is organized into subfolders (e.g., "microscopy,"
"imaging"), import the subfolders directly instead of the parent folder containing
them.
"imaging"), make sure to import the subfolders directly rather than the parent folder
they’re in.
</p>
</div>
<div
Expand Down Expand Up @@ -1224,6 +1222,27 @@ <h1 class="text-sub-step-title">Subjects specification</h1>
data-entity-type-string-plural="samples"
data-entity-type-prefix="sam-"
></div>
<div
id="guided-sites-entity-addition-tab"
data-page-name="Manage Site IDs"
class="guided--page"
data-component-type="entity-management-page"
data-entity-type="sites"
data-entity-type-string-singular="site"
data-entity-type-string-plural="sites"
data-entity-type-prefix="site-"
></div>
<div
id="guided-sites-entity-selection-tab"
data-page-name="Sites data selection"
class="guided--page"
data-component-type="entity-selection-page"
data-entity-type="sites"
data-entity-type-string-singular="site"
data-entity-type-string-plural="sites"
data-entity-type-prefix="site-"
></div>

<div
id="guided-source-derivative-folders-and-files-selector-tab"
data-page-name="Annotate Source and Derivative data"
Expand Down Expand Up @@ -1645,23 +1664,26 @@ <h1 class="text-sub-step-title">
</div>
</div>-->

<div id="guided-code-folder-tab" class="guided--page" data-page-name="Code files">
<div id="guided-code-folder-tab" class="guided--page" data-page-name="Code import">
<div class="guided--section">
<h1 class="text-sub-step-title">Code files</h1>
<h1 class="text-sub-step-title">Code importation</h1>
<p class="help-text">
You mentioned at the beginning that you have code files in your dataset. Add those
code files into the interface below. Make sure you include a README file that
describes the code and how to use it.
Import any scripts, computational models, analysis pipelines, or other code/tools used
during the study for data processing or analysis below.
</p>
</div>
<div class="guided--panel" id="guided-user-has-code-data"></div>
<div
data-component-type="data-importer"
data-data-type="code"
data-relative-folder-path-to-import-data-into="code/"
class="guided--section"
></div>
</div>
<div id="guided-protocol-folder-tab" class="guided--page" data-page-name="Protocol data">
<div id="guided-protocol-folder-tab" class="guided--page" data-page-name="Protocols import">
<div class="guided--section">
<h1 class="text-sub-step-title">Protocol data</h1>
<h1 class="text-sub-step-title">Protocol importation</h1>
<p class="help-text">
Protocol data refers to supplementary folders and files to accompany the experimental
protocols that must be submitted to protocols.io (more on that at a later step).
Import any files that describe the experimental procedures used in your study below.
</p>
</div>
<div
Expand All @@ -1671,13 +1693,11 @@ <h1 class="text-sub-step-title">Protocol data</h1>
class="guided--section"
></div>
</div>
<div id="guided-docs-folder-tab" class="guided--page" data-page-name="Docs data">
<div id="guided-docs-folder-tab" class="guided--page" data-page-name="Docs import">
<div class="guided--section">
<h1 class="text-sub-step-title">Docs data</h1>
<h1 class="text-sub-step-title">Docs importation</h1>
<p class="help-text">
Docs data refers to any data to be included in your dataset that does not belong to
any of the other five categories (primary, source, derivative, code, or protocol
data).
Import any files that provide documentation related to your study below.
</p>
</div>
<div
Expand All @@ -1696,11 +1716,9 @@ <h1 class="text-sub-step-title">Docs data</h1>
<div class="guided--section">
<h1 class="text-sub-step-title">Dataset structure review</h1>
<p class="help-text">
The SDS compliant dataset structure shown below will be generated by SODA (during the
last step of this process) based on the data files you specified in the previous
steps. Review and go back to make changes if needed. Please note that all empty
folders will be deleted before generating the dataset since empty folders are not
allowed in the SDS.
The interface below displays the structure of your dataset as it will be generated by
SODA. Review the structure to ensure that all data has been imported correctly, and
then click <span class="next-button-span"></span> to proceed.
</p>
</div>

Expand Down
Loading

0 comments on commit 0d0ac5b

Please sign in to comment.