Skip to content

Commit

Permalink
指摘事項の修正
Browse files Browse the repository at this point in the history
  • Loading branch information
tsuchiyama-araya committed Dec 16, 2024
1 parent d5986dd commit bb2ca81
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 50 deletions.
46 changes: 35 additions & 11 deletions frontend/src/components/Workspace/Experiment/ExperimentTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const TableImple = memo(function TableImple() {
const dispatch = useDispatch<AppDispatch>()
const [checkedList, setCheckedList] = useState<string[]>([])
const [open, setOpen] = useState(false)
const [openCopy, setOpenCopy] = useState(false)
const isRunning = useSelector((state: RootState) => {
const currentUid = selectPipelineLatestUid(state)
const isPending = selectPipelineIsStartedSuccess(state)
Expand All @@ -141,6 +142,10 @@ const TableImple = memo(function TableImple() {
}

const onClickCopy = () => {
setOpenCopy(true)
}

const onClickOkCopy = () => {
dispatch(copyExperimentByList(checkedList))
.unwrap()
.then(() => {
Expand All @@ -150,6 +155,8 @@ const TableImple = memo(function TableImple() {
.catch(() => {
enqueueSnackbar("Failed to copy", { variant: "error" })
})
setCheckedList([])
setOpenCopy(false)
}

const onCheckBoxClick = (uid: string) => {
Expand Down Expand Up @@ -228,6 +235,17 @@ const TableImple = memo(function TableImple() {
{checkedList.length} selected
</Typography>
)}
<Button
sx={{
margin: (theme) => theme.spacing(0, 1, 1, 1),
}}
variant="outlined"
endIcon={<ContentCopyIcon />}
onClick={onClickCopy}
disabled={checkedList.length === 0 || isRunning}
>
COPY
</Button>
<Button
sx={{
margin: (theme) => theme.spacing(0, 1, 1, 0),
Expand All @@ -252,17 +270,6 @@ const TableImple = memo(function TableImple() {
Delete
</Button>
)}
<Button
sx={{
margin: (theme) => theme.spacing(0, 1, 1, 1),
}}
variant="outlined"
endIcon={<ContentCopyIcon />}
onClick={onClickCopy}
disabled={checkedList.length === 0 || isRunning}
>
COPY
</Button>
</Box>
<ConfirmDialog
open={open}
Expand All @@ -281,6 +288,23 @@ const TableImple = memo(function TableImple() {
iconType="warning"
confirmLabel="delete"
/>
<ConfirmDialog
open={openCopy}
setOpen={setOpenCopy}
onConfirm={onClickOkCopy}
title="Copy records?"
content={
<>
{checkedList.map((uid) => (
<Typography key={uid}>
{experimentList[uid].name} ({uid})
</Typography>
))}
</>
}
iconType="warning"
confirmLabel="copy"
/>
<Paper
elevation={0}
variant="outlined"
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/store/slice/Experiments/ExperimentsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ export const experimentsSlice = createSlice({
status: "uninitialized",
}
})
.addMatcher(isAnyOf(copyExperimentByList.fulfilled), (state) => {
state.loading = false
})
.addMatcher(
isAnyOf(copyExperimentByList.fulfilled, copyExperimentByList.rejected),
(state) => {
state.loading = false
},
)
.addMatcher(isAnyOf(copyExperimentByList.pending), (state) => {
state.loading = true
})
.addMatcher(isAnyOf(copyExperimentByList.rejected), (state) => {
state.loading = false
})
},
})

Expand Down
86 changes: 56 additions & 30 deletions studio/app/common/core/experiment/experiment_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,36 +124,6 @@ def delete_data(self) -> bool:

return result

def copy_data(self, new_unique_id: str) -> bool:
logger = AppLogger.get_logger()
output_filepath = join_filepath(
[DIRPATH.OUTPUT_DIR, self.workspace_id, self.unique_id]
)
new_output_filepath = join_filepath(
[DIRPATH.OUTPUT_DIR, self.workspace_id, new_unique_id]
)

shutil.copytree(output_filepath, new_output_filepath)

# Update unique_id in experiment.yml
expt_filepath = join_filepath([new_output_filepath, DIRPATH.EXPERIMENT_YML])
try:
with open(expt_filepath, "r") as f:
config = yaml.safe_load(f)

config["unique_id"] = new_unique_id
original_name = config["name"]
config["name"] = f"{original_name}_copy"

with open(expt_filepath, "w") as f:
yaml.safe_dump(config, f)

logger.info("Unique ID updated successfully.")
return True
except Exception as e:
logger.info(f"Error updating unique_id: {e}")
return False

def rename(self, new_name: str) -> ExptConfig:
filepath = join_filepath(
[
Expand Down Expand Up @@ -187,3 +157,59 @@ def rename(self, new_name: str) -> ExptConfig:
nwb=config.get("nwb"),
snakemake=config.get("snakemake"),
)

def copy_data(self, new_unique_id: str) -> bool:
logger = AppLogger.get_logger()

try:
# Define file paths
output_filepath = join_filepath(
[DIRPATH.OUTPUT_DIR, self.workspace_id, self.unique_id]
)
new_output_filepath = join_filepath(
[DIRPATH.OUTPUT_DIR, self.workspace_id, new_unique_id]
)

# Copy directory
shutil.copytree(output_filepath, new_output_filepath)

# Update experiment.yml
if not self._update_experiment_config(new_output_filepath, new_unique_id):
logger.error("Failed to update experiment.yml after copying.")
return False

logger.info(f"Data successfully copied to {new_output_filepath}")
return True

except Exception as e:
logger.error(f"Error copying data: {e}")
raise Exception("Error copying data")

def _update_experiment_config(
self, new_output_filepath: str, new_unique_id: str
) -> bool:
logger = AppLogger.get_logger()
expt_filepath = join_filepath([new_output_filepath, DIRPATH.EXPERIMENT_YML])

try:
with open(expt_filepath, "r") as file:
config = yaml.safe_load(file)

if not config:
logger.error(f"Empty or invalid YAML in {expt_filepath}.")
return False

# Update config fields
config["unique_id"] = new_unique_id
config["name"] = f"{config.get('name', 'experiment')}_copy"

# Write back to the file
with open(expt_filepath, "w") as file:
yaml.safe_dump(config, file)

logger.info(f"experiment.yml updated successfully at {expt_filepath}")
return True

except Exception as e:
logger.error(f"Error updating experiment.yml: {e}")
raise Exception("Error updating experiment.yml")
6 changes: 3 additions & 3 deletions studio/app/common/routers/experiment.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
is_workspace_available,
is_workspace_owner,
)
from studio.app.common.schemas.experiment import DeleteItem, RenameItem
from studio.app.common.schemas.experiment import CopyItem, DeleteItem, RenameItem
from studio.app.dir_path import DIRPATH

router = APIRouter(prefix="/experiments", tags=["experiments"])
Expand Down Expand Up @@ -114,13 +114,13 @@ async def delete_experiment_list(workspace_id: str, deleteItem: DeleteItem):
response_model=bool,
dependencies=[Depends(is_workspace_owner)],
)
async def copy_experiment_list(workspace_id: str, copyItem: DeleteItem):
async def copy_experiment_list(workspace_id: str, copyItem: CopyItem):
logger = AppLogger.get_logger()
logger.info(f"workspace_id: {workspace_id}, copyItem: {copyItem}")
created_unique_ids = [] # Keep track of successfully created unique IDs
try:
for unique_id in copyItem.uidList:
logger.info(f"unique_id: {unique_id}")
logger.info(f"copying item with unique_id of {unique_id}")
new_unique_id = WorkflowRunner.create_workflow_unique_id()
ExptDataWriter(
workspace_id,
Expand Down

0 comments on commit bb2ca81

Please sign in to comment.