1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-02 20:35:25 +02:00

refactor(docker/services): migrate service tasks to react [EE-4676] (#10328)

This commit is contained in:
Chaim Lev-Ari 2023-10-23 13:52:49 +03:00 committed by GitHub
parent 70455320be
commit 1fa63f6ab7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 175 additions and 259 deletions

View file

@ -1,133 +0,0 @@
<div class="datatable">
<rd-widget>
<rd-widget-body classes="no-padding">
<div class="toolBar">
<div class="toolBarTitle vertical-center">
<div class="widget-icon space-right">
<pr-icon icon="$ctrl.titleIcon"></pr-icon>
</div>
{{ $ctrl.titleText }}
</div>
<div class="searchBar vertical-center">
<pr-icon icon="'search'"></pr-icon>
<input
type="text"
class="searchInput"
ng-model="$ctrl.state.textFilter"
ng-change="$ctrl.onTextFilterChange()"
placeholder="Search for a task..."
ng-model-options="{ debounce: 300 }"
/>
</div>
</div>
<div class="table-responsive">
<table class="table-hover nowrap-cells table">
<thead>
<tr>
<th>
<table-column-header
col-title="'Status'"
can-sort="true"
is-sorted="$ctrl.state.orderBy === 'Status'"
is-sorted-desc="$ctrl.state.orderBy === 'Status' && $ctrl.state.reverseOrder"
ng-click="$ctrl.changeOrderBy('Status')"
></table-column-header>
</th>
<th>
<table-column-header
col-title="'Id'"
can-sort="true"
is-sorted="$ctrl.state.orderBy === 'Id'"
is-sorted-desc="$ctrl.state.orderBy === 'Id' && $ctrl.state.reverseOrder"
ng-click="$ctrl.changeOrderBy('Id')"
></table-column-header>
</th>
<th>Actions</th>
<th ng-if="$ctrl.showSlotColumn">
<table-column-header
col-title="'Slot'"
can-sort="true"
is-sorted="$ctrl.state.orderBy === 'Slot'"
is-sorted-desc="$ctrl.state.orderBy === 'Slot' && $ctrl.state.reverseOrder"
ng-click="$ctrl.changeOrderBy('Slot')"
></table-column-header>
</th>
<th>
<table-column-header
col-title="'Node'"
can-sort="true"
is-sorted="$ctrl.state.orderBy === 'NodeId'"
is-sorted-desc="$ctrl.state.orderBy === 'NodeId' && $ctrl.state.reverseOrder"
ng-click="$ctrl.changeOrderBy('NodeId')"
></table-column-header>
</th>
<th>
<table-column-header
col-title="'Last Update'"
can-sort="true"
is-sorted="$ctrl.state.orderBy === 'Updated'"
is-sorted-desc="$ctrl.state.orderBy === 'Updated' && $ctrl.state.reverseOrder"
ng-click="$ctrl.changeOrderBy('Updated')"
></table-column-header>
</th>
</tr>
</thead>
<tbody>
<tr
dir-paginate="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit))"
ng-class="{ active: item.Checked }"
>
<td
><span class="label label-{{ item.Status.State | taskstatusbadge }}">{{ item.Status.State }}</span></td
>
<td>
<a ng-if="!$ctrl.agentProxy || !item.Container" ui-sref="docker.tasks.task({id: item.Id})" class="monospaced"
>{{ item.ServiceName }}{{ item.Slot ? '.' + item.Slot : '' }}{{ '.' + item.Id }}</a
>
<a ng-if="$ctrl.agentProxy && item.Container" ui-sref="docker.containers.container({ id: item.Container.Id, nodeName: item.Container.NodeName })" class="monospaced"
>{{ item.ServiceName }}{{ item.Slot ? '.' + item.Slot : '' }}{{ '.' + item.Id }}</a
>
</td>
<td>
<task-table-quick-actions ng-if="!$ctrl.agentProxy || !item.Container" task-id="item.Id" state="$ctrl.state"></task-table-quick-actions>
<container-quick-actions
ng-if="$ctrl.agentProxy && item.Container"
container-id="item.Container.Id"
node-name="item.Container.NodeName"
status="item.Status.State"
state="$ctrl.state"
></container-quick-actions>
</td>
<td ng-if="$ctrl.showSlotColumn">{{ item.Slot ? item.Slot : '-' }}</td>
<td>{{ item.NodeId | tasknodename: $ctrl.nodes }}</td>
<td>{{ item.Updated | getisodate }}</td>
</tr>
<tr ng-if="!$ctrl.dataset">
<td colspan="6" class="text-muted text-center">Loading...</td>
</tr>
<tr ng-if="$ctrl.state.filteredDataSet.length === 0">
<td colspan="6" class="text-muted text-center">No task available.</td>
</tr>
</tbody>
</table>
</div>
<div class="footer" ng-if="$ctrl.dataset">
<div class="paginationControls">
<form class="form-inline vertical-center">
<span class="limitSelector">
<span style="margin-right: 5px"> Items per page </span>
<select class="form-control" ng-model="$ctrl.state.paginatedItemLimit" ng-change="$ctrl.changePaginationLimit()" data-cy="component-paginationSelect">
<option value="0">All</option>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</span>
<dir-pagination-controls max-size="5"></dir-pagination-controls>
</form>
</div>
</div>
</rd-widget-body>
</rd-widget>
</div>

View file

@ -1,16 +0,0 @@
angular.module('portainer.docker').component('tasksDatatable', {
templateUrl: './tasksDatatable.html',
controller: 'TasksDatatableController',
bindings: {
titleText: '@',
titleIcon: '@',
dataset: '<',
tableKey: '@',
orderBy: '@',
reverseOrder: '<',
nodes: '<',
showSlotColumn: '<',
showLogsButton: '<',
agentProxy: '<',
},
});

View file

@ -1,49 +0,0 @@
angular.module('portainer.docker').controller('TasksDatatableController', [
'$scope',
'$controller',
'DatatableService',
function ($scope, $controller, DatatableService) {
angular.extend(this, $controller('GenericDatatableController', { $scope: $scope }));
this.state = Object.assign(this.state, {
showQuickActionStats: true,
showQuickActionLogs: true,
showQuickActionExec: true,
showQuickActionInspect: true,
showQuickActionAttach: false,
});
this.$onInit = function () {
this.setDefaults();
this.prepareTableFromDataset();
this.state.orderBy = this.orderBy;
var storedOrder = DatatableService.getDataTableOrder(this.tableKey);
if (storedOrder !== null) {
this.state.reverseOrder = storedOrder.reverse;
this.state.orderBy = storedOrder.orderBy;
}
var textFilter = DatatableService.getDataTableTextFilters(this.tableKey);
if (textFilter !== null) {
this.state.textFilter = textFilter;
this.onTextFilterChange();
}
var storedFilters = DatatableService.getDataTableFilters(this.tableKey);
if (storedFilters !== null) {
this.filters = storedFilters;
}
if (this.filters && this.filters.state) {
this.filters.state.open = false;
}
var storedSettings = DatatableService.getDataTableSettings(this.tableKey);
if (storedSettings !== null) {
this.settings = storedSettings;
this.settings.open = false;
}
this.onSettingsRepeaterChange();
};
},
]);

View file

@ -3,7 +3,6 @@ import angular from 'angular';
import { r2a } from '@/react-tools/react2angular';
import { withControlledInput } from '@/react-tools/withControlledInput';
import { StackContainersDatatable } from '@/react/common/stacks/ItemView/StackContainersDatatable';
import { ContainerQuickActions } from '@/react/docker/containers/components/ContainerQuickActions';
import { TemplateListDropdownAngular } from '@/react/docker/app-templates/TemplateListDropdown';
import { TemplateListSortAngular } from '@/react/docker/app-templates/TemplateListSort';
import { withCurrentUser } from '@/react-tools/withCurrentUser';
@ -40,15 +39,6 @@ const ngModule = angular
])
.component('dockerfileDetails', r2a(DockerfileDetails, ['image']))
.component('dockerHealthStatus', r2a(HealthStatus, ['health']))
.component(
'containerQuickActions',
r2a(withUIRouter(withCurrentUser(ContainerQuickActions)), [
'containerId',
'nodeName',
'state',
'status',
])
)
.component('templateListDropdown', TemplateListDropdownAngular)
.component('templateListSort', TemplateListSortAngular)
.component(

View file

@ -2,22 +2,18 @@ import angular from 'angular';
import { r2a } from '@/react-tools/react2angular';
import { withUIRouter } from '@/react-tools/withUIRouter';
import { TasksDatatable } from '@/react/docker/services/ListView/ServicesDatatable/TasksDatatable';
import { withCurrentUser } from '@/react-tools/withCurrentUser';
import { TaskTableQuickActions } from '@/react/docker/services/common/TaskTableQuickActions';
import { ServicesDatatable } from '@/react/docker/services/ListView/ServicesDatatable';
import { TasksDatatable } from '@/react/docker/services/ItemView/TasksDatatable';
export const servicesModule = angular
.module('portainer.docker.react.components.services', [])
.component(
'dockerServiceTasksDatatable',
r2a(withUIRouter(withCurrentUser(TasksDatatable)), ['dataset', 'search'])
)
.component(
'dockerTaskTableQuickActions',
r2a(withUIRouter(withCurrentUser(TaskTableQuickActions)), [
'state',
'taskId',
r2a(withUIRouter(withCurrentUser(TasksDatatable)), [
'serviceName',
'dataset',
'isSlotColumnVisible',
])
)
.component(

View file

@ -1,14 +1,6 @@
<div ng-if="tasks.length > 0 && nodes" id="service-tasks">
<tasks-datatable
title-text="Tasks"
title-icon="list"
dataset="tasks"
table-key="service-tasks"
order-by="Updated"
reverse-order="true"
nodes="nodes"
show-slot-column="service.Mode !== 'global'"
show-logs-button="applicationState.endpoint.apiVersion >= 1.30"
agent-proxy="applicationState.endpoint.mode.agentProxy"
></tasks-datatable>
</div>
<docker-service-tasks-datatable
ng-if="tasks.length > 0"
dataset="tasks"
is-slot-column-visible="service.Mode !== 'global'"
service-name="service.Name"
></docker-service-tasks-datatable>

View file

@ -253,6 +253,7 @@
<div id="service-labels" class="padding-top" ng-include="'app/docker/views/services/edit/includes/servicelabels.html'"></div>
<div id="service-configs" class="padding-top" ng-include="'app/docker/views/services/edit/includes/configs.html'"></div>
<div id="service-secrets" ng-if="applicationState.endpoint.apiVersion >= 1.25" class="padding-top" ng-include="'app/docker/views/services/edit/includes/secrets.html'"></div>
<div id="service-tasks" class="padding-top" ng-include="'app/docker/views/services/edit/includes/tasks.html'"></div>
</div>
</div>
<div id="service-tasks" class="padding-top" ng-include="'app/docker/views/services/edit/includes/tasks.html'"></div>