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
2 changes: 1 addition & 1 deletion public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@
},
"yaml": {
"copiedToClipboard": "YAML copied to clipboard!",
"YAML": "YAML"
"YAML": "File"
},
"createMCP": {
"dialogTitle": "Create Managed Control Plane",
Expand Down
5 changes: 5 additions & 0 deletions src/components/ControlPlane/FluxList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { timeAgo } from '../../utils/i18n/timeAgo.ts';
import { ResourceStatusCell } from '../Shared/ResourceStatusCell.tsx';
import { YamlViewButton } from '../Yaml/YamlViewButton.tsx';
import { useMemo } from 'react';
import StatusFilter from '../Shared/StatusFilter/StatusFilter.tsx';

export default function FluxList() {
const {
Expand Down Expand Up @@ -68,6 +69,7 @@ export default function FluxList() {
accessor: 'status',
width: 85,
hAlign: 'Center',
Filter: ({ column }) => <StatusFilter column={column} />,
Cell: (cellData: CellData<FluxRow['isReady']>) =>
cellData.cell.row.original?.isReady != null ? (
<ResourceStatusCell
Expand All @@ -85,6 +87,7 @@ export default function FluxList() {
hAlign: 'Center',
width: 85,
accessor: 'yaml',
disableFilters: true,
Cell: (cellData: CellData<KustomizationsResponse['items']>) => (
<YamlViewButton resourceObject={cellData.cell.row.original?.item} />
),
Expand All @@ -109,6 +112,7 @@ export default function FluxList() {
accessor: 'status',
width: 85,
hAlign: 'Center',
Filter: ({ column }) => <StatusFilter column={column} />,
Cell: (cellData: CellData<FluxRow['isReady']>) =>
cellData.cell.row.original?.isReady != null ? (
<ResourceStatusCell
Expand All @@ -127,6 +131,7 @@ export default function FluxList() {
hAlign: 'Center',
width: 85,
accessor: 'yaml',
disableFilters: true,
Cell: (cellData: CellData<FluxRow>) => (
<YamlViewButton resourceObject={cellData.cell.row.original?.item} />
),
Expand Down
6 changes: 5 additions & 1 deletion src/components/ControlPlane/ManagedResources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { resourcesInterval } from '../../lib/shared/constants';
import { ResourceStatusCell } from '../Shared/ResourceStatusCell';
import { YamlViewButton } from '../Yaml/YamlViewButton.tsx';
import { useMemo } from 'react';
import StatusFilter from '../Shared/StatusFilter/StatusFilter.tsx';

interface CellData<T> {
cell: {
Expand Down Expand Up @@ -66,6 +67,7 @@ export function ManagedResources() {
accessor: 'synced',
hAlign: 'Center',
width: 85,
Filter: ({ column }) => <StatusFilter column={column} />,
Cell: (cellData: CellData<ResourceRow['synced']>) =>
cellData.cell.row.original?.synced != null ? (
<ResourceStatusCell
Expand All @@ -79,6 +81,7 @@ export function ManagedResources() {
accessor: 'ready',
hAlign: 'Center',
width: 85,
Filter: ({ column }) => <StatusFilter column={column} />,
Cell: (cellData: CellData<ResourceRow['ready']>) =>
cellData.cell.row.original?.ready != null ? (
<ResourceStatusCell
Expand All @@ -92,8 +95,9 @@ export function ManagedResources() {
hAlign: 'Center',
width: 85,
accessor: 'yaml',
disableFilters: true,
Cell: (cellData: CellData<ResourceRow>) =>
!!cellData.cell.row.original?.item ? (
cellData.cell.row.original?.item ? (
<YamlViewButton resourceObject={cellData.cell.row.original?.item} />
) : undefined,
},
Expand Down
35 changes: 20 additions & 15 deletions src/components/ControlPlane/Providers.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import {
AnalyticalTable,
AnalyticalTableColumnDefinition,
AnalyticalTableScaleWidthMode,
Title,
} from '@ui5/webcomponents-react';

import useResource from '../../lib/api/useApiResource';
import IllustratedError from '../Shared/IllustratedError';
import '@ui5/webcomponents-icons/dist/sys-enter-2';
import '@ui5/webcomponents-icons/dist/sys-cancel-2';
import { ProvidersListRequest } from '../../lib/api/types/crossplane/listProviders';
import { resourcesInterval } from '../../lib/shared/constants';
import { timeAgo } from '../../utils/i18n/timeAgo';
import { ResourceStatusCell } from '../Shared/ResourceStatusCell';

import { YamlViewButton } from '../Yaml/YamlViewButton.tsx';
import { useMemo } from 'react';

import '@ui5/webcomponents-icons/dist/sys-enter-2';
import '@ui5/webcomponents-icons/dist/sys-cancel-2';
import StatusFilter from '../Shared/StatusFilter/StatusFilter.tsx';

interface CellData<T> {
cell: {
value: T | null; // null for grouping rows
value: T | null;
row: {
original?: ProvidersRow; // missing for grouping rows
original?: ProvidersRow;
};
};
}

type ProvidersRow = {
name: string;
version: string;
healthy: boolean;
healthy: string;
healthyTransitionTime: string;
installed: boolean;
installed: string;
installedTransitionTime: string;
created: string;
item: unknown;
Expand Down Expand Up @@ -67,10 +69,12 @@ export function Providers() {
accessor: 'installed',
hAlign: 'Center',
width: 85,
Filter: ({ column }) => <StatusFilter column={column} />,
filter: 'equals',
Cell: (cellData: CellData<ProvidersRow['installed']>) =>
cellData.cell.row.original?.installed != null ? (
<ResourceStatusCell
value={cellData.cell.row.original?.installed}
value={cellData.cell.row.original?.installed === 'true'}
transitionTime={
cellData.cell.row.original?.installedTransitionTime
}
Expand All @@ -82,26 +86,28 @@ export function Providers() {
accessor: 'healthy',
hAlign: 'Center',
width: 85,
Filter: ({ column }) => <StatusFilter column={column} />,
filter: 'equals',
Cell: (cellData: CellData<ProvidersRow['healthy']>) =>
cellData.cell.row.original?.installed != null ? (
<ResourceStatusCell
value={cellData.cell.row.original?.healthy}
value={cellData.cell.row.original?.healthy === 'true'}
transitionTime={cellData.cell.row.original?.healthyTransitionTime}
/>
) : null,
},

{
Header: t('yaml.YAML'),
hAlign: 'Center',
width: 85,
accessor: 'yaml',
disableFilters: true,
Cell: (cellData: CellData<ProvidersRow>) => (
<YamlViewButton resourceObject={cellData.cell.row.original?.item} />
),
},
],
[],
[t],
);

const rows: ProvidersRow[] =
Expand All @@ -115,9 +121,9 @@ export function Providers() {
return {
name: item.metadata.name,
created: timeAgo.format(new Date(item.metadata.creationTimestamp)),
installed: installed?.status === 'True',
installed: installed?.status === 'True' ? 'true' : 'false',
installedTransitionTime: installed?.lastTransitionTime ?? '',
healthy: healthy?.status === 'True',
healthy: healthy?.status === 'True' ? 'true' : 'false',
healthyTransitionTime: healthy?.lastTransitionTime ?? '',
version: item.spec.package.match(/\d+(\.\d+)+/g)?.toString() ?? '',
item: item,
Expand All @@ -138,7 +144,6 @@ export function Providers() {
scaleWidthMode={AnalyticalTableScaleWidthMode.Smart}
loading={isLoading}
filterable
// Prevent the table from resetting when the data changes
retainColumnWidth
reactTableOptions={{
autoResetHiddenColumns: false,
Expand Down
1 change: 1 addition & 0 deletions src/components/ControlPlane/ProvidersConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export function ProvidersConfig() {
hAlign: 'Center',
width: 85,
accessor: 'yaml',
disableFilters: true,
Cell: (cellData: CellData<Rows>) =>
cellData.cell.row.original?.resource ? (
<YamlViewButton
Expand Down
1 change: 1 addition & 0 deletions src/components/Projects/ProjectsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export default function ProjectsList() {
Header: t('yaml.YAML'),
accessor: 'yaml',
width: 85,
disableFilters: true,
hAlign: 'Center',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Cell: (instance: any) => (
Expand Down
61 changes: 61 additions & 0 deletions src/components/Shared/StatusFilter/StatusFilter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Select } from '@ui5/webcomponents-react';
import StatusFilterOption, {
StatusFilterOptionProps,
} from './StatusFilterOption';

interface StatusFilterProps {
column: {
filterValue?: string;
setFilter?: (value?: string) => void;
};
}

const options: Pick<
StatusFilterOptionProps,
'value' | 'iconName' | 'color' | 'labelKey'
>[] = [
{ value: 'all', iconName: 'filter', color: 'gray', labelKey: 'All' },
{
value: 'true',
iconName: 'sys-enter-2',
color: 'green',
labelKey: 'Enabled',
},
{
value: 'false',
iconName: 'sys-cancel-2',
color: 'red',
labelKey: 'Disabled',
},
];

const StatusFilter: React.FC<StatusFilterProps> = ({ column }) => {
const { t } = useTranslation();

const handleChange = (
e: CustomEvent<{ selectedOption: { dataset?: { value?: string } } }>,
) => {
const value = e.detail.selectedOption.dataset?.value;
column.setFilter?.(value === 'all' ? undefined : value);
};

return (
<Select onChange={handleChange}>
{options.map((option) => (
<StatusFilterOption
key={option.value}
{...option}
t={t}
isSelected={
column.filterValue === option.value ||
(option.value === 'all' && !column.filterValue)
}
/>
))}
</Select>
);
};

export default StatusFilter;
19 changes: 19 additions & 0 deletions src/components/Shared/StatusFilter/StatusFilterOption.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.option {
padding: 6px 10px;
}

.container {
display: flex;
align-items: center;
gap: 8px;
}

.icon {
width: 16px;
height: 16px;
flex-shrink: 0;
}

.label {
font-size: 14px;
}
35 changes: 35 additions & 0 deletions src/components/Shared/StatusFilter/StatusFilterOption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { Option, Icon } from '@ui5/webcomponents-react';
import styles from './StatusFilterOption.module.css';

export interface StatusFilterOptionProps {
value: string;
iconName: string;
color: string;
labelKey: string;
t: (key: string) => string;
isSelected: boolean;
}

const RenderOption: React.FC<StatusFilterOptionProps> = ({
value,
iconName,
color,
labelKey,
t,
isSelected,
}) => (
<Option
key={value}
data-value={value}
selected={isSelected}
className={styles.option}
>
<div className={styles.container}>
<Icon name={iconName} style={{ color }} className={styles.icon} />
<span className={styles.label}>{t(labelKey)}</span>
</div>
</Option>
);

export default RenderOption;
Loading