diff --git a/public/locales/en.json b/public/locales/en.json
index 773d7800..d6e49e35 100644
--- a/public/locales/en.json
+++ b/public/locales/en.json
@@ -294,7 +294,7 @@
},
"yaml": {
"copiedToClipboard": "YAML copied to clipboard!",
- "YAML": "YAML"
+ "YAML": "File"
},
"createMCP": {
"dialogTitle": "Create Managed Control Plane",
diff --git a/src/components/ControlPlane/FluxList.tsx b/src/components/ControlPlane/FluxList.tsx
index 772fa47f..621687f4 100644
--- a/src/components/ControlPlane/FluxList.tsx
+++ b/src/components/ControlPlane/FluxList.tsx
@@ -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 {
@@ -68,6 +69,7 @@ export default function FluxList() {
accessor: 'status',
width: 85,
hAlign: 'Center',
+ Filter: ({ column }) => ,
Cell: (cellData: CellData) =>
cellData.cell.row.original?.isReady != null ? (
) => (
),
@@ -109,6 +112,7 @@ export default function FluxList() {
accessor: 'status',
width: 85,
hAlign: 'Center',
+ Filter: ({ column }) => ,
Cell: (cellData: CellData) =>
cellData.cell.row.original?.isReady != null ? (
) => (
),
diff --git a/src/components/ControlPlane/ManagedResources.tsx b/src/components/ControlPlane/ManagedResources.tsx
index 3ad92b71..8531f21a 100644
--- a/src/components/ControlPlane/ManagedResources.tsx
+++ b/src/components/ControlPlane/ManagedResources.tsx
@@ -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 {
cell: {
@@ -66,6 +67,7 @@ export function ManagedResources() {
accessor: 'synced',
hAlign: 'Center',
width: 85,
+ Filter: ({ column }) => ,
Cell: (cellData: CellData) =>
cellData.cell.row.original?.synced != null ? (
,
Cell: (cellData: CellData) =>
cellData.cell.row.original?.ready != null ? (
) =>
- !!cellData.cell.row.original?.item ? (
+ cellData.cell.row.original?.item ? (
) : undefined,
},
diff --git a/src/components/ControlPlane/Providers.tsx b/src/components/ControlPlane/Providers.tsx
index 5242c9f0..d9e08add 100644
--- a/src/components/ControlPlane/Providers.tsx
+++ b/src/components/ControlPlane/Providers.tsx
@@ -1,3 +1,4 @@
+import { useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import {
AnalyticalTable,
@@ -5,23 +6,24 @@ import {
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 {
cell: {
- value: T | null; // null for grouping rows
+ value: T | null;
row: {
- original?: ProvidersRow; // missing for grouping rows
+ original?: ProvidersRow;
};
};
}
@@ -29,9 +31,9 @@ interface CellData {
type ProvidersRow = {
name: string;
version: string;
- healthy: boolean;
+ healthy: string;
healthyTransitionTime: string;
- installed: boolean;
+ installed: string;
installedTransitionTime: string;
created: string;
item: unknown;
@@ -67,10 +69,12 @@ export function Providers() {
accessor: 'installed',
hAlign: 'Center',
width: 85,
+ Filter: ({ column }) => ,
+ filter: 'equals',
Cell: (cellData: CellData) =>
cellData.cell.row.original?.installed != null ? (
,
+ filter: 'equals',
Cell: (cellData: CellData) =>
cellData.cell.row.original?.installed != null ? (
) : null,
},
-
{
Header: t('yaml.YAML'),
hAlign: 'Center',
width: 85,
accessor: 'yaml',
+ disableFilters: true,
Cell: (cellData: CellData) => (
),
},
],
- [],
+ [t],
);
const rows: ProvidersRow[] =
@@ -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,
@@ -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,
diff --git a/src/components/ControlPlane/ProvidersConfig.tsx b/src/components/ControlPlane/ProvidersConfig.tsx
index 04056e58..a888220b 100644
--- a/src/components/ControlPlane/ProvidersConfig.tsx
+++ b/src/components/ControlPlane/ProvidersConfig.tsx
@@ -76,6 +76,7 @@ export function ProvidersConfig() {
hAlign: 'Center',
width: 85,
accessor: 'yaml',
+ disableFilters: true,
Cell: (cellData: CellData) =>
cellData.cell.row.original?.resource ? (
(
diff --git a/src/components/Shared/StatusFilter/StatusFilter.tsx b/src/components/Shared/StatusFilter/StatusFilter.tsx
new file mode 100644
index 00000000..4e463fa5
--- /dev/null
+++ b/src/components/Shared/StatusFilter/StatusFilter.tsx
@@ -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 = ({ 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 (
+
+ );
+};
+
+export default StatusFilter;
diff --git a/src/components/Shared/StatusFilter/StatusFilterOption.module.css b/src/components/Shared/StatusFilter/StatusFilterOption.module.css
new file mode 100644
index 00000000..321a3a52
--- /dev/null
+++ b/src/components/Shared/StatusFilter/StatusFilterOption.module.css
@@ -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;
+}
\ No newline at end of file
diff --git a/src/components/Shared/StatusFilter/StatusFilterOption.tsx b/src/components/Shared/StatusFilter/StatusFilterOption.tsx
new file mode 100644
index 00000000..ce18abc9
--- /dev/null
+++ b/src/components/Shared/StatusFilter/StatusFilterOption.tsx
@@ -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 = ({
+ value,
+ iconName,
+ color,
+ labelKey,
+ t,
+ isSelected,
+}) => (
+
+);
+
+export default RenderOption;