mirror of
https://github.com/portainer/portainer.git
synced 2025-08-04 21:35:23 +02:00
refactor(app): details widget migration [EE-5352] (#8886)
This commit is contained in:
parent
fdd79cece8
commit
af77e33993
57 changed files with 2046 additions and 1079 deletions
|
@ -86,308 +86,7 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<div ng-if="!ctrl.isSystemNamespace()" class="mb-4 flex items-center gap-1">
|
||||
<button
|
||||
ng-if="!ctrl.isExternalApplication()"
|
||||
type="button"
|
||||
class="btn btn-sm btn-light vertical-center ml-2"
|
||||
ui-sref="kubernetes.applications.application.edit"
|
||||
style="margin-left: 0"
|
||||
data-cy="k8sAppDetail-editAppButton"
|
||||
>
|
||||
<pr-icon icon="'pencil'" class="mr-1"></pr-icon>{{ ctrl.stack.IsComposeFormat ? 'View this application' : 'Edit this application' }}
|
||||
</button>
|
||||
<button
|
||||
authorization="K8sApplicationDetailsW"
|
||||
ng-if="ctrl.isExternalApplication()"
|
||||
type="button"
|
||||
class="btn btn-sm btn-light ml-2"
|
||||
ui-sref="kubernetes.applications.application.edit"
|
||||
data-cy="k8sAppDetail-editAppButton"
|
||||
>
|
||||
<pr-icon icon="'pencil'" class-name="'mr-1'"></pr-icon>Edit external application
|
||||
</button>
|
||||
<be-teaser-button
|
||||
icon="'refresh-cw'"
|
||||
feature-id="ctrl.limitedFeature"
|
||||
message="'A rolling restart of the application is performed.'"
|
||||
heading="'Rolling restart'"
|
||||
button-text="'Rolling restart'"
|
||||
class-name="'be-tooltip-teaser'"
|
||||
className="'be-tooltip-teaser'"
|
||||
></be-teaser-button>
|
||||
<button
|
||||
ng-if="ctrl.application.ApplicationType !== ctrl.KubernetesApplicationTypes.POD"
|
||||
type="button"
|
||||
class="btn btn-sm btn-light ml-2"
|
||||
ng-click="ctrl.redeployApplication()"
|
||||
data-cy="k8sAppDetail-redeployButton"
|
||||
>
|
||||
<pr-icon icon="'rotate-cw'" class="'mr-1'"></pr-icon>Redeploy
|
||||
</button>
|
||||
<button
|
||||
ng-if="!ctrl.isExternalApplication()"
|
||||
type="button"
|
||||
class="btn btn-sm btn-light"
|
||||
ng-click="ctrl.rollbackApplication()"
|
||||
ng-disabled="ctrl.application.Revisions.length < 2 || ctrl.state.appType !== ctrl.KubernetesDeploymentTypes.APPLICATION_FORM"
|
||||
data-cy="k8sAppDetail-rollbackButton"
|
||||
>
|
||||
<pr-icon icon="'rotate-ccw'" class="mr-1"></pr-icon>Rollback to previous configuration
|
||||
</button>
|
||||
<a
|
||||
ng-if="ctrl.isStack() && ctrl.stackFileContent"
|
||||
class="btn btn-sm btn-primary space-left"
|
||||
ui-sref="kubernetes.templates.custom.new({fileContent: ctrl.stackFileContent})"
|
||||
>
|
||||
<pr-icon icon="'plus'" class="mr-1"></pr-icon>Create template from application
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- ACCESSING APPLICATION -->
|
||||
<div class="text-muted" style="margin-bottom: 15px"> <pr-icon icon="'external-link'" class="mr-1"></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="'info'" mode="'primary'" class="mr-1"></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="'info'" mode="'primary'" class="mr-1"></pr-icon>This application is exposed through service(s) as below: </p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- table -->
|
||||
<kubernetes-application-services-table
|
||||
services="ctrl.application.Services"
|
||||
application="ctrl.application"
|
||||
public-url="ctrl.state.publicUrl"
|
||||
></kubernetes-application-services-table>
|
||||
<!-- table -->
|
||||
|
||||
<!-- table -->
|
||||
<kubernetes-application-ingress-table application="ctrl.application" public-url="ctrl.state.publicUrl"></kubernetes-application-ingress-table>
|
||||
<!-- table -->
|
||||
</div>
|
||||
<!-- !ACCESSING APPLICATION -->
|
||||
<!-- AUTO SCALING -->
|
||||
<div class="text-muted" style="margin-bottom: 15px"> <pr-icon icon="'move'" class="mr-1"></pr-icon>Auto-scaling </div>
|
||||
|
||||
<div class="small text-muted" ng-if="!ctrl.application.AutoScaler" style="margin-bottom: 15px">
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1"></pr-icon>
|
||||
This application does not have an autoscaling policy defined.
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.application.AutoScaler">
|
||||
<div style="margin-top: 15px; width: 50%">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr class="text-muted">
|
||||
<td style="width: 33%">Minimum instances</td>
|
||||
<td style="width: 33%">Maximum instances</td>
|
||||
<td style="width: 33%">
|
||||
Target CPU usage
|
||||
<portainer-tooltip message="'The autoscaler will ensure enough instances are running to maintain an average CPU usage across all instances.'">
|
||||
</portainer-tooltip>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td data-cy="k8sAppDetail-minReplicas">{{ ctrl.application.AutoScaler.MinReplicas }}</td>
|
||||
<td data-cy="k8sAppDetail-maxReplicas">{{ ctrl.application.AutoScaler.MaxReplicas }}</td>
|
||||
<td data-cy="k8sAppDetail-targetCPU">{{ ctrl.application.AutoScaler.TargetCPUUtilization }}%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !AUTO SCALING -->
|
||||
|
||||
<!-- CONFIGURATIONS -->
|
||||
<div class="text-muted" style="margin-bottom: 15px; margin-top: 25px">
|
||||
<pr-icon icon="'file'" class="mr-1"></pr-icon>
|
||||
ConfigMap or Secret
|
||||
</div>
|
||||
|
||||
<div class="small text-muted" ng-if="!ctrl.application.Env.length > 0 && !ctrl.hasVolumeConfiguration()" style="margin-bottom: 15px">
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1"></pr-icon>
|
||||
This application is not using any environment variable, ConfigMap or Secret.
|
||||
</div>
|
||||
|
||||
<table class="table" ng-if="ctrl.application.Env.length > 0">
|
||||
<tr class="text-muted">
|
||||
<td style="width: 25%">Container</td>
|
||||
<td style="width: 25%">Environment variable</td>
|
||||
<td style="width: 25%">Value</td>
|
||||
<td style="width: 25%">ConfigMap or Secret</td>
|
||||
</tr>
|
||||
<tbody ng-repeat="container in ctrl.application.Containers" style="border-top: 0">
|
||||
<tr ng-repeat="envvar in container.Env | orderBy: 'name'">
|
||||
<td data-cy="k8sAppDetail-containerName">
|
||||
{{ container.Name }}
|
||||
<span ng-if="container.Type === ctrl.KubernetesPodContainerTypes.INIT">
|
||||
<pr-icon icon="'asterisk'"></pr-icon>
|
||||
{{ envvar.valueFrom.fieldRef.fieldPath }} (<a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" target="_blank">init container</a
|
||||
>)</span
|
||||
>
|
||||
</td>
|
||||
<td data-cy="k8sAppDetail-envVarName">{{ envvar.name }}</td>
|
||||
<td>
|
||||
<span ng-if="envvar.value" data-cy="k8sAppDetail-envVarValue">{{ envvar.value }}</span>
|
||||
<span ng-if="envvar.valueFrom.configMapKeyRef" data-cy="k8sAppDetail-envVarValue"
|
||||
><pr-icon icon="'key'" class="mr-1"></pr-icon>{{ envvar.valueFrom.configMapKeyRef.key }}</span
|
||||
>
|
||||
<span ng-if="envvar.valueFrom.secretKeyRef" data-cy="k8sAppDetail-envVarValue"
|
||||
><pr-icon icon="'key'" class="mr-1"></pr-icon>{{ envvar.valueFrom.secretKeyRef.key }}</span
|
||||
>
|
||||
<span ng-if="envvar.valueFrom.fieldRef" data-cy="k8sAppDetail-envVarValue"
|
||||
><pr-icon icon="'asterisk'"></pr-icon> {{ envvar.valueFrom.fieldRef.fieldPath }} (<a
|
||||
href="https://kubernetes.io/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/#capabilities-of-the-downward-api"
|
||||
target="_blank"
|
||||
>downward API</a
|
||||
>)</span
|
||||
>
|
||||
<span ng-if="!envvar.value && !envvar.valueFrom.secretKeyRef && !envvar.valueFrom.configMapKeyRef && !envvar.valueFrom.fieldRef">-</span>
|
||||
</td>
|
||||
<td>
|
||||
<span ng-if="envvar.value || envvar.valueFrom.fieldRef || (!envvar.valueFrom.secretKeyRef && !envvar.valueFrom.configMapKeyRef)">-</span>
|
||||
<span ng-if="envvar.valueFrom.configMapKeyRef" data-cy="k8sAppDetail-configName"
|
||||
><a ui-sref="kubernetes.configurations.configuration({ name: envvar.valueFrom.configMapKeyRef.name, namespace: ctrl.application.ResourcePool })"
|
||||
><pr-icon icon="'file'" class="mr-1"></pr-icon>{{ envvar.valueFrom.configMapKeyRef.name }}</a
|
||||
></span
|
||||
>
|
||||
<span ng-if="envvar.valueFrom.secretKeyRef" data-cy="k8sAppDetail-configName"
|
||||
><a ui-sref="kubernetes.configurations.configuration({ name: envvar.valueFrom.secretKeyRef.name, namespace: ctrl.application.ResourcePool })"
|
||||
><pr-icon icon="'file'" class="mr-1"></pr-icon>{{ envvar.valueFrom.secretKeyRef.name }}</a
|
||||
></span
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="table" ng-if="ctrl.hasVolumeConfiguration()">
|
||||
<tr class="text-muted">
|
||||
<td style="width: 25%">Container</td>
|
||||
<td style="width: 25%">Configuration path</td>
|
||||
<td style="width: 25%">Value</td>
|
||||
<td style="width: 25%">Configuration</td>
|
||||
</tr>
|
||||
<tbody ng-repeat="container in ctrl.application.Containers" style="border-top: 0">
|
||||
<tr ng-repeat="volume in container.ConfigurationVolumes track by $index" style="border-top: 0">
|
||||
<td>
|
||||
{{ container.Name }}
|
||||
<span ng-if="container.Type === ctrl.KubernetesPodContainerTypes.INIT"
|
||||
><pr-icon icon="'asterisk'"></pr-icon> {{ envvar.valueFrom.fieldRef.fieldPath }} (<a
|
||||
href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/"
|
||||
target="_blank"
|
||||
>init container</a
|
||||
>)</span
|
||||
>
|
||||
</td>
|
||||
<td>
|
||||
{{ volume.fileMountPath }}
|
||||
</td>
|
||||
<td>
|
||||
<pr-icon icon="'plus'" class="mr-1" ng-if="volume.configurationKey"></pr-icon>
|
||||
{{ volume.configurationKey ? volume.configurationKey : '-' }}
|
||||
</td>
|
||||
<td>
|
||||
<a ui-sref="kubernetes.configurations.configuration({ name: volume.configurationName, namespace: ctrl.application.ResourcePool })"
|
||||
><pr-icon icon="'plus'" class="mr-1"></pr-icon>{{ volume.configurationName }}</a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- !CONFIGURATIONS -->
|
||||
|
||||
<!-- DATA PERSISTENCE -->
|
||||
<div class="text-muted" style="margin-bottom: 15px; margin-top: 25px">
|
||||
<pr-icon icon="'database'" class="mr-1"></pr-icon>
|
||||
Data persistence
|
||||
</div>
|
||||
|
||||
<div class="small text-muted" ng-if="!ctrl.hasPersistedFolders()">
|
||||
<pr-icon icon="'info'" mode="'primary'" class="mr-1"></pr-icon>
|
||||
This application has no persisted folders.
|
||||
</div>
|
||||
|
||||
<div ng-if="ctrl.hasPersistedFolders()">
|
||||
<div class="small text-muted vertical-center" style="margin-bottom: 15px">
|
||||
Data access policy:
|
||||
<pr-icon icon="ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyIcon"></pr-icon>
|
||||
{{ ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyText }}
|
||||
<portainer-tooltip position="'right'" message="ctrl.application.DataAccessPolicy | kubernetesApplicationDataAccessPolicyTooltip"> </portainer-tooltip>
|
||||
</div>
|
||||
|
||||
<table class="table" ng-if="ctrl.application.DataAccessPolicy === ctrl.ApplicationDataAccessPolicies.SHARED">
|
||||
<tr class="text-muted">
|
||||
<td style="width: 33%">Persisted folder</td>
|
||||
<td style="width: 66%">Persistence</td>
|
||||
</tr>
|
||||
<tbody ng-repeat="container in ctrl.application.Containers" style="border-top: 0">
|
||||
<tr ng-repeat="volume in container.PersistedFolders track by $index">
|
||||
<td data-cy="k8sAppDetail-volMountPath">
|
||||
{{ volume.MountPath }}
|
||||
</td>
|
||||
<td ng-if="volume.PersistentVolumeClaimName">
|
||||
<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"></pr-icon>{{ volume.PersistentVolumeClaimName }}</a
|
||||
>
|
||||
</td>
|
||||
<td ng-if="volume.HostPath"> {{ volume.HostPath }} on host filesystem </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="table" ng-if="ctrl.application.DataAccessPolicy === ctrl.ApplicationDataAccessPolicies.ISOLATED">
|
||||
<thead>
|
||||
<tr class="text-muted">
|
||||
<td style="width: 25%">Container name</td>
|
||||
<td style="width: 25%">Pod name</td>
|
||||
<td style="width: 25%">Persisted folder</td>
|
||||
<td style="width: 25%">Persistence</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody ng-repeat="container in ctrl.allContainers track by $index" style="border-top: none">
|
||||
<tr ng-repeat="volume in container.PersistedFolders track by $index">
|
||||
<td>
|
||||
{{ container.Name }}
|
||||
<span ng-if="container.Type === ctrl.KubernetesPodContainerTypes.INIT"
|
||||
><pr-icon icon="'asterisk'"></pr-icon> {{ envvar.valueFrom.fieldRef.fieldPath }} (<a
|
||||
href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/"
|
||||
target="_blank"
|
||||
>init container</a
|
||||
>)</span
|
||||
>
|
||||
</td>
|
||||
<td>{{ container.PodName }}</td>
|
||||
<td>
|
||||
{{ volume.MountPath }}
|
||||
</td>
|
||||
<td ng-if="volume.PersistentVolumeClaimName">
|
||||
<a
|
||||
class="hyperlink"
|
||||
ui-sref="kubernetes.volumes.volume({ name: volume.PersistentVolumeClaimName + '-' + container.PodName, namespace: ctrl.application.ResourcePool })"
|
||||
>
|
||||
<pr-icon icon="'database'" class="mr-1"></pr-icon>{{ volume.PersistentVolumeClaimName + '-' + container.PodName }}</a
|
||||
>
|
||||
</td>
|
||||
<td ng-if="volume.HostPath"> {{ volume.HostPath }} on host filesystem </td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!-- !DATA PERSISTENCE -->
|
||||
</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
<application-details-widget></application-details-widget>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue