diff --git a/packages/api/src/controllers/archive.js b/packages/api/src/controllers/archive.js index 4924a4103..55869487e 100644 --- a/packages/api/src/controllers/archive.js +++ b/packages/api/src/controllers/archive.js @@ -38,4 +38,27 @@ module.exports = { type: 'jsonl', })); }, + + refreshFiles_meta: 'post', + async refreshFiles({ folder }) { + socket.emitChanged(`archive-files-changed-${folder}`); + }, + + refreshFolders_meta: 'post', + async refreshFolders() { + socket.emitChanged(`archive-folders-changed`); + }, + + deleteFile_meta: 'post', + async deleteFile({ folder, file }) { + await fs.unlink(path.join(archivedir(), folder, `${file}.jsonl`)); + socket.emitChanged(`archive-files-changed-${folder}`); + }, + + deleteFolder_meta: 'post', + async deleteFolder({ folder }) { + if (!folder) throw new Error('Missing folder parameter'); + await fs.rmdir(path.join(archivedir(), folder), { recursive: true }); + socket.emitChanged(`archive-folders-changed`); + }, }; diff --git a/packages/api/src/controllers/jsldata.js b/packages/api/src/controllers/jsldata.js index 72defc8b6..9c71bb634 100644 --- a/packages/api/src/controllers/jsldata.js +++ b/packages/api/src/controllers/jsldata.js @@ -1,7 +1,6 @@ -const path = require('path'); const fs = require('fs'); const lineReader = require('line-reader'); -const { jsldir, archivedir } = require('../utility/directories'); +const getJslFileName = require('../utility/getJslFileName'); const socket = require('../utility/socket'); function readFirstLine(file) { @@ -20,13 +19,6 @@ function readFirstLine(file) { }); } -function getJslFileName(jslid) { - const archiveMatch = jslid.match(/^archive:\/\/([^/]+)\/(.*)$/); - if (archiveMatch) { - return path.join(archivedir(), archiveMatch[1], `${archiveMatch[2]}.jsonl`); - } - return path.join(jsldir(), `${jslid}.jsonl`); -} module.exports = { openedReaders: {}, diff --git a/packages/api/src/shell/jslDataReader.js b/packages/api/src/shell/jslDataReader.js index c5b602bea..590a9946e 100644 --- a/packages/api/src/shell/jslDataReader.js +++ b/packages/api/src/shell/jslDataReader.js @@ -1,9 +1,8 @@ -const path = require('path'); -const { jsldir } = require('../utility/directories'); +const getJslFileName = require('../utility/getJslFileName'); const jsonLinesReader = require('./jsonLinesReader'); function jslDataReader({ jslid }) { - const fileName = path.join(jsldir(), `${jslid}.jsonl`); + const fileName = getJslFileName(jslid); return jsonLinesReader({ fileName }); } diff --git a/packages/api/src/utility/getJslFileName.js b/packages/api/src/utility/getJslFileName.js new file mode 100644 index 000000000..d74c1ffe6 --- /dev/null +++ b/packages/api/src/utility/getJslFileName.js @@ -0,0 +1,12 @@ +const path = require('path'); +const { jsldir, archivedir } = require('./directories'); + +function getJslFileName(jslid) { + const archiveMatch = jslid.match(/^archive:\/\/([^/]+)\/(.*)$/); + if (archiveMatch) { + return path.join(archivedir(), archiveMatch[1], `${archiveMatch[2]}.jsonl`); + } + return path.join(jsldir(), `${jslid}.jsonl`); +} + +module.exports = getJslFileName; diff --git a/packages/web/src/appobj/archiveFileAppObject.js b/packages/web/src/appobj/archiveFileAppObject.js index e01a35c3e..eebdbf3b4 100644 --- a/packages/web/src/appobj/archiveFileAppObject.js +++ b/packages/web/src/appobj/archiveFileAppObject.js @@ -4,9 +4,12 @@ import moment from 'moment'; import { DatabaseIcon, getIconImage, ArchiveTableIcon } from '../icons'; import { DropDownMenuItem } from '../modals/DropDownMenu'; import { openNewTab } from '../utility/common'; +import { filterName } from '@dbgate/datalib'; +import axios from '../utility/axios'; function Menu({ data, setOpenedTabs }) { const handleDelete = () => { + axios.post('archive/delete-file', { file: data.fileName, folder: data.folderName }); // setOpenedTabs((tabs) => tabs.filter((x) => x.tabid != data.tabid)); }; return ( @@ -32,8 +35,9 @@ const archiveFileAppObject = () => ({ fileName, folderName }, { setOpenedTabs }) }, }); }; + const matcher = (filter) => filterName(filter, fileName); - return { title: fileName, key, Icon, Menu, onClick }; + return { title: fileName, key, Icon, Menu, onClick, matcher }; }; export default archiveFileAppObject; diff --git a/packages/web/src/appobj/archiveFolderAppObject.js b/packages/web/src/appobj/archiveFolderAppObject.js index 06eec909b..d66213143 100644 --- a/packages/web/src/appobj/archiveFolderAppObject.js +++ b/packages/web/src/appobj/archiveFolderAppObject.js @@ -3,10 +3,12 @@ import _ from 'lodash'; import moment from 'moment'; import { LocalDbIcon, getIconImage } from '../icons'; import { DropDownMenuItem } from '../modals/DropDownMenu'; +import axios from '../utility/axios'; +import { filterName } from '@dbgate/datalib'; function Menu({ data, setOpenedTabs }) { const handleDelete = () => { - // setOpenedTabs((tabs) => tabs.filter((x) => x.tabid != data.tabid)); + axios.post('archive/delete-folder', { folder: data.name }); }; return ( <> @@ -20,8 +22,9 @@ const archiveFolderAppObject = () => ({ name }, { setOpenedTabs, currentArchive // const Icon = (props) => ; const Icon = LocalDbIcon; const isBold = name == currentArchive; + const matcher = (filter) => filterName(filter, name); - return { title: name, key, Icon, isBold, Menu }; + return { title: name, key, Icon, isBold, Menu, matcher }; }; export default archiveFolderAppObject; diff --git a/packages/web/src/widgets/ArchiveWidget.js b/packages/web/src/widgets/ArchiveWidget.js index 5750b87ee..5c647cb15 100644 --- a/packages/web/src/widgets/ArchiveWidget.js +++ b/packages/web/src/widgets/ArchiveWidget.js @@ -16,20 +16,34 @@ import savedSqlFileAppObject from '../appobj/savedSqlFileAppObject'; import { useArchiveFiles, useArchiveFolders } from '../utility/metadataLoaders'; import archiveFolderAppObject from '../appobj/archiveFolderAppObject'; import archiveFileAppObject from '../appobj/archiveFileAppObject'; +import SearchInput from './SearchInput'; +import InlineButton from './InlineButton'; +import axios from '../utility/axios'; function ArchiveFolderList() { const folders = useArchiveFolders(); + const inputRef = React.useRef(null); + const [filter, setFilter] = React.useState(''); const setArchive = useSetCurrentArchive(); + const handleRefreshFolders = () => { + axios.post('archive/refresh-folders', {}); + }; + return ( <> - Archive folder + Archive folder + + + Refresh + setArchive(archive.name)} + filter={filter} /> @@ -39,16 +53,26 @@ function ArchiveFolderList() { function ArchiveFilesList() { const folder = useCurrentArchive(); const files = useArchiveFiles({ folder }); + const inputRef = React.useRef(null); + const [filter, setFilter] = React.useState(''); + const handleRefreshFiles = () => { + axios.post('archive/refresh-files', { folder }); + }; return ( <> - Archive files + Archive files + + + Refresh + ({ fileName: file.name, folderName: folder, }))} + filter={filter} makeAppObj={archiveFileAppObject()} />