diff --git a/src/commands.js b/src/commands.js
index 84dc02a..6b00e7b 100644
--- a/src/commands.js
+++ b/src/commands.js
@@ -19,13 +19,19 @@ export default {
execute: async fileNameOrId => {
// try to find file by ID first, then by name
const file = findFileByNameOrId(fileNameOrId)
-
// quit if this file doesn't exist
if (!file)
return "File doesn't exist."
-
- // delete file from disk
- await store.getState().workingDirectory.directoryHandle?.removeEntry(file.name)
+
+ // delete file from disk, try to see if in subdirectory first else delete from root
+ const directory = file.id.split("/")[0]
+ try{
+ const tempDirectory = await store.getState().workingDirectory.directoryHandle.getDirectoryHandle(directory)
+ await tempDirectory.removeEntry(file.name)
+ }
+ catch{
+ await store.getState().workingDirectory.directoryHandle?.removeEntry(file.name)
+ }
// close panel if it's open
store.dispatch(panelsActions.closePanel(file.id))
diff --git a/src/components/activities/explorer/ExplorerActivityView.jsx b/src/components/activities/explorer/ExplorerActivityView.jsx
index e04c4d7..25285d1 100644
--- a/src/components/activities/explorer/ExplorerActivityView.jsx
+++ b/src/components/activities/explorer/ExplorerActivityView.jsx
@@ -24,7 +24,7 @@ export default function ExplorerActivityView({ }) {
return workingDirectory ?
<>
-
+
Switch Folder
diff --git a/src/components/activities/explorer/ExplorerList.jsx b/src/components/activities/explorer/ExplorerList.jsx
index 2e41121..acfa46b 100644
--- a/src/components/activities/explorer/ExplorerList.jsx
+++ b/src/components/activities/explorer/ExplorerList.jsx
@@ -6,15 +6,20 @@ import ExplorerListItem from './ExplorerListItem'
import SaveIndicatorDisplay from '../../saveIndicatorDisplay'
-export default function ExplorerList({currentDirectory}) {
+export default function ExplorerList({workDir}) {
// grab file handles
const files = useFiles()
+ let tempDirectory;
// handle creation
const createFile = useCreateFile()
- const handleCreateObject = objectType => fileName => {
- createFile(fileName + objectType.extension, objectType.id)
+ const handleCreateObject = objectType => async fileName => {
+ if(objectType.title === "Plasmid"){ // Retrieve Plasmid directory, if it doesn't exist create it first
+ tempDirectory = await workDir.getDirectoryHandle("plasmid", { create: true });
+
+ }
+ createFile(fileName + objectType.extension, objectType.id, tempDirectory)
}
// generate DragObjects based on data
@@ -29,7 +34,7 @@ export default function ExplorerList({currentDirectory}) {
return (
- Current Folder: {currentDirectory}
+ Current Folder: {workDir.name}
{
})
function Content({ id, ...props }) {
-
const panelType = usePanelType(id)
+ const fileHandle = usePanelProperty(id, 'fileHandle')
return (
-
+
)
}
diff --git a/src/components/panels/sbol-editor/CanvasFrame.jsx b/src/components/panels/sbol-editor/CanvasFrame.jsx
index 95ce8e2..bfe7b0c 100644
--- a/src/components/panels/sbol-editor/CanvasFrame.jsx
+++ b/src/components/panels/sbol-editor/CanvasFrame.jsx
@@ -5,10 +5,9 @@ import { PanelContext } from './SBOLEditorPanel'
import { usePanelProperty } from "../../../redux/hooks/panelsHooks"
-export default function CanvasFrame() {
+export default function CanvasFrame({fileTypeObjectId}) {
const panelId = useContext(PanelContext)
-
// state containing full SBOL content
const [sbolContent, setSBOLContent] = usePanelProperty(panelId, "sbol", false)
@@ -50,9 +49,10 @@ export default function CanvasFrame() {
// post message
iframeRef.current.contentWindow.postMessage(
+
sbolContent ?
- { sbol: sbolContent } : // either send SBOL content
- 'hello canvas', // or send dummy message
+ { sbol: sbolContent, panelType: fileTypeObjectId} : // either send SBOL content
+ {panelType: fileTypeObjectId}, // if no sbolContent, just send in panel type
import.meta.env.VITE_SBOL_CANVAS_URL
)
}
diff --git a/src/components/panels/sbol-editor/SBOLEditorPanel.jsx b/src/components/panels/sbol-editor/SBOLEditorPanel.jsx
index 0b01779..ddd5734 100644
--- a/src/components/panels/sbol-editor/SBOLEditorPanel.jsx
+++ b/src/components/panels/sbol-editor/SBOLEditorPanel.jsx
@@ -6,7 +6,7 @@ import { useSelector } from 'react-redux'
export const PanelContext = createContext()
-export default function SBOLEditorPanel({id}) {
+export default function SBOLEditorPanel({id, fileObjectTypeId}) {
const activePanel = useSelector(state => state.panels.active)
return (
@@ -27,7 +27,7 @@ export default function SBOLEditorPanel({id}) {
*/}
-
+
)
diff --git a/src/objectTypes.js b/src/objectTypes.js
index 5e1fd1d..05cc12f 100644
--- a/src/objectTypes.js
+++ b/src/objectTypes.js
@@ -1,7 +1,9 @@
import { BiWorld } from "react-icons/bi"
import { IoAnalyticsSharp } from "react-icons/io5"
import { TbComponents } from "react-icons/tb"
-
+import { GrTestDesktop } from "react-icons/gr";
+import { MdAlignVerticalTop } from "react-icons/md";
+import { VscOutput } from "react-icons/vsc";
export const ObjectTypes = {
SBOL: {
id: "synbio.object-type.sbol",
@@ -12,6 +14,7 @@ export const ObjectTypes = {
createable: true,
extension: '.xml',
badgeLabel: "SBOL",
+ directory: "main"
},
SBML: {
id: "synbio.object-type.sbml",
@@ -20,6 +23,7 @@ export const ObjectTypes = {
fileMatch: / ot.id == id)
}
-export async function classifyFile(file) {
+export async function classifyFile(file, subDirectoryName) {
// try to match by file name
const matchFromFileName = Object.values(ObjectTypes).find(
ot => ot.fileNameMatch?.test(file.name)
)?.id
- if(matchFromFileName)
- return matchFromFileName
-
+ if (!subDirectoryName && matchFromFileName && matchFromFileName && matchFromFileName != ObjectTypes.Plasmids.id) {
+ return matchFromFileName;
+ }
+ else if (subDirectoryName != null && subDirectoryName.toLowerCase() === "plasmid" && ObjectTypes.Plasmids.fileNameMatch?.test(file.name)) {
+ return ObjectTypes.Plasmids.id;
+ }
// otherwise, read file content
- const fileContent = await (await file.getFile()).text()
- return Object.values(ObjectTypes).find(
- ot => ot.fileMatch?.test(fileContent)
- )?.id
+ if(subDirectoryName == null){
+ const fileContent = await (await file.getFile()).text()
+ return Object.values(ObjectTypes).find(
+ ot => ot.fileMatch?.test(fileContent)
+ )?.id
+ }
}
\ No newline at end of file
diff --git a/src/panels.js b/src/panels.js
index 1b6bbc9..35b0114 100644
--- a/src/panels.js
+++ b/src/panels.js
@@ -25,12 +25,12 @@ export const PanelTypes = {
const { id, fileHandle, type, ...restOfPanel } = panel
return JSON.stringify(restOfPanel)
}
- },
+ },
SBOLEditor: {
id: "synbio.panel-type.sbol-editor",
title: "SBOL Canvas",
component: SBOLEditorPanel,
- objectTypes: [ ObjectTypes.SBOL.id ],
+ objectTypes: [ ObjectTypes.SBOL.id, ObjectTypes.Plasmids.id ],
icon: CanvasIcon,
deserialize: content => ({
diff --git a/src/redux/hooks/workingDirectoryHooks.js b/src/redux/hooks/workingDirectoryHooks.js
index 4460a9d..fb50d8c 100644
--- a/src/redux/hooks/workingDirectoryHooks.js
+++ b/src/redux/hooks/workingDirectoryHooks.js
@@ -46,14 +46,15 @@ export function useWorkingDirectory() {
// Action hooks
+
export function useCreateFile() {
const dispatch = useDispatch()
const openPanel = useOpenPanel()
const workDir = useSelector(state => state.workingDirectory.directoryHandle)
- return (fileName, objectType) => {
- workDir.getFileHandle(fileName, { create: true })
+ return (fileName, objectType, directory = workDir) => { // Optional arg directory in which the file will be created
+ directory.getFileHandle(fileName, { create: true })
.then(fileHandle => {
- addFileMetadata(fileHandle, { objectType })
+ addFileMetadata(fileHandle, directory.name, { objectType })
dispatch(actions.addFile(fileHandle))
openPanel(fileHandle)
})
@@ -72,7 +73,7 @@ export function useCreateFileWithFilePicker() {
}]
})
.then(fileHandle => {
- addFileMetadata(fileHandle)
+ addFileMetadata(fileHandle, null)
dispatch(actions.addFile(fileHandle))
openPanel(fileHandle)
})
@@ -103,24 +104,42 @@ export function useSafeName(baseName) {
// Utility
-async function findFilesInDirectory(dirHandle) {
+export async function findFilesInDirectory(dirHandle) {
const files = []
+
// loop through async iterator of file names (called keys here)
for await (const handle of dirHandle.values()) {
if (handle.kind == 'file') {
- await addFileMetadata(handle)
+ await addFileMetadata(handle, null)
files.push(handle)
}
+
}
+ // Check for subfolders "output" and "metadata"
+ for await (const [name, subHandle] of dirHandle.entries()) {
+ if (subHandle.kind === 'directory' && (name.toLowerCase() === 'output' || name.toLowerCase() === 'metadata' || name.toLowerCase() === "plasmid")) {
+ for await (const handle of subHandle.values()) {
+ if (handle.kind === 'file') {
+ await addFileMetadata(handle, name)
+ files.push(handle)
+ }
+ }
+ }
+ }
+
return files
}
-async function addFileMetadata(handle, { objectType } = {}) {
+async function addFileMetadata(handle, subDirectoryName, { objectType } = {}) {
// handle.id = uuidv4()
- handle.id = handle.name
- handle.objectType = objectType || await classifyFile(handle)
+ if (subDirectoryName === null) {
+ handle.id = handle.name;
+ } else {
+ handle.id = (subDirectoryName + '/' + handle.name);
+ }
+ handle.objectType = objectType || await classifyFile(handle, subDirectoryName)
}
export function titleFromFileName(fileName) {