import { useState, useMemo } from 'react'; import { PortainerSelect } from '@/react/components/form-components/PortainerSelect'; import { Link } from '@/react/components/Link'; import { InsightsBox } from '@@/InsightsBox'; import { SearchBar } from '@@/datatables/SearchBar'; import { Chart, HelmTemplatesListItem } from './HelmTemplatesListItem'; interface Props { loading: boolean; titleText: string; charts?: Chart[]; selectAction: (chart: Chart) => void; } /** * Get categories from charts * @param charts - The charts to get the categories from * @returns Categories */ function getCategories(charts: Chart[]) { const annotationCategories = charts .map((chart) => chart.annotations?.category) // get category .filter((c): c is string => !!c); // filter out nulls/undefined const availableCategories = [...new Set(annotationCategories)].sort(); // unique and sort // Create options array in the format expected by PortainerSelect return availableCategories.map((cat) => ({ label: cat, value: cat, })); } /** * Get filtered charts * @param charts - The charts to get the filtered charts from * @param textFilter - The text filter * @param selectedCategory - The selected category * @returns Filtered charts */ function getFilteredCharts( charts: Chart[], textFilter: string, selectedCategory: string | null ) { return charts.filter((chart) => { // Text filter if ( textFilter && !chart.name.toLowerCase().includes(textFilter.toLowerCase()) && !chart.description.toLowerCase().includes(textFilter.toLowerCase()) ) { return false; } // Category filter if ( selectedCategory && (!chart.annotations || chart.annotations.category !== selectedCategory) ) { return false; } return true; }); } export function HelmTemplatesList({ loading, titleText, charts = [], selectAction, }: Props) { const [textFilter, setTextFilter] = useState(''); const [selectedCategory, setSelectedCategory] = useState(null); const categories = useMemo(() => getCategories(charts), [charts]); const filteredCharts = useMemo( () => getFilteredCharts(charts, textFilter, selectedCategory), [charts, textFilter, selectedCategory] ); return (
{titleText}
setTextFilter(value)} placeholder="Search..." data-cy="helm-templates-search" className="!mr-0 h-9" />
setSelectedCategory(value)} isClearable bindToBody data-cy="helm-category-select" />
Select the Helm chart to use. Bring further Helm charts into your selection list via{' '} User settings - Helm repositories .
At present Portainer does not support OCI format Helm charts. Support for OCI charts will be available in a future release.
If you would like to provide feedback on OCI support or get access to early releases to test this functionality,{' '} please get in touch . } />
{filteredCharts.map((chart) => ( ))} {filteredCharts.length === 0 && textFilter && (
No Helm charts found
)} {loading && (
Loading...
Initial download of Helm charts can take a few minutes
)} {!loading && charts.length === 0 && (
No helm charts available.
)}
); }