@deephaven/file-explorer 0.46.2-beta.3 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,9 @@ export interface FileExplorerProps {
5
5
  storage: FileStorage;
6
6
  isMultiSelect?: boolean;
7
7
  focusedPath?: string;
8
+ onCopy?: (file: FileStorageItem) => void;
9
+ onCreateFile?: () => void;
10
+ onCreateFolder?: () => void;
8
11
  onDelete?: (files: FileStorageItem[]) => void;
9
12
  onRename?: (oldName: string, newName: string) => void;
10
13
  onSelect: (file: FileStorageItem, event: React.SyntheticEvent) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"FileExplorer.d.ts","sourceRoot":"","sources":["../src/FileExplorer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAEzE,OAAO,WAAW,EAAE,EAClB,eAAe,EAGhB,MAAM,eAAe,CAAC;AACvB,OAAO,qBAAqB,CAAC;AAQ7B,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,CAAC;IAErB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC;IACvE,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAE/D,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,CAyKlE;yBAzKe,YAAY;;;AA6K5B,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"FileExplorer.d.ts","sourceRoot":"","sources":["../src/FileExplorer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAEzE,OAAO,WAAW,EAAE,EAClB,eAAe,EAGhB,MAAM,eAAe,CAAC;AACvB,OAAO,qBAAqB,CAAC;AAQ7B,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,CAAC;IAErB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAC9C,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtD,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC;IACvE,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAE/D,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,CAiMlE;yBAjMe,YAAY;;;AAqM5B,eAAe,YAAY,CAAC"}
@@ -22,8 +22,11 @@ export function FileExplorer(props) {
22
22
  storage,
23
23
  isMultiSelect = false,
24
24
  focusedPath,
25
+ onCopy = () => undefined,
25
26
  onDelete = () => undefined,
26
27
  onRename = () => undefined,
28
+ onCreateFile = () => undefined,
29
+ onCreateFolder = () => undefined,
27
30
  onSelect,
28
31
  onSelectionChange,
29
32
  rowHeight = DEFAULT_ROW_HEIGHT
@@ -59,6 +62,18 @@ export function FileExplorer(props) {
59
62
  log.error(e);
60
63
  }
61
64
  }, []);
65
+ var handleCreateFile = useCallback(() => {
66
+ log.debug('handleCreateFile');
67
+ onCreateFile();
68
+ }, [onCreateFile]);
69
+ var handleCreateFolder = useCallback(() => {
70
+ log.debug('handleCreateFolder');
71
+ onCreateFolder();
72
+ }, [onCreateFolder]);
73
+ var handleCopyFile = useCallback(file => {
74
+ log.debug('handleCopyFile', file.filename);
75
+ onCopy(file);
76
+ }, [onCopy]);
62
77
  var handleDelete = useCallback(files => {
63
78
  log.debug('handleDelete, pending confirmation', files);
64
79
  setItemsToDelete(files);
@@ -133,6 +148,9 @@ export function FileExplorer(props) {
133
148
  isMultiSelect: isMultiSelect,
134
149
  focusedPath: focusedPath,
135
150
  showContextMenu: true,
151
+ onCopy: handleCopyFile,
152
+ onCreateFolder: handleCreateFolder,
153
+ onCreateFile: handleCreateFile,
136
154
  onMove: handleMove,
137
155
  onDelete: handleDelete,
138
156
  onRename: handleRename,
@@ -1 +1 @@
1
- {"version":3,"file":"FileExplorer.js","names":["BasicModal","Log","PromiseUtils","React","useCallback","useEffect","useMemo","useState","DEFAULT_ROW_HEIGHT","isDirectory","FileListContainer","FileUtils","FileExistsError","FileNotFoundError","log","module","FileExplorer","props","storage","isMultiSelect","focusedPath","onDelete","undefined","onRename","onSelect","onSelectionChange","rowHeight","itemsToDelete","setItemsToDelete","table","setTable","initializeTable","tablePromise","initTable","debug","makeCancelable","getTable","t","close","e","isCanceled","error","cancel","handleError","handleDelete","files","handleDeleteConfirm","forEach","file","deleteFile","makePath","filename","handleDeleteCancel","handleMove","path","filesToMove","reducePaths","map","newFile","isPath","getBaseName","substring","length","moveFile","then","catch","handleRename","item","newName","name","isDir","endsWith","destination","getParent","debug2","handleValidateRename","renameItem","basename","validateName","newValue","getPath","fileInfo","info","isDeleteConfirmationShown","deleteConfirmationMessage","displayName"],"sources":["../src/FileExplorer.tsx"],"sourcesContent":["import { BasicModal } from '@deephaven/components';\nimport Log from '@deephaven/log';\nimport { CancelablePromise, PromiseUtils } from '@deephaven/utils';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { DEFAULT_ROW_HEIGHT } from './FileListUtils';\nimport FileStorage, {\n FileStorageItem,\n FileStorageTable,\n isDirectory,\n} from './FileStorage';\nimport './FileExplorer.scss';\nimport FileListContainer from './FileListContainer';\nimport FileUtils from './FileUtils';\nimport FileExistsError from './FileExistsError';\nimport FileNotFoundError from './FileNotFoundError';\n\nconst log = Log.module('FileExplorer');\n\nexport interface FileExplorerProps {\n storage: FileStorage;\n\n isMultiSelect?: boolean;\n focusedPath?: string;\n\n onDelete?: (files: FileStorageItem[]) => void;\n onRename?: (oldName: string, newName: string) => void;\n onSelect: (file: FileStorageItem, event: React.SyntheticEvent) => void;\n onSelectionChange?: (selectedItems: FileStorageItem[]) => void;\n\n /** Height of each item in the list */\n rowHeight?: number;\n}\n\n/**\n * Component that displays and allows interaction with the file system in the provided FileStorage.\n */\nexport function FileExplorer(props: FileExplorerProps): JSX.Element {\n const {\n storage,\n isMultiSelect = false,\n focusedPath,\n onDelete = () => undefined,\n onRename = () => undefined,\n onSelect,\n onSelectionChange,\n rowHeight = DEFAULT_ROW_HEIGHT,\n } = props;\n const [itemsToDelete, setItemsToDelete] = useState<FileStorageItem[]>([]);\n const [table, setTable] = useState<FileStorageTable>();\n\n useEffect(\n function initializeTable() {\n let tablePromise: CancelablePromise<FileStorageTable>;\n async function initTable() {\n log.debug('initTable');\n\n tablePromise = PromiseUtils.makeCancelable(storage.getTable(), t =>\n t.close()\n );\n\n try {\n setTable(await tablePromise);\n } catch (e) {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Unable to initialize table', e);\n }\n }\n }\n initTable();\n return () => {\n tablePromise.cancel();\n };\n },\n [storage]\n );\n\n const handleError = useCallback((e: Error) => {\n if (!PromiseUtils.isCanceled(e)) {\n log.error(e);\n }\n }, []);\n\n const handleDelete = useCallback((files: FileStorageItem[]) => {\n log.debug('handleDelete, pending confirmation', files);\n setItemsToDelete(files);\n }, []);\n\n const handleDeleteConfirm = useCallback(() => {\n log.debug('handleDeleteConfirm', itemsToDelete);\n itemsToDelete.forEach(file =>\n storage.deleteFile(\n isDirectory(file) ? FileUtils.makePath(file.filename) : file.filename\n )\n );\n onDelete(itemsToDelete);\n setItemsToDelete([]);\n }, [itemsToDelete, onDelete, storage]);\n\n const handleDeleteCancel = useCallback(() => {\n log.debug('handleDeleteCancel');\n setItemsToDelete([]);\n }, []);\n\n const handleMove = useCallback(\n (files: FileStorageItem[], path: string) => {\n const filesToMove = FileUtils.reducePaths(\n files.map(file =>\n isDirectory(file) ? FileUtils.makePath(file.filename) : file.filename\n )\n );\n\n filesToMove.forEach(file => {\n const newFile = FileUtils.isPath(file)\n ? `${path}${FileUtils.getBaseName(\n file.substring(0, file.length - 1)\n )}/`\n : `${path}${FileUtils.getBaseName(file)}`;\n storage\n .moveFile(file, newFile)\n .then(() => {\n // Each moved file triggers a rename so parent knows something has happened\n // We signal each individually if for some reason there's an error moving one of the files\n onRename(file, newFile);\n })\n .catch(handleError);\n });\n },\n [handleError, onRename, storage]\n );\n\n const handleRename = useCallback(\n (item: FileStorageItem, newName: string) => {\n let name = item.filename;\n const isDir = isDirectory(item);\n if (isDir && !name.endsWith('/')) {\n name = `${name}/`;\n }\n let destination = `${FileUtils.getParent(name)}${newName}`;\n if (isDir && !destination.endsWith('/')) {\n destination = `${destination}/`;\n }\n log.debug2('handleRename', name, destination);\n storage.moveFile(name, destination).catch(handleError);\n onRename(name, destination);\n },\n [handleError, onRename, storage]\n );\n\n const handleValidateRename = useCallback(\n async (renameItem: FileStorageItem, newName: string): Promise<void> => {\n if (newName === renameItem.basename) {\n // Same name is fine\n return undefined;\n }\n FileUtils.validateName(newName);\n\n const newValue = `${FileUtils.getPath(renameItem.filename)}${newName}`;\n try {\n const fileInfo = await storage.info(newValue);\n throw new FileExistsError(fileInfo);\n } catch (e) {\n if (!(e instanceof FileNotFoundError)) {\n throw e;\n }\n // The file does not exist, fine to save at that path\n }\n },\n [storage]\n );\n\n const isDeleteConfirmationShown = itemsToDelete.length > 0;\n const deleteConfirmationMessage = useMemo(() => {\n if (itemsToDelete.length === 1) {\n return `Are you sure you want to delete \"${itemsToDelete[0].filename}\"?`;\n }\n return `Are you sure you want to delete the selected files?`;\n }, [itemsToDelete]);\n\n return (\n <div className=\"file-explorer\">\n {table && (\n <FileListContainer\n isMultiSelect={isMultiSelect}\n focusedPath={focusedPath}\n showContextMenu\n onMove={handleMove}\n onDelete={handleDelete}\n onRename={handleRename}\n onSelect={onSelect}\n onSelectionChange={onSelectionChange}\n rowHeight={rowHeight}\n table={table}\n validateRename={handleValidateRename}\n />\n )}\n <BasicModal\n isOpen={isDeleteConfirmationShown}\n headerText={deleteConfirmationMessage}\n bodyText=\"You cannot undo this action.\"\n onCancel={handleDeleteCancel}\n onConfirm={handleDeleteConfirm}\n confirmButtonText=\"Delete\"\n />\n </div>\n );\n}\n\nFileExplorer.displayName = 'FileExplorer';\n\nexport default FileExplorer;\n"],"mappings":"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"}
1
+ {"version":3,"file":"FileExplorer.js","names":["BasicModal","Log","PromiseUtils","React","useCallback","useEffect","useMemo","useState","DEFAULT_ROW_HEIGHT","isDirectory","FileListContainer","FileUtils","FileExistsError","FileNotFoundError","log","module","FileExplorer","props","storage","isMultiSelect","focusedPath","onCopy","undefined","onDelete","onRename","onCreateFile","onCreateFolder","onSelect","onSelectionChange","rowHeight","itemsToDelete","setItemsToDelete","table","setTable","initializeTable","tablePromise","initTable","debug","makeCancelable","getTable","t","close","e","isCanceled","error","cancel","handleError","handleCreateFile","handleCreateFolder","handleCopyFile","file","filename","handleDelete","files","handleDeleteConfirm","forEach","deleteFile","makePath","handleDeleteCancel","handleMove","path","filesToMove","reducePaths","map","newFile","isPath","getBaseName","substring","length","moveFile","then","catch","handleRename","item","newName","name","isDir","endsWith","destination","getParent","debug2","handleValidateRename","renameItem","basename","validateName","newValue","getPath","fileInfo","info","isDeleteConfirmationShown","deleteConfirmationMessage","displayName"],"sources":["../src/FileExplorer.tsx"],"sourcesContent":["import { BasicModal } from '@deephaven/components';\nimport Log from '@deephaven/log';\nimport { CancelablePromise, PromiseUtils } from '@deephaven/utils';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport { DEFAULT_ROW_HEIGHT } from './FileListUtils';\nimport FileStorage, {\n FileStorageItem,\n FileStorageTable,\n isDirectory,\n} from './FileStorage';\nimport './FileExplorer.scss';\nimport FileListContainer from './FileListContainer';\nimport FileUtils from './FileUtils';\nimport FileExistsError from './FileExistsError';\nimport FileNotFoundError from './FileNotFoundError';\n\nconst log = Log.module('FileExplorer');\n\nexport interface FileExplorerProps {\n storage: FileStorage;\n\n isMultiSelect?: boolean;\n focusedPath?: string;\n\n onCopy?: (file: FileStorageItem) => void;\n onCreateFile?: () => void;\n onCreateFolder?: () => void;\n onDelete?: (files: FileStorageItem[]) => void;\n onRename?: (oldName: string, newName: string) => void;\n onSelect: (file: FileStorageItem, event: React.SyntheticEvent) => void;\n onSelectionChange?: (selectedItems: FileStorageItem[]) => void;\n\n /** Height of each item in the list */\n rowHeight?: number;\n}\n\n/**\n * Component that displays and allows interaction with the file system in the provided FileStorage.\n */\nexport function FileExplorer(props: FileExplorerProps): JSX.Element {\n const {\n storage,\n isMultiSelect = false,\n focusedPath,\n onCopy = () => undefined,\n onDelete = () => undefined,\n onRename = () => undefined,\n onCreateFile = () => undefined,\n onCreateFolder = () => undefined,\n onSelect,\n onSelectionChange,\n rowHeight = DEFAULT_ROW_HEIGHT,\n } = props;\n const [itemsToDelete, setItemsToDelete] = useState<FileStorageItem[]>([]);\n const [table, setTable] = useState<FileStorageTable>();\n\n useEffect(\n function initializeTable() {\n let tablePromise: CancelablePromise<FileStorageTable>;\n async function initTable() {\n log.debug('initTable');\n\n tablePromise = PromiseUtils.makeCancelable(storage.getTable(), t =>\n t.close()\n );\n\n try {\n setTable(await tablePromise);\n } catch (e) {\n if (!PromiseUtils.isCanceled(e)) {\n log.error('Unable to initialize table', e);\n }\n }\n }\n initTable();\n return () => {\n tablePromise.cancel();\n };\n },\n [storage]\n );\n\n const handleError = useCallback((e: Error) => {\n if (!PromiseUtils.isCanceled(e)) {\n log.error(e);\n }\n }, []);\n\n const handleCreateFile = useCallback(() => {\n log.debug('handleCreateFile');\n onCreateFile();\n }, [onCreateFile]);\n\n const handleCreateFolder = useCallback(() => {\n log.debug('handleCreateFolder');\n onCreateFolder();\n }, [onCreateFolder]);\n\n const handleCopyFile = useCallback(\n (file: FileStorageItem) => {\n log.debug('handleCopyFile', file.filename);\n onCopy(file);\n },\n [onCopy]\n );\n\n const handleDelete = useCallback((files: FileStorageItem[]) => {\n log.debug('handleDelete, pending confirmation', files);\n setItemsToDelete(files);\n }, []);\n\n const handleDeleteConfirm = useCallback(() => {\n log.debug('handleDeleteConfirm', itemsToDelete);\n itemsToDelete.forEach(file =>\n storage.deleteFile(\n isDirectory(file) ? FileUtils.makePath(file.filename) : file.filename\n )\n );\n onDelete(itemsToDelete);\n setItemsToDelete([]);\n }, [itemsToDelete, onDelete, storage]);\n\n const handleDeleteCancel = useCallback(() => {\n log.debug('handleDeleteCancel');\n setItemsToDelete([]);\n }, []);\n\n const handleMove = useCallback(\n (files: FileStorageItem[], path: string) => {\n const filesToMove = FileUtils.reducePaths(\n files.map(file =>\n isDirectory(file) ? FileUtils.makePath(file.filename) : file.filename\n )\n );\n\n filesToMove.forEach(file => {\n const newFile = FileUtils.isPath(file)\n ? `${path}${FileUtils.getBaseName(\n file.substring(0, file.length - 1)\n )}/`\n : `${path}${FileUtils.getBaseName(file)}`;\n storage\n .moveFile(file, newFile)\n .then(() => {\n // Each moved file triggers a rename so parent knows something has happened\n // We signal each individually if for some reason there's an error moving one of the files\n onRename(file, newFile);\n })\n .catch(handleError);\n });\n },\n [handleError, onRename, storage]\n );\n\n const handleRename = useCallback(\n (item: FileStorageItem, newName: string) => {\n let name = item.filename;\n const isDir = isDirectory(item);\n if (isDir && !name.endsWith('/')) {\n name = `${name}/`;\n }\n let destination = `${FileUtils.getParent(name)}${newName}`;\n if (isDir && !destination.endsWith('/')) {\n destination = `${destination}/`;\n }\n log.debug2('handleRename', name, destination);\n storage.moveFile(name, destination).catch(handleError);\n onRename(name, destination);\n },\n [handleError, onRename, storage]\n );\n\n const handleValidateRename = useCallback(\n async (renameItem: FileStorageItem, newName: string): Promise<void> => {\n if (newName === renameItem.basename) {\n // Same name is fine\n return undefined;\n }\n FileUtils.validateName(newName);\n\n const newValue = `${FileUtils.getPath(renameItem.filename)}${newName}`;\n try {\n const fileInfo = await storage.info(newValue);\n throw new FileExistsError(fileInfo);\n } catch (e) {\n if (!(e instanceof FileNotFoundError)) {\n throw e;\n }\n // The file does not exist, fine to save at that path\n }\n },\n [storage]\n );\n\n const isDeleteConfirmationShown = itemsToDelete.length > 0;\n const deleteConfirmationMessage = useMemo(() => {\n if (itemsToDelete.length === 1) {\n return `Are you sure you want to delete \"${itemsToDelete[0].filename}\"?`;\n }\n return `Are you sure you want to delete the selected files?`;\n }, [itemsToDelete]);\n\n return (\n <div className=\"file-explorer\">\n {table && (\n <FileListContainer\n isMultiSelect={isMultiSelect}\n focusedPath={focusedPath}\n showContextMenu\n onCopy={handleCopyFile}\n onCreateFolder={handleCreateFolder}\n onCreateFile={handleCreateFile}\n onMove={handleMove}\n onDelete={handleDelete}\n onRename={handleRename}\n onSelect={onSelect}\n onSelectionChange={onSelectionChange}\n rowHeight={rowHeight}\n table={table}\n validateRename={handleValidateRename}\n />\n )}\n <BasicModal\n isOpen={isDeleteConfirmationShown}\n headerText={deleteConfirmationMessage}\n bodyText=\"You cannot undo this action.\"\n onCancel={handleDeleteCancel}\n onConfirm={handleDeleteConfirm}\n confirmButtonText=\"Delete\"\n />\n </div>\n );\n}\n\nFileExplorer.displayName = 'FileExplorer';\n\nexport default FileExplorer;\n"],"mappings":";;AAAA,SAASA,UAAU,QAAQ,uBAAuB;AAClD,OAAOC,GAAG,MAAM,gBAAgB;AAChC,SAA4BC,YAAY,QAAQ,kBAAkB;AAClE,OAAOC,KAAK,IAAIC,WAAW,EAAEC,SAAS,EAAEC,OAAO,EAAEC,QAAQ,QAAQ,OAAO;AAAC,SAChEC,kBAAkB;AAAA,SAIzBC,WAAW;AAAA;AAAA,OAGNC,iBAAiB;AAAA,OACjBC,SAAS;AAAA,OACTC,eAAe;AAAA,OACfC,iBAAiB;AAAA;AAAA;AAExB,IAAMC,GAAG,GAAGb,GAAG,CAACc,MAAM,CAAC,cAAc,CAAC;AAoBtC;AACA;AACA;AACA,OAAO,SAASC,YAAY,CAACC,KAAwB,EAAe;EAClE,IAAM;IACJC,OAAO;IACPC,aAAa,GAAG,KAAK;IACrBC,WAAW;IACXC,MAAM,GAAG,MAAMC,SAAS;IACxBC,QAAQ,GAAG,MAAMD,SAAS;IAC1BE,QAAQ,GAAG,MAAMF,SAAS;IAC1BG,YAAY,GAAG,MAAMH,SAAS;IAC9BI,cAAc,GAAG,MAAMJ,SAAS;IAChCK,QAAQ;IACRC,iBAAiB;IACjBC,SAAS,GAAGrB;EACd,CAAC,GAAGS,KAAK;EACT,IAAM,CAACa,aAAa,EAAEC,gBAAgB,CAAC,GAAGxB,QAAQ,CAAoB,EAAE,CAAC;EACzE,IAAM,CAACyB,KAAK,EAAEC,QAAQ,CAAC,GAAG1B,QAAQ,EAAoB;EAEtDF,SAAS,CACP,SAAS6B,eAAe,GAAG;IACzB,IAAIC,YAAiD;IAAC,SACvCC,SAAS;MAAA;IAAA;IAAA;MAAA,+BAAxB,aAA2B;QACzBtB,GAAG,CAACuB,KAAK,CAAC,WAAW,CAAC;QAEtBF,YAAY,GAAGjC,YAAY,CAACoC,cAAc,CAACpB,OAAO,CAACqB,QAAQ,EAAE,EAAEC,CAAC,IAC9DA,CAAC,CAACC,KAAK,EAAE,CACV;QAED,IAAI;UACFR,QAAQ,OAAOE,YAAY,CAAC;QAC9B,CAAC,CAAC,OAAOO,CAAC,EAAE;UACV,IAAI,CAACxC,YAAY,CAACyC,UAAU,CAACD,CAAC,CAAC,EAAE;YAC/B5B,GAAG,CAAC8B,KAAK,CAAC,4BAA4B,EAAEF,CAAC,CAAC;UAC5C;QACF;MACF,CAAC;MAAA;IAAA;IACDN,SAAS,EAAE;IACX,OAAO,MAAM;MACXD,YAAY,CAACU,MAAM,EAAE;IACvB,CAAC;EACH,CAAC,EACD,CAAC3B,OAAO,CAAC,CACV;EAED,IAAM4B,WAAW,GAAG1C,WAAW,CAAEsC,CAAQ,IAAK;IAC5C,IAAI,CAACxC,YAAY,CAACyC,UAAU,CAACD,CAAC,CAAC,EAAE;MAC/B5B,GAAG,CAAC8B,KAAK,CAACF,CAAC,CAAC;IACd;EACF,CAAC,EAAE,EAAE,CAAC;EAEN,IAAMK,gBAAgB,GAAG3C,WAAW,CAAC,MAAM;IACzCU,GAAG,CAACuB,KAAK,CAAC,kBAAkB,CAAC;IAC7BZ,YAAY,EAAE;EAChB,CAAC,EAAE,CAACA,YAAY,CAAC,CAAC;EAElB,IAAMuB,kBAAkB,GAAG5C,WAAW,CAAC,MAAM;IAC3CU,GAAG,CAACuB,KAAK,CAAC,oBAAoB,CAAC;IAC/BX,cAAc,EAAE;EAClB,CAAC,EAAE,CAACA,cAAc,CAAC,CAAC;EAEpB,IAAMuB,cAAc,GAAG7C,WAAW,CAC/B8C,IAAqB,IAAK;IACzBpC,GAAG,CAACuB,KAAK,CAAC,gBAAgB,EAAEa,IAAI,CAACC,QAAQ,CAAC;IAC1C9B,MAAM,CAAC6B,IAAI,CAAC;EACd,CAAC,EACD,CAAC7B,MAAM,CAAC,CACT;EAED,IAAM+B,YAAY,GAAGhD,WAAW,CAAEiD,KAAwB,IAAK;IAC7DvC,GAAG,CAACuB,KAAK,CAAC,oCAAoC,EAAEgB,KAAK,CAAC;IACtDtB,gBAAgB,CAACsB,KAAK,CAAC;EACzB,CAAC,EAAE,EAAE,CAAC;EAEN,IAAMC,mBAAmB,GAAGlD,WAAW,CAAC,MAAM;IAC5CU,GAAG,CAACuB,KAAK,CAAC,qBAAqB,EAAEP,aAAa,CAAC;IAC/CA,aAAa,CAACyB,OAAO,CAACL,IAAI,IACxBhC,OAAO,CAACsC,UAAU,CAChB/C,WAAW,CAACyC,IAAI,CAAC,GAAGvC,SAAS,CAAC8C,QAAQ,CAACP,IAAI,CAACC,QAAQ,CAAC,GAAGD,IAAI,CAACC,QAAQ,CACtE,CACF;IACD5B,QAAQ,CAACO,aAAa,CAAC;IACvBC,gBAAgB,CAAC,EAAE,CAAC;EACtB,CAAC,EAAE,CAACD,aAAa,EAAEP,QAAQ,EAAEL,OAAO,CAAC,CAAC;EAEtC,IAAMwC,kBAAkB,GAAGtD,WAAW,CAAC,MAAM;IAC3CU,GAAG,CAACuB,KAAK,CAAC,oBAAoB,CAAC;IAC/BN,gBAAgB,CAAC,EAAE,CAAC;EACtB,CAAC,EAAE,EAAE,CAAC;EAEN,IAAM4B,UAAU,GAAGvD,WAAW,CAC5B,CAACiD,KAAwB,EAAEO,IAAY,KAAK;IAC1C,IAAMC,WAAW,GAAGlD,SAAS,CAACmD,WAAW,CACvCT,KAAK,CAACU,GAAG,CAACb,IAAI,IACZzC,WAAW,CAACyC,IAAI,CAAC,GAAGvC,SAAS,CAAC8C,QAAQ,CAACP,IAAI,CAACC,QAAQ,CAAC,GAAGD,IAAI,CAACC,QAAQ,CACtE,CACF;IAEDU,WAAW,CAACN,OAAO,CAACL,IAAI,IAAI;MAC1B,IAAMc,OAAO,GAAGrD,SAAS,CAACsD,MAAM,CAACf,IAAI,CAAC,aAC/BU,IAAI,SAAGjD,SAAS,CAACuD,WAAW,CAC7BhB,IAAI,CAACiB,SAAS,CAAC,CAAC,EAAEjB,IAAI,CAACkB,MAAM,GAAG,CAAC,CAAC,CACnC,mBACER,IAAI,SAAGjD,SAAS,CAACuD,WAAW,CAAChB,IAAI,CAAC,CAAE;MAC3ChC,OAAO,CACJmD,QAAQ,CAACnB,IAAI,EAAEc,OAAO,CAAC,CACvBM,IAAI,CAAC,MAAM;QACV;QACA;QACA9C,QAAQ,CAAC0B,IAAI,EAAEc,OAAO,CAAC;MACzB,CAAC,CAAC,CACDO,KAAK,CAACzB,WAAW,CAAC;IACvB,CAAC,CAAC;EACJ,CAAC,EACD,CAACA,WAAW,EAAEtB,QAAQ,EAAEN,OAAO,CAAC,CACjC;EAED,IAAMsD,YAAY,GAAGpE,WAAW,CAC9B,CAACqE,IAAqB,EAAEC,OAAe,KAAK;IAC1C,IAAIC,IAAI,GAAGF,IAAI,CAACtB,QAAQ;IACxB,IAAMyB,KAAK,GAAGnE,WAAW,CAACgE,IAAI,CAAC;IAC/B,IAAIG,KAAK,IAAI,CAACD,IAAI,CAACE,QAAQ,CAAC,GAAG,CAAC,EAAE;MAChCF,IAAI,aAAMA,IAAI,MAAG;IACnB;IACA,IAAIG,WAAW,aAAMnE,SAAS,CAACoE,SAAS,CAACJ,IAAI,CAAC,SAAGD,OAAO,CAAE;IAC1D,IAAIE,KAAK,IAAI,CAACE,WAAW,CAACD,QAAQ,CAAC,GAAG,CAAC,EAAE;MACvCC,WAAW,aAAMA,WAAW,MAAG;IACjC;IACAhE,GAAG,CAACkE,MAAM,CAAC,cAAc,EAAEL,IAAI,EAAEG,WAAW,CAAC;IAC7C5D,OAAO,CAACmD,QAAQ,CAACM,IAAI,EAAEG,WAAW,CAAC,CAACP,KAAK,CAACzB,WAAW,CAAC;IACtDtB,QAAQ,CAACmD,IAAI,EAAEG,WAAW,CAAC;EAC7B,CAAC,EACD,CAAChC,WAAW,EAAEtB,QAAQ,EAAEN,OAAO,CAAC,CACjC;EAED,IAAM+D,oBAAoB,GAAG7E,WAAW;IAAA,6BACtC,WAAO8E,UAA2B,EAAER,OAAe,EAAoB;MACrE,IAAIA,OAAO,KAAKQ,UAAU,CAACC,QAAQ,EAAE;QACnC;QACA,OAAO7D,SAAS;MAClB;MACAX,SAAS,CAACyE,YAAY,CAACV,OAAO,CAAC;MAE/B,IAAMW,QAAQ,aAAM1E,SAAS,CAAC2E,OAAO,CAACJ,UAAU,CAAC/B,QAAQ,CAAC,SAAGuB,OAAO,CAAE;MACtE,IAAI;QACF,IAAMa,QAAQ,SAASrE,OAAO,CAACsE,IAAI,CAACH,QAAQ,CAAC;QAC7C,MAAM,IAAIzE,eAAe,CAAC2E,QAAQ,CAAC;MACrC,CAAC,CAAC,OAAO7C,CAAC,EAAE;QACV,IAAI,EAAEA,CAAC,YAAY7B,iBAAiB,CAAC,EAAE;UACrC,MAAM6B,CAAC;QACT;QACA;MACF;IACF,CAAC;IAAA;MAAA;IAAA;EAAA,KACD,CAACxB,OAAO,CAAC,CACV;EAED,IAAMuE,yBAAyB,GAAG3D,aAAa,CAACsC,MAAM,GAAG,CAAC;EAC1D,IAAMsB,yBAAyB,GAAGpF,OAAO,CAAC,MAAM;IAC9C,IAAIwB,aAAa,CAACsC,MAAM,KAAK,CAAC,EAAE;MAC9B,mDAA2CtC,aAAa,CAAC,CAAC,CAAC,CAACqB,QAAQ;IACtE;IACA;EACF,CAAC,EAAE,CAACrB,aAAa,CAAC,CAAC;EAEnB,oBACE;IAAK,SAAS,EAAC,eAAe;IAAA,WAC3BE,KAAK,iBACJ,KAAC,iBAAiB;MAChB,aAAa,EAAEb,aAAc;MAC7B,WAAW,EAAEC,WAAY;MACzB,eAAe;MACf,MAAM,EAAE6B,cAAe;MACvB,cAAc,EAAED,kBAAmB;MACnC,YAAY,EAAED,gBAAiB;MAC/B,MAAM,EAAEY,UAAW;MACnB,QAAQ,EAAEP,YAAa;MACvB,QAAQ,EAAEoB,YAAa;MACvB,QAAQ,EAAE7C,QAAS;MACnB,iBAAiB,EAAEC,iBAAkB;MACrC,SAAS,EAAEC,SAAU;MACrB,KAAK,EAAEG,KAAM;MACb,cAAc,EAAEiD;IAAqB,EAExC,eACD,KAAC,UAAU;MACT,MAAM,EAAEQ,yBAA0B;MAClC,UAAU,EAAEC,yBAA0B;MACtC,QAAQ,EAAC,8BAA8B;MACvC,QAAQ,EAAEhC,kBAAmB;MAC7B,SAAS,EAAEJ,mBAAoB;MAC/B,iBAAiB,EAAC;IAAQ,EAC1B;EAAA,EACE;AAEV;AAEAtC,YAAY,CAAC2E,WAAW,GAAG,cAAc;AAEzC,eAAe3E,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"FileList.d.ts","sourceRoot":"","sources":["../src/FileList.tsx"],"names":[],"mappings":"AAIA,OAAO,KAMN,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAe,MAAM,eAAe,CAAC;AAC/E,OAAO,iBAAiB,CAAC;AAEzB,OAAO,EAAgB,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAIvE,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,gBAAgB,CAAC;IAExB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,aAAa,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;IACxD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC;IACvE,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAE/D,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,GAAG,CAAC,OAAO,CAAC;IAE7D,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAOD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,GAAG,CAAC,OAAO,CAsY1D;AAED,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"FileList.d.ts","sourceRoot":"","sources":["../src/FileList.tsx"],"names":[],"mappings":"AAIA,OAAO,KAMN,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAe,MAAM,eAAe,CAAC;AAC/E,OAAO,iBAAiB,CAAC;AAEzB,OAAO,EAAgB,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAIvE,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,gBAAgB,CAAC;IAExB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,aAAa,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;IACxD,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,cAAc,KAAK,IAAI,CAAC;IACvE,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAE/D,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,GAAG,CAAC,OAAO,CAAC;IAE7D,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAOD;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,GAAG,CAAC,OAAO,CA0Z1D;AAED,eAAe,QAAQ,CAAC"}
package/dist/FileList.js CHANGED
@@ -46,6 +46,7 @@ export function FileList(props) {
46
46
  var [draggedItems, setDraggedItems] = useState();
47
47
  var [dragPlaceholder, setDragPlaceholder] = useState();
48
48
  var [selectedRanges, setSelectedRanges] = useState([]);
49
+ var focusedIndex = useRef();
49
50
  var itemList = useRef(null);
50
51
  var fileList = useRef(null);
51
52
  var getItems = useCallback(ranges => {
@@ -184,9 +185,10 @@ export function FileList(props) {
184
185
  dropItems();
185
186
  }
186
187
  }, [dropItems]);
187
- var handleSelectionChange = useCallback(newSelectedRanges => {
188
+ var handleSelectionChange = useCallback(function (newSelectedRanges) {
189
+ var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
188
190
  log.debug2('handleSelectionChange', newSelectedRanges);
189
- if (newSelectedRanges !== selectedRanges) {
191
+ if (force === true || newSelectedRanges !== selectedRanges) {
190
192
  setSelectedRanges(newSelectedRanges);
191
193
  var _selectedItems = getItems(newSelectedRanges);
192
194
  onSelectionChange(_selectedItems);
@@ -200,6 +202,7 @@ export function FileList(props) {
200
202
  } else {
201
203
  onFocusChange();
202
204
  }
205
+ focusedIndex.current = focusIndex;
203
206
  }, [getItems, onFocusChange]);
204
207
  var handleViewportChange = useCallback((top, bottom) => {
205
208
  log.debug('handleViewportChange', top, bottom);
@@ -260,6 +263,20 @@ export function FileList(props) {
260
263
  };
261
264
  }, [table]);
262
265
 
266
+ // if the loadedViewport changes, re-fire the focused
267
+ // item and the selected range items as they could have
268
+ // been updated
269
+ useEffect(function updateFocusAndSelection() {
270
+ if (focusedIndex.current != null) {
271
+ handleFocusChange(focusedIndex.current);
272
+ }
273
+ if (selectedRanges.length > 0) {
274
+ // force the update, as the selected range may be the same
275
+ // but the selected items may now be different
276
+ handleSelectionChange(selectedRanges, true);
277
+ }
278
+ }, [loadedViewport, handleFocusChange, handleSelectionChange, selectedRanges]);
279
+
263
280
  // Expand a folder if hovering over it
264
281
  useEffect(function expandFolderOnHover() {
265
282
  if (dropTargetItem != null && isDirectory(dropTargetItem) && dropTargetItem.filename !== '/') {
@@ -1 +1 @@
1
- {"version":3,"file":"FileList.js","names":["ItemList","Log","RangeUtils","classNames","React","useCallback","useEffect","useMemo","useRef","useState","isDirectory","DEFAULT_ROW_HEIGHT","getMoveOperation","FileListItem","log","module","DRAG_HOVER_TIMEOUT","ITEM_LIST_CLASS_NAME","FileList","props","isMultiSelect","table","onFocusChange","undefined","onMove","onSelect","onSelectionChange","renderItem","rowHeight","overscanCount","DEFAULT_OVERSCAN","loadedViewport","setLoadedViewport","items","offset","itemCount","viewport","setViewport","top","bottom","dropTargetItem","setDropTargetItem","draggedItems","setDraggedItems","dragPlaceholder","setDragPlaceholder","selectedRanges","setSelectedRanges","itemList","fileList","getItems","ranges","length","i","range","j","push","getItem","itemIndex","getDragPlaceholderText","count","index","item","filename","dropItems","debug","files","targetPath","current","focusItem","err","error","handleSelect","event","setExpanded","isExpanded","handleItemDragStart","e","debug2","draggedRanges","isSelected","resetMouseState","newDragPlaceholder","document","createElement","innerHTML","className","body","appendChild","dataTransfer","setDragImage","effectAllowed","handleItemDragOver","preventDefault","handleItemDragEnd","remove","handleItemDrop","handleItemDragExit","handleListDragOver","target","Element","classList","contains","type","basename","id","handleListDrop","handleSelectionChange","newSelectedRanges","selectedItems","handleFocusChange","focusIndex","focusedItem","handleViewportChange","isDropTargetValid","focusedPath","collapseAll","updateTableViewport","Math","max","setLoadedViewportAndReturnCleanup","listenerRemover","onUpdate","newViewport","map","itemName","size","expandFolderOnHover","timeout","setTimeout","clearTimeout","renderWrapper","itemProps","isDragInProgress","onDragStart","onDragEnd","onDragOver","onDragExit","onDrop"],"sources":["../src/FileList.tsx"],"sourcesContent":["import { ItemList, Range } from '@deephaven/components';\nimport Log from '@deephaven/log';\nimport { RangeUtils } from '@deephaven/utils';\nimport classNames from 'classnames';\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { FileStorageItem, FileStorageTable, isDirectory } from './FileStorage';\nimport './FileList.scss';\nimport { DEFAULT_ROW_HEIGHT, getMoveOperation } from './FileListUtils';\nimport { FileListItem, FileListRenderItemProps } from './FileListItem';\n\nconst log = Log.module('FileList');\n\nexport type LoadedViewport = {\n items: FileStorageItem[];\n offset: number;\n itemCount: number;\n};\n\nexport type ListViewport = {\n top: number;\n bottom: number;\n};\n\nexport interface FileListProps {\n table: FileStorageTable;\n\n isMultiSelect?: boolean;\n focusedPath?: string;\n\n onFocusChange?: (focusedItem?: FileStorageItem) => void;\n onMove?: (files: FileStorageItem[], path: string) => void;\n onSelect: (file: FileStorageItem, event: React.SyntheticEvent) => void;\n onSelectionChange?: (selectedItems: FileStorageItem[]) => void;\n\n renderItem?: (props: FileListRenderItemProps) => JSX.Element;\n\n /** Height of each item in the list */\n rowHeight?: number;\n\n overscanCount?: number;\n}\n\n// How long you need to hover over a directory before it expands\nconst DRAG_HOVER_TIMEOUT = 500;\n\nconst ITEM_LIST_CLASS_NAME = 'item-list-scroll-pane';\n\n/**\n * Component that displays and allows interaction with the file system in the provided FileStorageTable.\n */\nexport function FileList(props: FileListProps): JSX.Element {\n const {\n isMultiSelect = false,\n table,\n onFocusChange = () => undefined,\n onMove,\n onSelect,\n onSelectionChange = () => undefined,\n renderItem = FileListItem,\n rowHeight = DEFAULT_ROW_HEIGHT,\n overscanCount = ItemList.DEFAULT_OVERSCAN,\n } = props;\n const [loadedViewport, setLoadedViewport] = useState<LoadedViewport>(() => ({\n items: [],\n offset: 0,\n itemCount: 0,\n }));\n const [viewport, setViewport] = useState<ListViewport>({\n top: 0,\n bottom: 0,\n });\n\n const [dropTargetItem, setDropTargetItem] = useState<FileStorageItem>();\n const [draggedItems, setDraggedItems] = useState<FileStorageItem[]>();\n const [dragPlaceholder, setDragPlaceholder] = useState<HTMLDivElement>();\n const [selectedRanges, setSelectedRanges] = useState([] as Range[]);\n\n const itemList = useRef<ItemList<FileStorageItem>>(null);\n const fileList = useRef<HTMLDivElement>(null);\n\n const getItems = useCallback(\n (ranges: Range[]): FileStorageItem[] => {\n if (ranges.length === 0 || loadedViewport == null) {\n return [];\n }\n\n const items = [] as FileStorageItem[];\n for (let i = 0; i < ranges.length; i += 1) {\n const range = ranges[i];\n for (let j = range[0]; j <= range[1]; j += 1) {\n if (\n j >= loadedViewport.offset &&\n j < loadedViewport.offset + loadedViewport.items.length\n ) {\n items.push(loadedViewport.items[j - loadedViewport.offset]);\n }\n }\n }\n return items;\n },\n [loadedViewport]\n );\n\n const getItem = useCallback(\n (itemIndex: number): FileStorageItem | undefined => {\n const items = getItems([[itemIndex, itemIndex]]);\n if (items.length > 0) {\n return items[0];\n }\n },\n [getItems]\n );\n\n /**\n * Get the placeholder text to show when a drag operation is in progress\n */\n const getDragPlaceholderText = useCallback(() => {\n const count = RangeUtils.count(selectedRanges);\n if (count === 0) {\n return null;\n }\n\n if (count === 1) {\n const index = selectedRanges[0][0];\n const item = getItem(index);\n if (item != null) {\n return item.filename;\n }\n }\n return `${count} items`;\n }, [getItem, selectedRanges]);\n\n /**\n * Drop the currently dragged items at the currently set drop target.\n * If an itemIndex is provided, focus that index after the drop.\n */\n const dropItems = useCallback(\n (itemIndex?: number) => {\n if (!draggedItems || !dropTargetItem) {\n return;\n }\n\n log.debug('dropItems', draggedItems, 'to', itemIndex);\n\n try {\n const { files, targetPath } = getMoveOperation(\n draggedItems,\n dropTargetItem\n );\n onMove?.(files, targetPath);\n if (itemIndex != null) {\n setSelectedRanges([[itemIndex, itemIndex]]);\n itemList.current?.focusItem(itemIndex);\n }\n } catch (err) {\n log.error('Unable to complete move', err);\n }\n },\n [draggedItems, dropTargetItem, onMove]\n );\n\n const handleSelect = useCallback(\n (itemIndex: number, event: React.SyntheticEvent) => {\n const item = loadedViewport.items[itemIndex - loadedViewport.offset];\n if (item !== undefined) {\n log.debug('handleItemClick', item);\n\n onSelect(item, event);\n if (isDirectory(item)) {\n table?.setExpanded(item.filename, !item.isExpanded);\n }\n }\n },\n [loadedViewport, onSelect, table]\n );\n\n const handleItemDragStart = useCallback(\n (itemIndex: number, e: React.DragEvent<HTMLDivElement>) => {\n log.debug2('handleItemDragStart', itemIndex, selectedRanges);\n\n let draggedRanges = selectedRanges;\n if (!RangeUtils.isSelected(selectedRanges, itemIndex)) {\n draggedRanges = [[itemIndex, itemIndex]];\n setSelectedRanges(draggedRanges);\n }\n\n setDraggedItems(getItems(draggedRanges));\n\n // We need to reset reset the mouse state since we steal the drag\n itemList.current?.resetMouseState();\n\n const newDragPlaceholder = document.createElement('div');\n newDragPlaceholder.innerHTML = `<div class=\"dnd-placeholder-content\">${getDragPlaceholderText()}</div>`;\n newDragPlaceholder.className = 'file-list-dnd-placeholder';\n document.body.appendChild(newDragPlaceholder);\n e.dataTransfer.setDragImage(newDragPlaceholder, 0, 0);\n e.dataTransfer.effectAllowed = 'move';\n setDragPlaceholder(newDragPlaceholder);\n },\n [getDragPlaceholderText, getItems, selectedRanges]\n );\n\n const handleItemDragOver = useCallback(\n (itemIndex: number, e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n\n log.debug2('handleItemDragOver', e);\n setDropTargetItem(getItem(itemIndex));\n },\n [getItem]\n );\n\n const handleItemDragEnd = useCallback(\n (itemIndex: number, e: React.DragEvent<HTMLDivElement>) => {\n log.debug('handleItemDragEnd', itemIndex);\n\n dragPlaceholder?.remove();\n\n // Drag end is triggered after drop\n // Also drop isn't triggered if drag end is outside of the list\n setDraggedItems(undefined);\n setDropTargetItem(undefined);\n setDragPlaceholder(undefined);\n },\n [dragPlaceholder]\n );\n\n const handleItemDrop = useCallback(\n (itemIndex: number, e: React.DragEvent<HTMLDivElement>) => {\n dropItems(itemIndex);\n },\n [dropItems]\n );\n\n const handleItemDragExit = useCallback(() => {\n log.debug2('handleItemDragExit');\n setDropTargetItem(undefined);\n }, []);\n\n const handleListDragOver = useCallback(\n (e: React.DragEvent<HTMLDivElement>) => {\n if (\n e.target instanceof Element &&\n e.target.classList.contains(ITEM_LIST_CLASS_NAME)\n ) {\n // Need to prevent default to enable drop\n // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#droptargets\n e.preventDefault();\n\n log.debug2('handleListDragOver', e);\n setDropTargetItem({\n type: 'directory',\n filename: '/',\n basename: '/',\n id: '/',\n });\n }\n },\n []\n );\n\n const handleListDrop = useCallback(\n (e: React.DragEvent<HTMLDivElement>) => {\n if (\n e.target instanceof Element &&\n e.target.classList.contains(ITEM_LIST_CLASS_NAME)\n ) {\n log.debug('handleListDrop');\n dropItems();\n }\n },\n [dropItems]\n );\n\n const handleSelectionChange = useCallback(\n newSelectedRanges => {\n log.debug2('handleSelectionChange', newSelectedRanges);\n if (newSelectedRanges !== selectedRanges) {\n setSelectedRanges(newSelectedRanges);\n const selectedItems = getItems(newSelectedRanges);\n onSelectionChange(selectedItems);\n }\n },\n [getItems, onSelectionChange, selectedRanges]\n );\n\n const handleFocusChange = useCallback(\n focusIndex => {\n log.debug2('handleFocusChange', focusIndex);\n if (focusIndex != null) {\n const [focusedItem] = getItems([[focusIndex, focusIndex]]);\n onFocusChange(focusedItem);\n } else {\n onFocusChange();\n }\n },\n [getItems, onFocusChange]\n );\n\n const handleViewportChange = useCallback(\n (top: number, bottom: number) => {\n log.debug('handleViewportChange', top, bottom);\n if (top !== viewport.top || bottom !== viewport.bottom) {\n setViewport({ top, bottom });\n }\n },\n [viewport]\n );\n\n const isDropTargetValid = useMemo(() => {\n if (!draggedItems || !dropTargetItem) {\n return false;\n }\n\n try {\n getMoveOperation(draggedItems, dropTargetItem);\n log.debug('handleValidateDropTarget true');\n return true;\n } catch (e) {\n log.debug('handleValidateDropTarget false');\n return false;\n }\n }, [draggedItems, dropTargetItem]);\n\n const { focusedPath } = props;\n useEffect(() => {\n if (focusedPath !== undefined) {\n if (focusedPath === '/') {\n table.collapseAll();\n } else {\n table.setExpanded(focusedPath, false);\n table.setExpanded(focusedPath, true);\n }\n }\n }, [table, focusedPath]);\n\n useEffect(\n function updateTableViewport() {\n log.debug('updating table viewport', viewport);\n table?.setViewport({\n top: Math.max(0, viewport.top - overscanCount),\n bottom: viewport.bottom + overscanCount,\n });\n },\n [overscanCount, table, viewport]\n );\n\n // Listen for table updates\n useEffect(\n function setLoadedViewportAndReturnCleanup() {\n const listenerRemover = table.onUpdate(newViewport => {\n setLoadedViewport({\n items: newViewport.items.map(item => ({\n ...item,\n itemName: item.basename,\n })),\n offset: newViewport.offset,\n itemCount: table.size,\n });\n });\n return () => {\n listenerRemover();\n };\n },\n [table]\n );\n\n // Expand a folder if hovering over it\n useEffect(\n function expandFolderOnHover() {\n if (\n dropTargetItem != null &&\n isDirectory(dropTargetItem) &&\n dropTargetItem.filename !== '/'\n ) {\n const timeout = setTimeout(() => {\n if (!dropTargetItem.isExpanded) {\n table?.setExpanded(dropTargetItem.filename, true);\n }\n }, DRAG_HOVER_TIMEOUT);\n return () => clearTimeout(timeout);\n }\n },\n [dropTargetItem, table]\n );\n\n const renderWrapper = useCallback(\n itemProps =>\n renderItem({\n ...itemProps,\n isDragInProgress: draggedItems != null,\n dropTargetItem,\n draggedItems,\n isDropTargetValid,\n onDragStart: handleItemDragStart,\n onDragEnd: handleItemDragEnd,\n onDragOver: handleItemDragOver,\n onDragExit: handleItemDragExit,\n onDrop: handleItemDrop,\n }),\n [\n handleItemDragEnd,\n handleItemDragExit,\n handleItemDragOver,\n handleItemDragStart,\n handleItemDrop,\n draggedItems,\n dropTargetItem,\n isDropTargetValid,\n renderItem,\n ]\n );\n\n return (\n <div\n ref={fileList}\n className={classNames('file-list', {\n 'is-dragging': draggedItems != null,\n })}\n onDragOver={handleListDragOver}\n onDrop={handleListDrop}\n >\n <ItemList\n ref={itemList}\n items={loadedViewport.items}\n itemCount={loadedViewport.itemCount}\n offset={loadedViewport.offset}\n onFocusChange={handleFocusChange}\n onSelect={handleSelect}\n onSelectionChange={handleSelectionChange}\n onViewportChange={handleViewportChange}\n selectedRanges={selectedRanges}\n renderItem={renderWrapper}\n rowHeight={rowHeight}\n isMultiSelect={isMultiSelect}\n isDragSelect={false}\n isDeselectOnClick={false}\n />\n </div>\n );\n}\n\nexport default FileList;\n"],"mappings":"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"}
1
+ {"version":3,"file":"FileList.js","names":["ItemList","Log","RangeUtils","classNames","React","useCallback","useEffect","useMemo","useRef","useState","isDirectory","DEFAULT_ROW_HEIGHT","getMoveOperation","FileListItem","log","module","DRAG_HOVER_TIMEOUT","ITEM_LIST_CLASS_NAME","FileList","props","isMultiSelect","table","onFocusChange","undefined","onMove","onSelect","onSelectionChange","renderItem","rowHeight","overscanCount","DEFAULT_OVERSCAN","loadedViewport","setLoadedViewport","items","offset","itemCount","viewport","setViewport","top","bottom","dropTargetItem","setDropTargetItem","draggedItems","setDraggedItems","dragPlaceholder","setDragPlaceholder","selectedRanges","setSelectedRanges","focusedIndex","itemList","fileList","getItems","ranges","length","i","range","j","push","getItem","itemIndex","getDragPlaceholderText","count","index","item","filename","dropItems","debug","files","targetPath","current","focusItem","err","error","handleSelect","event","setExpanded","isExpanded","handleItemDragStart","e","debug2","draggedRanges","isSelected","resetMouseState","newDragPlaceholder","document","createElement","innerHTML","className","body","appendChild","dataTransfer","setDragImage","effectAllowed","handleItemDragOver","preventDefault","handleItemDragEnd","remove","handleItemDrop","handleItemDragExit","handleListDragOver","target","Element","classList","contains","type","basename","id","handleListDrop","handleSelectionChange","newSelectedRanges","force","selectedItems","handleFocusChange","focusIndex","focusedItem","handleViewportChange","isDropTargetValid","focusedPath","collapseAll","updateTableViewport","Math","max","setLoadedViewportAndReturnCleanup","listenerRemover","onUpdate","newViewport","map","itemName","size","updateFocusAndSelection","expandFolderOnHover","timeout","setTimeout","clearTimeout","renderWrapper","itemProps","isDragInProgress","onDragStart","onDragEnd","onDragOver","onDragExit","onDrop"],"sources":["../src/FileList.tsx"],"sourcesContent":["import { ItemList, Range } from '@deephaven/components';\nimport Log from '@deephaven/log';\nimport { RangeUtils } from '@deephaven/utils';\nimport classNames from 'classnames';\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { FileStorageItem, FileStorageTable, isDirectory } from './FileStorage';\nimport './FileList.scss';\nimport { DEFAULT_ROW_HEIGHT, getMoveOperation } from './FileListUtils';\nimport { FileListItem, FileListRenderItemProps } from './FileListItem';\n\nconst log = Log.module('FileList');\n\nexport type LoadedViewport = {\n items: FileStorageItem[];\n offset: number;\n itemCount: number;\n};\n\nexport type ListViewport = {\n top: number;\n bottom: number;\n};\n\nexport interface FileListProps {\n table: FileStorageTable;\n\n isMultiSelect?: boolean;\n focusedPath?: string;\n\n onFocusChange?: (focusedItem?: FileStorageItem) => void;\n onMove?: (files: FileStorageItem[], path: string) => void;\n onSelect: (file: FileStorageItem, event: React.SyntheticEvent) => void;\n onSelectionChange?: (selectedItems: FileStorageItem[]) => void;\n\n renderItem?: (props: FileListRenderItemProps) => JSX.Element;\n\n /** Height of each item in the list */\n rowHeight?: number;\n\n overscanCount?: number;\n}\n\n// How long you need to hover over a directory before it expands\nconst DRAG_HOVER_TIMEOUT = 500;\n\nconst ITEM_LIST_CLASS_NAME = 'item-list-scroll-pane';\n\n/**\n * Component that displays and allows interaction with the file system in the provided FileStorageTable.\n */\nexport function FileList(props: FileListProps): JSX.Element {\n const {\n isMultiSelect = false,\n table,\n onFocusChange = () => undefined,\n onMove,\n onSelect,\n onSelectionChange = () => undefined,\n renderItem = FileListItem,\n rowHeight = DEFAULT_ROW_HEIGHT,\n overscanCount = ItemList.DEFAULT_OVERSCAN,\n } = props;\n const [loadedViewport, setLoadedViewport] = useState<LoadedViewport>(() => ({\n items: [],\n offset: 0,\n itemCount: 0,\n }));\n const [viewport, setViewport] = useState<ListViewport>({\n top: 0,\n bottom: 0,\n });\n\n const [dropTargetItem, setDropTargetItem] = useState<FileStorageItem>();\n const [draggedItems, setDraggedItems] = useState<FileStorageItem[]>();\n const [dragPlaceholder, setDragPlaceholder] = useState<HTMLDivElement>();\n const [selectedRanges, setSelectedRanges] = useState([] as Range[]);\n\n const focusedIndex = useRef<number | null>();\n\n const itemList = useRef<ItemList<FileStorageItem>>(null);\n const fileList = useRef<HTMLDivElement>(null);\n\n const getItems = useCallback(\n (ranges: Range[]): FileStorageItem[] => {\n if (ranges.length === 0 || loadedViewport == null) {\n return [];\n }\n\n const items = [] as FileStorageItem[];\n for (let i = 0; i < ranges.length; i += 1) {\n const range = ranges[i];\n for (let j = range[0]; j <= range[1]; j += 1) {\n if (\n j >= loadedViewport.offset &&\n j < loadedViewport.offset + loadedViewport.items.length\n ) {\n items.push(loadedViewport.items[j - loadedViewport.offset]);\n }\n }\n }\n return items;\n },\n [loadedViewport]\n );\n\n const getItem = useCallback(\n (itemIndex: number): FileStorageItem | undefined => {\n const items = getItems([[itemIndex, itemIndex]]);\n if (items.length > 0) {\n return items[0];\n }\n },\n [getItems]\n );\n\n /**\n * Get the placeholder text to show when a drag operation is in progress\n */\n const getDragPlaceholderText = useCallback(() => {\n const count = RangeUtils.count(selectedRanges);\n if (count === 0) {\n return null;\n }\n\n if (count === 1) {\n const index = selectedRanges[0][0];\n const item = getItem(index);\n if (item != null) {\n return item.filename;\n }\n }\n return `${count} items`;\n }, [getItem, selectedRanges]);\n\n /**\n * Drop the currently dragged items at the currently set drop target.\n * If an itemIndex is provided, focus that index after the drop.\n */\n const dropItems = useCallback(\n (itemIndex?: number) => {\n if (!draggedItems || !dropTargetItem) {\n return;\n }\n\n log.debug('dropItems', draggedItems, 'to', itemIndex);\n\n try {\n const { files, targetPath } = getMoveOperation(\n draggedItems,\n dropTargetItem\n );\n onMove?.(files, targetPath);\n if (itemIndex != null) {\n setSelectedRanges([[itemIndex, itemIndex]]);\n itemList.current?.focusItem(itemIndex);\n }\n } catch (err) {\n log.error('Unable to complete move', err);\n }\n },\n [draggedItems, dropTargetItem, onMove]\n );\n\n const handleSelect = useCallback(\n (itemIndex: number, event: React.SyntheticEvent) => {\n const item = loadedViewport.items[itemIndex - loadedViewport.offset];\n if (item !== undefined) {\n log.debug('handleItemClick', item);\n\n onSelect(item, event);\n if (isDirectory(item)) {\n table?.setExpanded(item.filename, !item.isExpanded);\n }\n }\n },\n [loadedViewport, onSelect, table]\n );\n\n const handleItemDragStart = useCallback(\n (itemIndex: number, e: React.DragEvent<HTMLDivElement>) => {\n log.debug2('handleItemDragStart', itemIndex, selectedRanges);\n\n let draggedRanges = selectedRanges;\n if (!RangeUtils.isSelected(selectedRanges, itemIndex)) {\n draggedRanges = [[itemIndex, itemIndex]];\n setSelectedRanges(draggedRanges);\n }\n\n setDraggedItems(getItems(draggedRanges));\n\n // We need to reset reset the mouse state since we steal the drag\n itemList.current?.resetMouseState();\n\n const newDragPlaceholder = document.createElement('div');\n newDragPlaceholder.innerHTML = `<div class=\"dnd-placeholder-content\">${getDragPlaceholderText()}</div>`;\n newDragPlaceholder.className = 'file-list-dnd-placeholder';\n document.body.appendChild(newDragPlaceholder);\n e.dataTransfer.setDragImage(newDragPlaceholder, 0, 0);\n e.dataTransfer.effectAllowed = 'move';\n setDragPlaceholder(newDragPlaceholder);\n },\n [getDragPlaceholderText, getItems, selectedRanges]\n );\n\n const handleItemDragOver = useCallback(\n (itemIndex: number, e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n\n log.debug2('handleItemDragOver', e);\n setDropTargetItem(getItem(itemIndex));\n },\n [getItem]\n );\n\n const handleItemDragEnd = useCallback(\n (itemIndex: number, e: React.DragEvent<HTMLDivElement>) => {\n log.debug('handleItemDragEnd', itemIndex);\n\n dragPlaceholder?.remove();\n\n // Drag end is triggered after drop\n // Also drop isn't triggered if drag end is outside of the list\n setDraggedItems(undefined);\n setDropTargetItem(undefined);\n setDragPlaceholder(undefined);\n },\n [dragPlaceholder]\n );\n\n const handleItemDrop = useCallback(\n (itemIndex: number, e: React.DragEvent<HTMLDivElement>) => {\n dropItems(itemIndex);\n },\n [dropItems]\n );\n\n const handleItemDragExit = useCallback(() => {\n log.debug2('handleItemDragExit');\n setDropTargetItem(undefined);\n }, []);\n\n const handleListDragOver = useCallback(\n (e: React.DragEvent<HTMLDivElement>) => {\n if (\n e.target instanceof Element &&\n e.target.classList.contains(ITEM_LIST_CLASS_NAME)\n ) {\n // Need to prevent default to enable drop\n // https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#droptargets\n e.preventDefault();\n\n log.debug2('handleListDragOver', e);\n setDropTargetItem({\n type: 'directory',\n filename: '/',\n basename: '/',\n id: '/',\n });\n }\n },\n []\n );\n\n const handleListDrop = useCallback(\n (e: React.DragEvent<HTMLDivElement>) => {\n if (\n e.target instanceof Element &&\n e.target.classList.contains(ITEM_LIST_CLASS_NAME)\n ) {\n log.debug('handleListDrop');\n dropItems();\n }\n },\n [dropItems]\n );\n\n const handleSelectionChange = useCallback(\n (newSelectedRanges, force = false) => {\n log.debug2('handleSelectionChange', newSelectedRanges);\n if (force === true || newSelectedRanges !== selectedRanges) {\n setSelectedRanges(newSelectedRanges);\n const selectedItems = getItems(newSelectedRanges);\n onSelectionChange(selectedItems);\n }\n },\n [getItems, onSelectionChange, selectedRanges]\n );\n\n const handleFocusChange = useCallback(\n focusIndex => {\n log.debug2('handleFocusChange', focusIndex);\n if (focusIndex != null) {\n const [focusedItem] = getItems([[focusIndex, focusIndex]]);\n onFocusChange(focusedItem);\n } else {\n onFocusChange();\n }\n focusedIndex.current = focusIndex;\n },\n [getItems, onFocusChange]\n );\n\n const handleViewportChange = useCallback(\n (top: number, bottom: number) => {\n log.debug('handleViewportChange', top, bottom);\n if (top !== viewport.top || bottom !== viewport.bottom) {\n setViewport({ top, bottom });\n }\n },\n [viewport]\n );\n\n const isDropTargetValid = useMemo(() => {\n if (!draggedItems || !dropTargetItem) {\n return false;\n }\n\n try {\n getMoveOperation(draggedItems, dropTargetItem);\n log.debug('handleValidateDropTarget true');\n return true;\n } catch (e) {\n log.debug('handleValidateDropTarget false');\n return false;\n }\n }, [draggedItems, dropTargetItem]);\n\n const { focusedPath } = props;\n useEffect(() => {\n if (focusedPath !== undefined) {\n if (focusedPath === '/') {\n table.collapseAll();\n } else {\n table.setExpanded(focusedPath, false);\n table.setExpanded(focusedPath, true);\n }\n }\n }, [table, focusedPath]);\n\n useEffect(\n function updateTableViewport() {\n log.debug('updating table viewport', viewport);\n table?.setViewport({\n top: Math.max(0, viewport.top - overscanCount),\n bottom: viewport.bottom + overscanCount,\n });\n },\n [overscanCount, table, viewport]\n );\n\n // Listen for table updates\n useEffect(\n function setLoadedViewportAndReturnCleanup() {\n const listenerRemover = table.onUpdate(newViewport => {\n setLoadedViewport({\n items: newViewport.items.map(item => ({\n ...item,\n itemName: item.basename,\n })),\n offset: newViewport.offset,\n itemCount: table.size,\n });\n });\n return () => {\n listenerRemover();\n };\n },\n [table]\n );\n\n // if the loadedViewport changes, re-fire the focused\n // item and the selected range items as they could have\n // been updated\n useEffect(\n function updateFocusAndSelection() {\n if (focusedIndex.current != null) {\n handleFocusChange(focusedIndex.current);\n }\n if (selectedRanges.length > 0) {\n // force the update, as the selected range may be the same\n // but the selected items may now be different\n handleSelectionChange(selectedRanges, true);\n }\n },\n [loadedViewport, handleFocusChange, handleSelectionChange, selectedRanges]\n );\n\n // Expand a folder if hovering over it\n useEffect(\n function expandFolderOnHover() {\n if (\n dropTargetItem != null &&\n isDirectory(dropTargetItem) &&\n dropTargetItem.filename !== '/'\n ) {\n const timeout = setTimeout(() => {\n if (!dropTargetItem.isExpanded) {\n table?.setExpanded(dropTargetItem.filename, true);\n }\n }, DRAG_HOVER_TIMEOUT);\n return () => clearTimeout(timeout);\n }\n },\n [dropTargetItem, table]\n );\n\n const renderWrapper = useCallback(\n itemProps =>\n renderItem({\n ...itemProps,\n isDragInProgress: draggedItems != null,\n dropTargetItem,\n draggedItems,\n isDropTargetValid,\n onDragStart: handleItemDragStart,\n onDragEnd: handleItemDragEnd,\n onDragOver: handleItemDragOver,\n onDragExit: handleItemDragExit,\n onDrop: handleItemDrop,\n }),\n [\n handleItemDragEnd,\n handleItemDragExit,\n handleItemDragOver,\n handleItemDragStart,\n handleItemDrop,\n draggedItems,\n dropTargetItem,\n isDropTargetValid,\n renderItem,\n ]\n );\n\n return (\n <div\n ref={fileList}\n className={classNames('file-list', {\n 'is-dragging': draggedItems != null,\n })}\n onDragOver={handleListDragOver}\n onDrop={handleListDrop}\n >\n <ItemList\n ref={itemList}\n items={loadedViewport.items}\n itemCount={loadedViewport.itemCount}\n offset={loadedViewport.offset}\n onFocusChange={handleFocusChange}\n onSelect={handleSelect}\n onSelectionChange={handleSelectionChange}\n onViewportChange={handleViewportChange}\n selectedRanges={selectedRanges}\n renderItem={renderWrapper}\n rowHeight={rowHeight}\n isMultiSelect={isMultiSelect}\n isDragSelect={false}\n isDeselectOnClick={false}\n />\n </div>\n );\n}\n\nexport default FileList;\n"],"mappings":"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"}
@@ -102,8 +102,8 @@ export function FileListContainer(props) {
102
102
  }
103
103
  if (onCopy) {
104
104
  result.push({
105
- title: 'Copy',
106
- description: 'Copy',
105
+ title: 'Copy File',
106
+ description: 'Copy the selected file',
107
107
  action: handleCopyAction,
108
108
  group: ContextActions.groups.low,
109
109
  disabled: focusedItem == null || isDirectory(focusedItem)
@@ -1 +1 @@
1
- {"version":3,"file":"FileListContainer.js","names":["ContextActions","assertNotNull","React","useCallback","useMemo","useState","FileList","FileListItem","DEFAULT_ROW_HEIGHT","isDirectory","SHORTCUTS","FileUtils","FileListItemEditor","FileListContainer","props","isMultiSelect","focusedPath","showContextMenu","onCreateFile","onCreateFolder","onCopy","onDelete","onMove","onRename","onSelect","onSelectionChange","table","rowHeight","validateRename","Promise","resolve","renameItem","setRenameItem","selectedItems","setSelectedItems","focusedItem","setFocusedItem","handleSelectionChange","newSelectedItems","handleFocusChange","newFocusedItem","handleCopyAction","handleDeleteAction","length","handleNewFileAction","handleNewFolderAction","getPath","filename","handleRenameAction","handleRenameCancel","undefined","handleRenameSubmit","newName","actions","result","push","title","description","action","group","groups","medium","low","disabled","shortcut","FILE_EXPLORER","DELETE","RENAME","validateRenameItem","renderItem","itemProps","item","displayName"],"sources":["../src/FileListContainer.tsx"],"sourcesContent":["import { ContextAction, ContextActions } from '@deephaven/components';\nimport { assertNotNull } from '@deephaven/utils';\nimport React, { useCallback, useMemo, useState } from 'react';\nimport FileList from './FileList';\nimport { FileListItem, FileListRenderItemProps } from './FileListItem';\nimport { DEFAULT_ROW_HEIGHT } from './FileListUtils';\nimport { FileStorageItem, FileStorageTable, isDirectory } from './FileStorage';\nimport SHORTCUTS from './FileExplorerShortcuts';\nimport './FileExplorer.scss';\nimport FileUtils from './FileUtils';\nimport FileListItemEditor from './FileListItemEditor';\n\nexport interface FileListContainerProps {\n showContextMenu?: boolean;\n table: FileStorageTable;\n\n isMultiSelect?: boolean;\n focusedPath?: string;\n\n onCreateFile?: (path?: string) => void;\n onCreateFolder?: (path?: string) => void;\n onCopy?: (file: FileStorageItem) => void;\n onDelete?: (files: FileStorageItem[]) => void;\n onMove?: (files: FileStorageItem[], path: string) => void;\n onRename?: (file: FileStorageItem, newName: string) => void;\n onSelect: (file: FileStorageItem, event: React.SyntheticEvent) => void;\n validateRename?: (file: FileStorageItem, newName: string) => Promise<void>;\n onSelectionChange?: (selectedItems: FileStorageItem[]) => void;\n\n /** Height of each item in the list */\n rowHeight?: number;\n}\n\n/**\n * Component that displays and allows interaction with the file system in the provided FileStorage.\n */\nexport function FileListContainer(props: FileListContainerProps): JSX.Element {\n const {\n isMultiSelect = false,\n focusedPath,\n showContextMenu = false,\n onCreateFile,\n onCreateFolder,\n onCopy,\n onDelete,\n onMove,\n onRename,\n onSelect,\n onSelectionChange,\n table,\n rowHeight = DEFAULT_ROW_HEIGHT,\n validateRename = () => Promise.resolve(),\n } = props;\n const [renameItem, setRenameItem] = useState<FileStorageItem>();\n const [selectedItems, setSelectedItems] = useState([] as FileStorageItem[]);\n const [focusedItem, setFocusedItem] = useState<FileStorageItem>();\n\n const handleSelectionChange = useCallback(\n newSelectedItems => {\n setSelectedItems(newSelectedItems);\n onSelectionChange?.(newSelectedItems);\n },\n [onSelectionChange]\n );\n\n const handleFocusChange = useCallback(newFocusedItem => {\n setFocusedItem(newFocusedItem);\n }, []);\n\n const handleCopyAction = useCallback(() => {\n if (focusedItem) {\n onCopy?.(focusedItem);\n }\n }, [focusedItem, onCopy]);\n\n const handleDeleteAction = useCallback(() => {\n if (selectedItems.length > 0) {\n onDelete?.(selectedItems);\n }\n }, [onDelete, selectedItems]);\n\n const handleNewFileAction = useCallback(() => {\n onCreateFile?.();\n }, [onCreateFile]);\n\n const handleNewFolderAction = useCallback(() => {\n if (focusedItem) {\n onCreateFolder?.(FileUtils.getPath(focusedItem.filename));\n }\n }, [focusedItem, onCreateFolder]);\n\n const handleRenameAction = useCallback(() => {\n if (focusedItem) {\n setRenameItem(focusedItem);\n }\n }, [focusedItem]);\n\n const handleRenameCancel = useCallback((): void => {\n setRenameItem(undefined);\n }, []);\n\n const handleRenameSubmit = useCallback(\n (newName: string): void => {\n if (renameItem) {\n onRename?.(renameItem, newName);\n setRenameItem(undefined);\n }\n },\n [onRename, renameItem]\n );\n\n const actions = useMemo(() => {\n if (renameItem) {\n // While renaming, we don't want to enable any of the context actions or it may interfere with renaming input\n return [];\n }\n\n const result = [] as ContextAction[];\n if (onCreateFile) {\n result.push({\n title: 'New File',\n description: 'Create new file',\n action: handleNewFileAction,\n group: ContextActions.groups.medium,\n });\n }\n if (onCreateFolder) {\n result.push({\n title: 'New Folder',\n description: 'Create new folder',\n action: handleNewFolderAction,\n group: ContextActions.groups.medium,\n });\n }\n if (onCopy) {\n result.push({\n title: 'Copy',\n description: 'Copy',\n action: handleCopyAction,\n group: ContextActions.groups.low,\n disabled: focusedItem == null || isDirectory(focusedItem),\n });\n }\n if (onDelete && selectedItems.length > 0) {\n result.push({\n title: 'Delete',\n description: 'Delete',\n shortcut: SHORTCUTS.FILE_EXPLORER.DELETE,\n action: handleDeleteAction,\n group: ContextActions.groups.low,\n });\n }\n if (onRename) {\n result.push({\n title: 'Rename',\n description: 'Rename',\n shortcut: SHORTCUTS.FILE_EXPLORER.RENAME,\n action: handleRenameAction,\n group: ContextActions.groups.low,\n disabled: focusedItem == null,\n });\n }\n return result;\n }, [\n handleCopyAction,\n handleDeleteAction,\n handleNewFileAction,\n handleNewFolderAction,\n handleRenameAction,\n focusedItem,\n onCopy,\n onCreateFile,\n onCreateFolder,\n onDelete,\n onRename,\n selectedItems,\n renameItem,\n ]);\n\n const validateRenameItem = useCallback(\n (newName: string): Promise<void> => {\n assertNotNull(renameItem);\n return validateRename(renameItem, newName);\n },\n [renameItem, validateRename]\n );\n\n const renderItem = useCallback(\n (itemProps: FileListRenderItemProps): JSX.Element => {\n const { item } = itemProps;\n if (renameItem && renameItem.filename === item.filename) {\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <FileListItem {...itemProps}>\n <FileListItemEditor\n item={item}\n validate={validateRenameItem}\n onSubmit={handleRenameSubmit}\n onCancel={handleRenameCancel}\n />\n </FileListItem>\n );\n }\n // eslint-disable-next-line react/jsx-props-no-spreading\n return <FileListItem {...itemProps} />;\n },\n [handleRenameCancel, handleRenameSubmit, renameItem, validateRenameItem]\n );\n\n return (\n <div className=\"file-list-container\">\n {table != null && (\n <FileList\n onMove={onMove}\n onSelect={onSelect}\n onSelectionChange={handleSelectionChange}\n onFocusChange={handleFocusChange}\n renderItem={renderItem}\n rowHeight={rowHeight}\n table={table}\n isMultiSelect={isMultiSelect}\n focusedPath={focusedPath}\n />\n )}\n {showContextMenu && <ContextActions actions={actions} />}\n </div>\n );\n}\n\nFileListContainer.displayName = 'FileListContainer';\n\nexport default FileListContainer;\n"],"mappings":"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"}
1
+ {"version":3,"file":"FileListContainer.js","names":["ContextActions","assertNotNull","React","useCallback","useMemo","useState","FileList","FileListItem","DEFAULT_ROW_HEIGHT","isDirectory","SHORTCUTS","FileUtils","FileListItemEditor","FileListContainer","props","isMultiSelect","focusedPath","showContextMenu","onCreateFile","onCreateFolder","onCopy","onDelete","onMove","onRename","onSelect","onSelectionChange","table","rowHeight","validateRename","Promise","resolve","renameItem","setRenameItem","selectedItems","setSelectedItems","focusedItem","setFocusedItem","handleSelectionChange","newSelectedItems","handleFocusChange","newFocusedItem","handleCopyAction","handleDeleteAction","length","handleNewFileAction","handleNewFolderAction","getPath","filename","handleRenameAction","handleRenameCancel","undefined","handleRenameSubmit","newName","actions","result","push","title","description","action","group","groups","medium","low","disabled","shortcut","FILE_EXPLORER","DELETE","RENAME","validateRenameItem","renderItem","itemProps","item","displayName"],"sources":["../src/FileListContainer.tsx"],"sourcesContent":["import { ContextAction, ContextActions } from '@deephaven/components';\nimport { assertNotNull } from '@deephaven/utils';\nimport React, { useCallback, useMemo, useState } from 'react';\nimport FileList from './FileList';\nimport { FileListItem, FileListRenderItemProps } from './FileListItem';\nimport { DEFAULT_ROW_HEIGHT } from './FileListUtils';\nimport { FileStorageItem, FileStorageTable, isDirectory } from './FileStorage';\nimport SHORTCUTS from './FileExplorerShortcuts';\nimport './FileExplorer.scss';\nimport FileUtils from './FileUtils';\nimport FileListItemEditor from './FileListItemEditor';\n\nexport interface FileListContainerProps {\n showContextMenu?: boolean;\n table: FileStorageTable;\n\n isMultiSelect?: boolean;\n focusedPath?: string;\n\n onCreateFile?: (path?: string) => void;\n onCreateFolder?: (path?: string) => void;\n onCopy?: (file: FileStorageItem) => void;\n onDelete?: (files: FileStorageItem[]) => void;\n onMove?: (files: FileStorageItem[], path: string) => void;\n onRename?: (file: FileStorageItem, newName: string) => void;\n onSelect: (file: FileStorageItem, event: React.SyntheticEvent) => void;\n validateRename?: (file: FileStorageItem, newName: string) => Promise<void>;\n onSelectionChange?: (selectedItems: FileStorageItem[]) => void;\n\n /** Height of each item in the list */\n rowHeight?: number;\n}\n\n/**\n * Component that displays and allows interaction with the file system in the provided FileStorage.\n */\nexport function FileListContainer(props: FileListContainerProps): JSX.Element {\n const {\n isMultiSelect = false,\n focusedPath,\n showContextMenu = false,\n onCreateFile,\n onCreateFolder,\n onCopy,\n onDelete,\n onMove,\n onRename,\n onSelect,\n onSelectionChange,\n table,\n rowHeight = DEFAULT_ROW_HEIGHT,\n validateRename = () => Promise.resolve(),\n } = props;\n const [renameItem, setRenameItem] = useState<FileStorageItem>();\n const [selectedItems, setSelectedItems] = useState([] as FileStorageItem[]);\n const [focusedItem, setFocusedItem] = useState<FileStorageItem>();\n\n const handleSelectionChange = useCallback(\n newSelectedItems => {\n setSelectedItems(newSelectedItems);\n onSelectionChange?.(newSelectedItems);\n },\n [onSelectionChange]\n );\n\n const handleFocusChange = useCallback(newFocusedItem => {\n setFocusedItem(newFocusedItem);\n }, []);\n\n const handleCopyAction = useCallback(() => {\n if (focusedItem) {\n onCopy?.(focusedItem);\n }\n }, [focusedItem, onCopy]);\n\n const handleDeleteAction = useCallback(() => {\n if (selectedItems.length > 0) {\n onDelete?.(selectedItems);\n }\n }, [onDelete, selectedItems]);\n\n const handleNewFileAction = useCallback(() => {\n onCreateFile?.();\n }, [onCreateFile]);\n\n const handleNewFolderAction = useCallback(() => {\n if (focusedItem) {\n onCreateFolder?.(FileUtils.getPath(focusedItem.filename));\n }\n }, [focusedItem, onCreateFolder]);\n\n const handleRenameAction = useCallback(() => {\n if (focusedItem) {\n setRenameItem(focusedItem);\n }\n }, [focusedItem]);\n\n const handleRenameCancel = useCallback((): void => {\n setRenameItem(undefined);\n }, []);\n\n const handleRenameSubmit = useCallback(\n (newName: string): void => {\n if (renameItem) {\n onRename?.(renameItem, newName);\n setRenameItem(undefined);\n }\n },\n [onRename, renameItem]\n );\n\n const actions = useMemo(() => {\n if (renameItem) {\n // While renaming, we don't want to enable any of the context actions or it may interfere with renaming input\n return [];\n }\n\n const result = [] as ContextAction[];\n if (onCreateFile) {\n result.push({\n title: 'New File',\n description: 'Create new file',\n action: handleNewFileAction,\n group: ContextActions.groups.medium,\n });\n }\n if (onCreateFolder) {\n result.push({\n title: 'New Folder',\n description: 'Create new folder',\n action: handleNewFolderAction,\n group: ContextActions.groups.medium,\n });\n }\n if (onCopy) {\n result.push({\n title: 'Copy File',\n description: 'Copy the selected file',\n action: handleCopyAction,\n group: ContextActions.groups.low,\n disabled: focusedItem == null || isDirectory(focusedItem),\n });\n }\n if (onDelete && selectedItems.length > 0) {\n result.push({\n title: 'Delete',\n description: 'Delete',\n shortcut: SHORTCUTS.FILE_EXPLORER.DELETE,\n action: handleDeleteAction,\n group: ContextActions.groups.low,\n });\n }\n if (onRename) {\n result.push({\n title: 'Rename',\n description: 'Rename',\n shortcut: SHORTCUTS.FILE_EXPLORER.RENAME,\n action: handleRenameAction,\n group: ContextActions.groups.low,\n disabled: focusedItem == null,\n });\n }\n return result;\n }, [\n handleCopyAction,\n handleDeleteAction,\n handleNewFileAction,\n handleNewFolderAction,\n handleRenameAction,\n focusedItem,\n onCopy,\n onCreateFile,\n onCreateFolder,\n onDelete,\n onRename,\n selectedItems,\n renameItem,\n ]);\n\n const validateRenameItem = useCallback(\n (newName: string): Promise<void> => {\n assertNotNull(renameItem);\n return validateRename(renameItem, newName);\n },\n [renameItem, validateRename]\n );\n\n const renderItem = useCallback(\n (itemProps: FileListRenderItemProps): JSX.Element => {\n const { item } = itemProps;\n if (renameItem && renameItem.filename === item.filename) {\n return (\n // eslint-disable-next-line react/jsx-props-no-spreading\n <FileListItem {...itemProps}>\n <FileListItemEditor\n item={item}\n validate={validateRenameItem}\n onSubmit={handleRenameSubmit}\n onCancel={handleRenameCancel}\n />\n </FileListItem>\n );\n }\n // eslint-disable-next-line react/jsx-props-no-spreading\n return <FileListItem {...itemProps} />;\n },\n [handleRenameCancel, handleRenameSubmit, renameItem, validateRenameItem]\n );\n\n return (\n <div className=\"file-list-container\">\n {table != null && (\n <FileList\n onMove={onMove}\n onSelect={onSelect}\n onSelectionChange={handleSelectionChange}\n onFocusChange={handleFocusChange}\n renderItem={renderItem}\n rowHeight={rowHeight}\n table={table}\n isMultiSelect={isMultiSelect}\n focusedPath={focusedPath}\n />\n )}\n {showContextMenu && <ContextActions actions={actions} />}\n </div>\n );\n}\n\nFileListContainer.displayName = 'FileListContainer';\n\nexport default FileListContainer;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FileListItem.d.ts","sourceRoot":"","sources":["../src/FileListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAW,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKjE,OAAO,EAAE,eAAe,EAAe,MAAM,eAAe,CAAC;AAC7D,OAAO,iBAAiB,CAAC;AAsBzB,MAAM,MAAM,uBAAuB,GAAG,eAAe,CAAC,eAAe,CAAC,GAAG;IACvE,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAE3B,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IACrE,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IACpE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IACnE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;CACjE,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,uBAAuB,GAAG,GAAG,CAAC,OAAO,CA4ExE;AAED,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"FileListItem.d.ts","sourceRoot":"","sources":["../src/FileListItem.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAW,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKjE,OAAO,EAAE,eAAe,EAAe,MAAM,eAAe,CAAC;AAC7D,OAAO,iBAAiB,CAAC;AAsBzB,MAAM,MAAM,uBAAuB,GAAG,eAAe,CAAC,eAAe,CAAC,GAAG;IACvE,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAE3B,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IACrE,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IACpE,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IACnE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;CACjE,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,uBAAuB,GAAG,GAAG,CAAC,OAAO,CA0ExE;AAED,eAAe,YAAY,CAAC"}
@@ -13,6 +13,7 @@ import { getPathFromItem } from "./FileListUtils.js";
13
13
  * @returns Icon definition to pass in the FontAwesomeIcon icon prop
14
14
  */
15
15
  import { jsx as _jsx } from "react/jsx-runtime";
16
+ import { Fragment as _Fragment } from "react/jsx-runtime";
16
17
  import { jsxs as _jsxs } from "react/jsx-runtime";
17
18
  function getItemIcon(item) {
18
19
  if (isDirectory(item)) {
@@ -107,14 +108,13 @@ export function FileListItem(props) {
107
108
  icon: icon,
108
109
  className: "item-icon",
109
110
  fixedWidth: true
110
- }), ' ', /*#__PURE__*/_jsxs("span", {
111
+ }), ' ', /*#__PURE__*/_jsx("span", {
111
112
  className: "truncation-wrapper",
112
- children: [children !== null && children !== void 0 ? children : item.basename, /*#__PURE__*/_jsx(Tooltip, {
113
- options: {
114
- placement: 'left'
115
- },
116
- children: children !== null && children !== void 0 ? children : item.basename
117
- })]
113
+ children: children !== null && children !== void 0 ? children : /*#__PURE__*/_jsxs(_Fragment, {
114
+ children: [item.basename, /*#__PURE__*/_jsx(Tooltip, {
115
+ children: item.basename
116
+ })]
117
+ })
118
118
  })]
119
119
  });
120
120
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FileListItem.js","names":["React","Tooltip","dhPython","vsCode","vsFolder","vsFolderOpened","FontAwesomeIcon","classNames","isDirectory","FileUtils","MIME_TYPE","getPathFromItem","getItemIcon","item","isExpanded","mimeType","getMimeType","basename","PYTHON","FileListItem","props","children","draggedItems","isDragInProgress","isDropTargetValid","isSelected","itemIndex","dropTargetItem","onDragStart","onDragOver","onDragEnd","onDrop","isDragged","some","draggedItem","id","itemPath","dropTargetPath","isExactDropTarget","isInDropTarget","isInvalidDropTarget","icon","depth","getDepth","filename","depthLines","Array","fill","map","value","index","e","placement"],"sources":["../src/FileListItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Tooltip, RenderItemProps } from '@deephaven/components';\nimport { dhPython, vsCode, vsFolder, vsFolderOpened } from '@deephaven/icons';\nimport { IconDefinition } from '@fortawesome/fontawesome-svg-core';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport classNames from 'classnames';\nimport { FileStorageItem, isDirectory } from './FileStorage';\nimport './FileList.scss';\nimport FileUtils, { MIME_TYPE } from './FileUtils';\nimport { getPathFromItem } from './FileListUtils';\n\n/**\n * Get the icon definition for a file or folder item\n * @param item Item to get the icon for\n * @returns Icon definition to pass in the FontAwesomeIcon icon prop\n */\nfunction getItemIcon(item: FileStorageItem): IconDefinition {\n if (isDirectory(item)) {\n return item.isExpanded ? vsFolderOpened : vsFolder;\n }\n const mimeType = FileUtils.getMimeType(item.basename);\n switch (mimeType) {\n case MIME_TYPE.PYTHON:\n return dhPython;\n default:\n return vsCode;\n }\n}\n\nexport type FileListRenderItemProps = RenderItemProps<FileStorageItem> & {\n children?: JSX.Element;\n dropTargetItem?: FileStorageItem;\n draggedItems?: FileStorageItem[];\n isDragInProgress: boolean;\n isDropTargetValid: boolean;\n\n onDragStart(index: number, e: React.DragEvent<HTMLDivElement>): void;\n onDragOver(index: number, e: React.DragEvent<HTMLDivElement>): void;\n onDragEnd(index: number, e: React.DragEvent<HTMLDivElement>): void;\n onDrop(index: number, e: React.DragEvent<HTMLDivElement>): void;\n};\n\nexport function FileListItem(props: FileListRenderItemProps): JSX.Element {\n const {\n children,\n draggedItems,\n isDragInProgress,\n isDropTargetValid,\n isSelected,\n item,\n itemIndex,\n dropTargetItem,\n onDragStart,\n onDragOver,\n onDragEnd,\n onDrop,\n } = props;\n\n const isDragged =\n draggedItems?.some(draggedItem => draggedItem.id === item.id) ?? false;\n const itemPath = getPathFromItem(item);\n const dropTargetPath =\n isDragInProgress && dropTargetItem ? getPathFromItem(dropTargetItem) : null;\n\n const isExactDropTarget =\n isDragInProgress &&\n isDropTargetValid &&\n isDirectory(item) &&\n dropTargetPath === itemPath;\n const isInDropTarget =\n isDragInProgress && isDropTargetValid && dropTargetPath === itemPath;\n const isInvalidDropTarget =\n isDragInProgress && !isDropTargetValid && dropTargetPath === itemPath;\n\n const icon = getItemIcon(item);\n const depth = FileUtils.getDepth(item.filename);\n const depthLines = Array(depth)\n .fill(null)\n .map((value, index) => (\n // eslint-disable-next-line react/no-array-index-key\n <span className=\"file-list-depth-line\" key={index} />\n ));\n\n return (\n <div\n className={classNames(\n 'd-flex w-100 align-items-center',\n 'file-list-item',\n {\n 'is-dragged': isDragged,\n 'is-exact-drop-target': isExactDropTarget,\n 'is-in-drop-target': isInDropTarget,\n 'is-invalid-drop-target': isInvalidDropTarget,\n 'is-selected': isSelected,\n }\n )}\n onDragStart={e => onDragStart(itemIndex, e)}\n onDragOver={e => onDragOver(itemIndex, e)}\n onDragEnd={e => onDragEnd(itemIndex, e)}\n onDrop={e => onDrop(itemIndex, e)}\n draggable\n role=\"presentation\"\n aria-label={item.basename}\n >\n {depthLines}{' '}\n <FontAwesomeIcon icon={icon} className=\"item-icon\" fixedWidth />{' '}\n <span className=\"truncation-wrapper\">\n {children ?? item.basename}\n <Tooltip\n options={{\n placement: 'left',\n }}\n >\n {children ?? item.basename}\n </Tooltip>\n </span>\n </div>\n );\n}\n\nexport default FileListItem;\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,OAAO,QAAyB,uBAAuB;AAChE,SAASC,QAAQ,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,cAAc,QAAQ,kBAAkB;AAE7E,SAASC,eAAe,QAAQ,gCAAgC;AAChE,OAAOC,UAAU,MAAM,YAAY;AAAC,SACVC,WAAW;AAAA;AAAA,OAE9BC,SAAS,IAAIC,SAAS;AAAA,SACpBC,eAAe;AAExB;AACA;AACA;AACA;AACA;AAJA;AAAA;AAKA,SAASC,WAAW,CAACC,IAAqB,EAAkB;EAC1D,IAAIL,WAAW,CAACK,IAAI,CAAC,EAAE;IACrB,OAAOA,IAAI,CAACC,UAAU,GAAGT,cAAc,GAAGD,QAAQ;EACpD;EACA,IAAMW,QAAQ,GAAGN,SAAS,CAACO,WAAW,CAACH,IAAI,CAACI,QAAQ,CAAC;EACrD,QAAQF,QAAQ;IACd,KAAKL,SAAS,CAACQ,MAAM;MACnB,OAAOhB,QAAQ;IACjB;MACE,OAAOC,MAAM;EAAC;AAEpB;AAeA,OAAO,SAASgB,YAAY,CAACC,KAA8B,EAAe;EAAA;EACxE,IAAM;IACJC,QAAQ;IACRC,YAAY;IACZC,gBAAgB;IAChBC,iBAAiB;IACjBC,UAAU;IACVZ,IAAI;IACJa,SAAS;IACTC,cAAc;IACdC,WAAW;IACXC,UAAU;IACVC,SAAS;IACTC;EACF,CAAC,GAAGX,KAAK;EAET,IAAMY,SAAS,yBACbV,YAAY,aAAZA,YAAY,uBAAZA,YAAY,CAAEW,IAAI,CAACC,WAAW,IAAIA,WAAW,CAACC,EAAE,KAAKtB,IAAI,CAACsB,EAAE,CAAC,mEAAI,KAAK;EACxE,IAAMC,QAAQ,GAAGzB,eAAe,CAACE,IAAI,CAAC;EACtC,IAAMwB,cAAc,GAClBd,gBAAgB,IAAII,cAAc,GAAGhB,eAAe,CAACgB,cAAc,CAAC,GAAG,IAAI;EAE7E,IAAMW,iBAAiB,GACrBf,gBAAgB,IAChBC,iBAAiB,IACjBhB,WAAW,CAACK,IAAI,CAAC,IACjBwB,cAAc,KAAKD,QAAQ;EAC7B,IAAMG,cAAc,GAClBhB,gBAAgB,IAAIC,iBAAiB,IAAIa,cAAc,KAAKD,QAAQ;EACtE,IAAMI,mBAAmB,GACvBjB,gBAAgB,IAAI,CAACC,iBAAiB,IAAIa,cAAc,KAAKD,QAAQ;EAEvE,IAAMK,IAAI,GAAG7B,WAAW,CAACC,IAAI,CAAC;EAC9B,IAAM6B,KAAK,GAAGjC,SAAS,CAACkC,QAAQ,CAAC9B,IAAI,CAAC+B,QAAQ,CAAC;EAC/C,IAAMC,UAAU,GAAGC,KAAK,CAACJ,KAAK,CAAC,CAC5BK,IAAI,CAAC,IAAI,CAAC,CACVC,GAAG,CAAC,CAACC,KAAK,EAAEC,KAAK;EAAA;EAChB;EACA;IAAM,SAAS,EAAC;EAAsB,GAAMA,KAAK,CAClD,CAAC;EAEJ,oBACE;IACE,SAAS,EAAE3C,UAAU,CACnB,iCAAiC,EACjC,gBAAgB,EAChB;MACE,YAAY,EAAEyB,SAAS;MACvB,sBAAsB,EAAEM,iBAAiB;MACzC,mBAAmB,EAAEC,cAAc;MACnC,wBAAwB,EAAEC,mBAAmB;MAC7C,aAAa,EAAEf;IACjB,CAAC,CACD;IACF,WAAW;MAAA;QAAA;MAAA;MAAA;QAAA;MAAA;MAAA;IAAA,EAAE0B,CAAC,IAAIvB,WAAW,CAACF,SAAS,EAAEyB,CAAC,CAAC,CAAC;IAC5C,UAAU;MAAA;QAAA;MAAA;MAAA;QAAA;MAAA;MAAA;IAAA,EAAEA,CAAC,IAAItB,UAAU,CAACH,SAAS,EAAEyB,CAAC,CAAC,CAAC;IAC1C,SAAS;MAAA;QAAA;MAAA;MAAA;QAAA;MAAA;MAAA;IAAA,EAAEA,CAAC,IAAIrB,SAAS,CAACJ,SAAS,EAAEyB,CAAC,CAAC,CAAC;IACxC,MAAM;MAAA;QAAA;MAAA;MAAA;QAAA;MAAA;MAAA;IAAA,EAAEA,CAAC,IAAIpB,MAAM,CAACL,SAAS,EAAEyB,CAAC,CAAC,CAAC;IAClC,SAAS;IACT,IAAI,EAAC,cAAc;IACnB,cAAYtC,IAAI,CAACI,QAAS;IAAA,WAEzB4B,UAAU,EAAE,GAAG,eAChB,KAAC,eAAe;MAAC,IAAI,EAAEJ,IAAK;MAAC,SAAS,EAAC,WAAW;MAAC,UAAU;IAAA,EAAG,EAAC,GAAG,eACpE;MAAM,SAAS,EAAC,oBAAoB;MAAA,WACjCpB,QAAQ,aAARA,QAAQ,cAARA,QAAQ,GAAIR,IAAI,CAACI,QAAQ,eAC1B,KAAC,OAAO;QACN,OAAO,EAAE;UACPmC,SAAS,EAAE;QACb,CAAE;QAAA,UAED/B,QAAQ,aAARA,QAAQ,cAARA,QAAQ,GAAIR,IAAI,CAACI;MAAQ,EAClB;IAAA,EACL;EAAA,EACH;AAEV;AAEA,eAAeE,YAAY"}
1
+ {"version":3,"file":"FileListItem.js","names":["React","Tooltip","dhPython","vsCode","vsFolder","vsFolderOpened","FontAwesomeIcon","classNames","isDirectory","FileUtils","MIME_TYPE","getPathFromItem","getItemIcon","item","isExpanded","mimeType","getMimeType","basename","PYTHON","FileListItem","props","children","draggedItems","isDragInProgress","isDropTargetValid","isSelected","itemIndex","dropTargetItem","onDragStart","onDragOver","onDragEnd","onDrop","isDragged","some","draggedItem","id","itemPath","dropTargetPath","isExactDropTarget","isInDropTarget","isInvalidDropTarget","icon","depth","getDepth","filename","depthLines","Array","fill","map","value","index","e"],"sources":["../src/FileListItem.tsx"],"sourcesContent":["import React from 'react';\nimport { Tooltip, RenderItemProps } from '@deephaven/components';\nimport { dhPython, vsCode, vsFolder, vsFolderOpened } from '@deephaven/icons';\nimport { IconDefinition } from '@fortawesome/fontawesome-svg-core';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome';\nimport classNames from 'classnames';\nimport { FileStorageItem, isDirectory } from './FileStorage';\nimport './FileList.scss';\nimport FileUtils, { MIME_TYPE } from './FileUtils';\nimport { getPathFromItem } from './FileListUtils';\n\n/**\n * Get the icon definition for a file or folder item\n * @param item Item to get the icon for\n * @returns Icon definition to pass in the FontAwesomeIcon icon prop\n */\nfunction getItemIcon(item: FileStorageItem): IconDefinition {\n if (isDirectory(item)) {\n return item.isExpanded ? vsFolderOpened : vsFolder;\n }\n const mimeType = FileUtils.getMimeType(item.basename);\n switch (mimeType) {\n case MIME_TYPE.PYTHON:\n return dhPython;\n default:\n return vsCode;\n }\n}\n\nexport type FileListRenderItemProps = RenderItemProps<FileStorageItem> & {\n children?: JSX.Element;\n dropTargetItem?: FileStorageItem;\n draggedItems?: FileStorageItem[];\n isDragInProgress: boolean;\n isDropTargetValid: boolean;\n\n onDragStart(index: number, e: React.DragEvent<HTMLDivElement>): void;\n onDragOver(index: number, e: React.DragEvent<HTMLDivElement>): void;\n onDragEnd(index: number, e: React.DragEvent<HTMLDivElement>): void;\n onDrop(index: number, e: React.DragEvent<HTMLDivElement>): void;\n};\n\nexport function FileListItem(props: FileListRenderItemProps): JSX.Element {\n const {\n children,\n draggedItems,\n isDragInProgress,\n isDropTargetValid,\n isSelected,\n item,\n itemIndex,\n dropTargetItem,\n onDragStart,\n onDragOver,\n onDragEnd,\n onDrop,\n } = props;\n\n const isDragged =\n draggedItems?.some(draggedItem => draggedItem.id === item.id) ?? false;\n const itemPath = getPathFromItem(item);\n const dropTargetPath =\n isDragInProgress && dropTargetItem ? getPathFromItem(dropTargetItem) : null;\n\n const isExactDropTarget =\n isDragInProgress &&\n isDropTargetValid &&\n isDirectory(item) &&\n dropTargetPath === itemPath;\n const isInDropTarget =\n isDragInProgress && isDropTargetValid && dropTargetPath === itemPath;\n const isInvalidDropTarget =\n isDragInProgress && !isDropTargetValid && dropTargetPath === itemPath;\n\n const icon = getItemIcon(item);\n const depth = FileUtils.getDepth(item.filename);\n const depthLines = Array(depth)\n .fill(null)\n .map((value, index) => (\n // eslint-disable-next-line react/no-array-index-key\n <span className=\"file-list-depth-line\" key={index} />\n ));\n\n return (\n <div\n className={classNames(\n 'd-flex w-100 align-items-center',\n 'file-list-item',\n {\n 'is-dragged': isDragged,\n 'is-exact-drop-target': isExactDropTarget,\n 'is-in-drop-target': isInDropTarget,\n 'is-invalid-drop-target': isInvalidDropTarget,\n 'is-selected': isSelected,\n }\n )}\n onDragStart={e => onDragStart(itemIndex, e)}\n onDragOver={e => onDragOver(itemIndex, e)}\n onDragEnd={e => onDragEnd(itemIndex, e)}\n onDrop={e => onDrop(itemIndex, e)}\n draggable\n role=\"presentation\"\n aria-label={item.basename}\n >\n {depthLines}{' '}\n <FontAwesomeIcon icon={icon} className=\"item-icon\" fixedWidth />{' '}\n <span className=\"truncation-wrapper\">\n {children ?? (\n <>\n {item.basename}\n <Tooltip>{item.basename}</Tooltip>\n </>\n )}\n </span>\n </div>\n );\n}\n\nexport default FileListItem;\n"],"mappings":"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"}
@@ -64,6 +64,12 @@ export interface FileStorage {
64
64
  * @param newName The new file name, including path
65
65
  */
66
66
  moveFile(name: string, newName: string): Promise<void>;
67
+ /**
68
+ * Copy a file to a new location
69
+ * @param name The name of the file to copy
70
+ * @param newName The new file name, including path
71
+ */
72
+ copyFile(name: string, newName: string): Promise<void>;
67
73
  /**
68
74
  * Get the info for the file at the specified path.
69
75
  * If the file does not exists, rejects with a FileNotFoundError
@@ -1 +1 @@
1
- {"version":3,"file":"FileStorage.d.ts","sourceRoot":"","sources":["../src/FileStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IAEjB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE5C,MAAM,WAAW,eAAgB,SAAQ,WAAW,EAAE,YAAY;IAChE,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,eAAe,GACpB,IAAI,IAAI,oBAAoB,CAE9B;AAED;;GAEG;AACH,MAAM,WAAW,IAAK,SAAQ,YAAY;IACxC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAiB,SAAQ,YAAY,CAAC,eAAe,CAAC;IACrE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;;OAGG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAEnD;;OAEG;IACH,WAAW,IAAI,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEtC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAE7C;;;OAGG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACzD;AAED,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"FileStorage.d.ts","sourceRoot":"","sources":["../src/FileStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IAEjB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE5C,MAAM,WAAW,eAAgB,SAAQ,WAAW,EAAE,YAAY;IAChE,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,WAAW,CACzB,IAAI,EAAE,eAAe,GACpB,IAAI,IAAI,oBAAoB,CAE9B;AAED;;GAEG;AACH,MAAM,WAAW,IAAK,SAAQ,YAAY;IACxC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAiB,SAAQ,YAAY,CAAC,eAAe,CAAC;IACrE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;;OAGG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IAEnD;;OAEG;IACH,WAAW,IAAI,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEtC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAE7C;;;OAGG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACzD;AAED,eAAe,WAAW,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"FileStorage.js","names":["isDirectory","file","type"],"sources":["../src/FileStorage.ts"],"sourcesContent":["import { StorageTable, StorageItem } from '@deephaven/storage';\n\n/**\n * Basic metadata of the file\n */\nexport interface FileMetadata {\n /** Full path of the file */\n filename: string;\n\n /** Just the file name part of the file (no path) */\n basename: string;\n}\n\nexport type FileType = 'file' | 'directory';\n\nexport interface FileStorageItem extends StorageItem, FileMetadata {\n type: FileType;\n}\n\nexport interface DirectoryStorageItem extends FileStorageItem {\n type: 'directory';\n isExpanded: boolean;\n}\n\nexport function isDirectory(\n file: FileStorageItem\n): file is DirectoryStorageItem {\n return file.type === 'directory';\n}\n\n/**\n * A file including it's contents\n */\nexport interface File extends FileMetadata {\n content: string;\n}\n\nexport interface FileStorageTable extends StorageTable<FileStorageItem> {\n setSearch(search: string): void;\n\n /**\n * @param path The path to expand\n * @param expanded What expanded state to set\n */\n setExpanded(path: string, expanded: boolean): void;\n\n /**\n * Collapses all directories\n */\n collapseAll(): void;\n}\n\n/**\n * FileStorage abstraction. Has methods for managing files, and for retrieving a table to browse files.\n */\nexport interface FileStorage {\n /**\n * Retrieve a table to view the file list\n */\n getTable(): Promise<FileStorageTable>;\n\n /**\n * Save a file\n * @param file The file to save\n */\n saveFile(file: File): Promise<File>;\n\n /**\n * Load the contents of a file\n * @param name The file to load, including the full path\n */\n loadFile(name: string): Promise<File>;\n\n /**\n * Delete a file\n * @param name The full name of the file to delete\n */\n deleteFile(name: string): Promise<void>;\n\n /**\n * Move a file to a new location\n * @param name Source file name\n * @param newName The new file name, including path\n */\n moveFile(name: string, newName: string): Promise<void>;\n\n /**\n * Get the info for the file at the specified path.\n * If the file does not exists, rejects with a FileNotFoundError\n * @param name The file name to check, including path\n * @returns The FileStorageItem for the path specified, or reject with a FileNotFoundError if it does not exist.\n */\n info(name: string): Promise<FileStorageItem>;\n\n /**\n * Create the directory at the given path\n * @param name The full directory path\n */\n createDirectory(name: string): Promise<FileStorageItem>;\n}\n\nexport default FileStorage;\n"],"mappings":"AAEA;AACA;AACA;;AAoBA,OAAO,SAASA,WAAW,CACzBC,IAAqB,EACS;EAC9B,OAAOA,IAAI,CAACC,IAAI,KAAK,WAAW;AAClC;;AAEA;AACA;AACA"}
1
+ {"version":3,"file":"FileStorage.js","names":["isDirectory","file","type"],"sources":["../src/FileStorage.ts"],"sourcesContent":["import { StorageTable, StorageItem } from '@deephaven/storage';\n\n/**\n * Basic metadata of the file\n */\nexport interface FileMetadata {\n /** Full path of the file */\n filename: string;\n\n /** Just the file name part of the file (no path) */\n basename: string;\n}\n\nexport type FileType = 'file' | 'directory';\n\nexport interface FileStorageItem extends StorageItem, FileMetadata {\n type: FileType;\n}\n\nexport interface DirectoryStorageItem extends FileStorageItem {\n type: 'directory';\n isExpanded: boolean;\n}\n\nexport function isDirectory(\n file: FileStorageItem\n): file is DirectoryStorageItem {\n return file.type === 'directory';\n}\n\n/**\n * A file including it's contents\n */\nexport interface File extends FileMetadata {\n content: string;\n}\n\nexport interface FileStorageTable extends StorageTable<FileStorageItem> {\n setSearch(search: string): void;\n\n /**\n * @param path The path to expand\n * @param expanded What expanded state to set\n */\n setExpanded(path: string, expanded: boolean): void;\n\n /**\n * Collapses all directories\n */\n collapseAll(): void;\n}\n\n/**\n * FileStorage abstraction. Has methods for managing files, and for retrieving a table to browse files.\n */\nexport interface FileStorage {\n /**\n * Retrieve a table to view the file list\n */\n getTable(): Promise<FileStorageTable>;\n\n /**\n * Save a file\n * @param file The file to save\n */\n saveFile(file: File): Promise<File>;\n\n /**\n * Load the contents of a file\n * @param name The file to load, including the full path\n */\n loadFile(name: string): Promise<File>;\n\n /**\n * Delete a file\n * @param name The full name of the file to delete\n */\n deleteFile(name: string): Promise<void>;\n\n /**\n * Move a file to a new location\n * @param name Source file name\n * @param newName The new file name, including path\n */\n moveFile(name: string, newName: string): Promise<void>;\n\n /**\n * Copy a file to a new location\n * @param name The name of the file to copy\n * @param newName The new file name, including path\n */\n copyFile(name: string, newName: string): Promise<void>;\n\n /**\n * Get the info for the file at the specified path.\n * If the file does not exists, rejects with a FileNotFoundError\n * @param name The file name to check, including path\n * @returns The FileStorageItem for the path specified, or reject with a FileNotFoundError if it does not exist.\n */\n info(name: string): Promise<FileStorageItem>;\n\n /**\n * Create the directory at the given path\n * @param name The full directory path\n */\n createDirectory(name: string): Promise<FileStorageItem>;\n}\n\nexport default FileStorage;\n"],"mappings":"AAEA;AACA;AACA;;AAoBA,OAAO,SAASA,WAAW,CACzBC,IAAqB,EACS;EAC9B,OAAOA,IAAI,CAACC,IAAI,KAAK,WAAW;AAClC;;AAEA;AACA;AACA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deephaven/file-explorer",
3
- "version": "0.46.2-beta.3+f626876e",
3
+ "version": "0.47.0",
4
4
  "description": "Deephaven File Explorer React component",
5
5
  "author": "Deephaven Data Labs LLC",
6
6
  "license": "Apache-2.0",
@@ -22,11 +22,11 @@
22
22
  "build:sass": "sass --embed-sources --load-path=../../node_modules ./src:./dist"
23
23
  },
24
24
  "dependencies": {
25
- "@deephaven/components": "^0.46.2-beta.3+f626876e",
26
- "@deephaven/icons": "^0.46.2-beta.3+f626876e",
27
- "@deephaven/log": "^0.46.2-beta.3+f626876e",
28
- "@deephaven/storage": "^0.46.2-beta.3+f626876e",
29
- "@deephaven/utils": "^0.46.2-beta.3+f626876e",
25
+ "@deephaven/components": "^0.47.0",
26
+ "@deephaven/icons": "^0.47.0",
27
+ "@deephaven/log": "^0.47.0",
28
+ "@deephaven/storage": "^0.47.0",
29
+ "@deephaven/utils": "^0.47.0",
30
30
  "@fortawesome/fontawesome-svg-core": "^6.2.1",
31
31
  "@fortawesome/react-fontawesome": "^0.2.0",
32
32
  "classnames": "^2.3.1",
@@ -37,7 +37,7 @@
37
37
  "react": "^17.0.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@deephaven/mocks": "^0.46.2-beta.3+f626876e"
40
+ "@deephaven/mocks": "^0.47.0"
41
41
  },
42
42
  "files": [
43
43
  "dist"
@@ -48,5 +48,5 @@
48
48
  "publishConfig": {
49
49
  "access": "public"
50
50
  },
51
- "gitHead": "f626876e5c91da43404f9ab2fc6c9c7cc2af830a"
51
+ "gitHead": "8d890b724d6c8bdb73eb03463f9c850ca57094bd"
52
52
  }