mirror of https://github.com/portainer/portainer
fix(apps) UI release fixes [EE-5197] (#8702)
* fix(apps) searchbar flex resizing and insights * UI fixes * update stacks datatable --------- Co-authored-by: testa113 <testa113>pull/8716/head
parent
3636ac5c26
commit
30248eabb4
|
@ -14,6 +14,7 @@ import { DockerfileDetails } from '@/react/docker/images/ItemView/DockerfileDeta
|
|||
import { HealthStatus } from '@/react/docker/containers/ItemView/HealthStatus';
|
||||
import { GpusList } from '@/react/docker/host/SetupView/GpusList';
|
||||
import { GpusInsights } from '@/react/docker/host/SetupView/GpusInsights';
|
||||
import { InsightsBox } from '@/react/components/InsightsBox';
|
||||
|
||||
export const componentsModule = angular
|
||||
.module('portainer.docker.react.components', [])
|
||||
|
@ -53,4 +54,15 @@ export const componentsModule = angular
|
|||
'gpusList',
|
||||
r2a(withControlledInput(GpusList), ['value', 'onChange'])
|
||||
)
|
||||
.component(
|
||||
'insightsBox',
|
||||
r2a(InsightsBox, [
|
||||
'header',
|
||||
'content',
|
||||
'setHtmlContent',
|
||||
'insightCloseId',
|
||||
'type',
|
||||
'className',
|
||||
])
|
||||
)
|
||||
.component('gpusInsights', r2a(GpusInsights, [])).name;
|
||||
|
|
|
@ -1,132 +1,144 @@
|
|||
<div class="datatable">
|
||||
<!-- toolbar header actions and settings -->
|
||||
<div ng-if="$ctrl.isPrimary" class="toolBar !flex-col gap-1">
|
||||
<div class="toolBar vertical-center w-full flex-wrap !gap-x-5 !gap-y-1 !p-0">
|
||||
<div ng-if="$ctrl.isPrimary" class="toolBar !flex-col !gap-0">
|
||||
<div class="toolBar w-full !items-start !gap-x-5 !p-0">
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'box'"></pr-icon>
|
||||
</div>
|
||||
Applications
|
||||
</div>
|
||||
<div class="form-group namespaces !mb-0 !mr-0 min-w-[280px]">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
<pr-icon icon="'filter'"></pr-icon>
|
||||
Namespace
|
||||
</span>
|
||||
<select
|
||||
class="form-control"
|
||||
ng-model="$ctrl.state.namespace"
|
||||
ng-change="$ctrl.onChangeNamespace()"
|
||||
data-cy="component-namespaceSelect"
|
||||
ng-options="o.Value as (o.Name + (o.IsSystem ? ' - system' : '')) for o in $ctrl.state.namespaces"
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="searchBar vertical-center !mr-0 min-w-[280px]">
|
||||
<pr-icon icon="'search'" class-name="'searchIcon'"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for an application..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
data-cy="k8sApp-searchApplicationsInput"
|
||||
/>
|
||||
</div>
|
||||
<div class="actionBar !mr-0 !gap-3">
|
||||
<button
|
||||
ng-if="$ctrl.isPrimary"
|
||||
type="button"
|
||||
class="btn btn-sm btn-dangerlight vertical-center !ml-0 h-fit"
|
||||
ng-disabled="$ctrl.state.selectedItemCount === 0"
|
||||
ng-click="$ctrl.removeAction($ctrl.state.selectedItems)"
|
||||
data-cy="k8sApp-removeAppButton"
|
||||
>
|
||||
<pr-icon icon="'trash-2'"></pr-icon>
|
||||
Remove
|
||||
</button>
|
||||
<button
|
||||
ng-if="$ctrl.isPrimary"
|
||||
type="button"
|
||||
class="btn btn-sm btn-secondary vertical-center !ml-0 h-fit"
|
||||
ui-sref="kubernetes.applications.new"
|
||||
data-cy="k8sApp-addApplicationButton"
|
||||
>
|
||||
<pr-icon icon="'plus'" class-name="'!h-3'"></pr-icon>Add with form
|
||||
</button>
|
||||
<button
|
||||
ng-if="$ctrl.isPrimary"
|
||||
type="button"
|
||||
class="btn btn-sm btn-primary vertical-center !ml-0 h-fit"
|
||||
ui-sref="kubernetes.deploy"
|
||||
data-cy="k8sApp-deployFromManifestButton"
|
||||
>
|
||||
<pr-icon icon="'plus'" class-name="'!h-3'"></pr-icon>Create from manifest
|
||||
</button>
|
||||
</div>
|
||||
<div class="settings" data-cy="k8sApp-tableSettings">
|
||||
<span class="setting" ng-class="{ 'setting-active': $ctrl.settings.open }" uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.settings.open">
|
||||
<span uib-dropdown-toggle aria-label="Settings">
|
||||
<pr-icon icon="'more-vertical'" class-name="'!mr-0 !h-4'"></pr-icon>
|
||||
</span>
|
||||
<div class="dropdown-menu dropdown-menu-right" uib-dropdown-menu>
|
||||
<div class="tableMenu">
|
||||
<div class="menuHeader"> Table settings </div>
|
||||
<div class="menuContent">
|
||||
<div>
|
||||
<div class="md-checkbox" ng-if="$ctrl.isAdmin">
|
||||
<input id="applications_setting_show_system" type="checkbox" ng-model="$ctrl.settings.showSystem" ng-change="$ctrl.onSettingsShowSystemChange()" />
|
||||
<label for="applications_setting_show_system">Show system resources</label>
|
||||
</div>
|
||||
<div class="md-checkbox">
|
||||
<input
|
||||
id="setting_auto_refresh"
|
||||
type="checkbox"
|
||||
ng-model="$ctrl.settings.repeater.autoRefresh"
|
||||
ng-change="$ctrl.onSettingsRepeaterChange()"
|
||||
data-cy="k8sApp-autoRefreshCheckbox"
|
||||
/>
|
||||
<label for="setting_auto_refresh">Auto refresh</label>
|
||||
</div>
|
||||
<div ng-if="$ctrl.settings.repeater.autoRefresh">
|
||||
<label for="settings_refresh_rate"> Refresh rate </label>
|
||||
<select
|
||||
id="settings_refresh_rate"
|
||||
ng-model="$ctrl.settings.repeater.refreshRate"
|
||||
ng-change="$ctrl.onSettingsRepeaterChange()"
|
||||
class="small-select"
|
||||
data-cy="k8sApp-refreshRateDropdown"
|
||||
>
|
||||
<option value="10">10s</option>
|
||||
<option value="30">30s</option>
|
||||
<option value="60">1min</option>
|
||||
<option value="120">2min</option>
|
||||
<option value="300">5min</option>
|
||||
</select>
|
||||
<span>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" mode="'success'" style="display: none"></pr-icon>
|
||||
</span>
|
||||
<!-- use row reverse to make the left most items wrap first to the right side in the next line -->
|
||||
<div class="inline-flex flex-row-reverse flex-wrap !gap-x-5 gap-y-3">
|
||||
<div class="settings" data-cy="k8sApp-tableSettings">
|
||||
<span class="setting" ng-class="{ 'setting-active': $ctrl.settings.open }" uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.settings.open">
|
||||
<span uib-dropdown-toggle aria-label="Settings">
|
||||
<pr-icon icon="'more-vertical'" class-name="'!mr-0 !h-4'"></pr-icon>
|
||||
</span>
|
||||
<div class="dropdown-menu dropdown-menu-right" uib-dropdown-menu>
|
||||
<div class="tableMenu">
|
||||
<div class="menuHeader"> Table settings </div>
|
||||
<div class="menuContent">
|
||||
<div>
|
||||
<div class="md-checkbox" ng-if="$ctrl.isAdmin">
|
||||
<input id="applications_setting_show_system" type="checkbox" ng-model="$ctrl.settings.showSystem" ng-change="$ctrl.onSettingsShowSystemChange()" />
|
||||
<label for="applications_setting_show_system">Show system resources</label>
|
||||
</div>
|
||||
<div class="md-checkbox">
|
||||
<input
|
||||
id="setting_auto_refresh"
|
||||
type="checkbox"
|
||||
ng-model="$ctrl.settings.repeater.autoRefresh"
|
||||
ng-change="$ctrl.onSettingsRepeaterChange()"
|
||||
data-cy="k8sApp-autoRefreshCheckbox"
|
||||
/>
|
||||
<label for="setting_auto_refresh">Auto refresh</label>
|
||||
</div>
|
||||
<div ng-if="$ctrl.settings.repeater.autoRefresh">
|
||||
<label for="settings_refresh_rate"> Refresh rate </label>
|
||||
<select
|
||||
id="settings_refresh_rate"
|
||||
ng-model="$ctrl.settings.repeater.refreshRate"
|
||||
ng-change="$ctrl.onSettingsRepeaterChange()"
|
||||
class="small-select"
|
||||
data-cy="k8sApp-refreshRateDropdown"
|
||||
>
|
||||
<option value="10">10s</option>
|
||||
<option value="30">30s</option>
|
||||
<option value="60">1min</option>
|
||||
<option value="120">2min</option>
|
||||
<option value="300">5min</option>
|
||||
</select>
|
||||
<span>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" mode="'success'" style="display: none"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a type="button" class="btn btn-sm btn-default btn-sm" ng-click="$ctrl.settings.open = false;" data-cy="k8sApp-tableSettingsCloseButton">Close</a>
|
||||
<div>
|
||||
<a type="button" class="btn btn-sm btn-default btn-sm" ng-click="$ctrl.settings.open = false;" data-cy="k8sApp-tableSettingsCloseButton">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="actionBar !mr-0 !gap-3">
|
||||
<button
|
||||
ng-if="$ctrl.isPrimary"
|
||||
type="button"
|
||||
class="btn btn-sm btn-dangerlight vertical-center !ml-0 h-fit"
|
||||
ng-disabled="$ctrl.state.selectedItemCount === 0"
|
||||
ng-click="$ctrl.removeAction($ctrl.state.selectedItems)"
|
||||
data-cy="k8sApp-removeAppButton"
|
||||
>
|
||||
<pr-icon icon="'trash-2'"></pr-icon>
|
||||
Remove
|
||||
</button>
|
||||
<button
|
||||
ng-if="$ctrl.isPrimary"
|
||||
hide-deployment-option="form"
|
||||
type="button"
|
||||
class="btn btn-sm btn-secondary vertical-center !ml-0 h-fit"
|
||||
ui-sref="kubernetes.applications.new"
|
||||
data-cy="k8sApp-addApplicationButton"
|
||||
>
|
||||
<pr-icon icon="'plus'" class-name="'!h-3'"></pr-icon>Add with form
|
||||
</button>
|
||||
<button
|
||||
ng-if="$ctrl.isPrimary"
|
||||
type="button"
|
||||
class="btn btn-sm btn-primary vertical-center !ml-0 h-fit"
|
||||
ui-sref="kubernetes.deploy"
|
||||
data-cy="k8sApp-deployFromManifestButton"
|
||||
>
|
||||
<pr-icon icon="'plus'" class-name="'!h-3'"></pr-icon>Create from manifest
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="searchBar">
|
||||
<pr-icon icon="'search'" class-name="'searchIcon'"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
data-cy="k8sApp-searchApplicationsInput"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group namespaces !mb-0 !mr-0 !h-[30px] min-w-[140px]">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
<pr-icon icon="'filter'" size="'sm'"></pr-icon>
|
||||
Namespace
|
||||
</span>
|
||||
<select
|
||||
class="form-control !h-[30px] !py-1"
|
||||
ng-model="$ctrl.state.namespace"
|
||||
ng-change="$ctrl.onChangeNamespace()"
|
||||
data-cy="component-namespaceSelect"
|
||||
ng-options="o.Value as (o.Name + (o.IsSystem ? ' - system' : '')) for o in $ctrl.state.namespaces"
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex w-full flex-row" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<span class="small text-muted vertical-center mt-1">
|
||||
<pr-icon icon="'info'" mode="'primary'" class="vertical-center"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'"></pr-icon>
|
||||
System resources are hidden, this can be changed in the table settings.
|
||||
</span>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div class="w-fit">
|
||||
<insights-box class-name="'mt-2'" type="'slim'" header="'From 2.18 on, you can filter this view by namespace.'" insight-close-id="'k8s-namespace-filtering'"></insights-box>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- data table content -->
|
||||
<div ng-class="{ 'table-responsive': $ctrl.isPrimary, 'inner-datatable': !$ctrl.isPrimary }">
|
||||
|
|
|
@ -1,115 +1,122 @@
|
|||
<div class="datatable">
|
||||
<!-- table title and action menu -->
|
||||
<div class="toolBar !flex-col gap-1">
|
||||
<div class="toolBar vertical-center w-full flex-wrap !gap-x-5 !gap-y-1 !p-0">
|
||||
<!-- title -->
|
||||
<div class="toolBar !flex-col !gap-0">
|
||||
<div class="toolBar w-full !items-start !gap-x-5 !p-0">
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'list'"></pr-icon>
|
||||
</div>
|
||||
Stacks
|
||||
</div>
|
||||
<!-- actions -->
|
||||
<div class="form-group namespaces !mb-0 !mr-0 min-w-[280px]">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
<pr-icon icon="'filter'"></pr-icon>
|
||||
Namespace
|
||||
</span>
|
||||
<select
|
||||
class="form-control"
|
||||
ng-model="$ctrl.state.namespace"
|
||||
ng-change="$ctrl.onChangeNamespace()"
|
||||
data-cy="component-namespaceSelect"
|
||||
ng-options="o.Value as (o.Name + (o.IsSystem ? ' - system' : '')) for o in $ctrl.state.namespaces"
|
||||
<!-- use row reverse to make the left most items wrap first to the right side in the next line -->
|
||||
<div class="inline-flex flex-row-reverse flex-wrap !gap-x-5 gap-y-3">
|
||||
<div class="actionBar !mr-0 !gap-3">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-dangerlight vertical-center !ml-0 h-fit"
|
||||
ng-disabled="$ctrl.state.selectedItemCount === 0"
|
||||
ng-click="$ctrl.removeAction($ctrl.state.selectedItems)"
|
||||
data-cy="k8sApp-removeStackButton"
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
<pr-icon icon="'search'" class-name="'!h-3'"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput min-w-min self-start"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for a stack..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
<div class="actionBar !mr-0 !gap-3">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-dangerlight vertical-center !ml-0 h-fit"
|
||||
ng-disabled="$ctrl.state.selectedItemCount === 0"
|
||||
ng-click="$ctrl.removeAction($ctrl.state.selectedItems)"
|
||||
data-cy="k8sApp-removeStackButton"
|
||||
>
|
||||
<pr-icon icon="'trash-2'"></pr-icon>
|
||||
Remove
|
||||
</button>
|
||||
<div class="settings" data-cy="k8sApp-StackTableSettings">
|
||||
<span class="setting" ng-class="{ 'setting-active': $ctrl.settings.open }" uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.settings.open">
|
||||
<span uib-dropdown-toggle>
|
||||
<pr-icon icon="'more-vertical'" class-name="'!mr-0 !h-4'"></pr-icon>
|
||||
</span>
|
||||
<div class="dropdown-menu dropdown-menu-right" uib-dropdown-menu>
|
||||
<div class="tableMenu">
|
||||
<div class="menuHeader"> Table settings </div>
|
||||
<div class="menuContent">
|
||||
<div>
|
||||
<div class="md-checkbox" ng-if="$ctrl.isAdmin">
|
||||
<input id="applications_setting_show_system" type="checkbox" ng-model="$ctrl.settings.showSystem" ng-change="$ctrl.onSettingsShowSystemChange()" />
|
||||
<label for="applications_setting_show_system">Show system resources</label>
|
||||
</div>
|
||||
<div class="md-checkbox">
|
||||
<input
|
||||
id="setting_auto_refresh"
|
||||
type="checkbox"
|
||||
ng-model="$ctrl.settings.repeater.autoRefresh"
|
||||
ng-change="$ctrl.onSettingsRepeaterChange()"
|
||||
data-cy="k8sApp-autoRefreshCheckbox-stack"
|
||||
/>
|
||||
<label for="setting_auto_refresh">Auto refresh</label>
|
||||
</div>
|
||||
<div ng-if="$ctrl.settings.repeater.autoRefresh">
|
||||
<label for="settings_refresh_rate"> Refresh rate </label>
|
||||
<select
|
||||
id="settings_refresh_rate"
|
||||
ng-model="$ctrl.settings.repeater.refreshRate"
|
||||
ng-change="$ctrl.onSettingsRepeaterChange()"
|
||||
class="small-select"
|
||||
data-cy="k8sApp-refreshRateDropdown-stack"
|
||||
>
|
||||
<option value="10">10s</option>
|
||||
<option value="30">30s</option>
|
||||
<option value="60">1min</option>
|
||||
<option value="120">2min</option>
|
||||
<option value="300">5min</option>
|
||||
</select>
|
||||
<span>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" mode="'success'" style="display: none"></pr-icon>
|
||||
</span>
|
||||
<pr-icon icon="'trash-2'"></pr-icon>
|
||||
Remove
|
||||
</button>
|
||||
<div class="settings" data-cy="k8sApp-StackTableSettings">
|
||||
<span class="setting" ng-class="{ 'setting-active': $ctrl.settings.open }" uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.settings.open">
|
||||
<span uib-dropdown-toggle>
|
||||
<pr-icon icon="'more-vertical'" class-name="'!mr-0 !h-4'"></pr-icon>
|
||||
</span>
|
||||
<div class="dropdown-menu dropdown-menu-right" uib-dropdown-menu>
|
||||
<div class="tableMenu">
|
||||
<div class="menuHeader"> Table settings </div>
|
||||
<div class="menuContent">
|
||||
<div>
|
||||
<div class="md-checkbox" ng-if="$ctrl.isAdmin">
|
||||
<input id="applications_setting_show_system" type="checkbox" ng-model="$ctrl.settings.showSystem" ng-change="$ctrl.onSettingsShowSystemChange()" />
|
||||
<label for="applications_setting_show_system">Show system resources</label>
|
||||
</div>
|
||||
<div class="md-checkbox">
|
||||
<input
|
||||
id="setting_auto_refresh"
|
||||
type="checkbox"
|
||||
ng-model="$ctrl.settings.repeater.autoRefresh"
|
||||
ng-change="$ctrl.onSettingsRepeaterChange()"
|
||||
data-cy="k8sApp-autoRefreshCheckbox-stack"
|
||||
/>
|
||||
<label for="setting_auto_refresh">Auto refresh</label>
|
||||
</div>
|
||||
<div ng-if="$ctrl.settings.repeater.autoRefresh">
|
||||
<label for="settings_refresh_rate"> Refresh rate </label>
|
||||
<select
|
||||
id="settings_refresh_rate"
|
||||
ng-model="$ctrl.settings.repeater.refreshRate"
|
||||
ng-change="$ctrl.onSettingsRepeaterChange()"
|
||||
class="small-select"
|
||||
data-cy="k8sApp-refreshRateDropdown-stack"
|
||||
>
|
||||
<option value="10">10s</option>
|
||||
<option value="30">30s</option>
|
||||
<option value="60">1min</option>
|
||||
<option value="120">2min</option>
|
||||
<option value="300">5min</option>
|
||||
</select>
|
||||
<span>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" mode="'success'" style="display: none"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a type="button" class="btn btn-sm btn-default btn-sm" ng-click="$ctrl.settings.open = false;" data-cy="k8sApp-tableSettingsCloseButton-stack">Close</a>
|
||||
<div>
|
||||
<a type="button" class="btn btn-sm btn-default btn-sm" ng-click="$ctrl.settings.open = false;" data-cy="k8sApp-tableSettingsCloseButton-stack">Close</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
<pr-icon icon="'search'" class-name="'!h-3'"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput min-w-min self-start"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group namespaces !mb-0 !mr-0 !h-[30px] w-fit min-w-[140px]">
|
||||
<div class="input-group">
|
||||
<span class="input-group-addon">
|
||||
<pr-icon icon="'filter'" size="'sm'"></pr-icon>
|
||||
Namespace
|
||||
</span>
|
||||
<select
|
||||
class="form-control !h-[30px] !py-1"
|
||||
ng-model="$ctrl.state.namespace"
|
||||
ng-change="$ctrl.onChangeNamespace()"
|
||||
data-cy="component-namespaceSelect"
|
||||
ng-options="o.Value as (o.Name + (o.IsSystem ? ' - system' : '')) for o in $ctrl.state.namespaces"
|
||||
>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- info text -->
|
||||
<div class="flex w-full flex-row">
|
||||
<span class="small text-muted vertical-center mt-1" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<div class="flex w-full flex-row" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<span class="small text-muted vertical-center mt-1">
|
||||
<pr-icon icon="'info'" mode="'primary'"></pr-icon>
|
||||
System resources are hidden, this can be changed in the table settings.
|
||||
</span>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div class="w-fit">
|
||||
<insights-box class-name="'mt-2'" type="'slim'" header="'From 2.18 on, you can filter this view by namespace.'" insight-close-id="'k8s-namespace-filtering'"></insights-box>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table-hover nowrap-cells table">
|
||||
|
|
|
@ -66,7 +66,12 @@
|
|||
.toolBar .searchBar {
|
||||
margin-right: 10px;
|
||||
display: inline-flex;
|
||||
min-height: 30px;
|
||||
flex-basis: 7rem;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
align-items: center;
|
||||
min-width: 7rem;
|
||||
max-width: 14rem;
|
||||
}
|
||||
|
||||
.datatable .searchBar input[type='text'] {
|
||||
|
|
|
@ -8,13 +8,21 @@ import { Button } from '@@/buttons';
|
|||
import { insightStore } from './insights-store';
|
||||
|
||||
export type Props = {
|
||||
header: string;
|
||||
content: ReactNode;
|
||||
header?: string;
|
||||
content?: ReactNode;
|
||||
setHtmlContent?: boolean;
|
||||
insightCloseId?: string; // set if you want to be able to close the box and not show it again
|
||||
type?: 'default' | 'slim';
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function InsightsBox({ header, content, insightCloseId }: Props) {
|
||||
export function InsightsBox({
|
||||
header,
|
||||
content,
|
||||
insightCloseId,
|
||||
type = 'default',
|
||||
className,
|
||||
}: Props) {
|
||||
// allow to close the box and not show it again in local storage with zustand
|
||||
const { addInsightIDClosed, isClosed } = useStore(insightStore);
|
||||
const isInsightClosed = isClosed(insightCloseId);
|
||||
|
@ -24,26 +32,42 @@ export function InsightsBox({ header, content, insightCloseId }: Props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="relative flex w-full gap-1 rounded-lg bg-gray-modern-3 p-4 text-sm th-highcontrast:bg-legacy-grey-3 th-dark:bg-legacy-grey-3">
|
||||
<div className="shrink-0">
|
||||
<div
|
||||
className={clsx(
|
||||
'relative flex w-full gap-1 rounded-lg bg-gray-modern-3 p-4 text-sm th-highcontrast:bg-legacy-grey-3 th-dark:bg-legacy-grey-3',
|
||||
type === 'slim' && 'p-2',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<div className="mt-0.5 shrink-0">
|
||||
<Lightbulb className="h-4 text-warning-7 th-highcontrast:text-warning-6 th-dark:text-warning-6" />
|
||||
</div>
|
||||
<div>
|
||||
<p
|
||||
className={clsx(
|
||||
// text-[0.9em] matches .form-horizontal .control-label font-size used in many labels in portainer
|
||||
'mb-2 text-[0.9em] font-medium',
|
||||
insightCloseId && 'pr-4'
|
||||
)}
|
||||
>
|
||||
{header}
|
||||
</p>
|
||||
<div className="small">{content}</div>
|
||||
{header && (
|
||||
<p
|
||||
className={clsx(
|
||||
// text-[0.9em] matches .form-horizontal .control-label font-size used in many labels in portainer
|
||||
'align-middle text-[0.9em] font-medium',
|
||||
insightCloseId && 'pr-10',
|
||||
content ? 'mb-2' : 'mb-0'
|
||||
)}
|
||||
>
|
||||
{header}
|
||||
</p>
|
||||
)}
|
||||
{content && (
|
||||
<div className={clsx('small', !header && insightCloseId && 'pr-6')}>
|
||||
{content}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{insightCloseId && (
|
||||
<Button
|
||||
icon={X}
|
||||
className="absolute top-2 right-2 flex !text-gray-7 hover:!text-gray-8 th-highcontrast:!text-gray-6 th-highcontrast:hover:!text-gray-5 th-dark:!text-gray-6 th-dark:hover:!text-gray-5"
|
||||
className={clsx(
|
||||
'absolute top-3 right-2 flex !text-gray-7 hover:!text-gray-8 th-highcontrast:!text-gray-6 th-highcontrast:hover:!text-gray-5 th-dark:!text-gray-6 th-dark:hover:!text-gray-5',
|
||||
type === 'slim' && insightCloseId && 'top-1'
|
||||
)}
|
||||
color="link"
|
||||
size="medium"
|
||||
onClick={() => addInsightIDClosed(insightCloseId)}
|
||||
|
|
Loading…
Reference in New Issue