Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/components/ui/PropertiesDrawer/PropertiesDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import toast from 'react-hot-toast';
import { HiOutlineDocument, HiOutlineDuplicate, HiX } from 'react-icons/hi';
import { HiOutlineFolder } from 'react-icons/hi2';
import { useLocation } from 'react-router';

import PermissionsTable from '@/components/ui/PropertiesDrawer/PermissionsTable';
import OverviewTable from '@/components/ui/PropertiesDrawer/OverviewTable';
Expand Down Expand Up @@ -80,8 +81,10 @@ export default function PropertiesDrawer({
setShowPermissionsDialog,
setShowConvertFileDialog
}: PropertiesDrawerProps): JSX.Element {
const location = useLocation();
const [showDataLinkDialog, setShowDataLinkDialog] =
React.useState<boolean>(false);
const [activeTab, setActiveTab] = React.useState<string>('overview');

const { fileBrowserState } = useFileBrowserContext();
const { pathPreference, areDataLinksAutomatic } = usePreferencesContext();
Expand All @@ -95,6 +98,13 @@ export default function PropertiesDrawer({
handleDeleteDataLink
} = useDataToolLinks(setShowDataLinkDialog);

// Set active tab to 'convert' when navigating from jobs page
React.useEffect(() => {
if (location.state?.openConvertTab) {
setActiveTab('convert');
}
}, [location.state]);

const fullPath = getPreferredPathForDisplay(
pathPreference,
fileBrowserState.currentFileSharePath,
Expand Down Expand Up @@ -145,8 +155,9 @@ export default function PropertiesDrawer({
{fileBrowserState.propertiesTarget ? (
<Tabs
className="flex flex-col flex-1 min-h-0 "
defaultValue="overview"
key="file-properties-tabs"
onValueChange={setActiveTab}
value={activeTab}
>
<Tabs.List className="justify-start items-stretch shrink-0 min-w-fit w-full py-2 bg-surface dark:bg-surface-light">
<Tabs.Trigger
Expand Down
23 changes: 21 additions & 2 deletions src/components/ui/Table/jobsColumns.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Typography } from '@material-tailwind/react';
import { type ColumnDef } from '@tanstack/react-table';
import { useNavigate } from 'react-router';

import { useZoneAndFspMapContext } from '@/contexts/ZonesAndFspMapContext';
import { usePreferencesContext } from '@/contexts/PreferencesContext';
Expand All @@ -12,10 +13,13 @@ import {
} from '@/utils';
import { FileSharePath } from '@/shared.types';
import { FgStyledLink } from '../widgets/FgLink';
import toast from 'react-hot-toast';

function FilePathCell({ item }: { readonly item: Ticket }) {
const { zonesAndFileSharePathsMap } = useZoneAndFspMapContext();
const { pathPreference } = usePreferencesContext();
const { pathPreference, setLayoutWithPropertiesOpen } =
usePreferencesContext();
const navigate = useNavigate();

const itemFsp = zonesAndFileSharePathsMap[
makeMapKey('fsp', item.fsp_name)
Expand All @@ -26,9 +30,24 @@ function FilePathCell({ item }: { readonly item: Ticket }) {
item.path
);

const handleClick = async (e: React.MouseEvent<HTMLAnchorElement>) => {
e.preventDefault();
const result = await setLayoutWithPropertiesOpen();
if (!result.success) {
toast.error(`Error opening properties for file: ${result.error}`);
return;
}
navigate(makeBrowseLink(item.fsp_name, item.path), {
state: { openConvertTab: true }
});
};

return (
<div className="line-clamp-2 max-w-full">
<FgStyledLink to={makeBrowseLink(item.fsp_name, item.path)}>
<FgStyledLink
onClick={handleClick}
to={makeBrowseLink(item.fsp_name, item.path)}
>
{displayPath}
</FgStyledLink>
</div>
Expand Down
5 changes: 4 additions & 1 deletion src/components/ui/widgets/FgLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type StyledLinkProps = {
readonly target?: string;
readonly rel?: string;
readonly textSize?: 'default' | 'large' | 'small';
readonly onClick?: (e: React.MouseEvent<HTMLAnchorElement>) => void;
};

export function FgStyledLink({
Expand All @@ -17,7 +18,8 @@ export function FgStyledLink({
className = '',
target,
rel,
textSize = 'default'
textSize = 'default',
onClick
}: StyledLinkProps) {
const baseClasses = 'text-primary-light hover:underline focus:underline';
const textClasses = {
Expand All @@ -29,6 +31,7 @@ export function FgStyledLink({
return (
<Link
className={`${baseClasses} ${textClasses[textSize]} ${className}`}
onClick={onClick}
rel={rel}
target={target}
to={to}
Expand Down
16 changes: 16 additions & 0 deletions src/constants/layoutConstants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Shared constants for layout management between PreferencesContext and useLayoutPrefs

// Name is set by the autosaveId prop in PanelGroup
export const LAYOUT_NAME = 'react-resizable-panels:layout';

// Layout keys for the different panel combinations
// Confusingly, the names are in alphabetical order, but the order of the sizes is set by the order prop
// in the respective Panel components
export const WITH_PROPERTIES_AND_SIDEBAR = 'main,properties,sidebar';
export const ONLY_SIDEBAR = 'main,sidebar';
export const ONLY_PROPERTIES = 'main,properties';

export const DEFAULT_LAYOUT =
'{"main,properties,sidebar":{"expandToSizes":{},"layout":[24,50,26]}}';
export const DEFAULT_LAYOUT_SMALL_SCREENS =
'{"main":{"expandToSizes":{},"layout":[100]}}';
35 changes: 35 additions & 0 deletions src/contexts/PreferencesContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import { useFileBrowserContext } from './FileBrowserContext';
import { sendFetchRequest, makeMapKey, HTTPError } from '@/utils';
import { createSuccess, handleError, toHttpError } from '@/utils/errorHandling';
import type { Result } from '@/shared.types';
import {
LAYOUT_NAME,
WITH_PROPERTIES_AND_SIDEBAR,
ONLY_PROPERTIES
} from '@/constants/layoutConstants';

export type FolderFavorite = {
type: 'folder';
Expand Down Expand Up @@ -53,6 +58,7 @@ type PreferencesContextType = {
recentlyViewedFolders: FolderPreference[];
layout: string;
handleUpdateLayout: (layout: string) => Promise<void>;
setLayoutWithPropertiesOpen: () => Promise<Result<void>>;
loadingRecentlyViewedFolders: boolean;
isLayoutLoadedFromDB: boolean;
handleContextMenuFavorite: () => Promise<Result<boolean>>;
Expand Down Expand Up @@ -223,6 +229,34 @@ export const PreferencesProvider = ({
setLayout(layout);
};

const setLayoutWithPropertiesOpen = async (): Promise<Result<void>> => {
try {
// Keep sidebar in new layout if it is currently present
const hasSidebar = layout.includes('sidebar');

const layoutKey = hasSidebar
? WITH_PROPERTIES_AND_SIDEBAR
: ONLY_PROPERTIES;

const layoutSizes = hasSidebar ? [24, 50, 26] : [75, 25];

const newLayout = {
[LAYOUT_NAME]: {
[layoutKey]: {
expandToSizes: {},
layout: layoutSizes
}
}
};
const newLayoutString = JSON.stringify(newLayout);
await savePreferencesToBackend('layout', newLayoutString);
setLayout(newLayoutString);
return createSuccess(undefined);
} catch (error) {
return handleError(error);
}
};

const handlePathPreferenceSubmit = React.useCallback(
async (
localPathPreference: ['linux_path'] | ['windows_path'] | ['mac_path']
Expand Down Expand Up @@ -750,6 +784,7 @@ export const PreferencesProvider = ({
recentlyViewedFolders,
layout,
handleUpdateLayout,
setLayoutWithPropertiesOpen,
loadingRecentlyViewedFolders,
isLayoutLoadedFromDB,
handleContextMenuFavorite
Expand Down
22 changes: 8 additions & 14 deletions src/hooks/useLayoutPrefs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ import React from 'react';
import { usePreferencesContext } from '@/contexts/PreferencesContext';
import { useCentralServerHealthContext } from '@/contexts/CentralServerHealthContext';
import logger from '@/logger';
import {
LAYOUT_NAME,
WITH_PROPERTIES_AND_SIDEBAR,
ONLY_SIDEBAR,
ONLY_PROPERTIES,
DEFAULT_LAYOUT,
DEFAULT_LAYOUT_SMALL_SCREENS
} from '@/constants/layoutConstants';
/**
* Custom hook that provides storage interface for react-resizable-panels
* with debounced updates to reduce API calls when resizing panels
Expand All @@ -12,20 +20,6 @@ import logger from '@/logger';

const DEBOUNCE_MS = 500;

// Name is set by the autosaveId prop in PanelGroup
const LAYOUT_NAME = 'react-resizable-panels:layout';
// Confusingly, the names are in alphabetical order, but the order of the sizes is set by the order prop
// in the respective Panel components
const DEFAULT_LAYOUT =
'{"main,properties,sidebar":{"expandToSizes":{},"layout":[24,50,24]}}';
const DEFAULT_LAYOUT_SMALL_SCREENS =
'{"main":{"expandToSizes":{},"layout":[100]}}';

// Layout keys for the two possible panel combinations
const WITH_PROPERTIES_AND_SIDEBAR = 'main,properties,sidebar';
const ONLY_SIDEBAR = 'main,sidebar';
const ONLY_PROPERTIES = 'main,properties';

export default function useLayoutPrefs() {
const [showPropertiesDrawer, setShowPropertiesDrawer] =
React.useState<boolean>(false);
Expand Down