Skip to content

Commit

Permalink
Components: Add pages and tags for Transfers
Browse files Browse the repository at this point in the history
  • Loading branch information
fno2010 committed Dec 7, 2023
1 parent 29fe947 commit af90428
Show file tree
Hide file tree
Showing 12 changed files with 400 additions and 1 deletion.
15 changes: 15 additions & 0 deletions src/component-library/Pages/Transfers/ListTransfer.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Meta, StoryFn } from "@storybook/react";
import { ListTransfer as L } from "./ListTransfer";
import { fixtureTransferViewModel, mockUseComDOM } from "test/fixtures/table-fixtures";

export default {
title: 'Components/Pages/Transfers',
component: L,
} as Meta<typeof L>;

const Template: StoryFn<typeof L> = (args) => <L {...args} />;

export const ListTransfer = Template.bind({})
ListTransfer.args = {
comdom: mockUseComDOM(Array.from({ length: 50 }, () => fixtureTransferViewModel()))
};
76 changes: 76 additions & 0 deletions src/component-library/Pages/Transfers/ListTransfer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import useReponsiveHook from "@/component-library/Helpers/ResponsiveHook"
import { TableFilterDiscrete } from "@/component-library/StreamedTables/TableFilterDiscrete"
import { TableFilterString } from "@/component-library/StreamedTables/TableFilterString"
import { RequestTypeTag } from "@/component-library/Tags/RequestTypeTag"
import { RequestType } from "@/lib/core/entity/rucio"
import { TransferViewModel } from "@/lib/infrastructure/data/view-model/request"
import { UseComDOM } from "@/lib/infrastructure/hooks/useComDOM"
import { createColumnHelper } from "@tanstack/react-table"
import { HiDotsHorizontal } from "react-icons/hi"
import { twMerge } from "tailwind-merge"
import { Heading } from "../Helpers/Heading"
import { StreamedTable } from "@/component-library/StreamedTables/StreamedTable"
import { Body } from "../Helpers/Body"

