1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-05 05:45:22 +02:00

refactor(edge/stacks): migrate edit view to react [EE-2222] (#11648)
Some checks are pending
ci / build_images (map[arch:amd64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
ci / build_images (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
ci / build_images (map[arch:arm platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:arm64 platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:ppc64le platform:linux version:]) (push) Waiting to run
ci / build_images (map[arch:s390x platform:linux version:]) (push) Waiting to run
ci / build_manifests (push) Blocked by required conditions
/ triage (push) Waiting to run
Lint / Run linters (push) Waiting to run
Test / test-client (push) Waiting to run
Test / test-server (map[arch:amd64 platform:linux]) (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:1809]) (push) Waiting to run
Test / test-server (map[arch:amd64 platform:windows version:ltsc2022]) (push) Waiting to run
Test / test-server (map[arch:arm64 platform:linux]) (push) Waiting to run

This commit is contained in:
Chaim Lev-Ari 2024-05-09 18:02:20 +03:00 committed by GitHub
parent 27e309754e
commit cd5f342da0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
31 changed files with 847 additions and 499 deletions

View file

@ -1,11 +1,10 @@
import angular from 'angular';
import { AccessHeaders } from '@/portainer/authorization-guard';
import edgeStackModule from './views/edge-stacks';
import { reactModule } from './react';
angular
.module('portainer.edge', [edgeStackModule, reactModule])
.module('portainer.edge', [reactModule])
.config(function config($stateRegistryProvider) {
const edge = {
@ -82,7 +81,7 @@ angular
url: '/:stackId?tab&status',
views: {
'content@': {
component: 'editEdgeStackView',
component: 'edgeStacksItemView',
},
},
params: {

View file

@ -6,22 +6,15 @@ import { withReactQuery } from '@/react-tools/withReactQuery';
import { EdgeCheckinIntervalField } from '@/react/edge/components/EdgeCheckInIntervalField';
import { EdgeScriptForm } from '@/react/edge/components/EdgeScriptForm';
import { EdgeAsyncIntervalsForm } from '@/react/edge/components/EdgeAsyncIntervalsForm';
import { EdgeStackDeploymentTypeSelector } from '@/react/edge/edge-stacks/components/EdgeStackDeploymentTypeSelector';
import { EditEdgeStackForm } from '@/react/edge/edge-stacks/ItemView/EditEdgeStackForm/EditEdgeStackForm';
import { withCurrentUser } from '@/react-tools/withCurrentUser';
import { withUIRouter } from '@/react-tools/withUIRouter';
import { EdgeGroupAssociationTable } from '@/react/edge/components/EdgeGroupAssociationTable';
import { AssociatedEdgeEnvironmentsSelector } from '@/react/edge/components/AssociatedEdgeEnvironmentsSelector';
import { EnvironmentsDatatable } from '@/react/edge/edge-stacks/ItemView/EnvironmentsDatatable';
import { edgeJobsModule } from './edge-jobs';
const ngModule = angular
.module('portainer.edge.react.components', [edgeJobsModule])
.component(
'edgeStackEnvironmentsDatatable',
r2a(withUIRouter(withReactQuery(EnvironmentsDatatable)), [])
)
.component(
'edgeGroupsSelector',
r2a(withUIRouter(withReactQuery(EdgeGroupsSelector)), [
@ -64,27 +57,6 @@ const ngModule = angular
'fieldSettings',
])
)
.component(
'edgeStackDeploymentTypeSelector',
r2a(withReactQuery(EdgeStackDeploymentTypeSelector), [
'value',
'onChange',
'hasDockerEndpoint',
'hasKubeEndpoint',
'allowKubeToSelectCompose',
])
)
.component(
'editEdgeStackForm',
r2a(withUIRouter(withReactQuery(withCurrentUser(EditEdgeStackForm))), [
'edgeStack',
'fileContent',
'isSubmitting',
'onEditorChange',
'onSubmit',
'allowKubeToSelectCompose',
])
)
.component(
'edgeGroupAssociationTable',
r2a(withReactQuery(EdgeGroupAssociationTable), [

View file

@ -4,10 +4,20 @@ import { r2a } from '@/react-tools/react2angular';
import { withCurrentUser } from '@/react-tools/withCurrentUser';
import { withUIRouter } from '@/react-tools/withUIRouter';
import { CreateView } from '@/react/edge/edge-stacks/CreateView/CreateView';
import { ItemView } from '@/react/edge/edge-stacks/ItemView/ItemView';
import { ListView } from '@/react/edge/edge-stacks/ListView';
export const stacksModule = angular
.module('portainer.edge.react.views.stacks', [])
.component(
'edgeStacksCreateView',
r2a(withCurrentUser(withUIRouter(CreateView)), [])
)
.component(
'edgeStacksItemView',
r2a(withCurrentUser(withUIRouter(ItemView)), [])
)
.component(
'edgeStacksView',
r2a(withUIRouter(withCurrentUser(ListView)), [])
).name;

View file

@ -5,7 +5,6 @@ import { withCurrentUser } from '@/react-tools/withCurrentUser';
import { withReactQuery } from '@/react-tools/withReactQuery';
import { withUIRouter } from '@/react-tools/withUIRouter';
import { WaitingRoomView } from '@/react/edge/edge-devices/WaitingRoomView';
import { ListView as EdgeStacksListView } from '@/react/edge/edge-stacks/ListView';
import { ListView as EdgeGroupsListView } from '@/react/edge/edge-groups/ListView';
import { templatesModule } from './templates';
@ -22,10 +21,6 @@ export const viewsModule = angular
'waitingRoomView',
r2a(withUIRouter(withReactQuery(withCurrentUser(WaitingRoomView))), [])
)
.component(
'edgeStacksView',
r2a(withUIRouter(withCurrentUser(EdgeStacksListView)), [])
)
.component(
'edgeGroupsView',
r2a(withUIRouter(withCurrentUser(EdgeGroupsListView)), [])

View file

@ -1,39 +0,0 @@
<page-header title="'Edit Edge stack'" breadcrumbs="[{label:'Edge Stacks', link:'edge.stacks'}, $ctrl.stack.Name]" reload="true"> </page-header>
<div class="row" ng-if="$ctrl.stack">
<div class="col-sm-12">
<rd-widget>
<rd-widget-body classes="no-padding">
<uib-tabset active="$ctrl.state.activeTab" justified="true" type="pills">
<uib-tab index="0" classes="btn-sm">
<uib-tab-heading>
<span><pr-icon icon="'layers'"></pr-icon></span> Stack
</uib-tab-heading>
<div style="padding: 20px">
<edit-edge-stack-form
ng-if="$ctrl.edgeGroups && $ctrl.stack && $ctrl.formValues.content !== null"
edge-groups="$ctrl.edgeGroups"
edge-stack="$ctrl.stack"
is-submitting="$ctrl.state.actionInProgress"
on-submit="($ctrl.deployStack)"
on-editor-change="($ctrl.onEditorChange)"
file-content="$ctrl.formValues.content"
allow-kube-to-select-compose="$ctrl.allowKubeToSelectCompose"
></edit-edge-stack-form>
</div>
</uib-tab>
<uib-tab index="1" classes="btn-sm">
<uib-tab-heading>
<span><pr-icon icon="'hard-drive'"></pr-icon></span> Environments
</uib-tab-heading>
<div style="margin-top: 25px">
<edge-stack-environments-datatable></edge-stack-environments-datatable>
</div>
</uib-tab>
</uib-tabset>
</rd-widget-body>
</rd-widget>
</div>
</div>

View file

@ -1,117 +0,0 @@
import { confirmWebEditorDiscard } from '@@/modals/confirm';
import { EnvironmentType } from '@/react/portainer/environments/types';
import { createWebhookId } from '@/portainer/helpers/webhookHelper';
export class EditEdgeStackViewController {
/* @ngInject */
constructor($async, $state, $window, EdgeGroupService, EdgeStackService, Notifications) {
this.$async = $async;
this.$state = $state;
this.$window = $window;
this.EdgeGroupService = EdgeGroupService;
this.EdgeStackService = EdgeStackService;
this.Notifications = Notifications;
this.stack = null;
this.edgeGroups = null;
this.state = {
actionInProgress: false,
activeTab: 0,
isStackDeployed: false,
};
this.formValues = {
content: null,
};
this.deployStack = this.deployStack.bind(this);
this.deployStackAsync = this.deployStackAsync.bind(this);
this.onEditorChange = this.onEditorChange.bind(this);
this.isEditorDirty = this.isEditorDirty.bind(this);
}
async $onInit() {
return this.$async(async () => {
const { stackId, tab } = this.$state.params;
this.state.activeTab = tab ? parseInt(tab, 10) : 0;
try {
const [edgeGroups, model, file] = await Promise.all([
this.EdgeGroupService.groups(),
this.EdgeStackService.stack(stackId),
this.EdgeStackService.stackFile(stackId).catch(() => ''),
]);
this.edgeGroups = edgeGroups;
this.stack = model;
this.originalFileContent = file;
this.formValues = {
content: file,
};
const stackEdgeGroups = model.EdgeGroups.map((id) => this.edgeGroups.find((e) => e.Id === id));
const endpointTypes = stackEdgeGroups.flatMap((group) => group.EndpointTypes);
const initiallyContainsKubeEnv = endpointTypes.includes(EnvironmentType.EdgeAgentOnKubernetes);
const isComposeStack = this.stack.DeploymentType === 0;
this.allowKubeToSelectCompose = initiallyContainsKubeEnv && isComposeStack;
} catch (err) {
this.Notifications.error('Failure', err, 'Unable to retrieve stack data');
}
this.oldFileContent = this.formValues.StackFileContent;
this.$window.onbeforeunload = () => {
if (this.isEditorDirty()) {
return '';
}
};
});
}
$onDestroy() {
this.$window.onbeforeunload = undefined;
}
async uiCanExit() {
if (this.isEditorDirty()) {
return confirmWebEditorDiscard();
}
}
onEditorChange(content) {
this.formValues.content = content;
}
isEditorDirty() {
return !this.state.isStackDeployed && this.formValues.content.replace(/(\r\n|\n|\r)/gm, '') !== this.originalFileContent.replace(/(\r\n|\n|\r)/gm, '');
}
deployStack(values) {
return this.deployStackAsync(values);
}
async deployStackAsync(values) {
this.state.actionInProgress = true;
try {
const updateVersion = !!(this.originalFileContent != values.content || values.useManifestNamespaces !== this.stack.UseManifestNamespaces);
await this.EdgeStackService.updateStack(this.stack.Id, {
stackFileContent: values.content,
edgeGroups: values.edgeGroups,
deploymentType: values.deploymentType,
updateVersion,
retryDeploy: values.retryDeploy,
webhook: values.webhookEnabled ? this.stack.Webhook || createWebhookId() : '',
envVars: values.envVars,
});
this.Notifications.success('Success', 'Stack successfully deployed');
this.state.isStackDeployed = true;
this.$state.go('edge.stacks');
} catch (err) {
this.Notifications.error('Deployment error', err, 'Unable to deploy stack');
} finally {
this.state.actionInProgress = false;
}
}
}

View file

@ -1,8 +0,0 @@
import angular from 'angular';
import { EditEdgeStackViewController } from './editEdgeStackViewController';
angular.module('portainer.edge').component('editEdgeStackView', {
templateUrl: './editEdgeStackView.html',
controller: EditEdgeStackViewController,
});

View file

@ -1,3 +0,0 @@
import angular from 'angular';
export default angular.module('portainer.edge.stacks', []).name;