mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2026-09-02 21:03:34 +03:00
refactor(files): Local in the tree sets the source filter
It was a pseudo-tab with a view of its own: its own predicate for which files count, its own empty state, and a carve-out anywhere folders are involved - folder visibility, the New folder button, the heading. All of it to say "files with no server copy", which the source filter already says. Clicking it now sets that filter and nothing else, so it narrows whichever view you are in instead of taking you somewhere. The tab value goes with the machinery, and the strings only its empty state read.
This commit is contained in:
@@ -4419,10 +4419,6 @@ offlineHint = "Reconnect to load your cloud library."
|
||||
offlineTitle = "No cached cloud files"
|
||||
title = "No cloud files yet"
|
||||
|
||||
[filesPage.empty.local]
|
||||
hint = "Files saved without uploading stay here. Drop a file to add one."
|
||||
title = "No local-only files"
|
||||
|
||||
[filesPage.empty.noResults]
|
||||
hint = "No files in this folder match your filter. Try a different term or clear the filter."
|
||||
title = "No matching files"
|
||||
|
||||
@@ -153,7 +153,7 @@ interface FileGridProps {
|
||||
sortMode?: FilesPageSortMode;
|
||||
onChangeSortMode?: (mode: FilesPageSortMode) => void;
|
||||
/** Drives the empty-state copy. */
|
||||
currentTab?: "all" | "local" | "cloud" | "recent" | "shared" | "sharedByMe";
|
||||
currentTab?: "all" | "cloud" | "recent" | "shared" | "sharedByMe";
|
||||
/** A filter is applied; an empty result then means "no matches", not "no files". */
|
||||
searchActive?: boolean;
|
||||
/** Cloud reachability; switches the cloud empty-state copy. */
|
||||
@@ -384,7 +384,7 @@ function SkeletonGrid({ viewMode }: { viewMode: FilesPageViewMode }) {
|
||||
|
||||
interface EmptyStateProps {
|
||||
/** Drives copy + iconography. */
|
||||
tab?: "all" | "local" | "cloud" | "recent" | "shared" | "sharedByMe";
|
||||
tab?: "all" | "cloud" | "recent" | "shared" | "sharedByMe";
|
||||
/** When true the empty list is the result of a filter, not a bare folder. */
|
||||
searchActive?: boolean;
|
||||
/** Switches the cloud empty-state copy. */
|
||||
@@ -429,14 +429,6 @@ function EmptyState({
|
||||
|
||||
const { titleKey, titleFallback, hintKey, hintFallback } = (() => {
|
||||
switch (tab) {
|
||||
case "local":
|
||||
return {
|
||||
titleKey: "filesPage.empty.local.title",
|
||||
titleFallback: "No local-only files",
|
||||
hintKey: "filesPage.empty.local.hint",
|
||||
hintFallback:
|
||||
"Files saved without uploading stay here. Drop a file to add one.",
|
||||
};
|
||||
case "cloud":
|
||||
return serverReachable
|
||||
? {
|
||||
@@ -489,8 +481,7 @@ function EmptyState({
|
||||
const readOnlyTab =
|
||||
tab === "recent" || tab === "shared" || tab === "sharedByMe";
|
||||
const showUpload = Boolean(onUpload) && !readOnlyTab;
|
||||
const showCreateFolder =
|
||||
Boolean(onCreateFolder) && !readOnlyTab && tab !== "local";
|
||||
const showCreateFolder = Boolean(onCreateFolder) && !readOnlyTab;
|
||||
const showCtas = showUpload || showCreateFolder;
|
||||
return (
|
||||
<div className="files-page-empty">
|
||||
|
||||
@@ -290,7 +290,6 @@ export default function FileManagerView() {
|
||||
const visibleFolders = useMemo(() => {
|
||||
// Folders only appear in cloud-rooted tabs.
|
||||
if (
|
||||
currentTab === "local" ||
|
||||
currentTab === "recent" ||
|
||||
currentTab === "shared" ||
|
||||
currentTab === "sharedByMe"
|
||||
@@ -321,12 +320,6 @@ export default function FileManagerView() {
|
||||
const filesInCurrentFolder = useMemo(() => {
|
||||
// Tab overrides folder navigation for Local/Recent/Shared.
|
||||
switch (currentTab) {
|
||||
case "local":
|
||||
// Both halves: a local file inside a browser folder belongs to that folder,
|
||||
// not here as well.
|
||||
return allFiles.filter(
|
||||
(f) => f.remoteStorageId == null && (f.folderId ?? null) === null,
|
||||
);
|
||||
case "cloud":
|
||||
// Cloud bucket; search widens to subtree, else direct-folder match.
|
||||
return allFiles.filter((f) => {
|
||||
@@ -1101,7 +1094,6 @@ export default function FileManagerView() {
|
||||
const newFolderDisabledReason: string | null = useMemo(() => {
|
||||
// Only All/Cloud render folders, so creating one elsewhere would look inert.
|
||||
if (
|
||||
currentTab === "local" ||
|
||||
currentTab === "recent" ||
|
||||
currentTab === "shared" ||
|
||||
currentTab === "sharedByMe"
|
||||
@@ -1143,8 +1135,7 @@ export default function FileManagerView() {
|
||||
<header className="files-page-header">
|
||||
{/* Breadcrumb only for folder-rooted tabs. */}
|
||||
{(currentTab === "all" || currentTab === "cloud") && <Breadcrumbs />}
|
||||
{(currentTab === "local" ||
|
||||
currentTab === "recent" ||
|
||||
{(currentTab === "recent" ||
|
||||
currentTab === "shared" ||
|
||||
currentTab === "sharedByMe") && (
|
||||
<div
|
||||
@@ -1155,13 +1146,11 @@ export default function FileManagerView() {
|
||||
color: "var(--c-text)",
|
||||
}}
|
||||
>
|
||||
{currentTab === "local"
|
||||
? t("filesPage.tabName.local", "Local")
|
||||
: currentTab === "recent"
|
||||
? t("filesPage.tabName.recent", "Recent")
|
||||
: currentTab === "shared"
|
||||
? t("filesPage.tabName.shared", "Shared with me")
|
||||
: t("filesPage.tabName.sharedByMe", "Shared by me")}
|
||||
{currentTab === "recent"
|
||||
? t("filesPage.tabName.recent", "Recent")
|
||||
: currentTab === "shared"
|
||||
? t("filesPage.tabName.shared", "Shared with me")
|
||||
: t("filesPage.tabName.sharedByMe", "Shared by me")}
|
||||
</div>
|
||||
)}
|
||||
{(() => {
|
||||
|
||||
@@ -72,7 +72,13 @@ export function FolderTreeSidebar({
|
||||
}: FolderTreeSidebarProps) {
|
||||
const { t } = useTranslation();
|
||||
const { tree, currentFolderId, setCurrentFolderId } = useFolders();
|
||||
const { currentTab, setCurrentTab, moveFolderTo } = useFilesPage();
|
||||
const {
|
||||
currentTab,
|
||||
setCurrentTab,
|
||||
moveFolderTo,
|
||||
originFilter,
|
||||
setOriginFilter,
|
||||
} = useFilesPage();
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -99,8 +105,8 @@ export function FolderTreeSidebar({
|
||||
}
|
||||
/>
|
||||
<LocalRow
|
||||
isActive={currentTab === "local"}
|
||||
onSelect={() => setCurrentTab("local")}
|
||||
isActive={originFilter === "local"}
|
||||
onSelect={() => setOriginFilter("local")}
|
||||
/>
|
||||
{tree.map((node) => (
|
||||
<TreeNodeRow
|
||||
@@ -198,10 +204,9 @@ interface LocalRowProps {
|
||||
}
|
||||
|
||||
/**
|
||||
* Pinned pseudo-folder row that selects the Local tab. Local files don't
|
||||
* belong to a folder (folders are a cloud concept) so this row is not a
|
||||
* drop target and has no count badge - the Local view scopes by predicate
|
||||
* (`remoteStorageId == null`), not by folderId.
|
||||
* Sets the source filter to local, and nothing else: it narrows whatever view you
|
||||
* are in rather than being a place of its own. Not a drop target and no count
|
||||
* badge - a local file has no folder to be counted under.
|
||||
*/
|
||||
function LocalRow({ isActive, onSelect }: LocalRowProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -55,13 +55,7 @@ export type FilesPageOriginFilter =
|
||||
| "shared-with-me";
|
||||
|
||||
/** all|local|cloud|recent|shared filter presets. */
|
||||
export type FilesPageTab =
|
||||
| "all"
|
||||
| "local"
|
||||
| "cloud"
|
||||
| "recent"
|
||||
| "shared"
|
||||
| "sharedByMe";
|
||||
export type FilesPageTab = "all" | "cloud" | "recent" | "shared" | "sharedByMe";
|
||||
|
||||
export interface FolderNameDialogState {
|
||||
mode: "new" | "rename" | null;
|
||||
|
||||
Reference in New Issue
Block a user