1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-24 15:59:41 +02:00

chore(app): Migrate helm templates list to react (#492)

This commit is contained in:
James Player 2025-03-14 10:37:14 +13:00 committed by GitHub
parent 58317edb6d
commit 993f69db37
11 changed files with 459 additions and 203 deletions

View file

@ -1,9 +0,0 @@
.helm-template-item-details {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.helm-template-item-details .helm-template-item-details-sub {
width: 100%;
}

View file

@ -1,40 +0,0 @@
<!-- helm chart -->
<div ng-class="{ 'blocklist-item--selected': $ctrl.model.Selected }" class="blocklist-item template-item mx-0" ng-click="$ctrl.onSelect($ctrl.model)" role="listitem">
<div class="blocklist-item-box">
<!-- helmchart-image -->
<span class="shrink-0">
<fallback-image src="$ctrl.model.icon" fallback-icon="$ctrl.fallbackIcon" class-name="'blocklist-item-logo h-16 w-auto'" size="'3xl'"></fallback-image>
</span>
<!-- helmchart-details -->
<div class="col-sm-12 helm-template-item-details">
<!-- blocklist-item-line1 -->
<div class="blocklist-item-line">
<span>
<span class="blocklist-item-title">
{{ $ctrl.model.name }}
</span>
<span class="space-left blocklist-item-subtitle">
<span class="vertical-center">
<pr-icon icon="'svg-helm'" mode="'primary'"></pr-icon>
</span>
<span> Helm </span>
</span>
</span>
</div>
<!-- !blocklist-item-line1 -->
<span class="blocklist-item-actions" ng-transclude="actions"></span>
<!-- blocklist-item-line2 -->
<div class="blocklist-item-line helm-template-item-details-sub">
<span class="blocklist-item-desc">
{{ $ctrl.model.description }}
</span>
<span class="small text-muted" ng-if="$ctrl.model.annotations.category">
{{ $ctrl.model.annotations.category }}
</span>
</div>
<!-- !blocklist-item-line2 -->
</div>
<!-- !helmchart-details -->
</div>
<!-- !helm chart -->
</div>

View file

@ -1,17 +0,0 @@
import angular from 'angular';
import './helm-templates-list-item.css';
import { HelmIcon } from '../../HelmIcon';
angular.module('portainer.kubernetes').component('helmTemplatesListItem', {
templateUrl: './helm-templates-list-item.html',
bindings: {
model: '<',
onSelect: '<',
},
transclude: {
actions: '?templateItemActions',
},
controller() {
this.fallbackIcon = HelmIcon;
},
});

View file

@ -1,43 +0,0 @@
export default class HelmTemplatesListController {
/* @ngInject */
constructor($async, $scope, HelmService, Notifications) {
this.$async = $async;
this.$scope = $scope;
this.HelmService = HelmService;
this.Notifications = Notifications;
this.state = {
textFilter: '',
selectedCategory: '',
categories: [],
};
this.updateCategories = this.updateCategories.bind(this);
this.onCategoryChange = this.onCategoryChange.bind(this);
}
async updateCategories() {
try {
const annotationCategories = this.charts
.map((t) => t.annotations) // get annotations
.filter((a) => a) // filter out undefined/nulls
.map((c) => c.category); // get annotation category
const availableCategories = [...new Set(annotationCategories)].sort(); // unique and sort
this.state.categories = availableCategories.map((cat) => ({ label: cat, value: cat }));
} catch (err) {
this.Notifications.error('Failure', err, 'Unable to retrieve helm charts categories');
}
}
onCategoryChange(value) {
return this.$scope.$evalAsync(() => {
this.state.selectedCategory = value || '';
});
}
$onChanges() {
if (this.charts.length > 0) {
this.updateCategories();
}
}
}

View file

@ -1,79 +0,0 @@
<section class="datatable" aria-label="Helm charts">
<div class="toolBar vertical-center relative w-full flex-wrap !gap-x-5 !gap-y-1 !px-0">
<div class="toolBarTitle vertical-center"> {{ $ctrl.titleText }} </div>
<div class="searchBar vertical-center !mr-0">
<pr-icon icon="'search'" class="searchIcon"></pr-icon>
<input
type="text"
data-cy="helm-templates-search"
class="searchInput"
ng-model="$ctrl.state.textFilter"
placeholder="Search..."
auto-focus
ng-model-options="{ debounce: 300 }"
aria-label="Search input"
/>
</div>
<div class="w-1/5">
<por-select
placeholder="'Select a category'"
value="$ctrl.state.selectedCategory"
options="$ctrl.state.categories"
on-change="($ctrl.onCategoryChange)"
is-clearable="true"
bind-to-body="true"
></por-select>
</div>
</div>
<div class="w-full">
<div class="small text-muted mb-2"
>Select the Helm chart to use. Bring further Helm charts into your selection list via
<a ui-sref="portainer.account({'#': 'helm-repositories'})">User settings - Helm repositories</a>.</div
>
<div class="relative flex w-fit gap-1 rounded-lg bg-gray-modern-3 p-4 text-sm th-highcontrast:bg-legacy-grey-3 th-dark:bg-legacy-grey-3 mt-2">
<div class="mt-0.5 shrink-0">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="lucide lucide-lightbulb h-4 text-warning-7 th-highcontrast:text-warning-6 th-dark:text-warning-6"
>
<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"></path>
<path d="M9 18h6"></path>
<path d="M10 22h4"></path>
</svg>
</div>
<div>
<p class="align-middle text-[0.9em] font-medium pr-10 mb-2">Disclaimer</p>
<div class="small">
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>
</div>
</div>
<div class="blocklist !px-0" role="list">
<helm-templates-list-item
ng-repeat="chart in allCharts = ($ctrl.charts | filter:$ctrl.state.textFilter | filter: $ctrl.state.selectedCategory)"
model="chart"
type-label="helm"
on-select="($ctrl.selectAction)"
>
</helm-templates-list-item>
<div ng-if="!$ctrl.loading && !allCharts.length && $ctrl.charts.length !== 0" class="text-muted small mt-4"> No Helm charts found </div>
<div ng-if="$ctrl.loading" class="text-muted text-center">
Loading...
<div class="text-muted text-center"> Initial download of Helm charts can take a few minutes </div>
</div>
<div ng-if="!$ctrl.loading && $ctrl.charts.length === 0" class="text-muted text-center"> No helm charts available. </div>
</div>
</section>

View file

@ -1,14 +0,0 @@
import angular from 'angular';
import controller from './helm-templates-list.controller';
angular.module('portainer.kubernetes').component('helmTemplatesList', {
templateUrl: './helm-templates-list.html',
controller,
bindings: {
loading: '<',
titleText: '@',
charts: '<',
tableKey: '@',
selectAction: '<',
},
});

View file

@ -101,7 +101,7 @@
<div class="row" ng-if="!$ctrl.state.chart">
<div class="col-sm-12 p-0">
<helm-templates-list
title-text="Helm chart"
title-text="'Helm chart'"
charts="$ctrl.state.charts"
table-key="$ctrl.state.charts"
select-action="$ctrl.selectHelmChart"