mirror of
https://github.com/portainer/portainer.git
synced 2025-07-25 08:19:40 +02:00
feat(oci): oci helm support [r8s-361] (#787)
This commit is contained in:
parent
b6a6ce9aaf
commit
2697d6c5d7
80 changed files with 4264 additions and 812 deletions
|
@ -1,59 +1,47 @@
|
|||
import { useState, useMemo } from 'react';
|
||||
import { components, OptionProps } from 'react-select';
|
||||
|
||||
import {
|
||||
PortainerSelect,
|
||||
Option,
|
||||
} from '@/react/components/form-components/PortainerSelect';
|
||||
import { Link } from '@/react/components/Link';
|
||||
import { PortainerSelect } from '@/react/components/form-components/PortainerSelect';
|
||||
|
||||
import { InsightsBox } from '@@/InsightsBox';
|
||||
import { SearchBar } from '@@/datatables/SearchBar';
|
||||
import { InlineLoader } from '@@/InlineLoader';
|
||||
|
||||
import { Chart } from '../types';
|
||||
import { RepoValue } from '../components/HelmRegistrySelect';
|
||||
|
||||
import { HelmTemplatesListItem } from './HelmTemplatesListItem';
|
||||
|
||||
interface Props {
|
||||
isLoading: boolean;
|
||||
isLoadingCharts: boolean;
|
||||
charts?: Chart[];
|
||||
selectAction: (chart: Chart) => void;
|
||||
registries: string[];
|
||||
selectedRegistry: string | null;
|
||||
setSelectedRegistry: (registry: string | null) => void;
|
||||
selectedRegistry: RepoValue | null;
|
||||
}
|
||||
|
||||
export function HelmTemplatesList({
|
||||
isLoading,
|
||||
isLoadingCharts,
|
||||
charts = [],
|
||||
selectAction,
|
||||
registries,
|
||||
selectedRegistry,
|
||||
setSelectedRegistry,
|
||||
}: Props) {
|
||||
const [textFilter, setTextFilter] = useState('');
|
||||
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
|
||||
|
||||
const categories = useMemo(() => getCategories(charts), [charts]);
|
||||
const registryOptions = useMemo(
|
||||
() =>
|
||||
registries.map((registry) => ({
|
||||
label: registry,
|
||||
value: registry,
|
||||
})),
|
||||
[registries]
|
||||
);
|
||||
|
||||
const filteredCharts = useMemo(
|
||||
() => getFilteredCharts(charts, textFilter, selectedCategory),
|
||||
[charts, textFilter, selectedCategory]
|
||||
);
|
||||
|
||||
const isSelectedRegistryEmpty =
|
||||
!isLoadingCharts && charts.length === 0 && selectedRegistry;
|
||||
|
||||
return (
|
||||
<section className="datatable" aria-label="Helm charts">
|
||||
<div className="toolBar vertical-center relative w-full flex-wrap !gap-x-5 !gap-y-1 !px-0 !overflow-visible">
|
||||
<div className="toolBarTitle vertical-center">Helm chart</div>
|
||||
<div className="toolBar vertical-center relative w-full !gap-x-5 !gap-y-1 !px-0 overflow-auto">
|
||||
<div className="toolBarTitle vertical-center whitespace-nowrap">
|
||||
Select a helm chart from {selectedRegistry?.name}
|
||||
</div>
|
||||
|
||||
<SearchBar
|
||||
value={textFilter}
|
||||
|
@ -63,20 +51,7 @@ export function HelmTemplatesList({
|
|||
className="!mr-0 h-9"
|
||||
/>
|
||||
|
||||
<div className="w-full sm:w-1/4">
|
||||
<PortainerSelect
|
||||
placeholder="Select a registry"
|
||||
value={selectedRegistry ?? ''}
|
||||
options={registryOptions}
|
||||
onChange={setSelectedRegistry}
|
||||
isClearable
|
||||
bindToBody
|
||||
components={{ Option: RegistryOption }}
|
||||
data-cy="helm-registry-select"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="w-full sm:w-1/4">
|
||||
<div className="w-full sm:w-1/4 flex-none">
|
||||
<PortainerSelect
|
||||
placeholder="Select a category"
|
||||
value={selectedCategory}
|
||||
|
@ -88,42 +63,6 @@ export function HelmTemplatesList({
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-fit">
|
||||
<div className="small text-muted mb-2">
|
||||
Select the Helm chart to use. Bring further Helm charts into your
|
||||
selection list via{' '}
|
||||
<Link
|
||||
to="portainer.account"
|
||||
params={{ '#': 'helm-repositories' }}
|
||||
data-cy="helm-repositories-link"
|
||||
>
|
||||
User settings - Helm repositories
|
||||
</Link>
|
||||
.
|
||||
</div>
|
||||
|
||||
<InsightsBox
|
||||
header="Disclaimer"
|
||||
type="slim"
|
||||
content={
|
||||
<>
|
||||
At present Portainer does not support OCI format Helm charts.
|
||||
Support for OCI charts will be available in a future release.
|
||||
<br />
|
||||
If you would like to provide feedback on OCI support or get access
|
||||
to early releases to test this functionality,{' '}
|
||||
<a
|
||||
href="https://bit.ly/3WVkayl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
please get in touch
|
||||
</a>
|
||||
.
|
||||
</>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="blocklist !px-0" role="list">
|
||||
{filteredCharts.map((chart) => (
|
||||
|
@ -138,7 +77,7 @@ export function HelmTemplatesList({
|
|||
<div className="text-muted small mt-4">No Helm charts found</div>
|
||||
)}
|
||||
|
||||
{isLoading && (
|
||||
{isLoadingCharts && (
|
||||
<div className="flex flex-col">
|
||||
<InlineLoader className="justify-center">
|
||||
Loading helm charts...
|
||||
|
@ -151,15 +90,15 @@ export function HelmTemplatesList({
|
|||
</div>
|
||||
)}
|
||||
|
||||
{!isLoading && charts.length === 0 && selectedRegistry && (
|
||||
{isSelectedRegistryEmpty && (
|
||||
<div className="text-muted text-center">
|
||||
No helm charts available in this registry.
|
||||
No helm charts available in this repository.
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!selectedRegistry && (
|
||||
<div className="text-muted text-center">
|
||||
Please select a registry to view available Helm charts.
|
||||
Please select a repository to view available Helm charts.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -167,20 +106,6 @@ export function HelmTemplatesList({
|
|||
);
|
||||
}
|
||||
|
||||
// truncate the registry text, because some registry names are urls, which are too long
|
||||
function RegistryOption(props: OptionProps<Option<string>>) {
|
||||
const { data: registry } = props;
|
||||
|
||||
return (
|
||||
<div title={registry.value}>
|
||||
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
|
||||
<components.Option {...props} className="whitespace-nowrap truncate">
|
||||
{registry.value}
|
||||
</components.Option>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get categories from charts
|
||||
* @param charts - The charts to get the categories from
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue