Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions tavern/internal/www/build/asset-manifest.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tavern/internal/www/build/index.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

148 changes: 73 additions & 75 deletions tavern/internal/www/src/components/tavern-base-ui/table/Table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,82 +50,80 @@ export const Table = ({
};

return (
<div className="overflow-x-auto -mx-4 sm:-mx-6 xl:-mx-8">
<div className="inline-block min-w-full align-middle">
<table className="w-full divide-y divide-gray-200 table-fixed">
<thead className="bg-gray-50 sticky top-0 z-5">
{table.getHeaderGroups().map(headerGroup => (
<tr key={headerGroup.id}>
{headerGroup.headers.map(header => {
return (
<th
key={header.id}
colSpan={header.colSpan}
scope="col"
className={`px-4 sm:px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider ${header.column.getCanSort() && "cursor-pointer"}`}
onClick={header.column.getToggleSortingHandler()}
style={{
width: header.getSize() !== 0 ? header.getSize() : undefined,
}}
>
{header.isPlaceholder ? null : (
<div
{...{
className: header.column.getCanSort()
? 'cursor-pointer select-none'
: '',
onClick: header.column.getToggleSortingHandler(),
}}
>
{flexRender(
header.column.columnDef.header,
header.getContext()
)}
{{
asc: <TriangleUpIcon w={4} />,
desc: <TriangleDownIcon w={4} />
}[header.column.getIsSorted() as string] ?? null}
</div>
)}
</th>
)
})}
</tr>
))}
</thead>
<tbody className="bg-white divide-y divide-gray-200" ref={tbodyRef}>
{table.getRowModel().rows.map(row => {
return (
<Fragment key={row.id}>
<tr onClick={(event) => onRowClick && onRowClick(row, event)} tabIndex={0} onKeyDown={(e) => handleKeyDown(e, row)} className={onRowClick && `hover:cursor-pointer hover:bg-gray-100`}>
{/* first row is a normal row */}
{row.getVisibleCells().map(cell => {
return (
<td key={cell.id} className="px-4 sm:px-6 py-4" style={{
width: cell.column.getSize(),
}}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</td>
)
})}
</tr>
{row.getIsExpanded() && (
<tr>
{/* 2nd row is a custom 1 cell row */}
<td colSpan={row.getVisibleCells().length}>
{renderSubComponent && renderSubComponent({ row })}
<div className="inline-block min-w-full align-middle">
<table className="w-full divide-y divide-gray-200 table-fixed">
<thead className="bg-gray-50 sticky top-0 z-5">
{table.getHeaderGroups().map(headerGroup => (
<tr key={headerGroup.id}>
{headerGroup.headers.map(header => {
return (
<th
key={header.id}
colSpan={header.colSpan}
scope="col"
className={`px-4 sm:px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider ${header.column.getCanSort() && "cursor-pointer"}`}
onClick={header.column.getToggleSortingHandler()}
style={{
width: header.getSize() !== 0 ? header.getSize() : undefined,
}}
>
{header.isPlaceholder ? null : (
<div
{...{
className: header.column.getCanSort()
? 'cursor-pointer select-none'
: '',
onClick: header.column.getToggleSortingHandler(),
}}
>
{flexRender(
header.column.columnDef.header,
header.getContext()
)}
{{
asc: <TriangleUpIcon w={4} />,
desc: <TriangleDownIcon w={4} />
}[header.column.getIsSorted() as string] ?? null}
</div>
)}
</th>
)
})}
</tr>
))}
</thead>
<tbody className="bg-white divide-y divide-gray-200" ref={tbodyRef}>
{table.getRowModel().rows.map(row => {
return (
<Fragment key={row.id}>
<tr onClick={(event) => onRowClick && onRowClick(row, event)} tabIndex={0} onKeyDown={(e) => handleKeyDown(e, row)} className={onRowClick && `hover:cursor-pointer hover:bg-gray-100`}>
{/* first row is a normal row */}
{row.getVisibleCells().map(cell => {
return (
<td key={cell.id} className="px-4 sm:px-6 py-4" style={{
width: cell.column.getSize(),
}}>
{flexRender(
cell.column.columnDef.cell,
cell.getContext()
)}
</td>
</tr>
)}
</Fragment>
)
})}
</tbody>
</table>
</div>
)
})}
</tr>
{row.getIsExpanded() && (
<tr>
{/* 2nd row is a custom 1 cell row */}
<td colSpan={row.getVisibleCells().length}>
{renderSubComponent && renderSubComponent({ row })}
</td>
</tr>
)}
</Fragment>
)
})}
</tbody>
</table>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { EmptyState, EmptyStateType } from '../EmptyState';
import { ApolloError } from '@apollo/client';

type TableWrapperProps = {
totalItems: null | number;
totalItems?: number;
loading: boolean;
error: ApolloError | undefined;
title?: string;
Expand All @@ -30,7 +30,7 @@ export const TableWrapper: React.FC<TableWrapperProps> = ({
if (error) {
return <EmptyState type={EmptyStateType.error} label="Error loading data" />;
}
else if (loading || totalItems === null) {
else if (loading || totalItems === undefined) {
return <EmptyState type={EmptyStateType.loading} label="Loading data..." />;
}
else if (totalItems === 0) {
Expand All @@ -39,7 +39,7 @@ export const TableWrapper: React.FC<TableWrapperProps> = ({
else {
return (
<>
<div className="px-4 sm:px-6 xl:px-8">
<div className="overflow-x-auto">
{table}
</div>
{pagination}
Expand All @@ -49,24 +49,21 @@ export const TableWrapper: React.FC<TableWrapperProps> = ({
}

return (
<div className="flex flex-col justify-center items-center gap-6">
<div className="flex flex-col w-full -mx-4 sm:-mx-6 xl:-mx-8">
{/* Controls Section */}
{(filterControls || sortingControls) && (
<div className={`
flex flex-row justify-between items-center
px-4 sm:px-6 xl:px-8 py-2 border-b border-gray-200 bg-white gap-2
${stickyControls ? 'sticky top-0 z-5 shadow-sm' : ''}
`}>
<h3 className="text-xl font-semibold leading-6 text-gray-900 md:visible invisible">{title}</h3>
<div className="flex flex-row justify-end gap-2 w-full md:w-auto">
{sortingControls}
{filterControls}
</div>
<div className="flex flex-col w-full">
{/* Controls Section */}
{(filterControls || sortingControls) && (
<div className={`
flex flex-row justify-between items-center border-b border-gray-200 bg-white gap-2 pb-2
${stickyControls ? 'sticky top-0 z-5 shadow-sm' : ''}
`}>
<h3 className="text-xl font-semibold leading-6 text-gray-900 md:visible invisible">{title}</h3>
<div className="flex flex-row justify-end gap-2 w-full md:w-auto">
{sortingControls}
{filterControls}
</div>
)}
{renderTableContent()}
</div>
</div>
)}
{renderTableContent()}
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ const AccessHostActivityTable = ({ hostActivity, term }: { hostActivity: any, te
];

return (
<Table columns={columns} data={hostActivity} onRowClick={handleOnClick} />
<div className="w-full">
<Table columns={columns} data={hostActivity} onRowClick={handleOnClick} />
</div>
)
}
export default AccessHostActivityTable;
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const HostTaskTab = () => {
return (
<TableWrapper
title="Tasks"
totalItems={data?.tasks?.totalCount || null}
totalItems={data?.tasks?.totalCount}
loading={loading}
error={error}
filterControls={<FilterControls type={FilterPageType.HOST_TASK} />}
Expand Down
2 changes: 1 addition & 1 deletion tavern/internal/www/src/pages/host-list/HostList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const HostList: React.FC = () => {
/>
<TableWrapper
title="Hosts"
totalItems={data?.hosts?.totalCount || null}
totalItems={data?.hosts?.totalCount}
loading={loading}
error={error}
filterControls={<FilterControls type={FilterPageType.HOST} />}
Expand Down
2 changes: 1 addition & 1 deletion tavern/internal/www/src/pages/quest-list/Quests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const Quests = () => {
<QuestHeader />
<TableWrapper
title="Quests"
totalItems={data?.quests?.totalCount || null}
totalItems={data?.quests?.totalCount}
loading={loading}
error={error}
filterControls={<FilterControls type={FilterPageType.QUEST} />}
Expand Down
2 changes: 1 addition & 1 deletion tavern/internal/www/src/pages/tasks/Tasks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const Tasks = () => {
<EditablePageHeader />
<TableWrapper
title="Tasks"
totalItems={data?.tasks?.totalCount || null}
totalItems={data?.tasks?.totalCount}
loading={loading}
error={error}
filterControls={<FilterControls type={FilterPageType.TASK} />}
Expand Down
16 changes: 8 additions & 8 deletions tavern/internal/www/src/utils/constructQueryUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { sub } from "date-fns";
import { add, sub } from "date-fns";
import { Filters } from "../context/FilterContext";
import { FilterBarOption } from "./interfacesUI";
import { getBeaconFilterNameByTypes, getTomeFilterNameByTypes } from "./utils";
Expand Down Expand Up @@ -171,10 +171,10 @@ export function constructHostTaskFilterQuery(

};

const createRecentlyLostQuery = (start: Date, end: Date) => ({
const createRecentlyLostQuery = (currentTimestamp: Date) => ({
and: [
{ nextSeenAtGTE: start.toISOString() },
{ nextSeenAtLT: end.toISOString() }
{ nextSeenAtGTE: sub(currentTimestamp, { minutes: 5 }).toISOString() },
{ nextSeenAtLT: sub(currentTimestamp, { seconds: 15 }).toISOString() }
]
});

Expand All @@ -185,8 +185,8 @@ export function constructBeaconStatusFilter(
if (!currentTimestamp) return null;

const conditions = [
...status.includes(OnlineOfflineFilterType.OnlineBeacons) ? [{nextSeenAtGTE: currentTimestamp.toISOString()}] : [],
...status.includes(OnlineOfflineFilterType.RecentlyLostBeacons) ? [createRecentlyLostQuery(sub(currentTimestamp, { minutes: 5 }), currentTimestamp)] : [],
...status.includes(OnlineOfflineFilterType.OnlineBeacons) ? [{nextSeenAtGTE: add(currentTimestamp, {seconds: 15}).toISOString()}] : [],
...status.includes(OnlineOfflineFilterType.RecentlyLostBeacons) ? [createRecentlyLostQuery(currentTimestamp)] : [],
]

if (conditions.length === 0) return null;
Expand All @@ -201,8 +201,8 @@ export function constructHostStatusFilter(
if (!currentTimestamp) return null;

const conditions = [
...status.includes(OnlineOfflineFilterType.OfflineHost) ? [{nextSeenAtLT: currentTimestamp.toISOString()}] : [],
...status.includes(OnlineOfflineFilterType.RecentlyLostHost) ? [createRecentlyLostQuery(sub(currentTimestamp, { minutes: 5 }), currentTimestamp)] : [],
...status.includes(OnlineOfflineFilterType.OfflineHost) ? [{nextSeenAtLT: sub(currentTimestamp, {seconds: 15}).toISOString()}] : [],
...status.includes(OnlineOfflineFilterType.RecentlyLostHost) ? [createRecentlyLostQuery(currentTimestamp)] : [],
]

if (conditions.length === 0) return null;
Expand Down
Loading