feat(edge-devices): set specific page to view [EE-2082] (#6869)

This commit is contained in:
Chaim Lev-Ari
2022-05-23 10:57:22 +03:00
committed by GitHub
parent 12cddbd896
commit b031a30f62
54 changed files with 892 additions and 639 deletions
@@ -0,0 +1,35 @@
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]
);
return <RowContext.Provider value={state}>{children}</RowContext.Provider>;
}
export function useRowContext() {
const context = useContext(RowContext);
if (!context) {
throw new Error('should be nested under RowProvider');
}
return context;
}
@@ -0,0 +1,64 @@
import { CellProps, Column } from 'react-table';
import { MenuItem, MenuLink } from '@reach/menu-button';
import { useRouter, useSref } from '@uirouter/react';
import { Environment } from '@/portainer/environments/types';
import { ActionsMenu } from '@/portainer/components/datatables/components/ActionsMenu';
import { snapshotEndpoint } from '@/portainer/environments/environment.service';
import * as notifications from '@/portainer/services/notifications';
import { getRoute } from '@/portainer/environments/utils';
export const actions: Column<Environment> = {
Header: 'Actions',
accessor: () => 'actions',
id: 'actions',
disableFilters: true,
canHide: true,
disableResizing: true,
width: '5px',
sortType: 'string',
Filter: () => null,
Cell: ActionsCell,
};
export function ActionsCell({
row: { original: environment },
}: CellProps<Environment>) {
const router = useRouter();
const environmentRoute = getRoute(environment);
const browseLinkProps = useSref(environmentRoute, {
id: environment.Id,
endpointId: environment.Id,
});
const showRefreshSnapshot = false; // remove and show MenuItem when feature is available
return (
<ActionsMenu>
<MenuLink href={browseLinkProps.href} onClick={browseLinkProps.onClick}>
Browse
</MenuLink>
{showRefreshSnapshot && (
<MenuItem hidden onSelect={() => handleRefreshSnapshotClick()}>
Refresh Snapshot
</MenuItem>
)}
</ActionsMenu>
);
async function handleRefreshSnapshotClick() {
try {
await snapshotEndpoint(environment.Id);
notifications.success('Success', 'Environment updated');
} catch (err) {
notifications.error(
'Failure',
err as Error,
'An error occurred during environment snapshot'
);
} finally {
await router.stateService.reload();
}
}
}
@@ -0,0 +1,21 @@
import { 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,
id: 'groupName',
Filter: DefaultFilter,
canHide: true,
};
function GroupCell() {
const { groupName } = useRowContext();
return groupName;
}
@@ -0,0 +1,26 @@
import { CellProps, Column } from 'react-table';
import { Environment } from '@/portainer/environments/types';
import { EdgeIndicator } from '@/portainer/home/EnvironmentList/EnvironmentItem/EdgeIndicator';
export const heartbeat: Column<Environment> = {
Header: 'Heartbeat',
accessor: 'Status',
id: 'status',
Cell: StatusCell,
disableFilters: true,
canHide: true,
};
export function StatusCell({
row: { original: environment },
}: CellProps<Environment>) {
return (
<EdgeIndicator
checkInInterval={environment.EdgeCheckinInterval}
edgeId={environment.EdgeID}
lastCheckInDate={environment.LastCheckInDate}
queryDate={environment.QueryDate}
/>
);
}
@@ -0,0 +1,10 @@
import { useMemo } from 'react';
import { name } from './name';
import { heartbeat } from './heartbeat';
import { group } from './group';
import { actions } from './actions';
export function useColumns() {
return useMemo(() => [name, heartbeat, group, actions], []);
}
@@ -0,0 +1,38 @@
import { CellProps, Column } from 'react-table';
import { Environment } from '@/portainer/environments/types';
import { Link } from '@/portainer/components/Link';
import { ExpandingCell } from '@/portainer/components/datatables/components/ExpandingCell';
import { useRowContext } from './RowContext';
export const name: Column<Environment> = {
Header: 'Name',
accessor: (row) => row.Name,
id: 'name',
Cell: NameCell,
disableFilters: true,
Filter: () => null,
canHide: false,
sortType: 'string',
};
export function NameCell({ value: name, row }: CellProps<Environment>) {
const { isOpenAmtEnabled } = useRowContext();
const showExpandedRow = !!(
isOpenAmtEnabled &&
row.original.AMTDeviceGUID &&
row.original.AMTDeviceGUID.length > 0
);
return (
<ExpandingCell row={row} showExpandArrow={showExpandedRow}>
<Link
to="portainer.endpoints.endpoint"
params={{ id: row.original.Id }}
title={name}
>
{name}
</Link>
</ExpandingCell>
);
}