mirror of
https://github.com/portainer/portainer.git
synced 2025-08-05 13:55:21 +02:00
feat(app): introduce component library in react [EE-1816] (#6236)
* refactor(app): replace notification with es6 service (#6015) [EE-1897] chore(app): format * refactor(containers): remove the dependency on angular modal service (#6017) [EE-1898] * refactor(app): remove angular from http-request [EE-1899] (#6016) * feat(app): add axios [EE-2035](#6077) * refactor(feature): remove angular dependency from feature service [EE-2034] (#6078) * refactor(app): replace box-selector with react component (#6046) fix: rename angular2react refactor(app): make box-selector type generic feat(app): add story for box-selector feat(app): test box-selector feat(app): add stories for box selector item fix(app): remove unneccesary element refactor(app): remove assign * feat(feature): add be-indicator in react [EE-2005] (#6106) * refactor(app): add react components for headers [EE-1949] (#6023) * feat(auth): provide user context * feat(app): added base header component [EE-1949] style(app): reformat refactor(app/header): use same api as angular * feat(app): add breadcrumbs component [EE-2024] * feat(app): remove u element from user links * fix(users): handle axios errors Co-authored-by: Chaim Lev-Ari <chiptus@gmail.com> * refactor(app): convert switch component to react [EE-2005] (#6025) Co-authored-by: Marcelo Rydel <marcelorydel26@gmail.com>
This commit is contained in:
parent
eb9f6c77f4
commit
7ae5a3042c
157 changed files with 3204 additions and 1469 deletions
|
@ -149,11 +149,12 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<por-switch-field
|
||||
ng-model="$ctrl.state.autoUpdateSettings.Enabled"
|
||||
name="disableSysctlSettingForRegularUsers"
|
||||
label="Enable Change Window"
|
||||
feature="ctrl.limitedFeatureAutoWindow"
|
||||
tooltip="Specify a timeframe during which automatic updates can occur in this environment."
|
||||
checked="ctrl.state.autoUpdateSettings.Enabled"
|
||||
name="'disableSysctlSettingForRegularUsers'"
|
||||
label="'Enable Change Window'"
|
||||
feature-id="ctrl.limitedFeatureAutoWindow"
|
||||
tooltip="'Specify a timeframe during which automatic updates can occur in this environment.'"
|
||||
on-change="(ctrl.onToggleAutoUpdate)"
|
||||
>
|
||||
</por-switch-field>
|
||||
</div>
|
||||
|
@ -197,12 +198,12 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<por-switch-field
|
||||
label="Allow resource over-commit"
|
||||
name="resource-over-commit-switch"
|
||||
feature="ctrl.limitedFeature"
|
||||
ng-model="ctrl.formValues.EnableResourceOverCommit"
|
||||
ng-change="ctrl.onChangeEnableResourceOverCommit()"
|
||||
ng-data-cy="kubeSetup-resourceOverCommitToggle"
|
||||
data-cy="'kubeSetup-resourceOverCommitToggle'"
|
||||
label="'Allow resource over-commit'"
|
||||
name="'resource-over-commit-switch'"
|
||||
feature-id="ctrl.limitedFeature"
|
||||
checked="ctrl.formValues.EnableResourceOverCommit"
|
||||
on-change="(ctrl.onChangeEnableResourceOverCommit)"
|
||||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -6,8 +6,8 @@ import { KubernetesIngressClass } from 'Kubernetes/ingress/models';
|
|||
import KubernetesFormValidationHelper from 'Kubernetes/helpers/formValidationHelper';
|
||||
import { KubernetesIngressClassTypes } from 'Kubernetes/ingress/constants';
|
||||
import KubernetesNamespaceHelper from 'Kubernetes/helpers/namespaceHelper';
|
||||
import { K8S_SETUP_DEFAULT } from '@/portainer/feature-flags/feature-ids';
|
||||
import { HIDE_AUTO_UPDATE_WINDOW } from 'Portainer/feature-flags/feature-ids';
|
||||
import { FeatureId } from '@/portainer/feature-flags/enums';
|
||||
|
||||
class KubernetesConfigureController {
|
||||
/* #region CONSTRUCTOR */
|
||||
|
||||
|
@ -15,6 +15,7 @@ class KubernetesConfigureController {
|
|||
constructor(
|
||||
$async,
|
||||
$state,
|
||||
$scope,
|
||||
Notifications,
|
||||
KubernetesStorageService,
|
||||
EndpointService,
|
||||
|
@ -26,6 +27,7 @@ class KubernetesConfigureController {
|
|||
) {
|
||||
this.$async = $async;
|
||||
this.$state = $state;
|
||||
this.$scope = $scope;
|
||||
this.Notifications = Notifications;
|
||||
this.KubernetesStorageService = KubernetesStorageService;
|
||||
this.EndpointService = EndpointService;
|
||||
|
@ -39,8 +41,10 @@ class KubernetesConfigureController {
|
|||
|
||||
this.onInit = this.onInit.bind(this);
|
||||
this.configureAsync = this.configureAsync.bind(this);
|
||||
this.limitedFeature = K8S_SETUP_DEFAULT;
|
||||
this.limitedFeatureAutoWindow = HIDE_AUTO_UPDATE_WINDOW;
|
||||
this.limitedFeature = FeatureId.K8S_SETUP_DEFAULT;
|
||||
this.limitedFeatureAutoWindow = FeatureId.HIDE_AUTO_UPDATE_WINDOW;
|
||||
this.onToggleAutoUpdate = this.onToggleAutoUpdate.bind(this);
|
||||
this.onChangeEnableResourceOverCommit = this.onChangeEnableResourceOverCommit.bind(this);
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
|
@ -103,6 +107,15 @@ class KubernetesConfigureController {
|
|||
}
|
||||
/* #endregion */
|
||||
|
||||
onChangeEnableResourceOverCommit(enabled) {
|
||||
this.$scope.$evalAsync(() => {
|
||||
this.formValues.EnableResourceOverCommit = enabled;
|
||||
if (enabled) {
|
||||
this.formValues.ResourceOverCommitPercentage = 20;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* #region CONFIGURE */
|
||||
assignFormValuesToEndpoint(endpoint, storageClasses, ingressClasses) {
|
||||
endpoint.Kubernetes.Configuration.StorageClasses = storageClasses;
|
||||
|
@ -244,6 +257,12 @@ class KubernetesConfigureController {
|
|||
return this.formValues.RestrictDefaultNamespace && !this.oldFormValues.RestrictDefaultNamespace;
|
||||
}
|
||||
|
||||
onToggleAutoUpdate(value) {
|
||||
return this.$scope.$evalAsync(() => {
|
||||
this.state.autoUpdateSettings.Enabled = value;
|
||||
});
|
||||
}
|
||||
|
||||
/* #region ON INIT */
|
||||
async onInit() {
|
||||
this.state = {
|
||||
|
|
|
@ -39,18 +39,24 @@
|
|||
<div class="col-sm-12 form-section-title">
|
||||
Build method
|
||||
</div>
|
||||
<box-selector radio-name="method" ng-model="ctrl.state.BuildMethod" options="ctrl.methodOptions" data-cy="k8sAppDeploy-buildSelector"></box-selector>
|
||||
<box-selector
|
||||
radio-name="'method'"
|
||||
value="ctrl.state.BuildMethod"
|
||||
options="ctrl.methodOptions"
|
||||
data-cy="k8sAppDeploy-buildSelector"
|
||||
on-change="(ctrl.onChangeMethod)"
|
||||
></box-selector>
|
||||
|
||||
<div ng-if="ctrl.state.BuildMethod !== ctrl.BuildMethods.CUSTOM_TEMPLATE">
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Deployment type
|
||||
</div>
|
||||
<box-selector
|
||||
radio-name="deploy"
|
||||
ng-model="ctrl.state.DeployType"
|
||||
on-change="(ctrl.onDeployTypeChange)"
|
||||
radio-name="'deploy'"
|
||||
value="ctrl.state.DeployType"
|
||||
options="ctrl.deployOptions"
|
||||
data-cy="k8sAppDeploy-deploymentSelector"
|
||||
on-change="(ctrl.onChangeDeployType)"
|
||||
></box-selector>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -5,7 +5,8 @@ import uuidv4 from 'uuid/v4';
|
|||
import PortainerError from 'Portainer/error';
|
||||
|
||||
import { KubernetesDeployManifestTypes, KubernetesDeployBuildMethods, KubernetesDeployRequestMethods, RepositoryMechanismTypes } from 'Kubernetes/models/deploy';
|
||||
import { buildOption } from '@/portainer/components/box-selector';
|
||||
import { buildOption } from '@/portainer/components/BoxSelector';
|
||||
|
||||
class KubernetesDeployController {
|
||||
/* @ngInject */
|
||||
constructor($async, $state, $window, Authentication, ModalService, Notifications, KubernetesResourcePoolService, StackService, WebhookHelper, CustomTemplateService) {
|
||||
|
@ -67,7 +68,8 @@ class KubernetesDeployController {
|
|||
this.getNamespacesAsync = this.getNamespacesAsync.bind(this);
|
||||
this.onChangeFormValues = this.onChangeFormValues.bind(this);
|
||||
this.buildAnalyticsProperties = this.buildAnalyticsProperties.bind(this);
|
||||
this.onDeployTypeChange = this.onDeployTypeChange.bind(this);
|
||||
this.onChangeMethod = this.onChangeMethod.bind(this);
|
||||
this.onChangeDeployType = this.onChangeDeployType.bind(this);
|
||||
}
|
||||
|
||||
buildAnalyticsProperties() {
|
||||
|
@ -122,6 +124,19 @@ class KubernetesDeployController {
|
|||
}
|
||||
}
|
||||
|
||||
onChangeMethod(method) {
|
||||
this.state.BuildMethod = method;
|
||||
}
|
||||
|
||||
onChangeDeployType(type) {
|
||||
this.state.DeployType = type;
|
||||
if (type == this.ManifestDeployTypes.COMPOSE) {
|
||||
this.DeployMethod = 'compose';
|
||||
} else {
|
||||
this.DeployMethod = 'manifest';
|
||||
}
|
||||
}
|
||||
|
||||
disableDeploy() {
|
||||
const isGitFormInvalid =
|
||||
this.state.BuildMethod === KubernetesDeployBuildMethods.GIT &&
|
||||
|
@ -275,14 +290,6 @@ class KubernetesDeployController {
|
|||
return this.$async(this.getNamespacesAsync);
|
||||
}
|
||||
|
||||
onDeployTypeChange(value) {
|
||||
if (value == this.ManifestDeployTypes.COMPOSE) {
|
||||
this.DeployMethod = 'compose';
|
||||
} else {
|
||||
this.DeployMethod = 'manifest';
|
||||
}
|
||||
}
|
||||
|
||||
async uiCanExit() {
|
||||
if (this.formValues.EditorContent && this.state.isEditorDirty) {
|
||||
return this.ModalService.confirmWebEditorDiscard();
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import angular from 'angular';
|
||||
import controller from './storage-class-switch.controller.js';
|
||||
|
||||
export const storageClassSwitch = {
|
||||
templateUrl: './storage-class-switch.html',
|
||||
controller,
|
||||
bindings: {
|
||||
value: '<',
|
||||
onChange: '<',
|
||||
name: '<',
|
||||
},
|
||||
};
|
||||
|
||||
angular.module('portainer.kubernetes').component('storageClassSwitch', storageClassSwitch);
|
|
@ -0,0 +1,16 @@
|
|||
import { FeatureId } from '@/portainer/feature-flags/enums';
|
||||
|
||||
class StorageClassSwitchController {
|
||||
/* @ngInject */
|
||||
constructor() {
|
||||
this.featureId = FeatureId.K8S_RESOURCE_POOL_STORAGE_QUOTA;
|
||||
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
}
|
||||
|
||||
handleChange(value) {
|
||||
this.onChange(this.name, value);
|
||||
}
|
||||
}
|
||||
|
||||
export default StorageClassSwitchController;
|
|
@ -0,0 +1,12 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-2">
|
||||
<por-switch-field
|
||||
data-cy="'k8sNamespaceCreate-enableQuotaToggle'"
|
||||
label="'Enable quota'"
|
||||
name="'k8s-resourcepool-storagequota'"
|
||||
feature-id="$ctrl.featureId"
|
||||
checked="$ctrl.value"
|
||||
on-change="($ctrl.handleChange)"
|
||||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
|
@ -163,11 +163,12 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<por-switch-field
|
||||
ng-data-cy="k8sNamespaceCreate-loadBalancerQuotaToggle"
|
||||
label="Load Balancer quota"
|
||||
name="k8s-resourcepool-Ibquota"
|
||||
feature="$ctrl.LBQuotaFeatureId"
|
||||
ng-model="lbquota"
|
||||
data-cy="'k8sNamespaceCreate-loadBalancerQuotaToggle'"
|
||||
label="'Load Balancer quota'"
|
||||
name="'k8s-resourcepool-lbquota'"
|
||||
feature-id="$ctrl.LBQuotaFeatureId"
|
||||
checked="$ctrl.formValues.UseLoadBalancersQuota"
|
||||
on-change="($ctrl.onToggleLoadBalancerQuota)"
|
||||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -189,17 +190,9 @@
|
|||
<i class="fa fa-route" aria-hidden="true" style="margin-right: 2px;"></i>
|
||||
standard
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<por-switch-field
|
||||
ng-data-cy="k8sNamespaceCreate-enableQuotaToggle"
|
||||
label="Enable quota"
|
||||
name="k8s-resourcepool-storagequota"
|
||||
feature="$ctrl.StorageQuotaFeatureId"
|
||||
ng-model="storagequota"
|
||||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<storage-class-switch value="sc.Selected" name="sc.Name" on-change="(ctrl.onToggleStorageQuota)" authorization="K8sResourcePoolDetailsW"></storage-class-switch>
|
||||
|
||||
<!-- #endregion -->
|
||||
|
||||
<div ng-if="$ctrl.state.canUseIngress">
|
||||
|
|
|
@ -12,15 +12,16 @@ import KubernetesFormValidationHelper from 'Kubernetes/helpers/formValidationHel
|
|||
import { KubernetesFormValidationReferences } from 'Kubernetes/models/application/formValues';
|
||||
import { KubernetesIngressClassTypes } from 'Kubernetes/ingress/constants';
|
||||
|
||||
import { K8S_RESOURCE_POOL_LB_QUOTA, K8S_RESOURCE_POOL_STORAGE_QUOTA } from '@/portainer/feature-flags/feature-ids';
|
||||
import { FeatureId } from '@/portainer/feature-flags/enums';
|
||||
|
||||
class KubernetesCreateResourcePoolController {
|
||||
/* #region CONSTRUCTOR */
|
||||
/* @ngInject */
|
||||
constructor($async, $state, Notifications, KubernetesNodeService, KubernetesResourcePoolService, KubernetesIngressService, Authentication, EndpointService) {
|
||||
constructor($async, $state, $scope, Notifications, KubernetesNodeService, KubernetesResourcePoolService, KubernetesIngressService, Authentication, EndpointService) {
|
||||
Object.assign(this, {
|
||||
$async,
|
||||
$state,
|
||||
$scope,
|
||||
Notifications,
|
||||
KubernetesNodeService,
|
||||
KubernetesResourcePoolService,
|
||||
|
@ -30,11 +31,25 @@ class KubernetesCreateResourcePoolController {
|
|||
});
|
||||
|
||||
this.IngressClassTypes = KubernetesIngressClassTypes;
|
||||
this.LBQuotaFeatureId = K8S_RESOURCE_POOL_LB_QUOTA;
|
||||
this.StorageQuotaFeatureId = K8S_RESOURCE_POOL_STORAGE_QUOTA;
|
||||
this.LBQuotaFeatureId = FeatureId.K8S_RESOURCE_POOL_LB_QUOTA;
|
||||
|
||||
this.onToggleStorageQuota = this.onToggleStorageQuota.bind(this);
|
||||
this.onToggleLoadBalancerQuota = this.onToggleLoadBalancerQuota.bind(this);
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
onToggleStorageQuota(storageClassName, enabled) {
|
||||
this.$scope.$evalAsync(() => {
|
||||
this.formValues.StorageClasses = this.formValues.StorageClasses.map((sClass) => (sClass.Name !== storageClassName ? sClass : { ...sClass, Selected: enabled }));
|
||||
});
|
||||
}
|
||||
|
||||
onToggleLoadBalancerQuota(enabled) {
|
||||
this.$scope.$evalAsync(() => {
|
||||
this.formValues.UseLoadBalancersQuota = enabled;
|
||||
});
|
||||
}
|
||||
|
||||
onChangeIngressHostname() {
|
||||
const state = this.state.duplicates.ingressHosts;
|
||||
const hosts = _.flatMap(this.formValues.IngressClasses, 'Hosts');
|
||||
|
|
|
@ -147,11 +147,12 @@
|
|||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<por-switch-field
|
||||
ng-data-cy="k8sNamespaceCreate-loadBalancerQuotaToggle"
|
||||
label="Load Balancer quota"
|
||||
name="k8s-resourcepool-Lbquota"
|
||||
feature="ctrl.LBQuotaFeatureId"
|
||||
ng-model="lbquota"
|
||||
data-cy="'k8sNamespaceCreate-loadBalancerQuotaToggle'"
|
||||
label="'Load Balancer quota'"
|
||||
name="'k8s-resourcepool-Lbquota'"
|
||||
feature-id="ctrl.LBQuotaFeatureId"
|
||||
checked="ctrl.formValues.UseLoadBalancersQuota"
|
||||
on-change="(ctrl.onToggleLoadBalancersQuota)"
|
||||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -386,17 +387,9 @@
|
|||
<i class="fa fa-route" aria-hidden="true" style="margin-right: 2px;"></i>
|
||||
standard
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<por-switch-field
|
||||
ng-data-cy="k8sNamespaceCreate-enableQuotaToggle"
|
||||
label="Enable quota"
|
||||
name="k8s-resourcepool-storagequota"
|
||||
feature="ctrl.StorageQuotaFeatureId"
|
||||
ng-model="storagequota"
|
||||
></por-switch-field>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<storage-class-switch value="sc.Selected" name="sc.Name" on-change="(ctrl.onToggleStorageQuota)" authorization="K8sResourcePoolDetailsW"></storage-class-switch>
|
||||
|
||||
<!-- #endregion -->
|
||||
|
||||
<!-- summary -->
|
||||
|
|
|
@ -16,7 +16,7 @@ import KubernetesFormValidationHelper from 'Kubernetes/helpers/formValidationHel
|
|||
import { KubernetesIngressClassTypes } from 'Kubernetes/ingress/constants';
|
||||
import KubernetesResourceQuotaConverter from 'Kubernetes/converters/resourceQuota';
|
||||
import KubernetesNamespaceHelper from 'Kubernetes/helpers/namespaceHelper';
|
||||
import { K8S_RESOURCE_POOL_LB_QUOTA, K8S_RESOURCE_POOL_STORAGE_QUOTA } from '@/portainer/feature-flags/feature-ids';
|
||||
import { FeatureId } from '@/portainer/feature-flags/enums';
|
||||
|
||||
class KubernetesResourcePoolController {
|
||||
/* #region CONSTRUCTOR */
|
||||
|
@ -24,6 +24,7 @@ class KubernetesResourcePoolController {
|
|||
constructor(
|
||||
$async,
|
||||
$state,
|
||||
$scope,
|
||||
Authentication,
|
||||
Notifications,
|
||||
LocalStorage,
|
||||
|
@ -42,6 +43,7 @@ class KubernetesResourcePoolController {
|
|||
Object.assign(this, {
|
||||
$async,
|
||||
$state,
|
||||
$scope,
|
||||
Authentication,
|
||||
Notifications,
|
||||
LocalStorage,
|
||||
|
@ -61,11 +63,13 @@ class KubernetesResourcePoolController {
|
|||
this.IngressClassTypes = KubernetesIngressClassTypes;
|
||||
this.ResourceQuotaDefaults = KubernetesResourceQuotaDefaults;
|
||||
|
||||
this.LBQuotaFeatureId = K8S_RESOURCE_POOL_LB_QUOTA;
|
||||
this.StorageQuotaFeatureId = K8S_RESOURCE_POOL_STORAGE_QUOTA;
|
||||
this.LBQuotaFeatureId = FeatureId.K8S_RESOURCE_POOL_LB_QUOTA;
|
||||
this.StorageQuotaFeatureId = FeatureId.K8S_RESOURCE_POOL_STORAGE_QUOTA;
|
||||
|
||||
this.updateResourcePoolAsync = this.updateResourcePoolAsync.bind(this);
|
||||
this.getEvents = this.getEvents.bind(this);
|
||||
this.onToggleLoadBalancersQuota = this.onToggleLoadBalancersQuota.bind(this);
|
||||
this.onToggleStorageQuota = this.onToggleStorageQuota.bind(this);
|
||||
}
|
||||
/* #endregion */
|
||||
|
||||
|
@ -80,6 +84,18 @@ class KubernetesResourcePoolController {
|
|||
}
|
||||
/* #endregion */
|
||||
|
||||
onToggleLoadBalancersQuota(checked) {
|
||||
return this.$scope.$evalAsync(() => {
|
||||
this.formValues.UseLoadBalancersQuota = checked;
|
||||
});
|
||||
}
|
||||
|
||||
onToggleStorageQuota(storageClassName, enabled) {
|
||||
this.$scope.$evalAsync(() => {
|
||||
this.formValues.StorageClasses = this.formValues.StorageClasses.map((sClass) => (sClass.Name !== storageClassName ? sClass : { ...sClass, Selected: enabled }));
|
||||
});
|
||||
}
|
||||
|
||||
/* #region INGRESS MANAGEMENT */
|
||||
onChangeIngressHostname() {
|
||||
const state = this.state.duplicates.ingressHosts;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue