mirror of https://github.com/portainer/portainer
fix(ui): kubernetes-consistent-styling EE-3820 (#7425)
parent
b67f404d8d
commit
36c93c7f57
|
@ -881,3 +881,7 @@ input[style*='background-image: url("data:image/png'] + [data-cy='auth-passwordI
|
|||
input[style*='background-image: url("data:image/png'] {
|
||||
padding-right: 60px;
|
||||
}
|
||||
|
||||
.web-editor .trancluded-item:empty {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -98,7 +98,8 @@ fieldset[disabled] .btn {
|
|||
background-color: var(--ui-gray-3);
|
||||
}
|
||||
|
||||
.hyperlink {
|
||||
.hyperlink,
|
||||
.hyperlink:focus {
|
||||
color: var(--ui-blue-8);
|
||||
}
|
||||
|
||||
|
|
|
@ -210,6 +210,7 @@ code {
|
|||
|
||||
pre {
|
||||
border: 1px solid var(--border-pre-color);
|
||||
border-radius: 8px;
|
||||
background-color: var(--bg-pre-color);
|
||||
color: var(--text-pre-color);
|
||||
}
|
||||
|
@ -394,6 +395,10 @@ input:-webkit-autofill {
|
|||
|
||||
/* Overide Vendor CSS */
|
||||
|
||||
.btn-link:hover {
|
||||
color: var(--text-link-hover-color) !important;
|
||||
}
|
||||
|
||||
.multiSelect.inlineBlock button {
|
||||
margin: 0;
|
||||
}
|
||||
|
@ -425,3 +430,23 @@ input:-webkit-autofill {
|
|||
background-color: var(--bg-nav-tabs-active-color);
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
|
||||
/* Code Script Style */
|
||||
.code-script {
|
||||
background-color: var(--bg-code-script-color);
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.nav-container {
|
||||
border: 1px solid var(--border-nav-container-color);
|
||||
background-color: var(--bg-nav-container-color);
|
||||
border-radius: 8px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.nav-tabs > li {
|
||||
background-color: var(--bg-nav-tabs-active-color);
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="auto" height="auto" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-book"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="auto" height="auto" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-book"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path></svg><svg width="auto" height="auto" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M58.3333 9.45654V26.6671C58.3333 29.0007 58.3333 30.1675 58.7875 31.0588C59.1869 31.8428 59.8244 32.4802 60.6084 32.8797C61.4997 33.3338 62.6665 33.3338 65 33.3338H82.2106M58.3333 72.9168L68.75 62.5002L58.3333 52.0835M41.6667 52.0835L31.25 62.5002L41.6667 72.9168M83.3333 41.6178V71.6668C83.3333 78.6675 83.3333 82.1678 81.9709 84.8417C80.7725 87.1937 78.8602 89.106 76.5082 90.3044C73.8343 91.6668 70.334 91.6668 63.3333 91.6668H36.6667C29.666 91.6668 26.1657 91.6668 23.4918 90.3044C21.1398 89.106 19.2275 87.1937 18.0291 84.8417C16.6667 82.1678 16.6667 78.6675 16.6667 71.6668V28.3335C16.6667 21.3328 16.6667 17.8325 18.0291 15.1586C19.2275 12.8066 21.1398 10.8943 23.4918 9.69591C26.1657 8.3335 29.666 8.3335 36.6667 8.3335H50.0491C53.1064 8.3335 54.6351 8.3335 56.0737 8.67887C57.3492 8.98508 58.5685 9.49014 59.6869 10.1755C60.9484 10.9485 62.0293 12.0295 64.1912 14.1914L77.4755 27.4756C79.6374 29.6375 80.7183 30.7185 81.4913 31.9799C82.1767 33.0983 82.6818 34.3176 82.988 35.5931C83.3333 37.0317 83.3333 38.5604 83.3333 41.6178Z" stroke="currentColor" stroke-width="8.2" stroke-linecap="round" stroke-linejoin="round"/> </svg>
|
Before Width: | Height: | Size: 349 B After Width: | Height: | Size: 1.6 KiB |
|
@ -58,10 +58,11 @@
|
|||
<!-- ! don't use registry -->
|
||||
<!-- info message -->
|
||||
<div class="form-group" ng-show="$ctrl.form.image_name.$invalid">
|
||||
<div class="col-sm-12 small">
|
||||
<div ng-messages="$ctrl.form.image_name.$error">
|
||||
<p ng-message="required">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Image name is required.
|
||||
<div class="small">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8" ng-messages="$ctrl.form.image_name.$error">
|
||||
<p class="text-muted vertical-center" ng-message="required">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true" class="vertical-center"></pr-icon> Image name is required.
|
||||
<span ng-if="$ctrl.canPull">Tag must be specified otherwise Portainer will pull all tags associated to the image.</span>
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'server'" feather="true"></pr-icon>
|
||||
</div>
|
||||
|
||||
<span>
|
||||
{{ $ctrl.titleText }}
|
||||
</span>
|
||||
|
@ -162,15 +161,19 @@
|
|||
<a
|
||||
ng-if="item.Status === 'Running' && $ctrl.useServerMetrics"
|
||||
ui-sref="kubernetes.applications.application.stats({ pod: item.PodName, container: item.Name })"
|
||||
style="margin-right: 10px"
|
||||
class="vertical-center mr-1"
|
||||
>
|
||||
<pr-icon icon="'pie-chart'" class="mr-1" feather="true"></pr-icon>Stats
|
||||
<pr-icon icon="'bar-chart'" feather="true"></pr-icon>Stats
|
||||
</a>
|
||||
<a ui-sref="kubernetes.applications.application.logs({ pod: item.PodName, container: item.Name })">
|
||||
<pr-icon icon="'file-text'" class="mr-1" feather="true"></pr-icon>Logs
|
||||
<a ui-sref="kubernetes.applications.application.logs({ pod: item.PodName, container: item.Name })" class="vertical-center mr-1">
|
||||
<pr-icon icon="'file-text'" feather="true"></pr-icon>Logs
|
||||
</a>
|
||||
<a ng-if="item.Status === 'Running'" ui-sref="kubernetes.applications.application.console({ pod: item.PodName, container: item.Name })" style="margin-left: 10px">
|
||||
<pr-icon icon="'terminal'" class="mr-1" feather="true"></pr-icon>Console
|
||||
<a
|
||||
ng-if="item.Status === 'Running'"
|
||||
ui-sref="kubernetes.applications.application.console({ pod: item.PodName, container: item.Name })"
|
||||
class="vertical-center mr-1"
|
||||
>
|
||||
<pr-icon icon="'terminal'" feather="true"></pr-icon>Console
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
<div class="published-url-container">
|
||||
<div class="text-muted"> Published URL </div>
|
||||
<a ng-href="{{ $ctrl.publishedUrl }}" target="_blank" class="publish-url-link"> <i class="fa fa-external-link-alt" aria-hidden="true"></i> {{ $ctrl.publishedUrl }} </a>
|
||||
<a ng-href="{{ $ctrl.publishedUrl }}" target="_blank" class="publish-url-link vertical-center">
|
||||
<pr-icon icon="'external-link'" feather="true"></pr-icon>
|
||||
{{ $ctrl.publishedUrl }}
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
</div>
|
||||
Applications
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
<div class="searchBar vertical-center !mr-0 min-w-[280px]">
|
||||
<pr-icon icon="'search'" feather="true" class-name="'searchIcon'"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
|
@ -105,10 +105,10 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row w-full">
|
||||
<span class="small text-muted mt-1 vertical-center" ng-if="!$ctrl.settings.showSystem" authorization="K8sAccessSystemNamespaces">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<span> System resources are hidden, this can be changed in the table settings. </span>
|
||||
<div class="flex flex-row w-full" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<span class="small text-muted mt-1 vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class="vertical-center"></pr-icon>
|
||||
System resources are hidden, this can be changed in the table settings.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
<!-- title -->
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'repeat'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-dataflow'" class-name="'[&>*]:mr-0.5'"></pr-icon>
|
||||
</div>
|
||||
Port mappings
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
<div class="searchBar vertical-center !mr-0 min-w-[300px]">
|
||||
<pr-icon icon="'search'" feather="true" class-name="'icon !h-3'"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
|
@ -77,8 +77,8 @@
|
|||
</div>
|
||||
<!-- info text -->
|
||||
<div class="flex flex-row w-full">
|
||||
<span class="small text-muted mt-1" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<pr-icon icon="'info'" feather="true" class-name="'icon'"></pr-icon>
|
||||
<span class="small text-muted mt-1 vertical-center" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
System resources are hidden, this can be changed in the table settings.
|
||||
</span>
|
||||
</div>
|
||||
|
@ -162,7 +162,7 @@
|
|||
</span>
|
||||
</span>
|
||||
<!-- Internal -->
|
||||
<span ng-if="item.ServiceType === $ctrl.KubernetesServiceTypes.CLUSTER_IP"> <i class="fa fa-list-alt mr-0.5" aria-hidden="true"></i> ClusterIP </span>
|
||||
<span ng-if="item.ServiceType === $ctrl.KubernetesServiceTypes.CLUSTER_IP"> <pr-icon icon="'list'" feather="true"></pr-icon> ClusterIP </span>
|
||||
<!-- Cluster -->
|
||||
<span ng-if="item.ServiceType === $ctrl.KubernetesServiceTypes.NODE_PORT"> <pr-icon icon="'list'" feather="true" class-name="'icon'"></pr-icon> NodePort </span>
|
||||
</td>
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
<option value="300">5min</option>
|
||||
</select>
|
||||
<span>
|
||||
<i id="refreshRateChange" class="fa fa-check green-icon mt-2" aria-hidden="true"></i>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" feather="true" mode="'success'" size="'sm'"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -88,9 +88,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<!-- info text -->
|
||||
<div class="flex flex-row">
|
||||
<span class="small text-muted mt-1" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
||||
<div class="flex flex-row w-full">
|
||||
<span class="small text-muted mt-1 vertical-center" ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
System resources are hidden, this can be changed in the table settings.
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
<option value="300">5min</option>
|
||||
</select>
|
||||
<span>
|
||||
<i id="refreshRateChange" class="fa fa-check green-icon" aria-hidden="true" style="margin-top: 7px; display: none"></i>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" feather="true" mode="'success'" size="'sm'"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -90,7 +90,7 @@
|
|||
</div>
|
||||
<div ng-if="$ctrl.isAdmin && !$ctrl.settings.showSystem" class="flex flex-row w-full">
|
||||
<span class="small text-muted mt-1 vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" class-name="'!mb-0.5'" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class="vertical-center"></pr-icon>
|
||||
<div> System resources are hidden, this can be changed in the table settings. </div>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
<div class="toolBar">
|
||||
<div class="toolBarTitle flex">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'rotate-ccw'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-clockrewind'" feather="true"></pr-icon>
|
||||
</div>
|
||||
|
||||
{{ $ctrl.titleText }}
|
||||
</div>
|
||||
<div class="searchBar">
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<div class="datatable">
|
||||
<rd-widget>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<div class="toolBar">
|
||||
<div class="toolBar !gap-3">
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||
</div>
|
||||
{{ $ctrl.titleText }}
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
<div class="searchBar vertical-center !mr-0 min-w-[280px]">
|
||||
<pr-icon icon="'search'" feather="true" class="vertical-center"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
|
|
|
@ -4,26 +4,25 @@
|
|||
<div class="toolBar">
|
||||
<div class="toolBarTitle flex">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-laptopcode'"></pr-icon>
|
||||
</div>
|
||||
|
||||
<span class="vertical-center">
|
||||
{{ $ctrl.titleText }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="searchBar min-w-[260px]">
|
||||
<pr-icon icon="'search'" class="vertical-center" class-name="'searchIcon'" feather="true"></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 }"
|
||||
/>
|
||||
</div>
|
||||
<div class="settings vertical-center">
|
||||
<div class="searchBar">
|
||||
<pr-icon icon="'search'" class="vertical-center" feather="true"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput ml-1"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for an application..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
<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'" feather="true"></pr-icon></span>
|
||||
<div class="dropdown-menu dropdown-menu-right" uib-dropdown-menu>
|
||||
|
|
|
@ -3,7 +3,6 @@ angular.module('portainer.kubernetes').component('kubernetesNodeApplicationsData
|
|||
controller: 'KubernetesNodeApplicationsDatatableController',
|
||||
bindings: {
|
||||
titleText: '@',
|
||||
titleIcon: '@',
|
||||
dataset: '<',
|
||||
tableKey: '@',
|
||||
orderBy: '@',
|
||||
|
|
|
@ -4,26 +4,25 @@
|
|||
<div class="toolBar">
|
||||
<div class="toolBarTitle flex">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="$ctrl.titleIcon"></pr-icon>
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||
</div>
|
||||
|
||||
<span class="vertical-center">
|
||||
{{ $ctrl.titleText }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
<pr-icon icon="'search'" feather="true"></pr-icon>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for a node..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
<div class="settings">
|
||||
<div class="searchBar vertical-center">
|
||||
<pr-icon icon="'search'" feather="true" 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 }"
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
class="setting vertical-center"
|
||||
ng-class="{ 'setting-active': $ctrl.settings.open }"
|
||||
|
@ -132,7 +131,9 @@
|
|||
ng-click="$ctrl.changeOrderBy('IPAddress')"
|
||||
></table-column-header>
|
||||
</th>
|
||||
<th ng-if="$ctrl.useServerMetrics"> Actions </th>
|
||||
<th ng-if="$ctrl.useServerMetrics">
|
||||
<table-column-header col-title="'Actions'" can-sort="false"></table-column-header>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -154,7 +155,7 @@
|
|||
<td>{{ item.Version }}</td>
|
||||
<td>{{ item.IPAddress }}</td>
|
||||
<td ng-if="$ctrl.useServerMetrics">
|
||||
<a ui-sref="kubernetes.cluster.node.stats({ name: item.Name })" style="cursor: pointer"> <i class="fa fa-chart-area" aria-hidden="true"></i> Stats </a>
|
||||
<a ui-sref="kubernetes.cluster.node.stats({ name: item.Name })" class="vertical-center"> <pr-icon icon="'bar-chart'" feather="true"></pr-icon> Stats </a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="!$ctrl.dataset">
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<rd-widget-body classes="no-padding">
|
||||
<div class="toolBar">
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
{{ $ctrl.titleText }}
|
||||
</div>
|
||||
<div class="searchBar vertical-center">
|
||||
|
@ -13,7 +13,7 @@
|
|||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for an application"
|
||||
placeholder="Search for an application..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search for a namespace"
|
||||
placeholder="Search for a namespace..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
data-cy="k8sNamespace-namespaceSearchInput"
|
||||
|
@ -68,7 +68,7 @@
|
|||
<option value="300">5min</option>
|
||||
</select>
|
||||
<span>
|
||||
<i id="refreshRateChange" class="fa fa-check green-icon" aria-hidden="true" style="margin-top: 7px; display: none"></i>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" feather="true" mode="'success'" size="'sm'"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -82,9 +82,9 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row w-full">
|
||||
<span class="small text-muted mt-1 vertical-center" ng-if="!$ctrl.settings.showSystem && $ctrl.isAdmin">
|
||||
<pr-icon icon="'info'" feather="true" class-name="'!mb-0.5'" mode="'primary'"></pr-icon>
|
||||
<div class="flex flex-row w-full" ng-if="!$ctrl.settings.showSystem && $ctrl.isAdmin">
|
||||
<span class="small text-muted mt-1 vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class="vertical-center"></pr-icon>
|
||||
<div> System resources are hidden, this can be changed in the table settings. </div>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<rd-widget>
|
||||
<div class="toolBar px-5 pt-5">
|
||||
<div class="toolBarTitle">
|
||||
<div class="toolBarTitle vertical-center text-[16px] font-medium">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'svg-helm'"></pr-icon>
|
||||
</div>
|
||||
|
@ -31,7 +31,7 @@
|
|||
<div class="form-group nomargin" ng-show="addUserHelmRepoForm.repo.$invalid">
|
||||
<div class="small">
|
||||
<div ng-messages="addUserHelmRepoForm.repo.$error">
|
||||
<p class="vertical-center" ng-message="pattern"
|
||||
<p class="vertical-center text-muted" ng-message="pattern"
|
||||
><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> A valid URL beginning with http(s) is required.</p
|
||||
>
|
||||
</div>
|
||||
|
@ -41,7 +41,7 @@
|
|||
<div class="form-group nomargin" ng-show="$ctrl.doesRepoExist()">
|
||||
<div class="small">
|
||||
<div ng-messages="addUserHelmRepoForm.repo.$error">
|
||||
<p class="vertical-center"><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Helm repo already exists.</p>
|
||||
<p class="vertical-center text-muted"><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Helm repository already exists.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
src="$ctrl.model.icon"
|
||||
fallback-icon="'svg-helm'"
|
||||
class-name="'blocklist-item-logo h-16 w-auto'"
|
||||
fallback-class-name="'icon-nested-blue !h-12 !w-12'"
|
||||
fallback-class-name="'icon-nested-blue !h-12 !w-12 [&>*]:!h-8 [&>*]:!w-auto'"
|
||||
fallback-mode="'primary'"
|
||||
size="'xl'"
|
||||
></fallback-image>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search..."
|
||||
placeholder="Search for a chart..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
|
|
|
@ -31,8 +31,7 @@ export default class HelmTemplatesController {
|
|||
};
|
||||
}
|
||||
|
||||
editorUpdate(content) {
|
||||
const contentvalues = content.getValue();
|
||||
editorUpdate(contentvalues) {
|
||||
if (this.state.originalvalues === contentvalues) {
|
||||
this.state.isEditorDirty = false;
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<p class="inline-flex flex-row items-center">
|
||||
<pr-icon icon="'info'" feather="true" class="mr-1 vertical-center" mode="'primary'"></pr-icon>
|
||||
This is a first version for Helm charts, for more information see this <a
|
||||
class="text-blue-8 hover:underline hover:text-blue-8"
|
||||
class="hyperlink"
|
||||
href="https://www.portainer.io/blog/portainer-now-with-helm-support"
|
||||
target="_blank"
|
||||
>blog post</a
|
||||
|
@ -132,11 +132,14 @@
|
|||
yml="true"
|
||||
placeholder="# Define or paste the content of your values yaml file here"
|
||||
>
|
||||
<editor-description>
|
||||
You can get more information about Helm values file format in the
|
||||
<a href="https://helm.sh/docs/chart_template_guide/values_files/" target="_blank" class="text-blue-8 hover:text-blue-8 hover:underline"
|
||||
>official documentation</a
|
||||
>.
|
||||
<editor-description class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<span>
|
||||
You can get more information about Helm values file format in the
|
||||
<a href="https://helm.sh/docs/chart_template_guide/values_files/" target="_blank" class="text-blue-8 hover:text-blue-8 hover:underline"
|
||||
>official documentation</a
|
||||
>.
|
||||
</span>
|
||||
</editor-description>
|
||||
</web-editor-form>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<ng-form name="serviceForm">
|
||||
<div ng-if="$ctrl.isAdmin()" class="small" ng-show="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled">
|
||||
<p style="margin-top: 10px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> No Load balancer is available in this cluster, click
|
||||
<a ui-sref="kubernetes.cluster.setup">here</a> to configure load balancer.
|
||||
<p class="text-muted pt-2 vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> No Load balancer is available in this cluster, click
|
||||
<a class="hyperlink" ui-sref="kubernetes.cluster.setup">here</a> to configure load balancer.
|
||||
</p>
|
||||
</div>
|
||||
<div ng-if="!$ctrl.isAdmin()" class="small" ng-show="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER && !$ctrl.loadbalancerEnabled">
|
||||
<p style="margin-top: 10px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> No Load balancer is available in this cluster, contract your administrator.
|
||||
<p class="text-muted pt-2 vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> No Load balancer is available in this cluster, contact your administrator.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -18,16 +18,16 @@
|
|||
$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.NODE_PORT
|
||||
"
|
||||
>
|
||||
<div ng-show="!$ctrl.multiItemDisable" class="mt-5 mb-5">
|
||||
<label class="control-label text-left">Published ports</label>
|
||||
<span class="label label-default interactive ml-10 vertical-center" ng-click="$ctrl.addPort()" data-cy="k8sAppCreate-addNewPortButton">
|
||||
<div ng-show="!$ctrl.multiItemDisable" class="mt-5 mb-5 vertical-center">
|
||||
<label class="control-label text-left !pt-0">Published ports</label>
|
||||
<span class="label label-default interactive ml-2.5 vertical-center" ng-click="$ctrl.addPort()" data-cy="k8sAppCreate-addNewPortButton">
|
||||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> publish a new port
|
||||
</span>
|
||||
</div>
|
||||
<div ng-repeat="servicePort in $ctrl.servicePorts" class="mt-5 service-form row">
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">container port</span>
|
||||
<span class="input-group-addon required">Container port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
|
@ -47,17 +47,21 @@
|
|||
<div class="small mt-1" ng-if="$ctrl.state.duplicates.targetPort.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This container port is already used.
|
||||
</div>
|
||||
<div class="small mt-1" ng-messages="serviceForm['container_port_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
<p ng-message="max"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
<div class="small mt-1 text-muted" ng-messages="serviceForm['container_port_'+$index].$error">
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number is required.</p>
|
||||
<p class="vertical-center" ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p
|
||||
>
|
||||
<p class="vertical-center" ng-message="max"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p
|
||||
>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">service port</span>
|
||||
<span class="input-group-addon required">Service port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
|
@ -76,11 +80,15 @@
|
|||
<div class="small mt-1" ng-if="$ctrl.state.duplicates.servicePort.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This service port is already used.
|
||||
</div>
|
||||
<div class="small mt-1">
|
||||
<div class="small mt-1 text-muted">
|
||||
<div ng-messages="serviceForm['service_port_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Service port number is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
<p ng-message="max"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Container port number must be inside the range 1-65535.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Service port number is required.</p>
|
||||
<p class="vertical-center" ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Service port number must be inside the range 1-65535.</p
|
||||
>
|
||||
<p class="vertical-center" ng-message="max"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Service port number must be inside the range 1-65535.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
|
@ -88,7 +96,7 @@
|
|||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.NODE_PORT">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">nodeport</span>
|
||||
<span class="input-group-addon required">Nodeport</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
|
@ -97,20 +105,22 @@
|
|||
placeholder="30080"
|
||||
ng-min="30000"
|
||||
ng-max="32767"
|
||||
required
|
||||
ng-change="$ctrl.onChangeNodePort()"
|
||||
data-cy="k8sAppCreate-nodeportPort_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<span>
|
||||
<div class="small mt-1">
|
||||
<div class="small mt-1 text-muted">
|
||||
<div ng-messages="serviceForm['node_port_'+$index].$error">
|
||||
<p ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Node port number must be inside the range 30000-32767 or blank for system
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Nodeport is required.</p>
|
||||
<p class="vertical-center" ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Nodeport number must be inside the range 30000-32767 or blank for system
|
||||
allocated.</p
|
||||
>
|
||||
<p ng-message="max"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Node port number must be inside the range 30000-32767 or blank for system
|
||||
<p class="vertical-center" ng-message="max"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Nodeport number must be inside the range 30000-32767 or blank for system
|
||||
allocated.</p
|
||||
>
|
||||
</div>
|
||||
|
@ -120,7 +130,7 @@
|
|||
</div>
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.LOAD_BALANCER">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">loadbalancer port</span>
|
||||
<span class="input-group-addon">Loadbalancer port</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
|
@ -138,7 +148,7 @@
|
|||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">ingress</span>
|
||||
<span class="input-group-addon">Ingress</span>
|
||||
<select
|
||||
class="form-control"
|
||||
name="ingress_port_{{ $index }}"
|
||||
|
@ -152,9 +162,9 @@
|
|||
</select>
|
||||
</div>
|
||||
<span>
|
||||
<div class="small mt-5">
|
||||
<div class="small mt-5 text-muted">
|
||||
<div ng-messages="serviceForm['ingress_port_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Ingress selection is required.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Ingress selection is required.</p>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
|
@ -162,7 +172,7 @@
|
|||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">hostname</span>
|
||||
<span class="input-group-addon">Hostname</span>
|
||||
<select
|
||||
class="form-control"
|
||||
name="hostname_port_{{ $index }}"
|
||||
|
@ -176,9 +186,9 @@
|
|||
</select>
|
||||
</div>
|
||||
<span>
|
||||
<div class="small mt-1">
|
||||
<div class="small mt-1 text-muted">
|
||||
<div ng-messages="serviceForm['hostname_port_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Host is required.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Hostname is required.</p>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
|
@ -186,7 +196,7 @@
|
|||
|
||||
<div class="form-group !mx-0 !pl-0 col-sm-3 clear-both" ng-if="$ctrl.serviceType === $ctrl.KubernetesApplicationPublishingTypes.CLUSTER_IP && $ctrl.ingressType">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">route</span>
|
||||
<span class="input-group-addon">Route</span>
|
||||
<input
|
||||
class="form-control"
|
||||
name="ingress_route_{{ $index }}"
|
||||
|
@ -199,10 +209,10 @@
|
|||
/>
|
||||
</div>
|
||||
<span>
|
||||
<div class="small mt-1">
|
||||
<div class="small mt-1 text-muted">
|
||||
<div ng-messages="serviceForm['ingress_route_'+$index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Route is required.</p>
|
||||
<p ng-message="pattern"
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Route is required.</p>
|
||||
<p class="vertical-center" ng-message="pattern"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field must consist of alphanumeric characters or the special characters: '-', '_'
|
||||
or '/'. It must start and end with an alphanumeric character (e.g. 'my-route', or 'route-123').</p
|
||||
>
|
||||
|
@ -236,7 +246,7 @@
|
|||
<button
|
||||
ng-disabled="$ctrl.servicePorts.length === 1"
|
||||
ng-show="!$ctrl.multiItemDisable"
|
||||
class="btn btn-sm btn-light btn-only-icon"
|
||||
class="btn btn-sm btn-dangerlight btn-only-icon"
|
||||
type="button"
|
||||
ng-click="$ctrl.removePort($index)"
|
||||
data-cy="k8sAppCreate-rmPortButton_{{ $index }}"
|
||||
|
|
|
@ -9,13 +9,7 @@
|
|||
ng-options="item.typeValue as item.typeName for item in $ctrl.state.serviceType"
|
||||
data-cy="k8sAppCreate-publishingModeDropdown"
|
||||
></select>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-sm btn-default vertical-center"
|
||||
style="margin-left: 0"
|
||||
ng-click="$ctrl.addEntry( $ctrl.state.selected )"
|
||||
data-cy="k8sAppCreate-createServiceButton"
|
||||
>
|
||||
<button type="button" class="btn btn-md btn-default vertical-center !ml-0" ng-click="$ctrl.addEntry( $ctrl.state.selected )" data-cy="k8sAppCreate-createServiceButton">
|
||||
<pr-icon icon="'plus'" size="'sm'" feather="true"></pr-icon> Create service
|
||||
</button>
|
||||
</div>
|
||||
|
@ -25,8 +19,10 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12 form-inline" style="margin-top: 20px" ng-repeat="service in $ctrl.formValues.Services">
|
||||
<div ng-if="!$ctrl.formValues.Services[$index].Ingress">
|
||||
<div class="text-muted">
|
||||
<i class="{{ $ctrl.iconStyle(service.Type) }}" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<div class="text-muted vertical-center">
|
||||
<pr-icon ng-if="$ctrl.serviceType(service.Type) === 'ClusterIP'" icon="'list'" feather="true"></pr-icon>
|
||||
<pr-icon ng-if="$ctrl.serviceType(service.Type) === 'LoadBalancer'" icon="'svg-dataflow'"></pr-icon>
|
||||
<pr-icon ng-if="$ctrl.serviceType(service.Type) === 'NodePort'" icon="'list'" feather="true"></pr-icon>
|
||||
{{ $ctrl.serviceType(service.Type) }}
|
||||
</div>
|
||||
<kube-services-item-view
|
||||
|
@ -50,17 +46,17 @@
|
|||
|
||||
<div ng-if="$ctrl.formValues.Services[$index].Ingress && $ctrl.formValues.OriginalIngresses.length === 0">
|
||||
<div class="text-muted">
|
||||
<i class="fa fa-route" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'svg-route'" class-name="'mr-0.5'"></pr-icon>
|
||||
Ingress
|
||||
</div>
|
||||
<div ng-if="$ctrl.isAdmin()" class="small">
|
||||
<p style="margin-top: 10px">
|
||||
<p class="text-muted pt-2 vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Ingress is not configured in this namespace, select another namespace or click
|
||||
<a ui-sref="kubernetes.cluster.setup">here</a> to configure ingress.
|
||||
</p>
|
||||
</div>
|
||||
<div ng-if="!$ctrl.isAdmin()" class="small">
|
||||
<p style="margin-top: 10px">
|
||||
<p class="text-muted pt-2 vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Ingress is not configured in this namespace, select another namespace or contact your
|
||||
administrator.
|
||||
</p>
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
</p>
|
||||
</div>
|
||||
<div class="col-sm-12 small text-muted vertical-center" ng-if="$ctrl.formValues.IsSimple">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true" class="vertical-center"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Switch to advanced mode to copy and paste multiple key/values
|
||||
</div>
|
||||
<div class="col-sm-12 small text-muted vertical-center" ng-if="!$ctrl.formValues.IsSimple">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true" class="vertical-center"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Generate a configuration entry per line, use YAML format
|
||||
</div>
|
||||
</div>
|
||||
|
@ -35,7 +35,7 @@
|
|||
|
||||
<div ng-repeat="(index, entry) in $ctrl.formValues.Data" ng-if="$ctrl.formValues.IsSimple">
|
||||
<div class="form-group">
|
||||
<label for="configuration_data_key_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left">Key</label>
|
||||
<label for="configuration_data_key_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left required">Key</label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -76,7 +76,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.formValues.IsSimple && !entry.IsBinary">
|
||||
<label for="configuration_data_value_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left">Value</label>
|
||||
<label for="configuration_data_value_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left required">Value</label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<textarea
|
||||
class="form-control"
|
||||
|
@ -97,7 +97,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.formValues.IsSimple && entry.IsBinary">
|
||||
<label for="configuration_data_value_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left">Value</label>
|
||||
<label for="configuration_data_value_{{ index }}" class="col-sm-3 col-lg-2 control-label text-left required">Value</label>
|
||||
<div class="col-sm-8 control-label small text-muted text-left"
|
||||
>Binary data <portainer-tooltip message="'This key holds binary data and cannot be displayed.'"></portainer-tooltip
|
||||
></div>
|
||||
|
@ -117,15 +117,23 @@
|
|||
<pr-icon class="vertical-center" icon="'trash-2'" feather="true"></pr-icon> Remove entry
|
||||
</button>
|
||||
<span class="small text-muted" ng-if="entry.Used">
|
||||
<pr-icon icon="'alert-circle'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
This key is currently used by one or more applications
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="!$ctrl.formValues.IsSimple">
|
||||
<div class="form-group !px-[15px]" ng-if="!$ctrl.formValues.IsSimple">
|
||||
<input type="text" ng-model="$ctrl.formValues.DataYaml" required style="display: none" />
|
||||
<code-editor identifier="kubernetes-configuration-editor" value="$ctrl.formValues.DataYaml" read-only="false" yml="true" on-change="($ctrl.editorUpdate)"></code-editor>
|
||||
|
||||
<web-editor-form
|
||||
identifier="kubernetes-configuration-editor"
|
||||
value="$ctrl.formValues.DataYaml"
|
||||
on-change="($ctrl.editorUpdate)"
|
||||
yml="true"
|
||||
placeholder="# Define or paste key-value pairs, one pair per line"
|
||||
>
|
||||
</web-editor-form>
|
||||
</div>
|
||||
</ng-form>
|
||||
|
|
|
@ -43,15 +43,15 @@ class KubernetesConfigurationDataController {
|
|||
this.onChangeKey();
|
||||
}
|
||||
|
||||
async editorUpdateAsync(cm) {
|
||||
if (this.formValues.DataYaml !== cm.getValue()) {
|
||||
this.formValues.DataYaml = cm.getValue();
|
||||
async editorUpdateAsync(value) {
|
||||
if (this.formValues.DataYaml !== value) {
|
||||
this.formValues.DataYaml = value;
|
||||
this.isEditorDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
editorUpdate(cm) {
|
||||
return this.$async(this.editorUpdateAsync, cm);
|
||||
editorUpdate(value) {
|
||||
return this.$async(this.editorUpdateAsync, value);
|
||||
}
|
||||
|
||||
async onFileLoadAsync(event) {
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
<div class="row">
|
||||
<div class="col-sm-12 form-section-title"> Resource reservation </div>
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small">
|
||||
<p>
|
||||
{{ $ctrl.description }}
|
||||
</p>
|
||||
<span class="col-sm-12 text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
{{ $ctrl.description }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group" ng-if="$ctrl.memoryLimit !== 0">
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
<div>
|
||||
<code-editor identifier="application-details-yaml" read-only="true" value="$ctrl.data"></code-editor>
|
||||
<div class="p-5">
|
||||
<web-editor-form
|
||||
identifier="application-details-yaml"
|
||||
value="$ctrl.data"
|
||||
yml="true"
|
||||
placeholder="# Define or paste the content of your manifest here"
|
||||
read-only="true"
|
||||
hide-title="true"
|
||||
>
|
||||
</web-editor-form>
|
||||
<div class="py-5">
|
||||
<span class="btn btn-light btn-sm" ng-click="$ctrl.copyYAML()">
|
||||
<pr-icon class="vertical-center" icon="'copy'" feather="true"></pr-icon>
|
||||
Copy to clipboard
|
||||
</span>
|
||||
<span class="btn btn-light btn-sm space-left" ng-click="$ctrl.toggleYAMLInspectorExpansion()">
|
||||
<span class="btn btn-light btn-sm space-left !ml-0" ng-click="$ctrl.toggleYAMLInspectorExpansion()">
|
||||
<pr-icon class="vertical-center" icon="'minus'" size="'sm'" ng-if="$ctrl.expanded" feather="true"></pr-icon>
|
||||
<pr-icon class="vertical-center" icon="'plus'" size="'sm'" ng-if="!$ctrl.expanded" feather="true"></pr-icon>
|
||||
{{ $ctrl.expanded ? 'Collapse' : 'Expand' }}
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
<div class="col-sm-12">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0"
|
||||
ng-disabled="$ctrl.actionInProgress || $ctrl.form.$invalid || !$ctrl.formValues.Title || !$ctrl.formValues.FileContent"
|
||||
ng-click="$ctrl.submitAction()"
|
||||
button-spinner="$ctrl.actionInProgress"
|
||||
|
|
|
@ -63,9 +63,9 @@ angular
|
|||
return function (value) {
|
||||
switch (value) {
|
||||
case KubernetesApplicationDataAccessPolicies.ISOLATED:
|
||||
return 'fa-cubes';
|
||||
return 'svg-cubes';
|
||||
case KubernetesApplicationDataAccessPolicies.SHARED:
|
||||
return 'fa-cube';
|
||||
return 'box';
|
||||
}
|
||||
};
|
||||
})
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
Note: adding this registry will expose the registry credentials to all users of this namespace
|
||||
Adding this registry will expose the registry credentials to all users of this namespace.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</kubernetes-applications-datatable>
|
||||
</uib-tab>
|
||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||
<uib-tab-heading class="vertical-center"> <pr-icon icon="'repeat'" feather="true"></pr-icon> Port mappings </uib-tab-heading>
|
||||
<uib-tab-heading class="vertical-center"> <pr-icon icon="'svg-dataflow'"></pr-icon> Port mappings </uib-tab-heading>
|
||||
<kubernetes-applications-ports-datatable dataset="ctrl.state.ports" table-key="kubernetes.applications.ports" order-by="Name" refresh-callback="ctrl.getApplications">
|
||||
</kubernetes-applications-ports-datatable>
|
||||
</uib-tab>
|
||||
|
|
|
@ -97,10 +97,12 @@
|
|||
>
|
||||
<editor-description>
|
||||
<span class="text-muted small" ng-show="ctrl.stack.IsComposeFormat">
|
||||
<p>
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
Portainer uses <a href="https://kompose.io/" target="_blank">Kompose</a> to convert your Compose manifest to a Kubernetes compliant manifest. Be wary that not
|
||||
all the Compose format options are supported by Kompose at the moment.
|
||||
<span>
|
||||
Portainer uses <a href="https://kompose.io/" target="_blank">Kompose</a> to convert your Compose manifest to a Kubernetes compliant manifest. Be wary that
|
||||
not all the Compose format options are supported by Kompose at the moment.
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
You can get more information about Compose file format in the
|
||||
|
@ -108,8 +110,8 @@
|
|||
</p>
|
||||
</span>
|
||||
<span class="text-muted small" ng-show="!ctrl.stack.IsComposeFormat">
|
||||
<p>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
This feature allows you to deploy any kind of Kubernetes resource in this environment (Deployment, Secret, ConfigMap...).
|
||||
</p>
|
||||
<p>
|
||||
|
@ -124,7 +126,7 @@
|
|||
<div class="col-sm-12 form-section-title"> Application </div>
|
||||
<!-- #region NAME FIELD -->
|
||||
<div class="form-group">
|
||||
<label for="application_name" class="col-sm-3 col-lg-2 control-label text-left">Name</label>
|
||||
<label for="application_name" class="col-sm-3 col-lg-2 control-label text-left required">Name</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -142,17 +144,20 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="kubernetesApplicationCreationForm.application_name.$invalid || ctrl.state.alreadyExists">
|
||||
<div class="col-sm-12 small">
|
||||
<div ng-messages="kubernetesApplicationCreationForm.application_name.$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field is required.</p>
|
||||
<p ng-message="pattern">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
<div class="small">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8" ng-messages="kubernetesApplicationCreationForm.application_name.$error">
|
||||
<p class="text-muted vertical-center" ng-message="required"
|
||||
><pr-icon class="vertical-center" icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field is required.</p
|
||||
>
|
||||
<p class="text-muted vertical-center" ng-message="pattern">
|
||||
<pr-icon class="vertical-center" icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
This field must consist of lower case alphanumeric characters or '-', contain at most 63 characters, start with an alphabetic character, and end with an
|
||||
alphanumeric character (e.g. 'my-name', or 'abc-123').
|
||||
</p>
|
||||
</div>
|
||||
<p ng-if="ctrl.state.alreadyExists">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
<p class="text-muted vertical-center" ng-if="ctrl.state.alreadyExists">
|
||||
<pr-icon class="vertical-center" icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
An application with the same name already exists inside the selected namespace.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -166,8 +171,8 @@
|
|||
model="ctrl.formValues.ImageModel"
|
||||
ng-if="ctrl.formValues.ResourcePool"
|
||||
auto-complete="false"
|
||||
label-class="col-sm-1"
|
||||
input-class="col-sm-11"
|
||||
label-class="col-sm-3 col-lg-2"
|
||||
input-class="col-sm-8"
|
||||
namespace="ctrl.formValues.ResourcePool.Namespace.Name"
|
||||
endpoint="ctrl.endpoint"
|
||||
is-admin="ctrl.isAdmin"
|
||||
|
@ -182,8 +187,8 @@
|
|||
<div class="col-sm-12 form-section-title"> Stack </div>
|
||||
<!-- #region STACK -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Portainer can automatically bundle multiple applications inside a stack. Enter a name of a new stack or select an existing stack in the list. Leave empty to
|
||||
use the application name.
|
||||
</div>
|
||||
|
@ -209,8 +214,8 @@
|
|||
<div class="col-sm-12 form-section-title"> Environment </div>
|
||||
<!-- #region ENVIRONMENT VARIABLES -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">Environment variables</label>
|
||||
<div class="col-sm-12 vertical-center pt-2.5">
|
||||
<label class="control-label text-left !pt-0">Environment variables</label>
|
||||
<span
|
||||
ng-if="ctrl.formValues.Containers.length <= 1"
|
||||
class="label label-default interactive vertical-center"
|
||||
|
@ -227,7 +232,7 @@
|
|||
<div style="margin-top: 2px">
|
||||
<div class="col-sm-4 input-group input-group-sm">
|
||||
<div class="input-group col-sm-12 input-group-sm" ng-class="{ striked: envVar.NeedsDeletion }">
|
||||
<span class="input-group-addon">name</span>
|
||||
<span class="input-group-addon required">name</span>
|
||||
<input
|
||||
type="text"
|
||||
name="environment_variable_name_{{ $index }}"
|
||||
|
@ -257,7 +262,12 @@
|
|||
</div>
|
||||
|
||||
<div class="col-sm-2 input-group input-group-sm" ng-if="ctrl.formValues.Containers.length <= 1">
|
||||
<button ng-if="!envVar.NeedsDeletion" class="btn btn-md btn-light btn-only-icon" type="button" ng-click="ctrl.removeEnvironmentVariable(envVar)">
|
||||
<button
|
||||
ng-if="!envVar.NeedsDeletion"
|
||||
class="btn btn-md btn-dangerlight btn-only-icon !ml-0"
|
||||
type="button"
|
||||
ng-click="ctrl.removeEnvironmentVariable(envVar)"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
<button
|
||||
|
@ -277,7 +287,7 @@
|
|||
ctrl.state.duplicates.environmentVariables.refs[$index] !== undefined
|
||||
"
|
||||
>
|
||||
<div class="col-sm-4 input-group input-group-sm">
|
||||
<div class="col-sm-8 input-group input-group-sm">
|
||||
<div
|
||||
class="small"
|
||||
style="margin-top: 5px"
|
||||
|
@ -287,19 +297,19 @@
|
|||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['environment_variable_name_' + $index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Environment variable name is required.</p>
|
||||
<p ng-message="pattern"
|
||||
<p ng-message="required" class="text-muted vertical-center"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true" class-="vertical-center"></pr-icon> Environment variable name is required.</p
|
||||
>
|
||||
<p ng-message="pattern" class="text-muted vertical-center"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This field must consist of alphabetic characters, digits, '_', '-',
|
||||
or '.', and must not start with a digit (e.g. 'my.env-name', or 'MY_ENV.NAME', or 'MyEnvName1'.</p
|
||||
>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.duplicates.environmentVariables.refs[$index] !== undefined"
|
||||
<p class="text-muted vertical-center" ng-if="ctrl.state.duplicates.environmentVariables.refs[$index] !== undefined"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This environment variable is already defined.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 input-group input-group-sm"></div>
|
||||
<div class="col-sm-2 input-group input-group-sm"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -309,8 +319,8 @@
|
|||
<div class="col-sm-12 form-section-title"> Configurations </div>
|
||||
<!-- #region CONFIGURATIONS -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">Configurations</label>
|
||||
<div class="col-sm-12 vertical-center pt-2.5">
|
||||
<label class="control-label text-left !pt-0">Configurations</label>
|
||||
<span
|
||||
class="label label-default interactive vertical-center"
|
||||
style="margin-left: 10px"
|
||||
|
@ -321,8 +331,8 @@
|
|||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add configuration
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-sm-12 small text-muted" style="margin-top: 15px" ng-if="ctrl.formValues.Configurations.length">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center" style="margin-top: 15px" ng-if="ctrl.formValues.Configurations.length">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Portainer will automatically expose all the keys of a configuration as environment variables. This behavior can be overridden to filesystem mounts for each
|
||||
key via the override button.
|
||||
</div>
|
||||
|
@ -341,9 +351,9 @@
|
|||
data-cy="k8sAppCreate-addConfigSelect_{{ $index }}"
|
||||
></select>
|
||||
</div>
|
||||
<div class="col-sm-3" style="margin-top: 2px">
|
||||
<div class="col-sm-3">
|
||||
<button
|
||||
class="btn btn-sm btn-light vertical-center"
|
||||
class="btn btn-md btn-light vertical-center !ml-0"
|
||||
type="button"
|
||||
ng-if="!config.Overriden"
|
||||
ng-click="ctrl.overrideConfiguration(index)"
|
||||
|
@ -353,7 +363,7 @@
|
|||
<pr-icon icon="'list'" size="'md'" feather="true"></pr-icon> Override
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm btn-light vertical-center"
|
||||
class="btn btn-md btn-light vertical-center !ml-0"
|
||||
type="button"
|
||||
ng-if="config.Overriden"
|
||||
ng-click="ctrl.resetConfiguration(index)"
|
||||
|
@ -363,13 +373,13 @@
|
|||
<pr-icon icon="'rotate-cw'" size="'md'" feather="true"></pr-icon> Auto
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-sm btn-dangerlight vertical-center"
|
||||
class="btn btn-md btn-dangerlight vertical-center btn-only-icon h-[34px]"
|
||||
type="button"
|
||||
ng-click="ctrl.removeConfiguration(index)"
|
||||
ng-if="ctrl.formValues.Containers.length <= 1"
|
||||
data-cy="k8sAppCreate-configRemoveButton"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon> Remove
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
<!-- no-override -->
|
||||
|
@ -390,16 +400,16 @@
|
|||
<div ng-repeat="(keyIndex, overridenKey) in config.OverridenKeys" style="margin-top: 2px">
|
||||
<div class="row">
|
||||
<div class="col-sm-3 col-lg-2 form-group !m-0"><span> </span></div>
|
||||
<div class="col-sm-3 form-group" style="margin-left: -11px">
|
||||
<div class="col-sm-3 form-group !mr-1" style="margin-left: -11px">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">configuration key</span>
|
||||
<input type="text" class="form-control" ng-value="overridenKey.Key" disabled />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-3 form-group" ng-if="overridenKey.Type === ctrl.ApplicationConfigurationFormValueOverridenKeyTypes.FILESYSTEM">
|
||||
<div class="col-sm-3 form-group !mr-1" ng-if="overridenKey.Type === ctrl.ApplicationConfigurationFormValueOverridenKeyTypes.FILESYSTEM">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-addon">path on disk</span>
|
||||
<span class="input-group-addon required">path on disk</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -428,9 +438,11 @@
|
|||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['overriden_key_path_' + index + '_' + keyIndex].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required.</p>
|
||||
<p class="vertical-center" ng-message="required"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required.</p
|
||||
>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.duplicates.configurationPaths.refs[index + '_' + keyIndex] !== undefined"
|
||||
<p class="vertical-center" ng-if="ctrl.state.duplicates.configurationPaths.refs[index + '_' + keyIndex] !== undefined"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This path is already used.</p
|
||||
>
|
||||
</div>
|
||||
|
@ -459,17 +471,17 @@
|
|||
<div class="col-sm-12 form-section-title"> Persisting data </div>
|
||||
<!-- #region PERSISTED FOLDERS -->
|
||||
<div class="form-group" ng-if="!ctrl.storageClassAvailable()">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
No storage option is available to persist data, contact your administrator to enable a storage option.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.storageClassAvailable()">
|
||||
<div class="col-sm-12" style="margin-top: 5px" ng-if="!ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
||||
<label class="control-label text-left">Persisted folders</label>
|
||||
<div class="col-sm-12 vertical-center pt-2.5" style="margin-top: 5px" ng-if="!ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
||||
<label class="control-label text-left !pt-0">Persisted folders</label>
|
||||
<span
|
||||
class="label label-default interactive"
|
||||
class="label label-default interactive vertical-center"
|
||||
style="margin-left: 10px"
|
||||
ng-click="ctrl.addPersistedFolder()"
|
||||
ng-if="ctrl.isAddPersistentFolderButtonShowed()"
|
||||
|
@ -480,7 +492,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-sm-12" style="margin-top: 5px" ng-if="ctrl.allQuotasExhaustedAndNoVolumesAvailable()">
|
||||
<span class="small text-muted">
|
||||
<span class="small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
This namespace has exhausted its storage capacity. Contact your administrator to expand the capacity of the namespace.
|
||||
</span>
|
||||
|
@ -489,7 +501,7 @@
|
|||
<div class="col-sm-12 form-inline" style="margin-top: 10px" ng-repeat="persistedFolder in ctrl.formValues.PersistedFolders">
|
||||
<div style="margin-top: 2px">
|
||||
<div class="input-group col-sm-3 input-group-sm" ng-class="{ striked: persistedFolder.NeedsDeletion }">
|
||||
<span class="input-group-addon">path in container</span>
|
||||
<span class="input-group-addon required">path in container</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -514,7 +526,7 @@
|
|||
"
|
||||
>
|
||||
<label
|
||||
class="btn btn-primary"
|
||||
class="btn btn-light"
|
||||
ng-model="persistedFolder.UseNewVolume"
|
||||
uib-btn-radio="true"
|
||||
ng-change="ctrl.useNewVolume($index)"
|
||||
|
@ -522,7 +534,7 @@
|
|||
>New volume</label
|
||||
>
|
||||
<label
|
||||
class="btn btn-primary"
|
||||
class="btn btn-light"
|
||||
ng-model="persistedFolder.UseNewVolume"
|
||||
uib-btn-radio="false"
|
||||
ng-change="ctrl.useExistingVolume($index)"
|
||||
|
@ -533,22 +545,23 @@
|
|||
</div>
|
||||
|
||||
<div class="input-group col-sm-3 input-group-sm" ng-class="{ striked: persistedFolder.NeedsDeletion }" ng-if="persistedFolder.UseNewVolume">
|
||||
<span class="input-group-addon">requested size</span>
|
||||
<span class="input-group-addon required">requested size</span>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
class="form-control !rounded-none"
|
||||
name="persisted_folder_size_{{ $index }}"
|
||||
ng-model="persistedFolder.Size"
|
||||
placeholder="20"
|
||||
ng-min="0"
|
||||
min="0"
|
||||
required
|
||||
ng-disabled="ctrl.isEditAndExistingPersistedFolder($index) || ctrl.formValues.Containers.length > 1"
|
||||
ng-change="ctrl.onChangeVolumeRequestedSize()"
|
||||
/>
|
||||
<span class="input-group-addon" style="padding: 0">
|
||||
<span class="input-group-addon !p-0 !rounded-r-[5px]">
|
||||
<select
|
||||
class="form-control w-12 !h-[28px] !border-none !rounded-r-[5px] text-xs"
|
||||
ng-model="persistedFolder.SizeUnit"
|
||||
ng-style="{ width: '100%', height: '100%', cursor: ctrl.isEditAndExistingPersistedFolder($index) ? 'not-allowed' : 'auto' }"
|
||||
ng-style="{ height: '100%', cursor: ctrl.isEditAndExistingPersistedFolder($index) ? 'not-allowed' : 'auto' }"
|
||||
ng-options="unit for unit in ctrl.state.availableSizeUnits"
|
||||
ng-disabled="ctrl.isEditAndExistingPersistedFolder($index) || ctrl.formValues.Containers.length > 1"
|
||||
ng-change="ctrl.onChangeVolumeRequestedSize()"
|
||||
|
@ -595,12 +608,12 @@
|
|||
<div ng-if="!ctrl.isEditAndStatefulSet() && !ctrl.state.useExistingVolume[$index] && ctrl.formValues.Containers.length <= 1">
|
||||
<button
|
||||
ng-if="!persistedFolder.NeedsDeletion"
|
||||
class="btn btn-sm btn-danger"
|
||||
class="btn btn-sm btn-dangerlight !ml-0 h-[30px]"
|
||||
type="button"
|
||||
ng-click="ctrl.removePersistedFolder($index)"
|
||||
data-cy="k8sAppCreate-rmPersistentFolderButton"
|
||||
>
|
||||
<pr-icon icon="'trash-2'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'trash-2'" feather="true" size="'md'"></pr-icon>
|
||||
</button>
|
||||
<button
|
||||
ng-if="persistedFolder.NeedsDeletion"
|
||||
|
@ -616,6 +629,7 @@
|
|||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row gap-x-1"
|
||||
ng-show="
|
||||
kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$invalid ||
|
||||
ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined ||
|
||||
|
@ -627,36 +641,36 @@
|
|||
>
|
||||
<div class="input-group col-sm-3 input-group-sm">
|
||||
<div
|
||||
class="small text-warning"
|
||||
class="small text-muted"
|
||||
style="margin-top: 5px"
|
||||
ng-show="
|
||||
kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$invalid || ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined
|
||||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['persisted_folder_path_' + $index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Path is required.</p>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined"
|
||||
<p class="vertical-center" ng-if="ctrl.state.duplicates.persistedFolders.refs[$index] !== undefined"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This path is already defined.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group col-sm-2 input-group-sm"></div>
|
||||
|
||||
<div class="input-group col-sm-5 input-group-sm">
|
||||
<div class="input-group col-sm-offset-2 col-sm-3 input-group-sm">
|
||||
<div
|
||||
class="small text-warning"
|
||||
class="small text-muted"
|
||||
style="margin-top: 5px"
|
||||
ng-show="
|
||||
kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$invalid || ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined
|
||||
"
|
||||
>
|
||||
<ng-messages for="kubernetesApplicationCreationForm['persisted_folder_size_' + $index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Size is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This value must be greater than zero.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Size is required.</p>
|
||||
<p class="vertical-center" ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This value must be greater than zero.</p
|
||||
>
|
||||
</ng-messages>
|
||||
<p ng-if="ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined">
|
||||
<p class="vertical-center" ng-if="ctrl.state.exceeded.persistedFolders.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
You can only request up to
|
||||
{{ ctrl.state.storages.availabilities[persistedFolder.StorageClass.Name] | kubernetesAppStorageRequestSizeHumanReadable }} for
|
||||
|
@ -696,7 +710,7 @@
|
|||
|
||||
<!-- access policy options -->
|
||||
<div class="form-group" style="margin-bottom: 0">
|
||||
<div class="boxselector_wrapper">
|
||||
<div class="boxselector_wrapper !px-[15px]">
|
||||
<div
|
||||
ng-if="
|
||||
(!ctrl.state.isEdit && !ctrl.state.persistedFoldersUseExistingVolumes) ||
|
||||
|
@ -712,7 +726,7 @@
|
|||
/>
|
||||
<label for="data_access_isolated">
|
||||
<div class="boxselector_header">
|
||||
<pr-icon icon="'box'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-cubes'"></pr-icon>
|
||||
Isolated
|
||||
</div>
|
||||
<p>Application will be deployed as a StatefulSet with each instantiating their own data</p>
|
||||
|
@ -734,7 +748,7 @@
|
|||
style="cursor: pointer; border-color: #767676"
|
||||
>
|
||||
<div class="boxselector_header">
|
||||
<pr-icon icon="'box'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-cubes'"></pr-icon>
|
||||
Isolated
|
||||
</div>
|
||||
<p>Application will be deployed as a StatefulSet with each instantiating their own data</p>
|
||||
|
@ -750,7 +764,7 @@
|
|||
/>
|
||||
<label for="data_access_shared">
|
||||
<div class="boxselector_header">
|
||||
<pr-icon icon="'sliders'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'box'" feather="true"></pr-icon>
|
||||
Shared
|
||||
</div>
|
||||
<p>Application will be deployed as a Deployment with a shared storage access</p>
|
||||
|
@ -782,22 +796,22 @@
|
|||
<div class="col-sm-12 form-section-title"> Resource reservations </div>
|
||||
<!-- #region RESOURCE RESERVATIONS -->
|
||||
<div class="form-group" ng-if="!ctrl.state.resourcePoolHasQuota">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Resource reservations are applied per instance of the application.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded()">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
A resource quota is set on this namespace, you must specify resource reservations. Resource reservations are applied per instance of the application. Maximums
|
||||
are inherited from the namespace quota.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.state.resourcePoolHasQuota && ctrl.resourceQuotaCapacityExceeded()">
|
||||
<div class="col-sm-12 small text-danger">
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
This namespace has exhausted its resource capacity and you will not be able to deploy the application. Contact your administrator to expand the capacity of
|
||||
the namespace.
|
||||
|
@ -806,22 +820,22 @@
|
|||
|
||||
<!-- memory-limit-input -->
|
||||
<div
|
||||
class="form-group"
|
||||
class="form-group flex"
|
||||
ng-if="
|
||||
(!ctrl.state.resourcePoolHasQuota || (ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded())) && ctrl.formValues.Containers.length <= 1
|
||||
"
|
||||
>
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left" style="margin-top: 20px">
|
||||
Memory
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left flex flex-row items-center">
|
||||
Memory limit (MB)
|
||||
<portainer-tooltip
|
||||
message="'An instance of this application will reserve this amount of memory. If the instance memory usage exceeds the reservation, it might be subject to OOM.'"
|
||||
>
|
||||
</portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-3">
|
||||
<div class="col-sm-6">
|
||||
<slider model="ctrl.formValues.MemoryLimit" floor="ctrl.state.sliders.memory.min" ceil="ctrl.state.sliders.memory.max" step="128"></slider>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="col-sm-2 vertical-center">
|
||||
<input
|
||||
name="memory_limit"
|
||||
ng-model="ctrl.formValues.MemoryLimit"
|
||||
|
@ -834,14 +848,12 @@
|
|||
data-cy="k8sAppCreate-memoryLimit"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p class="small text-muted" style="margin-top: 7px"> Maximum memory usage (<b>MB</b>) </p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="kubernetesApplicationCreationForm.memory_limit.$invalid">
|
||||
<div class="col-sm-12 small text-warning">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8 small text-muted">
|
||||
<div ng-messages="kubernetesApplicationCreationForm.memory_limit.$error">
|
||||
<p
|
||||
<p class="vertical-center"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Value must be between {{ ctrl.state.sliders.memory.min }} and
|
||||
{{ ctrl.state.sliders.memory.max }}
|
||||
</p>
|
||||
|
@ -851,28 +863,26 @@
|
|||
<!-- !memory-limit-input -->
|
||||
<!-- cpu-limit-input -->
|
||||
<div
|
||||
class="form-group"
|
||||
class="form-group flex"
|
||||
ng-if="
|
||||
(!ctrl.state.resourcePoolHasQuota || (ctrl.state.resourcePoolHasQuota && !ctrl.resourceQuotaCapacityExceeded())) && ctrl.formValues.Containers.length <= 1
|
||||
"
|
||||
>
|
||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left" style="margin-top: 20px">
|
||||
CPU
|
||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left flex flex-row items-center">
|
||||
CPU limit
|
||||
<portainer-tooltip
|
||||
message="'An instance of this application will reserve this amount of CPU. If the instance CPU usage exceeds the reservation, it might be subject to CPU throttling.'"
|
||||
>
|
||||
</portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-5">
|
||||
<div class="col-sm-8">
|
||||
<slider model="ctrl.formValues.CpuLimit" floor="ctrl.state.sliders.cpu.min" ceil="ctrl.state.sliders.cpu.max" step="0.10" precision="2"></slider>
|
||||
</div>
|
||||
<div class="col-sm-4" style="margin-top: 20px">
|
||||
<p class="small text-muted"> Maximum CPU usage </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.nodeLimitsOverflow()">
|
||||
<div class="col-sm-12 small text-danger">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
These reservations would exceed the resources currently available in the cluster.
|
||||
</div>
|
||||
|
@ -888,7 +898,7 @@
|
|||
|
||||
<!-- deployment options -->
|
||||
<div class="form-group" style="margin-bottom: 0">
|
||||
<div class="boxselector_wrapper">
|
||||
<div class="boxselector_wrapper !px-[15px]">
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
|
@ -905,7 +915,7 @@
|
|||
<p>Run one or multiple instances of this container</p>
|
||||
</label>
|
||||
</div>
|
||||
<div style="color: #767676" ng-if="!ctrl.supportGlobalDeployment()">
|
||||
<div ng-if="!ctrl.supportGlobalDeployment()">
|
||||
<input type="radio" id="deployment_global" disabled />
|
||||
<label
|
||||
for="deployment_global"
|
||||
|
@ -913,10 +923,9 @@
|
|||
tooltip-placement="bottom"
|
||||
tooltip-class="portainer-tooltip"
|
||||
uib-tooltip="The storage or access policy used for persisted folders cannot be used with this option"
|
||||
style="cursor: pointer; border-color: #767676"
|
||||
>
|
||||
<div class="boxselector_header">
|
||||
<i class="fa fa-cubes" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'svg-cubes'"></pr-icon>
|
||||
Global
|
||||
</div>
|
||||
<p>Application will be deployed as a DaemonSet with an instance on each node of the cluster</p>
|
||||
|
@ -933,10 +942,10 @@
|
|||
/>
|
||||
<label for="deployment_global">
|
||||
<div class="boxselector_header">
|
||||
<i class="fa fa-cubes" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'svg-cubes'"></pr-icon>
|
||||
Global
|
||||
</div>
|
||||
<p>Application will be deployed as a DaemonSet with an instance on each node of the cluster</p>
|
||||
<p>Application will be deployed as a DaemonSet with an instance on each node of the sdfh</p>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -945,8 +954,8 @@
|
|||
|
||||
<!-- replica count -->
|
||||
<div class="form-group form-inline" ng-if="ctrl.formValues.DeploymentType === ctrl.ApplicationDeploymentTypes.REPLICATED">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left"> Instance count </label>
|
||||
<div class="col-sm-12 vertical-center">
|
||||
<label class="control-label text-left !pt-0"> Instance count </label>
|
||||
<input
|
||||
type="number"
|
||||
name="replica_count"
|
||||
|
@ -964,10 +973,12 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="kubernetesApplicationCreationForm['replica_count'].$invalid">
|
||||
<div class="col-sm-12 small">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<ng-messages for="kubernetesApplicationCreationForm['replica_count'].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count is required.</p>
|
||||
<p ng-message="min"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count must be greater than 0.</p>
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count is required.</p>
|
||||
<p class="vertical-center" ng-message="min"
|
||||
><pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Instance count must be greater than 0.</p
|
||||
>
|
||||
</ng-messages>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -977,33 +988,37 @@
|
|||
class="form-group"
|
||||
ng-if="!ctrl.resourceReservationsOverflow() && ctrl.formValues.ReplicaCount > 1 && (ctrl.formValues.CpuLimit !== 0 || ctrl.formValues.MemoryLimit !== 0)"
|
||||
>
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
This application will reserve the following resources:
|
||||
<b>{{ ctrl.formValues.CpuLimit * ctrl.formValues.ReplicaCount | kubernetesApplicationCPUValue }} CPU</b> and
|
||||
<b>{{ ctrl.formValues.MemoryLimit * ctrl.formValues.ReplicaCount }} MB</b> of memory.
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div>
|
||||
This application will reserve the following resources:
|
||||
<b>{{ ctrl.formValues.CpuLimit * ctrl.formValues.ReplicaCount | kubernetesApplicationCPUValue }} CPU</b> and
|
||||
<b>{{ ctrl.formValues.MemoryLimit * ctrl.formValues.ReplicaCount }} MB</b> of memory.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.resourceReservationsOverflow()">
|
||||
<div class="col-sm-12 small">
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'danger'" feather="true"></pr-icon>
|
||||
This application would exceed available resources. Please review resource reservations or the instance count.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="ctrl.state.storages.quotaExceeded">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
This application would exceed available storage. Please review the persisted folders or the instance count.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="!ctrl.supportScalableReplicaDeployment()">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
The following storage option(s) do not support concurrent access from multiples instances: <code>{{ ctrl.getNonScalableStorage() }}</code
|
||||
>. You will not be able to scale that application.
|
||||
<div>
|
||||
The following storage option(s) do not support concurrent access from multiples instances: <code>{{ ctrl.getNonScalableStorage() }}</code
|
||||
>. You will not be able to scale that application.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- #endregion -->
|
||||
|
@ -1013,8 +1028,10 @@
|
|||
|
||||
<div class="form-group" ng-if="ctrl.formValues.DeploymentType !== ctrl.ApplicationDeploymentTypes.GLOBAL && ctrl.state.useServerMetrics">
|
||||
<div class="col-sm-12">
|
||||
<label for="enable_auto_scaling" class="control-label text-left"> Enable auto scaling for this application </label>
|
||||
<label class="switch" style="margin-left: 20px">
|
||||
<div class="col-sm-3 col-lg-2 pl-0 pt-0">
|
||||
<label for="enable_auto_scaling" class="control-label text-left"> Enable auto scaling for this application </label>
|
||||
</div>
|
||||
<label class="switch ml-4 mt-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="form-control"
|
||||
|
@ -1022,7 +1039,7 @@
|
|||
ng-model="ctrl.formValues.AutoScaler.IsUsed"
|
||||
data-cy="k8sAppCreate-autoScaleCheckbox"
|
||||
/>
|
||||
<i></i>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1137,23 +1154,23 @@
|
|||
|
||||
<!-- #region PLACEMENTS -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">Placement rules</label>
|
||||
<div class="col-sm-12 vertical-center pt-2.5">
|
||||
<label class="control-label text-left !pt-0">Placement rules</label>
|
||||
<span class="label label-default interactive vertical-center" style="margin-left: 10px" ng-click="ctrl.addPlacement()">
|
||||
<pr-icon icon="'plus'" mode="'alt'" size="'sm'" feather="true"></pr-icon> add rule
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 small text-muted" ng-if="ctrl.formValues.Placements.length > 0" style="margin-top: 10px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
Deploy this application on nodes that respect <b>ALL</b> of the following placement rules. Placement rules are based on node labels.
|
||||
<div class="col-sm-12 small text-muted vertical-center" ng-if="ctrl.formValues.Placements.length > 0" style="margin-top: 10px">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div> Deploy this application on nodes that respect <b>ALL</b> of the following placement rules. Placement rules are based on node labels. </div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 form-inline" style="margin-top: 10px">
|
||||
<div ng-repeat-start="placement in ctrl.formValues.Placements" style="margin-top: 2px">
|
||||
<div class="col-sm-5 input-group" ng-class="{ striked: placement.NeedsDeletion }">
|
||||
<select
|
||||
class="form-control"
|
||||
class="form-control !rounded"
|
||||
ng-model="placement.Label"
|
||||
ng-options="label as (label.Key | kubernetesNodeLabelHumanReadbleText) for label in ctrl.nodesLabels"
|
||||
ng-change="ctrl.onChangePlacementLabel($index)"
|
||||
|
@ -1164,7 +1181,7 @@
|
|||
</div>
|
||||
<div class="col-sm-5 input-group" ng-class="{ striked: placement.NeedsDeletion }">
|
||||
<select
|
||||
class="form-control"
|
||||
class="form-control !rounded"
|
||||
ng-model="placement.Value"
|
||||
ng-options="value for value in placement.Label.Values"
|
||||
ng-disabled="ctrl.isEditAndNotNewPlacement($index)"
|
||||
|
@ -1176,7 +1193,7 @@
|
|||
<div class="col-sm-1 input-group">
|
||||
<button
|
||||
ng-if="!placement.NeedsDeletion"
|
||||
class="btn btn-sm btn-light btn-only-icon"
|
||||
class="btn btn-md btn-dangerlight btn-only-icon !ml-0"
|
||||
type="button"
|
||||
ng-click="ctrl.removePlacement($index)"
|
||||
data-cy="k8sAppCreate-deletePlacementButton"
|
||||
|
@ -1185,7 +1202,7 @@
|
|||
</button>
|
||||
<button
|
||||
ng-if="placement.NeedsDeletion"
|
||||
class="btn btn-sm btn-light btn-only-icon"
|
||||
class="btn btn-sm btn-light btn-only-icon !ml-0"
|
||||
type="button"
|
||||
ng-click="ctrl.restorePlacement($index)"
|
||||
data-cy="k8sAppCreate-restorePlacementButton"
|
||||
|
@ -1196,8 +1213,8 @@
|
|||
</div>
|
||||
<div ng-repeat-end ng-show="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<div class="col-sm-5 input-group">
|
||||
<div class="small text-warning" style="margin-top: 5px" ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<p ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<div class="small text-muted" style="margin-top: 5px" ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<p class="vertical-center" ng-if="ctrl.state.duplicates.placements.refs[$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> This label is already defined.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -1218,7 +1235,7 @@
|
|||
|
||||
<!-- placement policy options -->
|
||||
<div class="form-group" style="margin-bottom: 0" ng-if="ctrl.formValues.Placements.length">
|
||||
<div class="boxselector_wrapper">
|
||||
<div class="boxselector_wrapper !px-[15px]">
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
|
@ -1316,7 +1333,7 @@
|
|||
<button
|
||||
ng-if="ctrl.state.appType === ctrl.KubernetesDeploymentTypes.APPLICATION_FORM"
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0"
|
||||
ng-disabled="!kubernetesApplicationCreationForm.$valid || ctrl.isDeployUpdateButtonDisabled() || !ctrl.imageValidityIsValid()"
|
||||
ng-click="ctrl.deployApplication()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
<rd-widget-body classes="no-padding">
|
||||
<uib-tabset active="ctrl.state.activeTab" justified="true" type="pills">
|
||||
<uib-tab index="0" classes="btn-sm" select="ctrl.selectTab(0)">
|
||||
<uib-tab-heading> <pr-icon icon="'fa-laptop-code'" class-name="'mr-1'"></pr-icon> Application </uib-tab-heading>
|
||||
<uib-tab-heading> <pr-icon icon="'svg-laptopcode'" class-name="'mr-1'"></pr-icon> Application </uib-tab-heading>
|
||||
<div style="padding: 20px">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
|
@ -156,19 +156,19 @@
|
|||
|
||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||
<uib-tab-heading>
|
||||
<pr-icon icon="'fa-compress-arrows-alt'"></pr-icon> Placement
|
||||
<pr-icon icon="'svg-compress'"></pr-icon> Placement
|
||||
<div ng-if="ctrl.state.placementWarning" class="vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
warning
|
||||
</div>
|
||||
</uib-tab-heading>
|
||||
<div class="small text-muted vertical-center" style="padding: 20px">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
The placement component helps you understand whether or not this application can be deployed on a specific node.
|
||||
</div>
|
||||
<kubernetes-application-placements-datatable
|
||||
title-text="Placement constraints/preferences"
|
||||
title-icon="fa-compress-arrows-alt"
|
||||
title-icon="svg-compress"
|
||||
dataset="ctrl.placements"
|
||||
table-key="kubernetes.application.placements"
|
||||
order-by="Name"
|
||||
|
@ -180,7 +180,7 @@
|
|||
|
||||
<uib-tab index="2" classes="btn-sm" select="ctrl.selectTab(2)">
|
||||
<uib-tab-heading>
|
||||
<pr-icon icon="'fa-history'"></pr-icon> Events
|
||||
<pr-icon icon="'svg-clockrewind'"></pr-icon> Events
|
||||
<div ng-if="ctrl.hasEventWarnings()" class="vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||
|
@ -188,7 +188,7 @@
|
|||
</uib-tab-heading>
|
||||
<kubernetes-events-datatable
|
||||
title-text="Events"
|
||||
title-icon="fa-history"
|
||||
title-icon="svg-clockrewind"
|
||||
dataset="ctrl.events"
|
||||
table-key="kubernetes.application.events"
|
||||
order-by="Date"
|
||||
|
@ -200,7 +200,7 @@
|
|||
|
||||
<uib-tab index="3" ng-if="ctrl.application.Yaml" select="ctrl.showEditor()" classes="btn-sm">
|
||||
<uib-tab-heading> <pr-icon icon="'code'" feather="true"></pr-icon> YAML </uib-tab-heading>
|
||||
<div style="padding-right: 25px" ng-if="ctrl.state.showEditorTab">
|
||||
<div class="px-5" ng-if="ctrl.state.showEditorTab">
|
||||
<kubernetes-yaml-inspector key="application-yaml" data="ctrl.application.Yaml"></kubernetes-yaml-inspector>
|
||||
</div>
|
||||
</uib-tab>
|
||||
|
@ -270,14 +270,14 @@
|
|||
<div class="text-muted" style="margin-bottom: 15px"> <pr-icon icon="'external-link'" class="mr-1" feather="true"></pr-icon>Accessing the application </div>
|
||||
|
||||
<div class="small text-muted" ng-if="ctrl.application.PublishedPorts.length === 0" style="margin-bottom: 15px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" class="mr-1" feather="true"></pr-icon>This application is not exposing any port.
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1" feather="true"></pr-icon>This application is not exposing any port.
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.application.Services.length !== 0">
|
||||
<!-- Services notice -->
|
||||
<div>
|
||||
<div class="small text-muted">
|
||||
<p> <pr-icon icon="'alert-circle'" mode="'primary'" class="mr-1" feather="true"></pr-icon>This application is exposed through service(s) as below: </p>
|
||||
<p> <pr-icon icon="'info'" mode="'primary'" class="mr-1" feather="true"></pr-icon>This application is exposed through service(s) as below: </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -298,7 +298,7 @@
|
|||
<div class="text-muted" style="margin-bottom: 15px"> <pr-icon icon="'move'" class="mr-1" feather="true"></pr-icon>Auto-scaling </div>
|
||||
|
||||
<div class="small text-muted" ng-if="!ctrl.application.AutoScaler" style="margin-bottom: 15px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
This application does not have an autoscaling policy defined.
|
||||
</div>
|
||||
|
||||
|
@ -333,7 +333,7 @@
|
|||
</div>
|
||||
|
||||
<div class="small text-muted" ng-if="!ctrl.application.Env.length > 0 && !ctrl.hasVolumeConfiguration()" style="margin-bottom: 15px">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
This application is not using any environment variable or configuration.
|
||||
</div>
|
||||
|
||||
|
@ -434,13 +434,14 @@
|
|||
</div>
|
||||
|
||||
<div class="small text-muted" ng-if="!ctrl.hasPersistedFolders()">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1" feather="true"></pr-icon>
|
||||
This application has no persisted folders.
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.hasPersistedFolders()">
|
||||
<div class="small text-muted" style="margin-bottom: 15px">
|
||||
Data access policy: <i class="fa {{ ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyIcon }}" aria-hidden="true"></i>
|
||||
<div class="small text-muted vertical-center" style="margin-bottom: 15px">
|
||||
Data access policy:
|
||||
<pr-icon icon="ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyIcon" feather="true"></pr-icon>
|
||||
{{ ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyText }}
|
||||
<portainer-tooltip position="'right'" message="ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyTooltip"> </portainer-tooltip>
|
||||
</div>
|
||||
|
@ -456,7 +457,10 @@
|
|||
{{ volume.MountPath }}
|
||||
</td>
|
||||
<td ng-if="volume.PersistentVolumeClaimName">
|
||||
<a ui-sref="kubernetes.volumes.volume({ name: volume.PersistentVolumeClaimName, namespace: ctrl.application.ResourcePool })" data-cy="k8sAppDetail-volClaimName"
|
||||
<a
|
||||
class="hyperlink"
|
||||
ui-sref="kubernetes.volumes.volume({ name: volume.PersistentVolumeClaimName, namespace: ctrl.application.ResourcePool })"
|
||||
data-cy="k8sAppDetail-volClaimName"
|
||||
><pr-icon icon="'database'" class="mr-1" feather="true"></pr-icon>{{ volume.PersistentVolumeClaimName }}</a
|
||||
>
|
||||
</td>
|
||||
|
@ -491,7 +495,10 @@
|
|||
{{ volume.MountPath }}
|
||||
</td>
|
||||
<td ng-if="volume.PersistentVolumeClaimName">
|
||||
<a ui-sref="kubernetes.volumes.volume({ name: volume.PersistentVolumeClaimName + '-' + container.PodName, namespace: ctrl.application.ResourcePool })">
|
||||
<a
|
||||
class="hyperlink"
|
||||
ui-sref="kubernetes.volumes.volume({ name: volume.PersistentVolumeClaimName + '-' + container.PodName, namespace: ctrl.application.ResourcePool })"
|
||||
>
|
||||
<pr-icon icon="'database'" class="mr-1" feather="true"></pr-icon>{{ volume.PersistentVolumeClaimName + '-' + container.PodName }}</a
|
||||
>
|
||||
</td>
|
||||
|
|
|
@ -2,9 +2,8 @@
|
|||
<div class="toolBar">
|
||||
<div class="toolBarTitle flex">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true"></pr-icon>
|
||||
<pr-icon icon="$ctrl.titleIcon"></pr-icon>
|
||||
</div>
|
||||
|
||||
<span class="vertical-center">
|
||||
{{ $ctrl.titleText }}
|
||||
</span>
|
||||
|
@ -56,7 +55,7 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<div class="table-responsive border-none">
|
||||
<table class="table table-hover nowrap-cells">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
<td>{{ service.spec.clusterIP }}</td>
|
||||
<td ng-show="service.spec.type === 'LoadBalancer'">
|
||||
<div ng-show="service.status.loadBalancer.ingress">
|
||||
<a target="_blank" ng-href="http://{{ service.status.loadBalancer.ingress[0].ip }}:{{ service.spec.ports[0].port }}">
|
||||
<i class="fa fa-external-link-alt" aria-hidden="true"></i>
|
||||
<a class="vertical-center hyperlink" target="_blank" ng-href="http://{{ service.status.loadBalancer.ingress[0].ip }}:{{ service.spec.ports[0].port }}">
|
||||
<pr-icon icon="'external-link'" feather="true"></pr-icon>
|
||||
<span data-cy="k8sAppDetail-containerPort"> Access </span>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -32,8 +32,14 @@
|
|||
</td>
|
||||
<td ng-if="!ctrl.portHasIngressRules(port)">
|
||||
<div ng-repeat="port in service.spec.ports">
|
||||
<a ng-if="$ctrl.publicUrl && port.nodePort" ng-href="http://{{ $ctrl.publicUrl }}:{{ port.nodePort }}" target="_blank" style="margin-left: 5px">
|
||||
<i class="fa fa-external-link-alt" aria-hidden="true"></i>
|
||||
<a
|
||||
class="vertical-center hyperlink"
|
||||
ng-if="$ctrl.publicUrl && port.nodePort"
|
||||
ng-href="http://{{ $ctrl.publicUrl }}:{{ port.nodePort }}"
|
||||
target="_blank"
|
||||
style="margin-left: 5px"
|
||||
>
|
||||
<pr-icon icon="'external-link'" feather="true"></pr-icon>
|
||||
<span data-cy="k8sAppDetail-containerPort">
|
||||
{{ port.port }}
|
||||
</span>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
<div class="toolBarTitle text-muted small vertical-center px-5 !gap-0">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class-name="'!mr-1'" class="vertical-center"></pr-icon>
|
||||
This is a first version for Helm charts, for more information see this
|
||||
<a href="https://www.portainer.io/blog/portainer-now-with-helm-support" target="_blank" class="text-blue-8 hover:text-blue-8 hover:underline">blog post</a>.
|
||||
<a href="https://www.portainer.io/blog/portainer-now-with-helm-support" target="_blank" class="hyperlink">blog post</a>.
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<table class="table">
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
||||
|
||||
<div ng-if="ctrl.state.viewReady" style="height: 100%">
|
||||
<div ng-if="ctrl.state.viewReady">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
|
@ -75,8 +75,8 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="height: 54%">
|
||||
<div class="col-sm-12" style="height: 100%">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 h-[max(400px,calc(100vh-380px))]">
|
||||
<pre
|
||||
class="log_viewer widget"
|
||||
><div ng-repeat="line in ctrl.state.filteredLogs = (ctrl.applicationLogs | filter:ctrl.state.search) track by $index" class="line" ng-if="line"><p class="inner_line">{{ line }}</p></div><div ng-if="ctrl.applicationLogs.length && !ctrl.state.filteredLogs.length" class="line"><p class="inner_line">No log line matching the '{{ ctrl.state.search }}' filter</p></div><div ng-if="ctrl.applicationLogs.length === 0" class="line"><p class="inner_line">No logs available</p></div></pre>
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
|
||||
<div ng-if="ctrl.state.viewReady">
|
||||
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve container metrics">
|
||||
<span class="small text-muted">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<span class="small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Portainer was unable to retrieve any metrics associated to that container. Please contact your administrator to ensure that the Kubernetes metrics feature is properly
|
||||
configured.
|
||||
</span>
|
||||
|
@ -37,7 +37,12 @@
|
|||
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||
<div class="col-md-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-info-circle" title-text="About statistics"> </rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> About statistics </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
|
@ -57,12 +62,15 @@
|
|||
</select>
|
||||
</div>
|
||||
<span>
|
||||
<i id="refreshRateChange" class="fa fa-check green-icon" aria-hidden="true" style="margin-top: 7px; display: none"></i>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" feather="true" mode="'success'" size="'sm'"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group" ng-if="ctrl.state.networkStatsUnavailable">
|
||||
<div class="col-sm-12">
|
||||
<span class="small text-muted"> <i class="fa fa-exclamation-triangle orange-icon" aria-hidden="true"></i> Network stats are unavailable for this container. </span>
|
||||
<span class="small text-muted">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Network stats are unavailable for this container.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -74,7 +82,12 @@
|
|||
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-chart-area" title-text="Memory usage"></rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'svg-memory'" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> Memory usage </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<div class="chart-container" style="position: relative">
|
||||
<canvas id="memoryChart" width="770" height="300"></canvas>
|
||||
|
@ -84,7 +97,12 @@
|
|||
</div>
|
||||
<div class="col-lg-6 col-md-12 col-sm-12" ng-if="!ctrl.state.networkStatsUnavailable">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-chart-area" title-text="CPU usage"></rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'cpu'" feather="true" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> CPU usage </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<div class="chart-container" style="position: relative">
|
||||
<canvas id="cpuChart" width="770" height="300"></canvas>
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<div class="col-sm-12">
|
||||
<kubernetes-nodes-datatable
|
||||
title-text="Nodes"
|
||||
title-icon="fa-hdd"
|
||||
title-icon="hard-drive"
|
||||
dataset="ctrl.nodes"
|
||||
table-key="kubernetes.nodes"
|
||||
order-by="Name"
|
||||
|
|
|
@ -51,19 +51,21 @@
|
|||
<tr>
|
||||
<td class="col-xs-3"> Availability </td>
|
||||
<td class="col-xs-9">
|
||||
<select class="form-control" name="availability" style="display: inline-block; width: 16rem" ng-model="ctrl.formValues.Availability">
|
||||
<option>{{ ctrl.availabilities.ACTIVE }}</option>
|
||||
<option>{{ ctrl.availabilities.PAUSE }}</option>
|
||||
<option>{{ ctrl.availabilities.DRAIN }}</option>
|
||||
</select>
|
||||
<span class="small vertical-center" ng-if="ctrl.state.isDrainOperation && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Cannot use this action while another node is currently being drained.
|
||||
</span>
|
||||
<span class="small vertical-center" ng-if="ctrl.state.isContainPortainer && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Cannot drain a node where this Portainer instance is running.
|
||||
</span>
|
||||
<div class="flex flex-col">
|
||||
<select class="form-control" name="availability" style="display: inline-block; width: 16rem" ng-model="ctrl.formValues.Availability">
|
||||
<option>{{ ctrl.availabilities.ACTIVE }}</option>
|
||||
<option>{{ ctrl.availabilities.PAUSE }}</option>
|
||||
<option>{{ ctrl.availabilities.DRAIN }}</option>
|
||||
</select>
|
||||
<div class="small text-muted vertical-center" ng-if="ctrl.state.isDrainOperation && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Cannot use this action while another node is currently being drained.
|
||||
</div>
|
||||
<div class="small text-muted vertical-center" ng-if="ctrl.state.isContainPortainer && ctrl.formValues.Availability === ctrl.availabilities.DRAIN">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Cannot drain a node where this Portainer instance is running.
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -126,14 +128,14 @@
|
|||
>
|
||||
<pr-icon icon="'x'" feather="true" mode="'error'" size="'sm'"></pr-icon>
|
||||
</button>
|
||||
<button ng-if="!ctrl.isSystemLabel($index) && label.NeedsDeletion" class="btn btn-sm btn-primary" type="button" ng-click="ctrl.restoreLabel($index)">
|
||||
<button ng-if="!ctrl.isSystemLabel($index) && label.NeedsDeletion" class="btn btn-sm btn-secondary" type="button" ng-click="ctrl.restoreLabel($index)">
|
||||
Restore
|
||||
</button>
|
||||
<span class="label label-warning label-sm image-tag" ng-if="label.IsUsed && !ctrl.isSystemLabel($index)" style="margin-left: 5px">used</span>
|
||||
<span class="label label-info image-tag" ng-if="ctrl.isSystemLabel($index)" style="margin-left: 5px">system</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="small mt-2" ng-show="kubernetesNodeUpdateForm['label_key_' + $index].$invalid || ctrl.state.duplicateLabelKeys[$index] !== undefined">
|
||||
<div class="small mt-2 text-muted" ng-show="kubernetesNodeUpdateForm['label_key_' + $index].$invalid || ctrl.state.duplicateLabelKeys[$index] !== undefined">
|
||||
<ng-messages for="kubernetesNodeUpdateForm['label_key_' + $index].$error">
|
||||
<p ng-message="required" class="vertical-center"> <pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Label key is required. </p>
|
||||
</ng-messages>
|
||||
|
@ -179,11 +181,11 @@
|
|||
<button ng-if="!taint.NeedsDeletion" class="btn btn-sm btn-dangerlight btn-only-icon" type="button" ng-click="ctrl.removeTaint($index)">
|
||||
<pr-icon icon="'x'" feather="true" mode="'error'" size="'sm'"></pr-icon>
|
||||
</button>
|
||||
<button ng-if="taint.NeedsDeletion" class="btn btn-sm btn-primary" type="button" ng-click="ctrl.restoreTaint($index)"> Restore </button>
|
||||
<button ng-if="taint.NeedsDeletion" class="btn btn-sm btn-secondary" type="button" ng-click="ctrl.restoreTaint($index)"> Restore </button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="small"
|
||||
class="small text-muted"
|
||||
style="margin-top: 5px"
|
||||
ng-show="kubernetesNodeUpdateForm['taint_key_' + $index].$invalid || ctrl.state.duplicateTaintKeys[$index] !== undefined"
|
||||
>
|
||||
|
@ -223,7 +225,7 @@
|
|||
</uib-tab>
|
||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||
<uib-tab-heading>
|
||||
<div class="flex-center gap-1"> <pr-icon icon="'rotate-ccw'" size="'sm'" feather="true"></pr-icon> Events </div>
|
||||
<div class="flex-center gap-1"> <pr-icon icon="'svg-clockrewind'" size="'sm'" feather="true"></pr-icon> Events </div>
|
||||
<div class="flex-center gap-1" ng-if="ctrl.hasEventWarnings()">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning-alt'" size="'sm'" feather="true"></pr-icon>
|
||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||
|
@ -231,7 +233,7 @@
|
|||
</uib-tab-heading>
|
||||
<kubernetes-events-datatable
|
||||
title-text="Events"
|
||||
title-icon="fa-history"
|
||||
title-icon="icon-nested-blue"
|
||||
dataset="ctrl.events"
|
||||
table-key="kubernetes.node.events"
|
||||
order-by="Date"
|
||||
|
@ -264,7 +266,6 @@
|
|||
refresh-callback="ctrl.getApplications"
|
||||
loading="ctrl.state.applicationsLoading"
|
||||
title-text="Applications running on this node"
|
||||
title-icon="box"
|
||||
>
|
||||
</kubernetes-node-applications-datatable>
|
||||
</div>
|
||||
|
|
|
@ -17,15 +17,20 @@
|
|||
|
||||
<div ng-if="ctrl.state.viewReady">
|
||||
<information-panel ng-if="!ctrl.state.getMetrics" title-text="Unable to retrieve node metrics">
|
||||
<span class="small text-muted">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<span class="small text-muted vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'primary'"></pr-icon>
|
||||
Portainer was unable to retrieve any metrics associated to that node. Please contact your administrator to ensure that the Kubernetes metrics feature is properly configured.
|
||||
</span>
|
||||
</information-panel>
|
||||
<div class="row" ng-if="ctrl.state.getMetrics">
|
||||
<div class="col-md-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-info-circle" title-text="About statistics"> </rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> About statistics </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
|
@ -45,7 +50,7 @@
|
|||
</select>
|
||||
</div>
|
||||
<span>
|
||||
<i id="refreshRateChange" class="fa fa-check green-icon" aria-hidden="true" style="margin-top: 7px; display: none"></i>
|
||||
<pr-icon id="refreshRateChange" icon="'check'" feather="true" mode="'success'" size="'sm'"></pr-icon>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -57,7 +62,12 @@
|
|||
<div class="row" ng-show="ctrl.state.getMetrics">
|
||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-chart-area" title-text="Memory usage"></rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'svg-memory'" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> Memory usage </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<div class="chart-node" style="position: relative">
|
||||
<canvas id="memoryChart" width="770" height="300"></canvas>
|
||||
|
@ -67,7 +77,12 @@
|
|||
</div>
|
||||
<div class="col-lg-6 col-md-12 col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="fa-chart-area" title-text="CPU usage"></rd-widget-header>
|
||||
<div class="toolBar pt-5 px-5">
|
||||
<div class="toolBarTitle flex">
|
||||
<pr-icon icon="'cpu'" feather="true" mode="'primary'" class-name="'icon-nested-blue'"></pr-icon>
|
||||
<span class="vertical-center"> CPU usage </span>
|
||||
</div>
|
||||
</div>
|
||||
<rd-widget-body>
|
||||
<div class="chart-node" style="position: relative">
|
||||
<canvas id="cpuChart" width="770" height="300"></canvas>
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
<form class="form-horizontal" name="kubernetesConfigurationCreationForm" autocomplete="off">
|
||||
<!-- name -->
|
||||
<div class="form-group">
|
||||
<label for="configuration_name" class="col-sm-3 col-lg-2 control-label text-left">Name</label>
|
||||
<div class="col-sm-8">
|
||||
<label for="configuration_name" class="col-sm-3 col-lg-2 control-label text-left required">Name</label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -32,7 +32,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="kubernetesConfigurationCreationForm.configuration_name.$invalid || ctrl.state.alreadyExist">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8 col-lg-9 small text-muted">
|
||||
<div ng-messages="kubernetesConfigurationCreationForm.configuration_name.$error">
|
||||
<p ng-message="required" class="vertical-center"><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> This field is required.</p>
|
||||
<p ng-message="pattern" class="vertical-center"
|
||||
|
@ -52,7 +53,7 @@
|
|||
<!-- resource-pool -->
|
||||
<div class="form-group" ng-if="ctrl.formValues.ResourcePool">
|
||||
<label for="resource-pool-selector" class="col-sm-3 col-lg-2 control-label text-left">Namespace</label>
|
||||
<div class="col-sm-8">
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<select
|
||||
class="form-control"
|
||||
id="resource-pool-selector"
|
||||
|
@ -86,13 +87,13 @@
|
|||
</div>
|
||||
|
||||
<!-- type options -->
|
||||
<div class="form-group" style="margin-bottom: 0">
|
||||
<div class="form-group px-[15px]" style="margin-bottom: 0">
|
||||
<div class="boxselector_wrapper">
|
||||
<div>
|
||||
<input type="radio" id="type_basic" ng-value="ctrl.KubernetesConfigurationTypes.CONFIGMAP" ng-model="ctrl.formValues.Type" />
|
||||
<label for="type_basic" data-cy="k8sConfigCreate-nonSensitiveButton">
|
||||
<div class="boxselector_header">
|
||||
<pr-icon icon="'code'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'svg-filecode'"></pr-icon>
|
||||
ConfigMap
|
||||
</div>
|
||||
<p>This configuration holds non-sensitive information</p>
|
||||
|
@ -102,7 +103,7 @@
|
|||
<input type="radio" id="type_secret" ng-value="ctrl.KubernetesConfigurationTypes.SECRET" ng-model="ctrl.formValues.Type" />
|
||||
<label for="type_secret" data-cy="k8sConfigCreate-sensitiveButton">
|
||||
<div class="boxselector_header">
|
||||
<pr-icon icon="'shield'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'lock'" feather="true"></pr-icon>
|
||||
Secret
|
||||
</div>
|
||||
<p>This configuration holds sensitive information</p>
|
||||
|
|
|
@ -60,13 +60,13 @@
|
|||
<pr-icon icon="'svg-clockrewind'"></pr-icon>
|
||||
Events
|
||||
<div ng-if="ctrl.hasEventWarnings()">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||
</div>
|
||||
</uib-tab-heading>
|
||||
<kubernetes-events-datatable
|
||||
title-text="Events"
|
||||
title-icon="fa-history"
|
||||
title-icon="svg-clockrewind"
|
||||
dataset="ctrl.events"
|
||||
table-key="kubernetes.configuration.events"
|
||||
order-by="Date"
|
||||
|
@ -143,9 +143,11 @@
|
|||
<td>
|
||||
<div style="white-space: pre-wrap">{{ item.Value }}</div>
|
||||
<div style="margin-top: 2px">
|
||||
<span class="btn btn-primary btn-xs" ng-click="ctrl.copyConfigurationValue($index)"> <i class="fa fa-copy space-right" aria-hidden="true"></i>Copy </span>
|
||||
<span class="btn btn-primary btn-xs" ng-click="ctrl.copyConfigurationValue($index)">
|
||||
<pr-icon icon="'copy'" feather="true" class-name="'mr-0.5'"></pr-icon>Copy
|
||||
</span>
|
||||
<span id="copyValueNotification_{{ $index }}" style="display: none; color: #23ae89; margin-left: 5px" class="small">
|
||||
<i class="fa fa-check" aria-hidden="true"></i> copied
|
||||
<pr-icon icon="'check'" feather="true"></pr-icon> copied
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left col-sm-3 col-lg-2 px-0"> Allow users to use external load balancer </label>
|
||||
<label class="control-label text-left col-sm-5 col-lg-4 px-0"> Allow users to use external load balancer </label>
|
||||
<label class="switch mb-0 col-sm-8">
|
||||
<input type="checkbox" ng-model="ctrl.formValues.UseLoadBalancer" /><span class="slider round" data-cy="kubeSetup-loadBalancerToggle"></span>
|
||||
</label>
|
||||
|
@ -42,7 +42,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 text-muted small">
|
||||
<div class="col-sm-12 text-muted small mt-4">
|
||||
<p> Configuring ingress controllers will allow users to expose application they deploy over a HTTP route. </p>
|
||||
<p class="mt-1 vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
|
@ -165,7 +165,7 @@
|
|||
feature-id="ctrl.limitedFeatureAutoWindow"
|
||||
tooltip="'Specify a timeframe during which automatic updates can occur in this environment.'"
|
||||
on-change="(ctrl.onToggleAutoUpdate)"
|
||||
label-class="'col-sm-3 col-lg-2 px-0 !m-0'"
|
||||
label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
|
||||
switch-class="'col-sm-8'"
|
||||
>
|
||||
</por-switch-field>
|
||||
|
@ -185,7 +185,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left col-sm-3 col-lg-2 px-0"> Restrict access to the default namespace </label>
|
||||
<label class="control-label text-left col-sm-5 col-lg-4 px-0"> Restrict access to the default namespace </label>
|
||||
<label class="switch col-sm-8">
|
||||
<input type="checkbox" ng-model="ctrl.formValues.RestrictDefaultNamespace" /><span class="slider round" data-cy="kubeSetup-restrictDefaultNsToggle"></span>
|
||||
</label>
|
||||
|
@ -216,7 +216,7 @@
|
|||
feature-id="ctrl.limitedFeature"
|
||||
checked="ctrl.formValues.EnableResourceOverCommit"
|
||||
on-change="(ctrl.onChangeEnableResourceOverCommit)"
|
||||
label-class="'col-sm-3 col-lg-2 px-0 !m-0'"
|
||||
label-class="'col-sm-5 col-lg-4 px-0 !m-0'"
|
||||
switch-class="'col-sm-8'"
|
||||
></por-switch-field>
|
||||
</div>
|
||||
|
@ -234,14 +234,14 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left col-sm-3 col-lg-2 px-0"> Enable features using the metrics API </label>
|
||||
<label class="control-label text-left col-sm-5 col-lg-4 px-0"> Enable features using the metrics API </label>
|
||||
<label class="switch col-sm-8">
|
||||
<input type="checkbox" ng-model="ctrl.formValues.UseServerMetrics" ng-change="ctrl.enableMetricsServer()" />
|
||||
<span class="slider round" data-cy="kubeSetup-metricsToggle"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div ng-if="ctrl.state.metrics.pending && ctrl.state.metrics.userClick" class="col-sm-12 small text-muted" style="margin-top: 5px">
|
||||
Checking metrics API... <i class="fa fa-spinner fa-spin" style="margin-left: 2px"></i>
|
||||
Checking metrics API... <pr-icon icon="'loader'" feather="true" class-name="'ml-0.5'"></pr-icon>
|
||||
</div>
|
||||
<div
|
||||
ng-if="!ctrl.state.metrics.pending && ctrl.state.metrics.isServerRunning && ctrl.state.metrics.userClick"
|
||||
|
@ -291,7 +291,7 @@
|
|||
</tr>
|
||||
<tr ng-repeat="class in ctrl.StorageClasses">
|
||||
<td>
|
||||
<div class="flex-center justify-start">
|
||||
<div class="flex-row vertical-center">
|
||||
<label class="switch mr-2 mb-0">
|
||||
<input type="checkbox" ng-model="class.selected" /><span class="slider round" data-cy="kubeSetup-storageToggle{{ class.Name }}"></span>
|
||||
</label>
|
||||
|
@ -341,7 +341,7 @@
|
|||
<div class="col-sm-12">
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0"
|
||||
ng-click="ctrl.configure()"
|
||||
ng-disabled="ctrl.state.actionInProgress || !kubernetesClusterSetupForm.$valid || !ctrl.hasValidStorageConfiguration()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
</div>
|
||||
<div ng-if="ctrl.configurations" data-cy="k8sDashboard-configurations">
|
||||
<a ui-sref="kubernetes.configurations">
|
||||
<dashboard-item feather-icon="true" icon="'lock'" type="'Configuration'" value="ctrl.configurations.length"></dashboard-item>
|
||||
<dashboard-item feather-icon="true" icon="'lock'" type="'ConfigMaps & Secret'" value="ctrl.configurations.length"></dashboard-item>
|
||||
</a>
|
||||
</div>
|
||||
<div ng-if="ctrl.volumes" data-cy="k8sDashboard-volumes">
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="stack_name" class="col-lg-2 col-sm-3 control-label text-left">Name</label>
|
||||
<label for="stack_name" class="col-lg-2 col-sm-3 control-label text-left required">Name</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" ng-model="ctrl.formValues.StackName" id="stack_name" placeholder="my-app" auto-focus />
|
||||
</div>
|
||||
|
@ -117,10 +117,12 @@
|
|||
>
|
||||
<editor-description>
|
||||
<span class="col-sm-12 text-muted small" ng-show="ctrl.state.DeployType === ctrl.ManifestDeployTypes.COMPOSE">
|
||||
<p>
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'alert-circle'" mode="'warning'" feather="true"></pr-icon>
|
||||
Portainer uses <a href="https://kompose.io/" target="_blank">Kompose</a> to convert your Compose manifest to a Kubernetes compliant manifest. Be wary that
|
||||
not all the Compose format options are supported by Kompose at the moment.
|
||||
<span>
|
||||
Portainer uses <a href="https://kompose.io/" target="_blank">Kompose</a> to convert your Compose manifest to a Kubernetes compliant manifest. Be wary
|
||||
that not all the Compose format options are supported by Kompose at the moment.
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
You can get more information about Compose file format in the
|
||||
|
@ -128,8 +130,8 @@
|
|||
</p>
|
||||
</span>
|
||||
<span class="col-sm-12 text-muted small" ng-show="ctrl.state.DeployType === ctrl.ManifestDeployTypes.KUBERNETES">
|
||||
<p>
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
This feature allows you to deploy any kind of Kubernetes resource in this environment (Deployment, Secret, ConfigMap...).
|
||||
</p>
|
||||
<p>
|
||||
|
@ -149,7 +151,7 @@
|
|||
<span class="col-sm-12 text-muted small"> Indicate the URL to the manifest. </span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="manifest_url" class="col-sm-3 col-lg-2 control-label text-left">URL</label>
|
||||
<label for="manifest_url" class="col-sm-3 col-lg-2 control-label text-left required">URL</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -170,7 +172,7 @@
|
|||
<div class="col-sm-12">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0"
|
||||
ng-disabled="!deploymentForm.$valid ||ctrl.disableDeploy()"
|
||||
ng-click="ctrl.deploy()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
|
|
|
@ -43,6 +43,14 @@
|
|||
<rd-widget-header icon="svg-userlock" title-text="Create access"></rd-widget-header>
|
||||
<rd-widget-body>
|
||||
<form class="form-horizontal">
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
Adding user access will require the affected user(s) to logout and login for the changes to be taken into account.
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 col-lg-2 control-label text-left"> Select user(s) and/or team(s) </label>
|
||||
<div class="col-sm-9 col-lg-4">
|
||||
|
@ -92,7 +100,7 @@
|
|||
<div class="col-sm-12">
|
||||
<access-datatable
|
||||
ng-if="ctrl.authorizedUsersAndTeams"
|
||||
title-text="Access"
|
||||
title-text="Namespace access"
|
||||
title-icon="svg-userlock"
|
||||
table-key="kubernetes_resourcepool_access"
|
||||
order-by="Name"
|
||||
|
|
|
@ -76,19 +76,20 @@
|
|||
<div ng-if="$ctrl.formValues.HasQuota">
|
||||
<div class="col-sm-12 form-section-title"> Resource limits </div>
|
||||
<div>
|
||||
<div class="form-group" ng-if="$ctrl.formValues.HasQuota && !$ctrl.isQuotaValid()">
|
||||
<span class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center"
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 small text-muted" ng-switch on="$ctrl.formValues.HasQuota && !$ctrl.isQuotaValid()">
|
||||
<p class="vertical-center mb-0" ng-switch-when="true"
|
||||
><pr-icon class="vertical-center" icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> At least a single limit must be set for the quota to be
|
||||
valid.
|
||||
</p>
|
||||
<p class="vertical-center mb-0" ng-switch-default></p>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- memory-limit-input -->
|
||||
<div class="form-group">
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left"> Memory </label>
|
||||
<div class="col-sm-3">
|
||||
<div class="form-group flex flex-row !mb-0">
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left"> Memory limit (MB) </label>
|
||||
<div class="col-xs-6">
|
||||
<slider
|
||||
model="$ctrl.formValues.MemoryLimit"
|
||||
floor="$ctrl.defaults.MemoryLimit"
|
||||
|
@ -99,7 +100,7 @@
|
|||
>
|
||||
</slider>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="col-sm-2 vertical-center">
|
||||
<input
|
||||
name="memory_limit"
|
||||
type="number"
|
||||
|
@ -111,29 +112,29 @@
|
|||
data-cy="k8sNamespaceCreate-memoryLimitInput"
|
||||
required
|
||||
/>
|
||||
<span class="help-block">
|
||||
<div class="form-group" ng-show="resourcePoolCreationForm.memory_limit.$invalid">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<div ng-messages="resourcePoolCreationForm.pool_name.$error">
|
||||
<p class="vertical-center"
|
||||
><pr-icon class="vertical-center" icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Value must be between
|
||||
{{ $ctrl.defaults.MemoryLimit }} and
|
||||
{{ $ctrl.state.sliderMaxMemory }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row w-full">
|
||||
<span class="col-sm-3 col-lg-2"></span>
|
||||
<span class="help-block col-sm-9 col-lg-10">
|
||||
<div ng-show="resourcePoolCreationForm.memory_limit.$invalid">
|
||||
<div class="small text-muted">
|
||||
<div ng-messages="resourcePoolCreationForm.pool_name.$error">
|
||||
<p class="vertical-center"
|
||||
><pr-icon class="vertical-center" icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Value must be between
|
||||
{{ $ctrl.defaults.MemoryLimit }} and
|
||||
{{ $ctrl.state.sliderMaxMemory }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p class="small text-muted"> Maximum memory usage (MB) </p>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<!-- !memory-limit-input -->
|
||||
<!-- cpu-limit-input -->
|
||||
<div class="form-group">
|
||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left"> CPU </label>
|
||||
<div class="col-sm-5">
|
||||
<div class="form-group flex flex-row">
|
||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left"> CPU limit </label>
|
||||
<div class="col-xs-8">
|
||||
<slider
|
||||
model="$ctrl.formValues.CpuLimit"
|
||||
floor="$ctrl.defaults.CpuLimit"
|
||||
|
@ -145,9 +146,6 @@
|
|||
>
|
||||
</slider>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p class="small text-muted"> Maximum CPU usage </p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !cpu-limit-input -->
|
||||
</div>
|
||||
|
@ -159,7 +157,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'" class="vertical-center"></pr-icon>
|
||||
You can set a quota on the amount of external load balancers that can be created inside this namespace. Set this quota to 0 to effectively disable the use of load
|
||||
balancers in this namespace.
|
||||
</span>
|
||||
|
@ -184,7 +182,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Quotas can be set on each storage option to prevent users from exceeding a specific threshold when deploying applications. You can set a quota to 0 to effectively
|
||||
prevent the usage of a specific storage option inside this namespace.
|
||||
</span>
|
||||
|
@ -211,7 +209,7 @@
|
|||
<div class="form-group" ng-if="$ctrl.formValues.IngressClasses.length > 0">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Enable and configure ingresses available to users when deploying applications.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -268,8 +266,8 @@
|
|||
data-cy="namespaceCreate-hostnameInput{{ ic.IngressClass.Name }}_{{ $index }}"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-sm-1 input-group input-group-sm" ng-if="$index > 0">
|
||||
<button class="btn btn-md btn-dangerlight btn-only-icon !h-[30px]" type="button" ng-click="$ctrl.removeHostname(ic, $index)">
|
||||
<div class="col-sm-1 input-group input-group-sm !pt-2" ng-if="$index > 0">
|
||||
<button class="btn btn-md btn-dangerlight btn-only-icon" type="button" ng-click="$ctrl.removeHostname(ic, $index)">
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -282,13 +280,13 @@
|
|||
"
|
||||
>
|
||||
<ng-messages for="resourcePoolCreationForm['hostname_' + ic.IngressClass.Name + '_' + $index].$error">
|
||||
<p ng-message="required"><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Hostname is required.</p>
|
||||
<p ng-message="pattern">
|
||||
<p class="vertical-center" ng-message="required"><pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Hostname is required.</p>
|
||||
<p class="vertical-center" ng-message="pattern">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
This field must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com').
|
||||
</p>
|
||||
</ng-messages>
|
||||
<p ng-if="$ctrl.state.duplicates.ingressHosts.refs[ic.IngressClass.Name][$index] !== undefined">
|
||||
<p class="vertical-center" ng-if="$ctrl.state.duplicates.ingressHosts.refs[ic.IngressClass.Name][$index] !== undefined">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> This hostname is already used.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -299,7 +297,7 @@
|
|||
<div ng-repeat-end class="form-group" ng-if="ic.Selected">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
You can specify a list of annotations that will be associated to the ingress.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -376,7 +374,7 @@
|
|||
</div>
|
||||
<div class="input-group input-group-sm col-sm-1">
|
||||
<button
|
||||
class="btn btn-sm btn-dangerlight btn-only-icon !h-[30px]"
|
||||
class="btn btn-md btn-dangerlight btn-only-icon"
|
||||
type="button"
|
||||
ng-click="$ctrl.removeAnnotation(ic, $index)"
|
||||
data-cy="namespaceCreate-deleteAnnotationButton{{ ic.IngressClass.Name }}"
|
||||
|
@ -395,17 +393,17 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="'primary'"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Define which registries can be used by users who have access to this namespace.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 col-lg-2 control-label text-left"> Select registries </label>
|
||||
<div class="col-sm-9 col-lg-4">
|
||||
<label class="col-sm-3 col-lg-2 control-label text-left !pt-0"> Select registries </label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<span class="small text-muted" ng-if="!$ctrl.registries.length && $ctrl.state.isAdmin">
|
||||
No registries available. Head over <a ui-sref="portainer.registries">registry view</a> to define container registry.
|
||||
No registries available. Head over to the <a ui-sref="portainer.registries">registry view</a> to define a container registry.
|
||||
</span>
|
||||
<span class="small text-muted" ng-if="!$ctrl.registries.length && !$ctrl.state.isAdmin">
|
||||
No registries available. Contact your administrator to create a container registry.
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
{{ path.Host ? path.Host : path.IP }}{{ path.Path }}
|
||||
</a>
|
||||
<span ng-if="path.ApplicationName !== '-'">
|
||||
<i class="fas fa-long-arrow-alt-right" style="margin: 2px"></i>
|
||||
<pr-icon icon="'svg-arrowright'" class-name="'m-0.5'"></pr-icon>
|
||||
<a ui-sref="kubernetes.applications.application({ name: path.ApplicationName, namespace: item.Namespace })">{{ path.ApplicationName }}</a>
|
||||
</span>
|
||||
<span class="label label-warning image-tag label-margins" ng-if="path.ApplicationName === '-'">unused</span>
|
||||
|
|
|
@ -77,9 +77,9 @@
|
|||
<div class="col-sm-12 form-section-title"> Resource limits </div>
|
||||
<div>
|
||||
<!-- memory-limit-input -->
|
||||
<div class="form-group">
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left" style="margin-top: 20px"> Memory limit </label>
|
||||
<div class="col-sm-3">
|
||||
<div class="form-group flex">
|
||||
<label for="memory-limit" class="col-sm-3 col-lg-2 control-label text-left vertical-center"> Memory limit (MB) </label>
|
||||
<div class="col-sm-6">
|
||||
<slider
|
||||
model="ctrl.formValues.MemoryLimit"
|
||||
floor="ctrl.ResourceQuotaDefaults.MemoryLimit"
|
||||
|
@ -88,7 +88,7 @@
|
|||
ng-if="ctrl.state.sliderMaxMemory"
|
||||
></slider>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="col-sm-2 vertical-center">
|
||||
<input
|
||||
name="memory_limit"
|
||||
type="number"
|
||||
|
@ -100,12 +100,10 @@
|
|||
required
|
||||
/>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<p class="small text-muted" style="margin-top: 7px"> Memory limit (<b>MB</b>) </p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="resourcePoolEditForm.memory_limit.$invalid">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<div class="col-sm-3 col-lg-2"></div>
|
||||
<div class="col-sm-8 small text-muted">
|
||||
<div ng-messages="resourcePoolEditForm.pool_name.$error">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon> Value must be between {{ ctrl.ResourceQuotaDefaults.MemoryLimit }} and
|
||||
|
@ -118,7 +116,7 @@
|
|||
<!-- cpu-limit-input -->
|
||||
<div class="form-group">
|
||||
<label for="cpu-limit" class="col-sm-3 col-lg-2 control-label text-left" style="margin-top: 20px"> CPU limit </label>
|
||||
<div class="col-sm-5">
|
||||
<div class="col-sm-8">
|
||||
<slider
|
||||
model="ctrl.formValues.CpuLimit"
|
||||
floor="ctrl.ResourceQuotaDefaults.CpuLimit"
|
||||
|
@ -128,9 +126,6 @@
|
|||
ng-if="ctrl.state.sliderMaxCpu"
|
||||
></slider>
|
||||
</div>
|
||||
<div class="col-sm-4" style="margin-top: 20px">
|
||||
<p class="small text-muted"> Maximum CPU usage </p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !cpu-limit-input -->
|
||||
</div>
|
||||
|
@ -141,7 +136,7 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
You can set a quota on the amount of external load balancers that can be created inside this namespace. Set this quota to 0 to effectively disable the use of
|
||||
load balancers in this namespace.
|
||||
</p>
|
||||
|
@ -174,7 +169,7 @@
|
|||
<div class="form-group" ng-if="ctrl.formValues.IngressClasses.length > 0">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Enable and configure ingresses available to users when deploying applications.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -220,7 +215,7 @@
|
|||
<div ng-repeat="item in ic.Hosts track by $index" style="margin-top: 2px">
|
||||
<div class="form-inline">
|
||||
<div class="col-sm-10 input-group input-group-sm" ng-class="{ striked: item.NeedsDeletion }">
|
||||
<span class="input-group-addon">Hostname</span>
|
||||
<span class="input-group-addon required">Hostname</span>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
|
@ -257,7 +252,7 @@
|
|||
'example.com').
|
||||
</p>
|
||||
</ng-messages>
|
||||
<p ng-if="item.Duplicate">
|
||||
<p class="vertical-center" ng-if="item.Duplicate">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
This hostname is already used.
|
||||
</p>
|
||||
|
@ -269,7 +264,7 @@
|
|||
<div ng-repeat-end class="form-group" ng-if="ic.Selected" style="margin-bottom: 20px">
|
||||
<div class="col-sm-12 small text-muted" style="margin-top: 5px">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
You can specify a list of annotations that will be associated to the ingress.
|
||||
</p>
|
||||
</div>
|
||||
|
@ -338,8 +333,8 @@
|
|||
/>
|
||||
</div>
|
||||
<div class="col-sm-1 input-group input-group-sm">
|
||||
<button class="btn btn-sm btn-dangerlight" type="button" ng-click="ctrl.removeAnnotation(ic, $index)">
|
||||
<pr-icon icon="'trash-2'" feather="true"></pr-icon>
|
||||
<button class="btn btn-md btn-dangerlight btn-only-icon" type="button" ng-click="ctrl.removeAnnotation(ic, $index)">
|
||||
<pr-icon icon="'trash-2'" feather="true" size="'md'"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -363,18 +358,18 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Define which registries can be used by users who have access to this namespace.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 col-lg-2 control-label text-left" style="padding-top: 0"> Select registries </label>
|
||||
<div class="col-sm-9 col-lg-4">
|
||||
<span class="small text-muted" ng-if="!ctrl.registries.length && ctrl.state.isAdmin">
|
||||
No registries available. Head over <a ui-sref="portainer.registries">registry view</a> to define container registry.
|
||||
<label class="col-sm-3 col-lg-2 control-label text-left !pt-0"> Select registries </label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<span class="small text-muted" ng-if="!ctrl.registries.length && ctrl.isAdmin">
|
||||
No registries available. Head over to the <a ui-sref="portainer.registries">registry view</a> to define a container registry.
|
||||
</span>
|
||||
<span class="small text-muted" ng-if="!ctrl.registries.length && !ctrl.state.isAdmin">
|
||||
<span class="small text-muted" ng-if="!ctrl.registries.length && !ctrl.isAdmin">
|
||||
No registries available. Contact your administrator to create a container registry.
|
||||
</span>
|
||||
<span
|
||||
|
@ -402,7 +397,7 @@
|
|||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small">
|
||||
<p class="vertical-center">
|
||||
<pr-icon icon="'info'" feather="true" mode="primary"></pr-icon>
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Quotas can be set on each storage option to prevent users from exceeding a specific threshold when deploying applications. You can set a quota to 0 to
|
||||
effectively prevent the usage of a specific storage option inside this namespace.
|
||||
</p>
|
||||
|
@ -433,7 +428,7 @@
|
|||
<button
|
||||
type="button"
|
||||
ng-if="!ctrl.isSystem"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0 !mr-1"
|
||||
ng-disabled="!resourcePoolEditForm.$valid || ctrl.isUpdateButtonDisabled()"
|
||||
ng-click="ctrl.updateResourcePool()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
|
@ -444,7 +439,7 @@
|
|||
<button
|
||||
ng-if="!ctrl.isDefaultNamespace"
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-light btn-sm !ml-0"
|
||||
ng-click="ctrl.markUnmarkAsSystem()"
|
||||
button-spinner="ctrl.state.actionInProgress"
|
||||
data-cy="k8sNamespaceEdit-markSystem"
|
||||
|
@ -459,9 +454,9 @@
|
|||
</uib-tab>
|
||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||
<uib-tab-heading class="vertical-center">
|
||||
<pr-icon icon="'file-text'" feather="true"></pr-icon> Events
|
||||
<pr-icon icon="'svg-clockrewind'"></pr-icon> Events
|
||||
<div ng-if="ctrl.hasEventWarnings()">
|
||||
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px"></i>
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'" class-name="'mr-0.5'"></pr-icon>
|
||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||
</div>
|
||||
</uib-tab-heading>
|
||||
|
@ -478,7 +473,7 @@
|
|||
</uib-tab>
|
||||
<uib-tab index="2" ng-if="ctrl.pool.Yaml" select="ctrl.showEditor()" classes="btn-sm">
|
||||
<uib-tab-heading class="vertical-center"><pr-icon icon="'code'" feather="true"></pr-icon> YAML </uib-tab-heading>
|
||||
<div style="padding-right: 25px" ng-if="ctrl.state.showEditorTab">
|
||||
<div class="px-5" ng-if="ctrl.state.showEditorTab">
|
||||
<kubernetes-yaml-inspector key="resource-pool-yaml" data="ctrl.pool.Yaml"></kubernetes-yaml-inspector>
|
||||
</div>
|
||||
</uib-tab>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
endpoint="ctrl.endpoint"
|
||||
dataset="ctrl.resourcePools"
|
||||
table-key="kubernetes.resourcePools"
|
||||
order-by="Namespace.Name"
|
||||
order-by="Name"
|
||||
remove-action="ctrl.removeAction"
|
||||
refresh-callback="ctrl.getResourcePools"
|
||||
endpoint="ctrl.endpoint"
|
||||
|
|
|
@ -14,7 +14,7 @@ ctrl.state.transition.name,
|
|||
|
||||
<kubernetes-view-loading view-ready="ctrl.state.viewReady"></kubernetes-view-loading>
|
||||
|
||||
<div ng-if="ctrl.state.viewReady" style="height: 100%">
|
||||
<div ng-if="ctrl.state.viewReady">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
|
@ -23,19 +23,22 @@ ctrl.state.transition.name,
|
|||
<div class="col-sm-12 form-section-title"> Actions </div>
|
||||
<!-- auto-refresh -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">
|
||||
Auto-refresh
|
||||
<portainer-tooltip message="'Automatically refresh logs every 30 seconds'"></portainer-tooltip>
|
||||
<label class="control-label text-left col-sm-3 col-lg-2 vertical-center !py-2">
|
||||
Auto-refresh
|
||||
<portainer-tooltip message="'Automatically refresh logs every 30 seconds'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-8 col-sm-9 vertical-center">
|
||||
<label class="switch col-sm-8 col-sm-9 vertical-center !mb-0">
|
||||
<input type="checkbox" ng-model="ctrl.state.autoRefresh" ng-change="ctrl.updateAutoRefresh()" />
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
<label class="switch" style="margin-left: 20px"> <input type="checkbox" ng-model="ctrl.state.autoRefresh" ng-change="ctrl.updateAutoRefresh()" /><i></i> </label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !auto-refresh -->
|
||||
<!-- search -->
|
||||
<div class="form-group">
|
||||
<label for="logs_search" class="col-sm-1 control-label text-left"> Search </label>
|
||||
<div class="col-sm-11">
|
||||
<label for="logs_search" class="col-sm-3 col-lg-2 control-label text-left"> Search </label>
|
||||
<div class="col-sm-8 col-lg-9">
|
||||
<input
|
||||
class="form-control"
|
||||
type="text"
|
||||
|
@ -51,7 +54,10 @@ ctrl.state.transition.name,
|
|||
<!-- actions -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<button class="btn btn-primary btn-sm" type="button" ng-click="ctrl.downloadLogs()" style="margin-left: 0"><i class="fa fa-download"></i> Download logs</button>
|
||||
<button class="btn btn-primary btn-sm !ml-0 vertical-center" type="button" ng-click="ctrl.downloadLogs()">
|
||||
<pr-icon icon="'download'" feather="true"></pr-icon>
|
||||
Download logs
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !actions -->
|
||||
|
@ -61,8 +67,8 @@ ctrl.state.transition.name,
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row" style="height: 54%">
|
||||
<div class="col-sm-12" style="height: 100%">
|
||||
<div class="row">
|
||||
<div class="col-sm-12 h-[max(400px,calc(100vh-380px))]">
|
||||
<pre
|
||||
class="log_viewer"
|
||||
><div ng-repeat="line in ctrl.state.filteredLogs = (ctrl.stackLogs | filter:ctrl.state.search) track by $index" class="line" ng-if="line"><p class="inner_line"><span ng-style="{'color': line.Color, 'font-weight': 'bold'};">{{ line.AppName }}</span> {{ line.Line }}</p></div><div ng-if="ctrl.stackLogs.length && !ctrl.state.filteredLogs.length" class="line"><p class="inner_line">No log line matching the '{{ ctrl.state.search }}' filter</p></div><div ng-if="ctrl.stackLogs.length === 0" class="line"><p class="inner_line">No logs available</p></div></pre>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<div class="flex justify-start form-section-title interactive" ng-click="$ctrl.toggleSummary()" ng-if="$ctrl.state.resources.length > 0">
|
||||
<pr-icon icon="$ctrl.state.expandedTemplate ? 'chevron-down' : 'chevron-right'" feather="true" class="!mr-1 vertical-center pb-1"></pr-icon>
|
||||
<div class="flex justify-start items-center form-section-title interactive" ng-click="$ctrl.toggleSummary()" ng-if="$ctrl.state.resources.length > 0">
|
||||
<pr-icon icon="$ctrl.state.expandedTemplate ? 'chevron-down' : 'chevron-right'" feather="true" class="!mr-1 vertical-center"></pr-icon>
|
||||
Summary
|
||||
</div>
|
||||
|
||||
<div class="form-group" ng-if="$ctrl.state.expandedTemplate">
|
||||
<div class="col-sm-12 small text-muted">
|
||||
<pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon>
|
||||
<div class="col-sm-12 small text-muted vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
Portainer will execute the following Kubernetes actions.
|
||||
</div>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class="toolBar vertical-center !gap-x-5 !gap-y-1 flex-wrap !p-0 w-full">
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<div class="widget-icon space-right">
|
||||
<pr-icon icon="'database'" feather="true"></pr-icon>
|
||||
<pr-icon icon="'hard-drive'" feather="true"></pr-icon>
|
||||
</div>
|
||||
Storage
|
||||
</div>
|
||||
|
|
|
@ -142,7 +142,7 @@
|
|||
|
||||
<uib-tab index="1" classes="btn-sm" select="ctrl.selectTab(1)">
|
||||
<uib-tab-heading class="vertical-center" data-cy="k8sVolDetail-volEventsTab">
|
||||
<pr-icon icon="'file-text'" feather="true"></pr-icon> Events
|
||||
<pr-icon icon="'svg-clockrewind'" feather="true"></pr-icon> Events
|
||||
<div ng-if="ctrl.hasEventWarnings()">
|
||||
<pr-icon icon="'alert-triangle'" feather="true" mode="'warning'"></pr-icon>
|
||||
{{ ctrl.state.eventWarningCount }} warning(s)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<!-- !access-control-switch -->
|
||||
<!-- restricted-access -->
|
||||
<div class="form-group" ng-if="$ctrl.formData.AccessControlEnabled" style="margin-bottom: 0">
|
||||
<div class="boxselector_wrapper">
|
||||
<div class="boxselector_wrapper px-[15px]">
|
||||
<div ng-if="$ctrl.isAdmin">
|
||||
<input type="radio" id="access_administrators" ng-model="$ctrl.formData.Ownership" value="administrators" />
|
||||
<label for="access_administrators" data-cy="portainer-selectAdminAccess">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<ng-form name="commonCustomTemplateForm">
|
||||
<!-- title-input -->
|
||||
<div class="form-group mb-0">
|
||||
<label for="template_title" class="col-sm-3 col-lg-2 control-label text-left"> Title </label>
|
||||
<label for="template_title" class="col-sm-3 col-lg-2 control-label text-left required"> Title </label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -33,7 +33,7 @@
|
|||
|
||||
<!-- description-input -->
|
||||
<div class="form-group mb-0">
|
||||
<label for="description" class="col-sm-3 col-lg-2 control-label text-left">Description</label>
|
||||
<label for="description" class="col-sm-3 col-lg-2 control-label text-left required">Description</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" id="description" ng-model="$ctrl.formValues.Description" name="description" required />
|
||||
<span class="help-block">
|
||||
|
|
|
@ -12,8 +12,7 @@
|
|||
<option value="" label="Select a Custom template" disabled selected="selected"> </option>
|
||||
</select>
|
||||
<span class="small text-muted pt-[7px]" ng-if="!$ctrl.templates.length">
|
||||
No custom templates are available. Head over to the <a class="text-blue-8 hover:underline hover:text-blue-8" ui-state="$ctrl.newTemplatePath">custom template view</a> to
|
||||
create one.
|
||||
No custom templates are available. Head over to the <a class="hyperlink" ui-state="$ctrl.newTemplatePath">custom template view</a> to create one.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
<rd-widget>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<div class="toolBar vertical-center !gap-x-5 !gap-y-1 flex-wrap">
|
||||
<rd-widget-header icon="{{ $ctrl.titleIcon }}" feather-icon="true" title-text="Custom Templates" class="!flex-auto !mr-0" parent-classes="!p-0"></rd-widget-header>
|
||||
<div class="toolBarTitle vertical-center">
|
||||
<pr-icon icon="$ctrl.titleIcon" feather="true" class-name="'icon-nested-blue'" mode="'primary'"></pr-icon>
|
||||
Custom Templates
|
||||
</div>
|
||||
<div class="searchBar vertical-center !mr-0">
|
||||
<pr-icon icon="'search'" feather="true" class-name="'searchIcon'"></pr-icon>
|
||||
<input
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
overflow: auto;
|
||||
padding: 20px;
|
||||
font-size: 16px;
|
||||
border-radius: 8px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -99,9 +99,11 @@
|
|||
{{ item.URL }}
|
||||
</td>
|
||||
<td>
|
||||
<a ng-if="$ctrl.canManageAccess(item)" ng-click="$ctrl.redirectToManageAccess(item)"> <pr-icon icon="'users'" feather="true"></pr-icon> Manage access </a>
|
||||
<a class="vertical-center" ng-if="$ctrl.canManageAccess(item)" ng-click="$ctrl.redirectToManageAccess(item)">
|
||||
<pr-icon icon="'users'" feather="true"></pr-icon> Manage access
|
||||
</a>
|
||||
<be-feature-indicator feature="$ctrl.limitedFeature" ng-if="$ctrl.canBrowse(item)">
|
||||
<span class="text-muted space-left" style="padding-right: 5px"> <pr-icon icon="'search'" feather="true" class-name="'searchIcon'"></pr-icon> Browse </span>
|
||||
<span class="text-muted space-left" style="padding-right: 5px"> <pr-icon icon="'search'" feather="true"></pr-icon> Browse </span>
|
||||
</be-feature-indicator>
|
||||
|
||||
<span ng-if="!$ctrl.canBrowse(item) && !$ctrl.canManageAccess(item)"> - </span>
|
||||
|
|
|
@ -11,6 +11,7 @@ export const webEditorForm = {
|
|||
value: '<',
|
||||
readOnly: '<',
|
||||
onChange: '<',
|
||||
hideTitle: '<',
|
||||
},
|
||||
|
||||
transclude: {
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<ng-form name="$ctrl.webEditorForm">
|
||||
<div class="web-editor">
|
||||
<div class="col-sm-12 form-section-title"> Web editor </div>
|
||||
<div class="form-group col-sm-12 col-lg-12">
|
||||
<div class="text-muted small" ng-transclude="description"> </div>
|
||||
</div>
|
||||
<div class="web-editor overflow-auto">
|
||||
<div ng-if="!$ctrl.hideTitle" class="col-sm-12 form-section-title">Web editor</div>
|
||||
<div class="trancluded-item form-group col-sm-12 col-lg-12 text-muted small" ng-transclude="description"></div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12 col-lg-12">
|
||||
<code-editor
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="form-group col-sm-12">
|
||||
<div class="form-inline mt-3">
|
||||
<div class="input-group col-sm-5 input-group-sm">
|
||||
<span class="input-group-addon">path</span>
|
||||
<span class="input-group-addon required">path</span>
|
||||
<input
|
||||
type="text"
|
||||
name="name"
|
||||
|
@ -13,7 +13,7 @@
|
|||
required
|
||||
/>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-light btn-only-icon" type="button" ng-click="$ctrl.removeValue()" title="Remove">
|
||||
<button class="btn btn-sm btn-dangerlight btn-only-icon" type="button" ng-click="$ctrl.removeValue()" title="Remove">
|
||||
<pr-icon icon="'trash-2'" size="'md'" feather="true"></pr-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</div>
|
||||
<div ng-if="$ctrl.model.RepositoryAuthentication" class="row">
|
||||
<div class="form-group">
|
||||
<label for="repository_username" class="col-lg-2 col-sm-3 control-label text-left"> Username </label>
|
||||
<label for="repository_username" class="col-lg-2 col-sm-3 control-label text-left required"> Username </label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -30,9 +30,9 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="repository_password" class="col-lg-2 col-sm-3 control-label text-left">
|
||||
Personal Access Token
|
||||
<div class="form-group flex">
|
||||
<label for="repository_password" class="col-lg-2 col-sm-3 control-label text-left !pt-0">
|
||||
<div class="required"> Personal Access Token </div>
|
||||
<portainer-tooltip message="'Provide a personal access token or password'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-8">
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="small" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<div class="small vertical-center" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon>
|
||||
<span class="text-muted">Any changes to this stack or application made locally in Portainer will be overridden, which may cause service interruption.</span>
|
||||
</div>
|
||||
|
@ -35,8 +35,8 @@
|
|||
<label for="repository_mechanism" class="col-sm-3 col-lg-2 control-label text-left"> Webhook </label>
|
||||
<div class="col-sm-8">
|
||||
<span class="text-muted"> {{ $ctrl.model.RepositoryWebhookURL | truncatelr }} </span>
|
||||
<button type="button" class="btn btn-sm btn-light btn-sm space-left" ng-if="$ctrl.model.RepositoryWebhookURL" ng-click="$ctrl.copyWebhook()">
|
||||
<span><pr-icon icon="'copy'" size="'sm'" feather="true"></pr-icon> Copy link</span>
|
||||
<button type="button" class="btn btn-sm btn-light btn-sm space-left vertical-center" ng-if="$ctrl.model.RepositoryWebhookURL" ng-click="$ctrl.copyWebhook()">
|
||||
<pr-icon icon="'copy'" size="'sm'" feather="true"></pr-icon> Copy link
|
||||
</button>
|
||||
<span>
|
||||
<pr-icon icon="'check'" mode="'success'" feather="true" style="display: none"></pr-icon>
|
||||
|
@ -44,7 +44,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-if="$ctrl.model.RepositoryAutomaticUpdates && $ctrl.model.RepositoryMechanism === 'Interval'">
|
||||
<label for="repository_fetch_interval" class="col-sm-3 col-lg-2 control-label text-left"> Fetch interval </label>
|
||||
<label for="repository_fetch_interval" class="col-sm-3 col-lg-2 control-label text-left required"> Fetch interval </label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
|
@ -94,11 +94,11 @@
|
|||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="small" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<div class="small vertical-center" ng-if="$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
<span class="text-muted">When enabled, enforces automatic deployment at each interval or webhook invocation.</span>
|
||||
</div>
|
||||
<div class="small" ng-if="!$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<div class="small vertical-center" ng-if="!$ctrl.model.RepositoryAutomaticUpdates">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
<span class="text-muted">When enabled, updates from the git repository will occur automatically at an interval or webhook.</span>
|
||||
</div>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<ng-form name="pathForm">
|
||||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small"
|
||||
><pr-icon icon="'alert-circle'" mode="'primary'" feather="true"></pr-icon> Indicate the path to the {{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} file from
|
||||
the root of your repository (requires a yaml, yml, json, or hcl file extension)
|
||||
<span class="col-sm-12 text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon> Indicate the path to the {{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} file from the root
|
||||
of your repository (requires a yaml, yml, json, or hcl file extension)
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="stack_repository_path" class="col-lg-2 col-sm-3 control-label text-left">{{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} path</label>
|
||||
<label for="stack_repository_path" class="col-lg-2 col-sm-3 control-label text-left required">{{ $ctrl.deployMethod == 'compose' ? 'Compose' : 'Manifest' }} path</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
<div class="form-group">
|
||||
<span class="col-sm-12 text-muted small">
|
||||
Specify a reference of the repository using the following syntax: branches with <code>refs/heads/branch_name</code> or tags with <code>refs/tags/tag_name</code>. If not
|
||||
specified, will use the default <code>HEAD</code> reference normally the <code>master</code> branch.
|
||||
<span class="col-sm-12 text-muted small vertical-center">
|
||||
<pr-icon icon="'info'" mode="'primary'" feather="true"></pr-icon>
|
||||
<span>
|
||||
Specify a reference of the repository using the following syntax: branches with <code>refs/heads/branch_name</code> or tags with <code>refs/tags/tag_name</code>. If not
|
||||
specified, will use the default <code>HEAD</code> reference normally the <code>master</code> branch.
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<span class="col-sm-12 text-muted small"> You can use the URL of a git repository. </span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="stack_repository_url" class="col-lg-2 col-sm-3 control-label text-left">Repository URL</label>
|
||||
<label for="stack_repository_url" class="col-lg-2 col-sm-3 control-label text-left required">Repository URL</label>
|
||||
<div class="col-sm-8">
|
||||
<input
|
||||
type="text"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="row" ng-if="$ctrl.registry">
|
||||
<div class="col-lg-12 col-md-12 col-xs-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="svg-plug" title-text="Registry"></rd-widget-header>
|
||||
<rd-widget-header icon="radio" feather-icon="true" title-text="Registry"></rd-widget-header>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
<div ng-class="{ 'blocklist-item--selected': $ctrl.model.Selected }" class="blocklist-item template-item !mr-0 !my-0" ng-click="$ctrl.onSelect($ctrl.model)">
|
||||
<div class="blocklist-item-box">
|
||||
<!-- template-image -->
|
||||
<div ng-if="$ctrl.model.Logo" class="vertical-center justify-center">
|
||||
<img class="blocklist-item-logo" ng-src="{{ $ctrl.model.Logo }}" />
|
||||
</div>
|
||||
<div class="blocklist-item-logo vertical-center justify-center" ng-if="!$ctrl.model.Logo">
|
||||
<pr-icon icon="'svg-rocket'" class-name="'[&>*]:!h-10 [&>*]:!w-auto [&>*>path]:stroke-blue-8'" mode="'primary'"></pr-icon>
|
||||
<div class="vertical-center justify-center min-w-[56px]">
|
||||
<fallback-image
|
||||
src="$ctrl.model.Logo"
|
||||
fallback-icon="'svg-rocket'"
|
||||
class-name="'blocklist-item-logo'"
|
||||
fallback-class-name="'!h-14 !w-14 [&>*]:!h-8 [&>*]:!w-auto icon-nested-blue'"
|
||||
fallback-mode="'primary'"
|
||||
></fallback-image>
|
||||
</div>
|
||||
<!-- !template-image -->
|
||||
<!-- template-details -->
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
<div class="col-sm-12">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
class="btn btn-primary btn-sm !ml-0"
|
||||
ng-disabled="$ctrl.actionInProgress || customTemplateForm.$invalid
|
||||
|| !$ctrl.formValues.Title
|
||||
|| !$ctrl.formValues.FileContent
|
||||
|
|
|
@ -17,6 +17,7 @@ import checked from '@/assets/ico/checked.svg?c';
|
|||
import circlenotch from '@/assets/ico/circle-notch.svg?c';
|
||||
import clockrewind from '@/assets/ico/clock-rewind.svg?c';
|
||||
import compress from '@/assets/ico/compress.svg?c';
|
||||
import cubes from '@/assets/ico/cubes.svg?c';
|
||||
import custom from '@/assets/ico/custom.svg?c';
|
||||
import dataflow from '@/assets/ico/dataflow-1.svg?c';
|
||||
import dataflow2 from '@/assets/ico/dataflow-2.svg?c';
|
||||
|
@ -96,6 +97,7 @@ export const SvgIcons = {
|
|||
circlenotch,
|
||||
clockrewind,
|
||||
compress,
|
||||
cubes,
|
||||
custom,
|
||||
expand,
|
||||
filecode,
|
||||
|
|
|
@ -6,3 +6,13 @@
|
|||
.inner-datatable table thead {
|
||||
border-top: none !important;
|
||||
}
|
||||
|
||||
.inner-datatable tr > th:first-child,
|
||||
.inner-datatable tr > td:first-child {
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.inner-datatable tr > th:last-child,
|
||||
.inner-datatable tr > td:last-child {
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
|
|
@ -6,14 +6,20 @@
|
|||
width: 100vw;
|
||||
z-index: 1000;
|
||||
height: 495px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
|
||||
.root.minimized {
|
||||
height: 35px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 35px;
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
@ -21,11 +27,11 @@
|
|||
background: rgb(245, 245, 245);
|
||||
border-top: 1px solid rgb(190, 190, 190);
|
||||
|
||||
padding: 0 30px;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
|
@ -36,5 +42,6 @@
|
|||
|
||||
.terminal-container .loading-message {
|
||||
position: fixed;
|
||||
padding: 10px 16px 0px 16px;
|
||||
color: #fff;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import { EnvironmentId } from '@/portainer/environments/types';
|
|||
import { error as notifyError } from '@/portainer/services/notifications';
|
||||
import { useLocalStorage } from '@/portainer/hooks/useLocalStorage';
|
||||
|
||||
import { Icon } from '@@/Icon';
|
||||
import { Button } from '@@/buttons';
|
||||
|
||||
import styles from './KubectlShell.module.css';
|
||||
|
@ -125,27 +126,26 @@ export function KubeCtlShell({ environmentId, onClose }: Props) {
|
|||
return (
|
||||
<div className={clsx(styles.root, { [styles.minimized]: shell.minimized })}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.title}>
|
||||
<i className="fas fa-terminal space-right" />
|
||||
<div className={clsx(styles.title, 'vertical-center')}>
|
||||
<Icon icon="terminal" feather />
|
||||
kubectl shell
|
||||
</div>
|
||||
<div className={clsx(styles.actions, 'space-x-8')}>
|
||||
<Button color="link" onClick={clearScreen}>
|
||||
<i className="fas fa-redo-alt" data-cy="k8sShell-refreshButton" />
|
||||
<Icon icon="rotate-cw" feather size="md" />
|
||||
</Button>
|
||||
<Button color="link" onClick={toggleMinimize}>
|
||||
<i
|
||||
className={clsx(
|
||||
'fas',
|
||||
shell.minimized ? 'fa-window-restore' : 'fa-window-minimize'
|
||||
)}
|
||||
<Icon
|
||||
icon={shell.minimized ? 'maximize-2' : 'minimize-2'}
|
||||
feather
|
||||
size="md"
|
||||
data-cy={
|
||||
shell.minimized ? 'k8sShell-restore' : 'k8sShell-minimise'
|
||||
}
|
||||
/>
|
||||
</Button>
|
||||
<Button color="link" onClick={handleClose}>
|
||||
<i className="fas fa-times" data-cy="k8sShell-closeButton" />
|
||||
<Icon icon="x" feather size="md" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.root {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
margin: -5px auto -8px auto;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import clsx from 'clsx';
|
||||
import { useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
|
@ -5,6 +6,7 @@ import { EnvironmentId } from '@/portainer/environments/types';
|
|||
import { useAnalytics } from '@/angulartics.matomo/analytics-services';
|
||||
|
||||
import { Button } from '@@/buttons';
|
||||
import { Icon } from '@@/Icon';
|
||||
|
||||
import { KubeCtlShell } from './KubectlShell';
|
||||
import styles from './KubectlShellButton.module.css';
|
||||
|
@ -19,13 +21,14 @@ export function KubectlShellButton({ environmentId }: Props) {
|
|||
<>
|
||||
<Button
|
||||
color="primary"
|
||||
size="xsmall"
|
||||
size="small"
|
||||
disabled={open}
|
||||
data-cy="k8sSidebar-shellButton"
|
||||
onClick={() => handleOpen()}
|
||||
className={styles.root}
|
||||
className={clsx(styles.root, '!flex')}
|
||||
>
|
||||
<i className="fa fa-terminal space-right" /> kubectl shell
|
||||
<Icon icon="terminal" feather className="vertical-center" size="md" />{' '}
|
||||
kubectl shell
|
||||
</Button>
|
||||
|
||||
{open &&
|
||||
|
|
Loading…
Reference in New Issue