Skip to content
Open
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: 13 additions & 0 deletions src/pages/function-edit/FunctionEditPage.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,19 @@ describe('FunctionEditPage', () => {
expect(screen.getByRole('button', { name: /Back to Functions/ })).toBeInTheDocument();
});

it('shows info bar with function name and repo link after loading', async () => {
setupFetchHandlers();

renderEditPage('my-func');

await waitFor(() => {
expect(screen.getByText('func.yaml')).toBeInTheDocument();
});

const repoLink = screen.getByRole('link', { name: 'twoGiants/my-func' });
expect(repoLink).toHaveAttribute('target', '_blank');
});

it('auto-selects handler file based on runtime from func.yaml', async () => {
setupFetchHandlers();

Expand Down
39 changes: 25 additions & 14 deletions src/pages/function-edit/FunctionEditPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { CodeEditor, DocumentTitle, ListPageHeader } from '@openshift-console/dynamic-plugin-sdk';
import type { Language } from '@patternfly/react-code-editor';
import { EmptyState, EmptyStateBody, Flex, FlexItem, PageSection } from '@patternfly/react-core';
import {
Content,
ContentVariants,
EmptyState,
EmptyStateBody,
PageSection,
Sidebar,
SidebarContent,
SidebarPanel,
} from '@patternfly/react-core';
import { CodeIcon } from '@patternfly/react-icons';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
Expand Down Expand Up @@ -40,24 +49,26 @@ function FunctionEditPageContent() {
</ListPageHeader>
<PageSection>
<EditToolbar hasChanges={state.hasChanges} onSave={state.saveFiles} />
<Flex
direction={{ default: 'row' }}
flexWrap={{ default: 'nowrap' }}
alignItems={{ default: 'alignItemsStretch' }}
>
<FlexItem
flex={{ default: 'flexNone' }}
style={{ width: '16rem', overflowX: 'auto', overflowY: 'auto' }}
>
{state.repoMetadata && (
<Content component={ContentVariants.p}>
{state.repoMetadata.name}
{' · '}
<a href={state.repoMetadata.url} target="_blank" rel="noopener noreferrer">
{state.repoMetadata.owner}/{state.repoMetadata.name}
</a>
</Content>
)}
<Sidebar hasGutter hasBorder>
<SidebarPanel width={{ default: 'width_25' }}>
<FileTreeView
files={state.files}
selectedPath={state.selectedPath}
dirtyPaths={state.dirtyPaths}
isLoading={state.isLoading}
onSelect={state.onFileSelect}
/>
</FlexItem>
<FlexItem grow={{ default: 'grow' }} style={{ minWidth: '32rem' }}>
</SidebarPanel>
<SidebarContent>
<CodeEditor
value={state.selectedContent}
language={state.selectedLanguage}
Expand All @@ -73,8 +84,8 @@ function FunctionEditPageContent() {
}
isLanguageLabelVisible
/>
</FlexItem>
</Flex>
</SidebarContent>
</Sidebar>
</PageSection>
</>
);
Expand Down
17 changes: 17 additions & 0 deletions src/pages/function-edit/components/FileTreeView.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,23 @@ describe('FileTreeView', () => {
expect(screen.queryByText('No files')).not.toBeInTheDocument();
});

it('renders folder icons on directory nodes but not files', () => {
render(
<FileTreeView
files={nodeFuncFiles}
selectedPath={null}
dirtyPaths={new Set()}
onSelect={vi.fn()}
/>,
);

const testDir = screen.getByText('test').closest('[role="treeitem"]');
expect(testDir?.querySelector('.pf-v6-c-tree-view__node-icon')).toBeInTheDocument();

const fileItem = screen.getByText('index.js').closest('[role="treeitem"]');
expect(fileItem?.querySelector('.pf-v6-c-tree-view__node-icon')).not.toBeInTheDocument();
});

it('shows dirty indicator for modified files', () => {
render(
<FileTreeView
Expand Down
7 changes: 6 additions & 1 deletion src/pages/function-edit/components/FileTreeView.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useMemo } from 'react';
import { Spinner, TreeView, TreeViewDataItem } from '@patternfly/react-core';
import { FolderIcon, FolderOpenIcon } from '@patternfly/react-icons';
import { FileEntry } from '../../../common/services/types';
import * as React from 'react';

Expand Down Expand Up @@ -146,7 +147,11 @@ function buildFileTree(files: FileEntry[], dirtyPaths: Set<string>): TreeViewDat
name: dirtyPaths.has(id) ? `${name} \u25CF` : name,
defaultExpanded: true,
};
if (isDir) item.children = [];
if (isDir) {
item.children = [];
item.icon = <FolderIcon />;
item.expandedIcon = <FolderOpenIcon />;
}
items.push(item);
}

Expand Down