fix(UI) Update all network pages EE-3509 (#7324)

* EE-3509 update all network pages

* EE-3509 update access control panel and network container table
pull/7307/head^2
Rex Wang 2022-07-25 07:57:18 +08:00 committed by GitHub
parent 5f5cb36df1
commit 5b3f099f4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 71 additions and 60 deletions

View File

@ -93,78 +93,78 @@
<th>
<a ng-click="$ctrl.changeOrderBy('Name')">
Name
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Name' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Name' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'Name' && !$ctrl.state.reverseOrder"> </pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'Name' && $ctrl.state.reverseOrder"> </pr-icon>
</a>
</th>
<th>
<a ng-click="$ctrl.changeOrderBy('StackName')">
Stack
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'StackName' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'StackName' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'StackName' && !$ctrl.state.reverseOrder"> </pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'StackName' && $ctrl.state.reverseOrder"> </pr-icon>
</a>
</th>
<th>
<a ng-click="$ctrl.changeOrderBy('Driver')">
Driver
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Driver' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Driver' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'Driver' && !$ctrl.state.reverseOrder"> </pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'Driver' && $ctrl.state.reverseOrder"> </pr-icon>
</a>
</th>
<th>
<a ng-click="$ctrl.changeOrderBy('Attachable')">
Attachable
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Attachable' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Attachable' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'Attachable' && !$ctrl.state.reverseOrder"> </pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'Attachable' && $ctrl.state.reverseOrder"> </pr-icon>
</a>
</th>
<th>
<a ng-click="$ctrl.changeOrderBy('IPAM.Driver')">
IPAM Driver
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'IPAM.Driver' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'IPAM.Driver' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'IPAM.Driver' && !$ctrl.state.reverseOrder"> </pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'IPAM.Driver' && $ctrl.state.reverseOrder"> </pr-icon>
</a>
</th>
<th>
<a ng-click="$ctrl.changeOrderBy('IPAM.IPV4Configs[0].Subnet')">
IPV4 IPAM Subnet
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV4Configs[0].Subnet' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV4Configs[0].Subnet' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV4Configs[0].Subnet' && !$ctrl.state.reverseOrder"> </pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV4Configs[0].Subnet' && $ctrl.state.reverseOrder"> </pr-icon>
</a>
</th>
<th>
<a ng-click="$ctrl.changeOrderBy('IPAM.IPV4Configs[0].Gateway')">
IPV4 IPAM Gateway
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV4Configs[0].Gateway' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV4Configs[0].Gateway' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV4Configs[0].Gateway' && !$ctrl.state.reverseOrder"> </pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV4Configs[0].Gateway' && $ctrl.state.reverseOrder"> </pr-icon>
</a>
</th>
<th>
<a ng-click="$ctrl.changeOrderBy('IPAM.IPV6Configs[0].Subnet')">
IPV6 IPAM Subnet
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV6Configs[0].Subnet' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV6Configs[0].Subnet' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV6Configs[0].Subnet' && !$ctrl.state.reverseOrder"> </pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV6Configs[0].Subnet' && $ctrl.state.reverseOrder"> </pr-icon>
</a>
</th>
<th>
<a ng-click="$ctrl.changeOrderBy('IPAM.IPV6Configs[0].Gateway')">
IPV6 IPAM Gateway
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV6Configs[0].Gateway' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV6Configs[0].Gateway' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV6Configs[0].Gateway' && !$ctrl.state.reverseOrder"> </pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'IPAM.IPV6Configs[0].Gateway' && $ctrl.state.reverseOrder"> </pr-icon>
</a>
</th>
<th ng-if="$ctrl.showHostColumn">
<a ng-click="$ctrl.changeOrderBy('NodeName')">
Host
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'NodeName' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'NodeName' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'NodeName' && !$ctrl.state.reverseOrder"> </pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'NodeName' && $ctrl.state.reverseOrder"> </pr-icon>
</a>
</th>
<th>
<a ng-click="$ctrl.changeOrderBy('ResourceControl.Ownership')">
Ownership
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'ResourceControl.Ownership' && !$ctrl.state.reverseOrder"></i>
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'ResourceControl.Ownership' && $ctrl.state.reverseOrder"></i>
<pr-icon icon="'arrow-down'" feather="true" ng-if="$ctrl.state.orderBy === 'ResourceControl.Ownership' && !$ctrl.state.reverseOrder"></pr-icon>
<pr-icon icon="'arrow-up'" feather="true" ng-if="$ctrl.state.orderBy === 'ResourceControl.Ownership' && $ctrl.state.reverseOrder"></pr-icon>
</a>
</th>
</tr>

View File

@ -45,7 +45,7 @@
<input type="text" class="form-control" ng-model="option.value" placeholder="e.g. true" />
</div>
<button class="btn btn-sm btn-light" type="button" ng-click="removeDriverOption($index)">
<pr-icon icon="'trash'" feather="true" class-name="'icon-secondary icon-md'"></pr-icon>
<pr-icon icon="'trash-2'" feather="true" class-name="'icon-secondary icon-md'"></pr-icon>
</button>
</div>
<div class="small interactive text-muted vertical-center mt-1" ng-click="addDriverOption()">
@ -92,7 +92,7 @@
/>
</div>
<button class="btn btn-md btn-light" type="button" ng-click="removeIPV4AuxAddress($index)">
<pr-icon icon="'trash'" feather="true" class-name="'icon-secondary icon-md'"></pr-icon>
<pr-icon icon="'trash-2'" feather="true" class-name="'icon-secondary icon-md'"></pr-icon>
</button>
<div class="col-sm-12 small text-warning" ng-if="state.IPV4AuxiliaryAddressesError[$index]">
<p class="vertical-center"> <pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Exclude ip cannot be the same as gateway.</p>
@ -139,7 +139,7 @@
/>
</div>
<button class="btn btn-md btn-light" type="button" ng-click="removeIPV6AuxAddress($index)">
<pr-icon icon="'trash'" feather="true" class-name="'icon-secondary icon-md'"></pr-icon>
<pr-icon icon="'trash-2'" feather="true" class-name="'icon-secondary icon-md'"></pr-icon>
</button>
<div class="col-sm-12 small text-warning" ng-show="state.IPV6AuxiliaryAddressesError[$index]">
<p class="vertical-center"> <pr-icon icon="'alert-triangle'" mode="'warning'" feather="true"></pr-icon> Exclude ip cannot be the same as gateway.</p>
@ -167,7 +167,7 @@
<input type="text" class="form-control" ng-model="label.value" placeholder="e.g. bar" />
</div>
<button class="btn btn-sm btn-light" type="button" ng-click="removeLabel($index)">
<pr-icon icon="'trash'" feather="true" class-name="'icon-secondary icon-md'"></pr-icon>
<pr-icon icon="'trash-2'" feather="true" class-name="'icon-secondary icon-md'"></pr-icon>
</button>
</div>
<div class="form-group">

View File

@ -5,7 +5,7 @@ import { r2a } from '@/react-tools/react2angular';
import { TeamMembership, Role } from '@/portainer/teams/types';
import { useUserMembership } from '@/portainer/users/queries';
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
import { Table, TableContainer, TableTitle } from '@@/datatables';
import { Button } from '@@/buttons';
import { ResourceControlType, ResourceId } from '../types';
@ -45,9 +45,9 @@ export function AccessControlPanel({
return (
<div className="row">
<div className="col-sm-12">
<Widget>
<WidgetTitle title="Access control" icon="fa-eye" />
<WidgetBody className="no-padding">
<TableContainer>
<TableTitle label="Access control" icon="eye" featherIcon />
<Table className="no-padding">
<AccessControlPanelDetails
resourceType={resourceType}
resourceControl={resourceControl}
@ -73,8 +73,8 @@ export function AccessControlPanel({
onUpdateSuccess={handleUpdateSuccess}
/>
)}
</WidgetBody>
</Widget>
</Table>
</TableContainer>
</div>
</div>
);

View File

@ -3,13 +3,14 @@
<!-- access-control-switch -->
<div class="form-group">
<div class="col-sm-12">
<label for="ownership" class="control-label text-left">
Enable access control
<portainer-tooltip message="'When enabled, you can restrict the access and management of this resource.'"></portainer-tooltip>
</label>
<label class="switch" style="margin-left: 20px">
<input name="ownership" type="checkbox" ng-model="$ctrl.formData.AccessControlEnabled" /><i data-cy="portainer-accessMgmtToggle"></i>
</label>
<por-switch-field
label-class="'col-sm-2'"
checked="$ctrl.formData.AccessControlEnabled"
label="'Enable access control'"
tooltip="'When enabled, you can restrict the access and management of this resource.'"
on-change="($ctrl.onChangeEnablement)"
data-cy="portainer-accessMgmtToggle"
></por-switch-field>
</div>
</div>
<!-- !access-control-switch -->

View File

@ -3,12 +3,13 @@ import { ResourceControlOwnership as RCO } from '@/portainer/access-control/type
angular.module('portainer.app').controller('porAccessControlFormController', [
'$q',
'$scope',
'UserService',
'TeamService',
'Notifications',
'Authentication',
'ResourceControlService',
function ($q, UserService, TeamService, Notifications, Authentication, ResourceControlService) {
function ($q, $scope, UserService, TeamService, Notifications, Authentication, ResourceControlService) {
var ctrl = this;
ctrl.RCO = RCO;
@ -79,6 +80,12 @@ angular.module('portainer.app').controller('porAccessControlFormController', [
.catch(function error(err) {
Notifications.error('Failure', err, 'Unable to retrieve access control information');
});
this.onChangeEnablement = function (enable) {
$scope.$evalAsync(() => {
ctrl.formData.AccessControlEnabled = enable;
});
};
}
},
]);

View File

@ -1,7 +1,7 @@
import { Authorized } from '@/portainer/hooks/useUser';
import { EnvironmentId } from '@/portainer/environments/types';
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
import { Table, TableContainer, TableTitle } from '@@/datatables';
import { DetailsTable } from '@@/DetailsTable';
import { Button } from '@@/buttons';
import { Link } from '@@/Link';
@ -39,9 +39,9 @@ export function NetworkContainersTable({
return (
<div className="row">
<div className="col-lg-12 col-md-12 col-xs-12">
<Widget>
<WidgetTitle title="Containers in network" icon="fa-server" />
<WidgetBody className="nopadding">
<TableContainer>
<TableTitle label="Containers in network" icon="server" featherIcon />
<Table className="nopadding">
<DetailsTable
headers={tableHeaders}
dataCy="networkDetails-networkContainers"
@ -90,8 +90,8 @@ export function NetworkContainersTable({
</tr>
))}
</DetailsTable>
</WidgetBody>
</Widget>
</Table>
</TableContainer>
</div>
</div>
);

View File

@ -3,9 +3,10 @@ import DockerNetworkHelper from 'Docker/helpers/networkHelper';
import { Authorized } from '@/portainer/hooks/useUser';
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
import { Table, TableContainer, TableTitle } from '@@/datatables';
import { DetailsTable } from '@@/DetailsTable';
import { Button } from '@@/buttons';
import { Icon } from '@@/Icon';
import { isSystemNetwork } from '../network.helper';
import { DockerNetwork, IPConfig } from '../types';
@ -30,9 +31,9 @@ export function NetworkDetailsTable({
return (
<div className="row">
<div className="col-lg-12 col-md-12 col-xs-12">
<Widget>
<WidgetTitle title="Network details" icon="fa-sitemap" />
<WidgetBody className="nopadding">
<TableContainer>
<TableTitle label="Network details" icon="share-2" featherIcon />
<Table className="nopadding">
<DetailsTable dataCy="networkDetails-detailsTable">
{/* networkRowContent */}
<DetailsTable.Row label="Name">{network.Name}</DetailsTable.Row>
@ -46,8 +47,10 @@ export function NetworkDetailsTable({
color="danger"
onClick={() => onRemoveNetworkClicked()}
>
<i
className="fa fa-trash-alt space-right"
<Icon
icon="trash-2"
feather
className="space-right"
aria-hidden="true"
/>
Delete this network
@ -102,8 +105,8 @@ export function NetworkDetailsTable({
</Fragment>
))}
</DetailsTable>
</WidgetBody>
</Widget>
</Table>
</TableContainer>
</div>
</div>
);

View File

@ -1,4 +1,4 @@
import { Widget, WidgetBody, WidgetTitle } from '@@/Widget';
import { Table, TableContainer, TableTitle } from '@@/datatables';
import { DetailsTable } from '@@/DetailsTable';
import { NetworkOptions } from '../types';
@ -17,9 +17,9 @@ export function NetworkOptionsTable({ options }: Props) {
return (
<div className="row">
<div className="col-lg-12 col-md-12 col-xs-12">
<Widget>
<WidgetTitle title="Network options" icon="fa-cogs" />
<WidgetBody className="nopadding">
<TableContainer>
<TableTitle label="Network options" icon="share-2" featherIcon />
<Table className="nopadding">
<DetailsTable dataCy="networkDetails-networkOptionsTable">
{networkEntries.map(([key, value]) => (
<DetailsTable.Row key={key} label={key}>
@ -27,8 +27,8 @@ export function NetworkOptionsTable({ options }: Props) {
</DetailsTable.Row>
))}
</DetailsTable>
</WidgetBody>
</Widget>
</Table>
</TableContainer>
</div>
</div>
);