Skip to content

feat(ws): Apply theme dependent components #313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { home } from '~/__tests__/cypress/cypress/pages/home';
const useFilter = (filterName: string, searchValue: string) => {
cy.get("[id$='filter-workspaces-dropdown']").click();
cy.get(`[id$='filter-workspaces-dropdown-${filterName}']`).click();
cy.get("[id$='filter-workspaces-search-input']").type(searchValue);
cy.get("[data-testid='filter-workspaces-search-input']").type(searchValue);
cy.get("[class$='pf-v6-c-toolbar__group']").contains(filterName);
cy.get("[class$='pf-v6-c-toolbar__group']").contains(searchValue);
};
Expand All @@ -19,6 +19,7 @@ describe('Application', () => {
cy.intercept('GET', '/api/v1/workspaces/default', {
body: mockBFFResponse(mockWorkspaces),
});
cy.intercept('GET', '/api/namespaces/test-namespace/workspaces').as('getWorkspaces');
});
it('filter rows with single filter', () => {
home.visit();
Expand Down
22 changes: 22 additions & 0 deletions workspaces/frontend/src/app/components/FormFieldset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React, { ReactNode } from 'react';

interface FormFieldsetProps {
component: ReactNode;
field?: string;
className?: string;
}

const FormFieldset: React.FC<FormFieldsetProps> = ({ component, field, className }) => (
<div className={className ?? 'form-fieldset-wrapper'}>
{component}
<fieldset aria-hidden="true" className="form-fieldset">
{field && (
<legend className="form-fieldset-legend">
<span>{field}</span>
</legend>
)}
</fieldset>
</div>
);

export default FormFieldset;
68 changes: 68 additions & 0 deletions workspaces/frontend/src/app/components/ThemeAwareSearchInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as React from 'react';
import { SearchInput, SearchInputProps, TextInput } from '@patternfly/react-core';
import FormFieldset from 'app/components/FormFieldset';
import { isMUITheme } from 'app/const';

type ThemeAwareSearchInputProps = Omit<SearchInputProps, 'onChange' | 'onClear'> & {
onChange: (value: string) => void; // Simplified onChange signature
onClear?: () => void; // Simplified optional onClear signature
fieldLabel?: string; // Additional prop for MUI FormFieldset label
'data-testid'?: string;
};

const ThemeAwareSearchInput: React.FC<ThemeAwareSearchInputProps> = ({
value,
onChange,
onClear,
fieldLabel,
placeholder,
isDisabled,
className,
style,
'aria-label': ariaLabel = 'Search',
'data-testid': dataTestId,
...rest
}) => {
if (isMUITheme()) {
// Render MUI version using TextInput + FormFieldset
return (
<FormFieldset
className={className}
field={fieldLabel}
component={
<TextInput
value={value}
type="text"
onChange={(_event, newValue) => onChange(newValue)} // Adapt signature
isDisabled={isDisabled}
aria-label={ariaLabel}
data-testid={dataTestId}
style={style}
/>
}
/>
);
}

// Render PF version using SearchInput
return (
<SearchInput
{...rest} // Pass all other applicable SearchInputProps
className={className}
style={style}
placeholder={placeholder}
value={value}
isDisabled={isDisabled}
aria-label={ariaLabel}
data-testid={dataTestId}
onChange={(_event, newValue) => onChange(newValue)} // Adapt signature
onClear={(event) => {
event.stopPropagation();
onChange('');
onClear?.(); // Adapt signature
}}
/>
);
};

export default ThemeAwareSearchInput;
48 changes: 19 additions & 29 deletions workspaces/frontend/src/app/pages/WorkspaceKinds/WorkspaceKinds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
Brand,
Tooltip,
Label,
SearchInput,
Toolbar,
ToolbarContent,
ToolbarItem,
Expand Down Expand Up @@ -44,6 +43,7 @@ import { WorkspaceKind } from '~/shared/api/backendApiTypes';
import useWorkspaceKinds from '~/app/hooks/useWorkspaceKinds';
import { useWorkspaceCountPerKind } from '~/app/hooks/useWorkspaceCountPerKind';
import { WorkspaceKindsColumnNames } from '~/app/types';
import ThemeAwareSearchInput from '~/app/components/ThemeAwareSearchInput';

export enum ActionType {
ViewDetails,
Expand Down Expand Up @@ -178,32 +178,6 @@ export const WorkspaceKinds: React.FunctionComponent = () => {
[sortedWorkspaceKinds, onFilter],
);

// Set up name search input
const searchNameInput = React.useMemo(
() => (
<SearchInput
placeholder="Filter by name"
value={searchNameValue}
onChange={(_event, value) => onSearchNameChange(value)}
onClear={() => onSearchNameChange('')}
/>
),
[searchNameValue, onSearchNameChange],
);

// Set up description search input
const searchDescriptionInput = React.useMemo(
() => (
<SearchInput
placeholder="Filter by description"
value={searchDescriptionValue}
onChange={(_event, value) => onSearchDescriptionChange(value)}
onClear={() => onSearchDescriptionChange('')}
/>
),
[searchDescriptionValue, onSearchDescriptionChange],
);

// Set up status single select
const [isStatusMenuOpen, setIsStatusMenuOpen] = React.useState<boolean>(false);
const statusToggleRef = React.useRef<HTMLButtonElement>(null);
Expand Down Expand Up @@ -509,7 +483,15 @@ export const WorkspaceKinds: React.FunctionComponent = () => {
categoryName="Name"
showToolbarItem={activeAttributeMenu === 'Name'}
>
{searchNameInput}
<ToolbarItem>
<ThemeAwareSearchInput
value={searchNameValue}
onChange={onSearchNameChange}
placeholder="Filter by Name"
fieldLabel="Find by Name"
aria-label="Filter by Name"
/>
</ToolbarItem>
</ToolbarFilter>
<ToolbarFilter
labels={
Expand All @@ -522,7 +504,15 @@ export const WorkspaceKinds: React.FunctionComponent = () => {
categoryName="Description"
showToolbarItem={activeAttributeMenu === 'Description'}
>
{searchDescriptionInput}
<ToolbarItem>
<ThemeAwareSearchInput
value={searchDescriptionValue}
onChange={onSearchDescriptionChange}
placeholder="Filter by Description"
fieldLabel="Find by Description"
aria-label="Filter by Description"
/>
</ToolbarItem>
</ToolbarFilter>
<ToolbarFilter
labels={statusSelection !== '' ? [statusSelection] : ([] as string[])}
Expand Down
12 changes: 1 addition & 11 deletions workspaces/frontend/src/app/pages/Workspaces/Workspaces.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
Label,
PaginationVariant,
Pagination,
Button,
Content,
Brand,
Tooltip,
Expand All @@ -32,8 +31,7 @@ import {
QuestionCircleIcon,
CodeIcon,
} from '@patternfly/react-icons';
import { useCallback, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useState } from 'react';
import { Workspace, WorkspaceState } from '~/shared/api/backendApiTypes';
import { WorkspaceDetails } from '~/app/pages/Workspaces/Details/WorkspaceDetails';
import { ExpandedWorkspaceRow } from '~/app/pages/Workspaces/ExpandedWorkspaceRow';
Expand Down Expand Up @@ -63,11 +61,6 @@ export enum ActionType {
}

export const Workspaces: React.FunctionComponent = () => {
const navigate = useNavigate();
const createWorkspace = useCallback(() => {
navigate('/workspaces/create');
}, [navigate]);

const [workspaceKinds] = useWorkspaceKinds();
const kindLogoDict = buildKindLogoDictionary(workspaceKinds);
const workspaceRedirectStatus = buildWorkspaceRedirectStatus(workspaceKinds);
Expand Down Expand Up @@ -455,9 +448,6 @@ export const Workspaces: React.FunctionComponent = () => {
<br />
<Content style={{ display: 'flex', alignItems: 'flex-start', columnGap: '20px' }}>
<Filter id="filter-workspaces" onFilter={onFilter} columnNames={filterableColumns} />
<Button variant="primary" ouiaId="Primary" onClick={createWorkspace}>
Create Workspace
</Button>
</Content>
<Table aria-label="Sortable table" ouiaId="SortableTable">
<Thead>
Expand Down
24 changes: 18 additions & 6 deletions workspaces/frontend/src/shared/components/Filter.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import * as React from 'react';
import {
Button,
Menu,
MenuContent,
MenuItem,
MenuList,
MenuToggle,
MenuToggleElement,
Popper,
SearchInput,
Toolbar,
ToolbarContent,
ToolbarFilter,
Expand All @@ -16,6 +16,9 @@ import {
ToolbarToggleGroup,
} from '@patternfly/react-core';
import { FilterIcon } from '@patternfly/react-icons';
import { useNavigate } from 'react-router';
import { useCallback } from 'react';
import ThemeAwareSearchInput from '~/app/components/ThemeAwareSearchInput';

export interface FilterProps {
id: string;
Expand All @@ -41,6 +44,11 @@ const Filter: React.FC<FilterProps> = ({ id, onFilter, columnNames }) => {
const filterMenuRef = React.useRef<HTMLDivElement | null>(null);
const filterContainerRef = React.useRef<HTMLDivElement | null>(null);

const navigate = useNavigate();
const createWorkspace = useCallback(() => {
navigate('/workspaces/create');
}, [navigate]);

const handleFilterMenuKeys = React.useCallback(
(event: KeyboardEvent) => {
if (!isFilterMenuOpen) {
Expand Down Expand Up @@ -202,12 +210,13 @@ const Filter: React.FC<FilterProps> = ({ id, onFilter, columnNames }) => {
<ToolbarGroup variant="filter-group">
<ToolbarItem id={`${id}-dropdown`}>{filterDropdown}</ToolbarItem>
<ToolbarItem>
<SearchInput
id={`${id}-search-input`}
placeholder={`Filter by ${activeFilter.columnName}`}
<ThemeAwareSearchInput
data-testid={`${id}-search-input`}
value={searchValue}
onChange={(_event, value) => onSearchChange(value)}
onClear={() => onSearchChange('')}
onChange={onSearchChange}
placeholder={`Filter by ${activeFilter.columnName}`}
fieldLabel={`Find by ${activeFilter.columnName}`}
aria-label={`Filter by ${activeFilter.columnName}`}
/>
</ToolbarItem>
{filters.map((filter) => (
Expand All @@ -222,6 +231,9 @@ const Filter: React.FC<FilterProps> = ({ id, onFilter, columnNames }) => {
</ToolbarFilter>
))}
</ToolbarGroup>
<Button variant="primary" ouiaId="Primary" onClick={createWorkspace}>
Create Workspace
</Button>
</ToolbarToggleGroup>
</ToolbarContent>
</Toolbar>
Expand Down
11 changes: 10 additions & 1 deletion workspaces/frontend/src/shared/style/MUI-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@

}

.mui-theme .pf-v6-c-progress-stepper__step.pf-m-info,
.mui-theme .pf-v6-c-progress-stepper__step.pf-m-info,
.mui-theme .pf-v6-c-progress-stepper__step.pf-m-success {
--pf-v6-c-progress-stepper__step-icon--BackgroundColor: var(--mui-palette-primary-main);
--pf-v6-c-progress-stepper__step-icon--Color: var(--mui-palette-common-white);
Expand Down Expand Up @@ -828,4 +828,13 @@
.mui-theme .pf-v6-c-masthead {
padding-left: var(--kf-central-app-drawer-width);
}
}

.mui-theme .pf-v6-c-toolbar__group.pf-m-filter-group .pf-v6-c-form-control {

// Override default form control padding to match button padding in this context
--pf-v6-c-form-control--PaddingBlockStart: var(--mui-spacing-8px);
--pf-v6-c-form-control--PaddingBlockEnd: var(--mui-spacing-8px);


}