diff --git a/changelog.md b/changelog.md index 37e926e..8c77a28 100644 --- a/changelog.md +++ b/changelog.md @@ -8,6 +8,7 @@ - Localizations improvements (Thanks @madejackson) - Improved local IP detection (Thanks @r41d) - Updated LEGO to 4.21.0 + - Fixed file picker prefix issue in docker container - Fix RClone not starting ## Version 0.17.7 diff --git a/client/src/api/backup.ts b/client/src/api/backup.ts index f34a3f7..bf86a3d 100644 --- a/client/src/api/backup.ts +++ b/client/src/api/backup.ts @@ -26,12 +26,11 @@ function listSnapshots(name: string) { } function listFolders(name: string, snapshot: string, path?: string) { - return wrap(fetch(`/cosmos/api/backups/${name}/folders?path=${path || ''}`, { + return wrap(fetch(`/cosmos/api/backups/${name}/${snapshot}/folders?path=${path || '/'}`, { method: 'GET', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ snapshot }) })) } diff --git a/client/src/components/tabbedView/tabbedView.jsx b/client/src/components/tabbedView/tabbedView.jsx index 3070c55..a0bdc88 100644 --- a/client/src/components/tabbedView/tabbedView.jsx +++ b/client/src/components/tabbedView/tabbedView.jsx @@ -1,6 +1,7 @@ -import React, { useState } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import { Box, Tab, Tabs, Typography, MenuItem, Select, useMediaQuery, CircularProgress } from '@mui/material'; import { styled } from '@mui/system'; +import { createPartiallyEmittedExpression } from 'typescript'; const StyledTabs = styled(Tabs)` border-right: 1px solid ${({ theme }) => theme.palette.divider}; @@ -37,13 +38,35 @@ const a11yProps = (index) => { }; }; -const PrettyTabbedView = ({ tabs, isLoading, currentTab, setCurrentTab }) => { +const PrettyTabbedView = ({ rootURL, tabs, isLoading, currentTab, setCurrentTab }) => { const [value, setValue] = useState(0); const isMobile = useMediaQuery((theme) => theme.breakpoints.down('md')); - + const [initialMount, setInitialMount] = useState(true); + if((currentTab != null && typeof currentTab === 'number') && value !== currentTab) setValue(currentTab); + useEffect(() => { + if (!rootURL) return; + + if (initialMount) { + // On initial mount, check if URL matches any tab + const currentPath = decodeURIComponent(window.location.pathname).replace(/\/$/, ''); + const matchingTabIndex = tabs.findIndex(tab => { + return tab.url != '/' && currentPath.startsWith(`${rootURL}${tab.url}`); + }); + + if (matchingTabIndex !== -1) { + setValue(matchingTabIndex); + } + + setInitialMount(false); + } else { + // After initial mount, update URL when value changes + window.history.pushState({}, '', `${rootURL}${tabs[value].url}`); + } + }, [rootURL, tabs, value]); + const handleChange = (event, newValue) => { setValue(newValue); setCurrentTab && setCurrentTab(newValue); diff --git a/client/src/layout/MainLayout/Header/HeaderContent/sudoModal.jsx b/client/src/layout/MainLayout/Header/HeaderContent/sudoModal.jsx index 15efc62..e2e5522 100644 --- a/client/src/layout/MainLayout/Header/HeaderContent/sudoModal.jsx +++ b/client/src/layout/MainLayout/Header/HeaderContent/sudoModal.jsx @@ -28,6 +28,12 @@ const SudoModal = () => { try { setLoading(true); await API.auth.sudo(values); + + // if on /cosmos-ui/config-general refresh page because we need new infos + if (window.location.pathname.includes('/cosmos-ui/config-general')) { + window.location.reload(); + } + setOpen(false); resetForm(); } catch (error) { diff --git a/client/src/routes/MainRoutes.jsx b/client/src/routes/MainRoutes.jsx index fd90898..67c251a 100644 --- a/client/src/routes/MainRoutes.jsx +++ b/client/src/routes/MainRoutes.jsx @@ -19,6 +19,7 @@ import { CronManager } from '../pages/cron/jobsManage'; import PrivateRoute from '../PrivateRoute'; import TrustPage from '../pages/config/trust'; import { Backups } from '../pages/backups'; +import SingleBackupIndex from '../pages/backups/single-backup-index'; // ==============================|| MAIN ROUTING ||============================== // @@ -48,6 +49,14 @@ const MainRoutes = { path: '/cosmos-ui/backups', element: }, + { + path: '/cosmos-ui/backups/:backupName/', + element: + }, + { + path: '/cosmos-ui/backups/:backupName/:subpath', + element: + }, { path: '/cosmos-ui/storage', element: diff --git a/readme.md b/readme.md index c6612d9..f88d5bc 100644 --- a/readme.md +++ b/readme.md @@ -8,9 +8,8 @@ null Phobes null -Ricardo Escaran null -null +jwr1 John Richardson

diff --git a/src/httpServer.go b/src/httpServer.go index 6bf340b..b3da84b 100644 --- a/src/httpServer.go +++ b/src/httpServer.go @@ -560,7 +560,7 @@ func InitServer() *mux.Router { srapiAdmin.HandleFunc("/api/list-dir", storage.ListDirectoryRoute) srapiAdmin.HandleFunc("/api/backups/{name}/snapshots", backups.ListSnapshotsRoute) - srapiAdmin.HandleFunc("/api/backups/{name}/folders", backups.ListFoldersRoute) + srapiAdmin.HandleFunc("/api/backups/{name}/{snapshot}/folders", backups.ListFoldersRoute) srapiAdmin.HandleFunc("/api/backups/{name}/restore", backups.RestoreBackupRoute) srapiAdmin.HandleFunc("/api/backups", backups.AddBackupRoute) srapiAdmin.HandleFunc("/api/backups/{name}", backups.RemoveBackupRoute) diff --git a/src/storage/listdir.go b/src/storage/filepicker.go similarity index 94% rename from src/storage/listdir.go rename to src/storage/filepicker.go index 3cd95ac..392059d 100644 --- a/src/storage/listdir.go +++ b/src/storage/filepicker.go @@ -6,6 +6,7 @@ import ( "path/filepath" "io/ioutil" "syscall" + "strings" "github.com/azukaar/cosmos-server/src/utils" ) @@ -132,6 +133,12 @@ func ListDirectory(path string) ([]DirectoryListing, error) { } } + fullPath := filepath.Join(path, file.Name()) + + if utils.IsInsideContainer { + fullPath = strings.TrimPrefix(fullPath, "/mnt/host") + } + listing := DirectoryListing{ Name: file.Name(), Ext: filepath.Ext(file.Name()), @@ -141,7 +148,7 @@ func ListDirectory(path string) ([]DirectoryListing, error) { Created: file.ModTime().Unix(), UID: uid, GID: gid, - FullPath: filepath.Join(path, file.Name()), + FullPath: fullPath, } listings = append(listings, listing) }