From 4a9236967bce532600c04d4bd622138d6f6d5c84 Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Mon, 22 May 2023 03:44:25 +0700 Subject: [PATCH] refactor(settings): move app settings to panel fix(settings): fix app panel fix(settings/apps): limit features --- .../application-settings-panel.controller.js | 88 +++++++++++ .../application-settings-panel.html | 148 ++++++++++++++++++ .../application-settings-panel/index.js | 12 ++ app/portainer/views/settings/settings.html | 133 +--------------- .../views/settings/settingsController.js | 57 +------ 5 files changed, 257 insertions(+), 181 deletions(-) create mode 100644 app/portainer/views/settings/components/application-settings-panel/application-settings-panel.controller.js create mode 100644 app/portainer/views/settings/components/application-settings-panel/application-settings-panel.html create mode 100644 app/portainer/views/settings/components/application-settings-panel/index.js diff --git a/app/portainer/views/settings/components/application-settings-panel/application-settings-panel.controller.js b/app/portainer/views/settings/components/application-settings-panel/application-settings-panel.controller.js new file mode 100644 index 000000000..dc65a9cc5 --- /dev/null +++ b/app/portainer/views/settings/components/application-settings-panel/application-settings-panel.controller.js @@ -0,0 +1,88 @@ +import { FeatureId } from '@/react/portainer/feature-flags/enums'; + +/* @ngInject */ +export default function ApplicationSettingsPanelController($scope, $async, StateManager) { + this.saveApplicationSettings = saveApplicationSettings.bind(this); + this.onChangeCheckInInterval = onChangeCheckInInterval.bind(this); + this.onToggleCustomLogo = onToggleCustomLogo.bind(this); + this.$onInit = $onInit.bind(this); + this.onToggleEnableTelemetry = onToggleEnableTelemetry.bind(this); + this.onToggleCustomLoginBanner = onToggleCustomLoginBanner.bind(this); + this.onChangeFormValues = onChangeFormValues.bind(this); + + this.customBannerFeatureId = FeatureId.CUSTOM_LOGIN_BANNER; + + this.formValues = { + logoURL: '', + logoEnabled: false, + customLoginBannerEnabled: false, + customLoginBanner: '', + snapshotInterval: '', + enableTelemetry: false, + templatesUrl: '', + edgeAgentCheckinInterval: '', + }; + + this.state = { + isDemo: false, + actionInProgress: false, + }; + + async function saveApplicationSettings() { + $async(async () => { + const appSettingsPayload = { + SnapshotInterval: this.settings.SnapshotInterval, + LogoURL: this.formValues.customLogo ? this.settings.LogoURL : '', + EnableTelemetry: this.settings.EnableTelemetry, + CustomLoginBanner: this.formValues.customLoginBanner ? this.settings.CustomLoginBanner : '', + TemplatesURL: this.settings.TemplatesURL, + EdgeAgentCheckinInterval: this.settings.EdgeAgentCheckinInterval, + }; + + this.state.actionInProgress = true; + await this.onSubmit(appSettingsPayload, 'Application settings updated'); + this.state.actionInProgress = false; + }); + } + + function onToggleCustomLogo(logoEnabled) { + this.onChangeFormValues({ logoEnabled }); + } + + function onChangeCheckInInterval(edgeAgentCheckinInterval) { + this.onChangeFormValues({ edgeAgentCheckinInterval }); + } + + function onToggleEnableTelemetry(enableTelemetry) { + this.onChangeFormValues({ enableTelemetry }); + } + + function onToggleCustomLoginBanner(customLoginBannerEnabled) { + this.onChangeFormValues({ customLoginBannerEnabled }); + } + + function onChangeFormValues(newPartialValues) { + $scope.$evalAsync(() => { + this.formValues = { + ...this.formValues, + ...newPartialValues, + }; + }); + } + + function $onInit() { + const state = StateManager.getState(); + this.state.isDemo = state.application.demoEnvironment.enabled; + + this.formValues = { + logoURL: this.settings.LogoURL, + logoEnabled: !!this.settings.LogoURL, + customLoginBannerEnabled: !!this.settings.CustomLoginBanner, + customLoginBanner: this.settings.CustomLoginBanner, + snapshotInterval: this.settings.SnapshotInterval, + enableTelemetry: this.settings.EnableTelemetry, + templatesUrl: this.settings.TemplatesURL, + edgeAgentCheckinInterval: this.settings.EdgeAgentCheckinInterval, + }; + } +} diff --git a/app/portainer/views/settings/components/application-settings-panel/application-settings-panel.html b/app/portainer/views/settings/components/application-settings-panel/application-settings-panel.html new file mode 100644 index 000000000..95e58232e --- /dev/null +++ b/app/portainer/views/settings/components/application-settings-panel/application-settings-panel.html @@ -0,0 +1,148 @@ +
+
+ + + +
+ +
+ +
+ +
+
+ + + + + + + +
+ +
+ You cannot use this feature in the demo version of Portainer. +
+
+ +
+
+ You can specify the URL to your logo here. For an optimal display, logo dimensions should be 155px by 55px. +
+
+ +
+ +
+
+
+ + +
+ +
+ You cannot use this feature in the demo version of Portainer. +
+
+ You can find more information about this in our + privacy policy. +
+
+ + +
+ +
+ You cannot use this feature in the demo version of Portainer. +
+
You can set a custom banner that will be shown to all users during login.
+
+ +
+
+ +
+ +
+
+
+ + + +
App Templates
+
+
+ + You can specify the URL to your own template definitions file here. See + Portainer documentation for more details. + +
+
+ +
+ +
+
+
+ + +
+
+ +
+
+ +
+
+
+
+
diff --git a/app/portainer/views/settings/components/application-settings-panel/index.js b/app/portainer/views/settings/components/application-settings-panel/index.js new file mode 100644 index 000000000..aa8220e69 --- /dev/null +++ b/app/portainer/views/settings/components/application-settings-panel/index.js @@ -0,0 +1,12 @@ +import angular from 'angular'; + +import controller from './application-settings-panel.controller'; + +angular.module('portainer.app').component('applicationSettingsPanel', { + templateUrl: './application-settings-panel.html', + controller, + bindings: { + settings: '<', + onSubmit: '<', + }, +}); diff --git a/app/portainer/views/settings/settings.html b/app/portainer/views/settings/settings.html index 9b846fb3f..1faebd028 100644 --- a/app/portainer/views/settings/settings.html +++ b/app/portainer/views/settings/settings.html @@ -1,137 +1,6 @@ -
-
- - - -
- -
- -
- -
-
- - - - - - - -
- -
- You cannot use this feature in the demo version of Portainer. -
-
- -
-
- You can specify the URL to your logo here. For an optimal display, logo dimensions should be 155px by 55px. -
-
- -
- -
-
-
- - -
- -
- You cannot use this feature in the demo version of Portainer. -
-
- You can find more information about this in our - privacy policy. -
-
- -
- -
- - -
App Templates
-
-
- - You can specify the URL to your own template definitions file here. See - Portainer documentation for more details. - -
-
- -
- -
-
-
- - -
-
- -
-
- -
-
-
-
-
+
diff --git a/app/portainer/views/settings/settingsController.js b/app/portainer/views/settings/settingsController.js index 5ad50e716..bd127e25c 100644 --- a/app/portainer/views/settings/settingsController.js +++ b/app/portainer/views/settings/settingsController.js @@ -15,10 +15,11 @@ angular.module('portainer.app').controller('SettingsController', [ $scope.s3BackupFeatureId = FeatureId.S3_BACKUP_SETTING; $scope.enforceDeploymentOptions = FeatureId.ENFORCE_DEPLOYMENT_OPTIONS; + $scope.updateSettings = updateSettings; + $scope.backupOptions = options; $scope.state = { - isDemo: false, actionInProgress: false, availableKubeconfigExpiryOptions: [ { @@ -50,32 +51,16 @@ angular.module('portainer.app').controller('SettingsController', [ $scope.BACKUP_FORM_TYPES = { S3: 's3', FILE: 'file' }; $scope.formValues = { - customLogo: false, KubeconfigExpiry: undefined, HelmRepositoryURL: undefined, BlackListedLabels: [], labelName: '', labelValue: '', - enableTelemetry: false, passwordProtect: false, password: '', backupFormType: $scope.BACKUP_FORM_TYPES.FILE, }; - $scope.initialFormValues = {}; - - $scope.onToggleEnableTelemetry = function onToggleEnableTelemetry(checked) { - $scope.$evalAsync(() => { - $scope.formValues.enableTelemetry = checked; - }); - }; - - $scope.onToggleCustomLogo = function onToggleCustomLogo(checked) { - $scope.$evalAsync(() => { - $scope.formValues.customLogo = checked; - }); - }; - $scope.onToggleAutoBackups = function onToggleAutoBackups(checked) { $scope.$evalAsync(() => { $scope.formValues.scheduleAutomaticBackups = checked; @@ -87,13 +72,6 @@ angular.module('portainer.app').controller('SettingsController', [ $scope.state.featureLimited = limited; }; - $scope.onChangeCheckInInterval = function (interval) { - $scope.$evalAsync(() => { - var settings = $scope.settings; - settings.EdgeAgentCheckinInterval = interval; - }); - }; - $scope.removeFilteredContainerLabel = function (index) { const filteredSettings = $scope.formValues.BlackListedLabels.filter((_, i) => i !== index); const filteredSettingsPayload = { BlackListedLabels: filteredSettings }; @@ -133,20 +111,6 @@ angular.module('portainer.app').controller('SettingsController', [ }); }; - // only update the values from the app settings widget. In future separate the api endpoints - $scope.saveApplicationSettings = function () { - const appSettingsPayload = { - SnapshotInterval: $scope.settings.SnapshotInterval, - LogoURL: $scope.formValues.customLogo ? $scope.settings.LogoURL : '', - EnableTelemetry: $scope.formValues.enableTelemetry, - TemplatesURL: $scope.settings.TemplatesURL, - EdgeAgentCheckinInterval: $scope.settings.EdgeAgentCheckinInterval, - }; - - $scope.state.actionInProgress = true; - updateSettings(appSettingsPayload, 'Application settings updated'); - }; - // only update the values from the kube settings widget. In future separate the api endpoints $scope.saveKubernetesSettings = function () { const kubeSettingsPayload = { @@ -160,13 +124,17 @@ angular.module('portainer.app').controller('SettingsController', [ }; function updateSettings(settings, successMessage = 'Settings updated') { - SettingsService.update(settings) + // ignore CloudApiKeys to avoid overriding them + // + // it is not ideal solution as API still accepts CloudAPIKeys + // which may override the cloud provider API keys + settings.CloudApiKeys = undefined; + return SettingsService.update(settings) .then(function success(response) { Notifications.success('Success', successMessage); StateManager.updateLogo(settings.LogoURL); StateManager.updateSnapshotInterval(settings.SnapshotInterval); StateManager.updateEnableTelemetry(settings.EnableTelemetry); - $scope.initialFormValues.enableTelemetry = response.EnableTelemetry; $scope.formValues.BlackListedLabels = response.BlackListedLabels; }) .catch(function error(err) { @@ -179,23 +147,14 @@ angular.module('portainer.app').controller('SettingsController', [ } function initView() { - const state = StateManager.getState(); - $scope.state.isDemo = state.application.demoEnvironment.enabled; - SettingsService.settings() .then(function success(data) { var settings = data; $scope.settings = settings; - if (settings.LogoURL !== '') { - $scope.formValues.customLogo = true; - } - - $scope.formValues.enableTelemetry = settings.EnableTelemetry; $scope.formValues.KubeconfigExpiry = settings.KubeconfigExpiry; $scope.formValues.HelmRepositoryURL = settings.HelmRepositoryURL; $scope.formValues.BlackListedLabels = settings.BlackListedLabels; - $scope.initialFormValues.enableTelemetry = settings.EnableTelemetry; }) .catch(function error(err) { Notifications.error('Failure', err, 'Unable to retrieve application settings');