Compare commits
2 Commits
refactor/E
...
fix/EE-283
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b9131eaa5 | ||
|
|
e9738e2e6d |
@@ -8,7 +8,6 @@ import {
|
||||
usePagination,
|
||||
} from 'react-table';
|
||||
import { useRowSelectColumn } from '@lineup-lite/hooks';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
import { PaginationControls } from '@/portainer/components/pagination-controls';
|
||||
@@ -65,7 +64,6 @@ export function EdgeDevicesDatatable({
|
||||
showWaitingRoomLink,
|
||||
mpsServer,
|
||||
dataset,
|
||||
groups,
|
||||
onRefresh,
|
||||
setLoadingMessage,
|
||||
}: EdgeDevicesTableProps) {
|
||||
@@ -140,8 +138,6 @@ export function EdgeDevicesDatatable({
|
||||
environment.AMTDeviceGUID && environment.AMTDeviceGUID !== ''
|
||||
);
|
||||
|
||||
const groupsById = _.groupBy(groups, 'Id');
|
||||
|
||||
return (
|
||||
<TableContainer>
|
||||
<TableTitle icon="fa-plug" label="Edge Devices">
|
||||
@@ -213,13 +209,8 @@ export function EdgeDevicesDatatable({
|
||||
{page.map((row) => {
|
||||
prepareRow(row);
|
||||
const { key, className, role, style } = row.getRowProps();
|
||||
const group = groupsById[row.original.GroupId];
|
||||
return (
|
||||
<RowProvider
|
||||
key={key}
|
||||
isOpenAmtEnabled={isOpenAmtEnabled}
|
||||
groupName={group[0]?.Name}
|
||||
>
|
||||
<RowProvider key={key} isOpenAmtEnabled={isOpenAmtEnabled}>
|
||||
<TableRow<Environment>
|
||||
cells={row.cells}
|
||||
key={key}
|
||||
|
||||
@@ -2,25 +2,19 @@ import { createContext, useContext, useMemo, PropsWithChildren } from 'react';
|
||||
|
||||
interface RowContextState {
|
||||
isOpenAmtEnabled: boolean;
|
||||
groupName?: string;
|
||||
}
|
||||
|
||||
const RowContext = createContext<RowContextState | null>(null);
|
||||
|
||||
export interface RowProviderProps {
|
||||
groupName?: string;
|
||||
isOpenAmtEnabled: boolean;
|
||||
}
|
||||
|
||||
export function RowProvider({
|
||||
groupName,
|
||||
isOpenAmtEnabled,
|
||||
children,
|
||||
}: PropsWithChildren<RowProviderProps>) {
|
||||
const state = useMemo(
|
||||
() => ({ groupName, isOpenAmtEnabled }),
|
||||
[groupName, isOpenAmtEnabled]
|
||||
);
|
||||
const state = useMemo(() => ({ isOpenAmtEnabled }), [isOpenAmtEnabled]);
|
||||
|
||||
return <RowContext.Provider value={state}>{children}</RowContext.Provider>;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { CellProps, Column } from 'react-table';
|
||||
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
import { DefaultFilter } from '@/portainer/components/datatables/components/Filter';
|
||||
|
||||
export const edgeGroup: Column<Environment> = {
|
||||
Header: 'Edge Groups',
|
||||
accessor: (row) => row.EdgeGroupName,
|
||||
Cell: ({ row }: CellProps<Environment>) => row.original.EdgeGroupName,
|
||||
id: 'edgeGroupName',
|
||||
Filter: DefaultFilter,
|
||||
canHide: true,
|
||||
};
|
||||
@@ -1,21 +1,13 @@
|
||||
import { Column } from 'react-table';
|
||||
import { CellProps, Column } from 'react-table';
|
||||
|
||||
import { Environment } from '@/portainer/environments/types';
|
||||
import { DefaultFilter } from '@/portainer/components/datatables/components/Filter';
|
||||
|
||||
import { useRowContext } from './RowContext';
|
||||
|
||||
export const group: Column<Environment> = {
|
||||
Header: 'Group',
|
||||
accessor: (row) => row.GroupId,
|
||||
Cell: GroupCell,
|
||||
accessor: (row) => row.GroupName,
|
||||
Cell: ({ row }: CellProps<Environment>) => row.original.GroupName,
|
||||
id: 'groupName',
|
||||
Filter: DefaultFilter,
|
||||
canHide: true,
|
||||
};
|
||||
|
||||
function GroupCell() {
|
||||
const { groupName } = useRowContext();
|
||||
|
||||
return groupName;
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@ import { useMemo } from 'react';
|
||||
|
||||
import { name } from './name';
|
||||
import { heartbeat } from './heartbeat';
|
||||
import { edgeGroup } from './edgeGroup';
|
||||
import { group } from './group';
|
||||
import { actions } from './actions';
|
||||
|
||||
export function useColumns() {
|
||||
return useMemo(() => [name, heartbeat, group, actions], []);
|
||||
return useMemo(() => [name, heartbeat, edgeGroup, group, actions], []);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { getEndpoints } from 'Portainer/environments/environment.service';
|
||||
|
||||
angular.module('portainer.edge').controller('EdgeDevicesViewController', EdgeDevicesViewController);
|
||||
/* @ngInject */
|
||||
export function EdgeDevicesViewController($q, $async, EndpointService, GroupService, SettingsService, ModalService, Notifications) {
|
||||
export function EdgeDevicesViewController($q, $async, EndpointService, EdgeGroupService, GroupService, SettingsService, ModalService, Notifications) {
|
||||
var ctrl = this;
|
||||
|
||||
ctrl.edgeDevices = [];
|
||||
@@ -10,13 +10,34 @@ export function EdgeDevicesViewController($q, $async, EndpointService, GroupServ
|
||||
this.getEnvironments = function () {
|
||||
return $async(async () => {
|
||||
try {
|
||||
const [endpointsResponse, groups] = await Promise.all([
|
||||
getEndpoints(0, 100, {
|
||||
edgeDeviceFilter: 'trusted',
|
||||
}),
|
||||
const [endpointsResponse, groups, edgeGroups] = await Promise.all([
|
||||
getEndpoints(0, 100, { edgeDeviceFilter: 'trusted' }),
|
||||
GroupService.groups(),
|
||||
EdgeGroupService.groups(),
|
||||
]);
|
||||
ctrl.groups = groups;
|
||||
// Update GroupName and EdgeGroupName for each endpoint
|
||||
let groupNameMap = new Map();
|
||||
groups.forEach(function (group) {
|
||||
groupNameMap[group.Id] = group.Name;
|
||||
});
|
||||
let endpointEdgeGroupMap = new Map();
|
||||
endpointsResponse.value.forEach(function (endpoint) {
|
||||
endpoint.GroupName = groupNameMap[endpoint.GroupId] ? groupNameMap[endpoint.GroupId] : groupNameMap[1];
|
||||
endpoint.EdgeGroupName = 'Unassigned';
|
||||
endpointEdgeGroupMap[endpoint.Id] = [];
|
||||
});
|
||||
edgeGroups.forEach(function (edgeGroup) {
|
||||
edgeGroup.Endpoints.forEach(function (endpointId) {
|
||||
if (endpointEdgeGroupMap[Number(endpointId)]) {
|
||||
endpointEdgeGroupMap[Number(endpointId)].push(edgeGroup.Name);
|
||||
}
|
||||
});
|
||||
});
|
||||
endpointsResponse.value.forEach(function (endpoint) {
|
||||
if (endpointEdgeGroupMap[endpoint.Id].length > 0) {
|
||||
endpoint.EdgeGroupName = endpointEdgeGroupMap[endpoint.Id].join(', ');
|
||||
}
|
||||
});
|
||||
ctrl.edgeDevices = endpointsResponse.value;
|
||||
} catch (err) {
|
||||
Notifications.error('Failure', err, 'Unable to retrieve edge devices');
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Menu, MenuButton, MenuPopover } from '@reach/menu-button';
|
||||
import { ColumnInstance } from 'react-table';
|
||||
|
||||
export function DefaultFilter({
|
||||
column: { filterValue, setFilter, preFilteredRows, id },
|
||||
column: { filterValue, setFilter, preFilteredRows, id, Header },
|
||||
}: {
|
||||
column: ColumnInstance;
|
||||
}) {
|
||||
@@ -22,6 +22,7 @@ export function DefaultFilter({
|
||||
options={options}
|
||||
filterKey={id}
|
||||
value={filterValue}
|
||||
header={String(Header)}
|
||||
onChange={setFilter}
|
||||
/>
|
||||
);
|
||||
@@ -31,6 +32,7 @@ interface MultipleSelectionFilterProps {
|
||||
options: string[];
|
||||
value: string[];
|
||||
filterKey: string;
|
||||
header: string;
|
||||
onChange: (value: string[]) => void;
|
||||
}
|
||||
|
||||
@@ -38,6 +40,7 @@ function MultipleSelectionFilter({
|
||||
options,
|
||||
value = [],
|
||||
filterKey,
|
||||
header,
|
||||
onChange,
|
||||
}: MultipleSelectionFilterProps) {
|
||||
const enabled = value.length > 0;
|
||||
@@ -59,7 +62,7 @@ function MultipleSelectionFilter({
|
||||
</MenuButton>
|
||||
<MenuPopover className="dropdown-menu">
|
||||
<div className="tableMenu">
|
||||
<div className="menuHeader">Filter by state</div>
|
||||
<div className="menuHeader">Filter by {header}</div>
|
||||
<div className="menuContent">
|
||||
{options.map((option, index) => (
|
||||
<div className="md-checkbox" key={index}>
|
||||
|
||||
@@ -59,8 +59,10 @@ export type Environment = {
|
||||
Type: EnvironmentType;
|
||||
TagIds: TagId[];
|
||||
GroupId: EnvironmentGroupId;
|
||||
GroupName: string;
|
||||
EdgeID?: string;
|
||||
EdgeCheckinInterval?: number;
|
||||
EdgeGroupName?: string;
|
||||
QueryDate?: number;
|
||||
LastCheckInDate?: number;
|
||||
Name: string;
|
||||
|
||||
@@ -61,6 +61,7 @@ function mockEnvironment(type: EnvironmentType): Environment {
|
||||
Id: 1,
|
||||
Name: 'environment',
|
||||
GroupId: 1,
|
||||
GroupName: 'Unassigned',
|
||||
Snapshots: [],
|
||||
Status: EnvironmentStatus.Up,
|
||||
TagIds: [],
|
||||
|
||||
@@ -15,6 +15,7 @@ test('loads component', async () => {
|
||||
const env: Environment = {
|
||||
TagIds: [],
|
||||
GroupId: 1,
|
||||
GroupName: 'Unassigned',
|
||||
Type: 1,
|
||||
Name: 'environment',
|
||||
Status: 1,
|
||||
@@ -36,6 +37,7 @@ test('shows group name', async () => {
|
||||
const env: Environment = {
|
||||
TagIds: [],
|
||||
GroupId: groupId,
|
||||
GroupName: 'Unassigned',
|
||||
Type: 1,
|
||||
Name: 'environment',
|
||||
Status: 1,
|
||||
|
||||
Reference in New Issue
Block a user