export const ListTransfer = (
props: {
comdom: UseComDOM<TransferViewModel>
}
) => {
const columnHelper = createColumnHelper<TransferViewModel>()
const tablecolumns = [
columnHelper.accessor("scope", {}),
columnHelper.accessor("name", {}),
columnHelper.accessor("request_type", {
id: "request_type",
header: info => {
return (
<TableFilterDiscrete<RequestType>
name="Request Type"
keys={Object.values(RequestType)}
renderFunc={key => key === undefined ? <HiDotsHorizontal className="text-2xl text-gray-500 dark:text-gray-200" /> : <RequestTypeTag requesttype={key} forcesmall />}
column={info.column}
stack
/>
)
},
cell: info => <RequestTypeTag requesttype={info.getValue()} />,
meta: {
style: "w-8 md:w-32"
}
}),
columnHelper.accessor("requested_at", {
}),
columnHelper.accessor("bytes", {
}),
columnHelper.accessor("priority", {
}),
columnHelper.accessor("transfertool", {
})
]

const responsive = useReponsiveHook()

return (
<div
className={twMerge(
"flex flex-col space-y-2 w-full"
)}
>
<Heading
title="List Active Transfers"
/>
<Body>
<StreamedTable<TransferViewModel>
tablecomdom={props.comdom}
tablecolumns={tablecolumns}
tablestyling={{
tableHeadRowStyle: "md:h-16",
visibility: {
}
}}
/>
</Body>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Meta, StoryFn } from "@storybook/react";
import { ListTransferStatistics as L } from "./ListTransferStatistics";
import { fixtureTransferStatsViewModel, mockUseComDOM } from "test/fixtures/table-fixtures";

export default {
title: 'Components/Pages/Transfers',
component: L,
} as Meta<typeof L>;

const Template: StoryFn<typeof L> = (args) => <L {...args} />;

export const ListTransferStatistics = Template.bind({})
ListTransferStatistics.args = {
comdom: mockUseComDOM(Array.from({ length: 50 }, () => fixtureTransferStatsViewModel()))
}
48 changes: 48 additions & 0 deletions src/component-library/Pages/Transfers/ListTransferStatistics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { StreamedTable } from "@/component-library/StreamedTables/StreamedTable"
import { TransferStatsViewModel } from "@/lib/infrastructure/data/view-model/request-stats"
import { UseComDOM } from "@/lib/infrastructure/hooks/useComDOM"
import { Heading } from "../Helpers/Heading"
import { createColumnHelper } from "@tanstack/react-table"
import { Body } from "../Helpers/Body"
import { Contenttd, Generaltable, Titleth } from "@/component-library/Helpers/Metatable"
import { H3 } from "@/component-library/Text/Headings/H3"
import { TransferStatistics } from "./TransferStatistics"

export const ListTransferStatistics = (
props: {
comdom: UseComDOM<TransferStatsViewModel>
}
) => {
const columnHelper = createColumnHelper<TransferStatsViewModel>()
const tablecolumns = [
columnHelper.accessor("source_rse", {
}),
columnHelper.accessor("dest_rse", {
}),
columnHelper.accessor("request_stats", {
id: "request_stats",
header: info => <H3>Transfer Statistics</H3>,
cell: info => {
return <TransferStatistics request_stats={info.getValue()} />
}
})
]

return (
<div>
<Heading
title="Transfer Statistics"
/>
<Body>
<StreamedTable<TransferStatsViewModel>
tablecomdom={props.comdom}
tablecolumns={tablecolumns}
tablestyling={{
tableHeadRowStyle: "md:h-16",
visibility: {}
}}
/>
</Body>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Meta, StoryFn } from "@storybook/react";
import { TransferStatistics as T } from "./TransferStatistics";
import { fixtureRequestStatsPerPair } from "test/fixtures/table-fixtures";

export default {
title: 'Components/Pages/Transfers',
component: T,
} as Meta<typeof T>

const Template: StoryFn<typeof T> = (args) => <T {...args} />;

export const TransferStatistics = Template.bind({})
TransferStatistics.args = {
request_stats: fixtureRequestStatsPerPair()
}
26 changes: 26 additions & 0 deletions src/component-library/Pages/Transfers/TransferStatistics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { NormalTable } from "@/component-library/StreamedTables/NormalTable"
import { TableStyling } from "@/component-library/StreamedTables/types"
import { RequestStatsPerPair } from "@/lib/core/entity/rucio"
import { createColumnHelper } from "@tanstack/react-table"

export const TransferStatistics = (
props: {
request_stats: RequestStatsPerPair[]
}
) => {
const columnHelper = createColumnHelper<RequestStatsPerPair>()
const tablecolumns: any[] = [
columnHelper.accessor("activity", {}),
columnHelper.accessor("counter", {}),
columnHelper.accessor("bytes", {}),
]
return (
<NormalTable<RequestStatsPerPair>
tabledata={props.request_stats}
tablecolumns={tablecolumns}
tablestyling={{
pageSize: 5
} as TableStyling}
/>
)
}
15 changes: 15 additions & 0 deletions src/component-library/Tags/RequestTypeTag.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Meta, StoryFn } from "@storybook/react";
import { RequestTypeTag as R } from "./RequestTypeTag";
import { RequestType } from "@/lib/core/entity/rucio";

export default {
title: 'Components/Tags',
component: R,
} as Meta<typeof R>;

const Template: StoryFn<typeof R> = (args) => <R {...args} />;

export const RequestTypeTag = Template.bind({});
RequestTypeTag.args = {
requesttype: RequestType.TRANSFER
}
68 changes: 68 additions & 0 deletions src/component-library/Tags/RequestTypeTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { RequestType } from "@/lib/core/entity/rucio";
import { RowSelection } from "@tanstack/react-table";
import React, { useEffect, useState } from "react";
import { twMerge } from "tailwind-merge";

type RequestTypeTagProps = JSX.IntrinsicElements["span"] & {
requesttype: RequestType;
forcesmall?: boolean;
neversmall?: boolean;
};

export const RequestTypeTag: React.FC<RequestTypeTagProps> = (
{
requesttype = RequestType.TRANSFER,
forcesmall = false,
neversmall = false,
...props
}
) => {
const { className, ...restprops } = props

const [windowWidth, setWindowWidth] = useState(720)
useEffect(() => {
const handleResize = () => setWindowWidth(window.innerWidth)
handleResize()
window.addEventListener('resize', handleResize)
}, [])
const belowMedium = (windowWidth < 768) || forcesmall
const stringMatch = {
[RequestType.UPLOAD]: "Upload",
[RequestType.DOWNLOAD]: "Download",
[RequestType.STAGEIN]: "Stage In",
[RequestType.STAGEOUT]: "Stage Out",
[RequestType.TRANSFER]: "Transfer"
}

const colPicker = (requesttype: RequestType) => {
switch (requesttype) {
case RequestType.UPLOAD:
return "emerald"
case RequestType.DOWNLOAD:
return "blue"
case RequestType.STAGEIN:
return "rose"
case RequestType.STAGEOUT:
return "amber"
case RequestType.TRANSFER:
return "gray"
}
}

const color = colPicker(requesttype)

return (
<span
className={twMerge(
"h-6 rounded text-center flex justify-center items-center",
"font-bold",
!neversmall ? "w-6 md:w-24 rounded-full md:rounded" : "w-24",
forcesmall ? "w-6 md:w-6 rounded-full md:rounded-full" : "",
`bg-${color}-100 text-${color}-800 dark:bg-${color}-900 dark:text-${color}-300`,
className ?? ""
)}
>
{belowMedium && !neversmall ? stringMatch[requesttype].split(' ').slice(-1)[0].slice(0, 1) : stringMatch[requesttype]}
</span>
);
};
22 changes: 22 additions & 0 deletions src/lib/core/entity/rucio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,28 @@ export type Request = {
requested_at: DateISO,
priority: number,
transfertool: string,
source_rse: string,
dest_rse: string,
}

/**
* Represents statistics for the nubmer of transfer requests over dest_rse and
* source_rse in Rucio.
*/
export type RequestStatsPerPair = {
activity: string,
counter: number,
bytes: number,
}

export type RequestStats = {
account: string,
state: RequestState,
dest_rse_id: string,
source_rse_id: string,
dest_rse: string,
source_rse: string,
request_stats: RequestStatsPerPair[],
}

/*
Expand Down
4 changes: 4 additions & 0 deletions src/lib/infrastructure/data/view-model/request-stats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { RequestStats, RequestStatsPerPair } from "@/lib/core/entity/rucio";
import { BaseViewModel } from "@/lib/sdk/view-models";

export interface TransferStatsViewModel extends BaseViewModel, RequestStats {}
32 changes: 32 additions & 0 deletions src/lib/infrastructure/data/view-model/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { DIDType, Request, RequestState, RequestType } from "@/lib/core/entity/rucio";
import { BaseViewModel } from "@/lib/sdk/view-models";

export interface TransferViewModel extends BaseViewModel, Request {}

/**
* A utility function to retrieve an empty {@link TransferViewModel}.
* @return an empty TransferViewModel
*/
export function getEmptyTransferViewModel(): TransferViewModel {
const viewModel: TransferViewModel = {
status: 'error',
id: '',
request_type: RequestType.TRANSFER,
scope: '',
name: '',
did_type: DIDType.UNKNOWN,
dest_rse_id: '',
source_rse_id: '',
attributes: '',
state: RequestState.FAILED,
activity: '',
bytes: 0,
account: '',
requested_at: '',
priority: 0,
transfertool: '',
source_rse: '',
dest_rse: '',
}
return viewModel
}
Loading

0 comments on commit af90428

Please sign in to comment.