diff --git a/src/app/(rucio)/rule/create/page.tsx b/src/app/(rucio)/rule/create/page.tsx index c8d88932..cd58c070 100644 --- a/src/app/(rucio)/rule/create/page.tsx +++ b/src/app/(rucio)/rule/create/page.tsx @@ -3,21 +3,50 @@ import { CreateRule as CreateRuleStory } from "@/component-library/Pages/Rule/Cr import { RSEAccountUsageLimitViewModel } from "@/lib/infrastructure/data/view-model/rse"; import { DIDLongViewModel } from "@/lib/infrastructure/data/view-model/did"; import { - CreateRuleQuery, + TCreateRuleRequest, + TFetchCreateRuleSummaryRequest, TypedDIDValidationQuery, TypedDIDValidationResponse, } from '@/lib/infrastructure/data/view-model/create-rule' import { HTTPRequest } from "@/lib/sdk/http"; import useComDOM from "@/lib/infrastructure/hooks/useComDOM"; +import { RuleSummaryViewModel } from "@/lib/infrastructure/data/view-model/rule"; export default function CreateRule() { - const onSubmit = (query: CreateRuleQuery) => { + const onSubmit = (query: TCreateRuleRequest) => { return Promise.resolve({ success: true, }) } - + const fetchSummary = ( + query: TFetchCreateRuleSummaryRequest, + setSummaryViewModel: (viewModel: RuleSummaryViewModel) => void, + setActivePage: (int: number) => void, + setError: (error: string) => void, + ) => { + const url: URL = new URL(`${process.env.NEXT_PUBLIC_WEBUI_HOST}/api/feature/create-rule-summary`) + fetch(url.toString(), { + method: "POST", + headers: new Headers({ + 'Content-Type': 'application/json' + } as HeadersInit), + body: JSON.stringify(query) + }).then((response) => { + if(response.ok) { + return response.json() + } else { + setError(`Error fetching summary. HTTP Status Code: ${response.status}`) + } + }).then((data: RuleSummaryViewModel) => { + setSummaryViewModel(data) + setActivePage(3) + }).catch((error) => { + setError(`Error fetching summary. Error: ${error}`) + }) + return query + } + const didValidation = (query: TypedDIDValidationQuery) => { // if the DID contains the string "error", it will be added to the error list var localErrorDIDs: TypedDIDValidationResponse = { ErrorList: [] } @@ -57,6 +86,7 @@ export default function CreateRule() { return ( export const CreateRule: Story = { args: { - onSubmit: (query: CreateRuleQuery) => { + onSubmit: (query: TCreateRuleRequest) => { return Promise.resolve({ success: true, }) diff --git a/src/component-library/Pages/Rule/CreateRule.stories.tsx b/src/component-library/Pages/Rule/CreateRule.stories.tsx index c4870fba..f07d384e 100644 --- a/src/component-library/Pages/Rule/CreateRule.stories.tsx +++ b/src/component-library/Pages/Rule/CreateRule.stories.tsx @@ -3,9 +3,11 @@ import { fixtureDIDLongViewModel, fixtureRSEAccountUsageLimitViewModel, mockUseC import { CreateRule as CR } from './CreateRule' import { - CreateRuleQuery, + TCreateRuleRequest, + TFetchCreateRuleSummaryRequest, TypedDIDValidationQuery, TypedDIDValidationResponse, } from '@/lib/infrastructure/data/view-model/create-rule' +import { RuleSummaryViewModel } from '@/lib/infrastructure/data/view-model/rule' export default { title: 'Components/Pages/Rule', @@ -16,11 +18,25 @@ const Template: StoryFn = args => export const CreateRule = Template.bind({}) CreateRule.args = { - onSubmit: (query: CreateRuleQuery) => { + onSubmit: (query: TCreateRuleRequest) => { return Promise.resolve({ success: true, }) }, + fetchSummary: ( + query: TFetchCreateRuleSummaryRequest, + setSummaryViewModel: (viewModel: RuleSummaryViewModel) => void, + setActivePage: (int: number) => void, + setError: (error: string) => void, + ) => { + setSummaryViewModel({ + ...query, + status: 'success', + DIDList: query.DIDViewModels.map((did) => `${did.scope}:${did.name}`), + RSEList: query.RSEViewModels.map((rse) => rse.rse), + }) + setActivePage(3) + }, didListComDOM: mockUseComDOM(Array.from({ length: 100 }, () => fixtureDIDLongViewModel())), didValidation: (query: TypedDIDValidationQuery) => { // if the DID contains the string "error", it will be added to the error list diff --git a/src/component-library/Pages/Rule/CreateRule.tsx b/src/component-library/Pages/Rule/CreateRule.tsx index 28985f2e..e925a5f1 100644 --- a/src/component-library/Pages/Rule/CreateRule.tsx +++ b/src/component-library/Pages/Rule/CreateRule.tsx @@ -24,11 +24,12 @@ import { Body } from '../Helpers/Body'; * Importing Types and Interfaces * ================================================= */ import { - CreateRuleQuery, CreateRuleResponse, DIDName, TypedDIDValidationQuery, + TCreateRuleRequest, CreateRuleResponse, DIDName, TypedDIDValidationQuery, TypedDIDValidationResponse, + TFetchCreateRuleSummaryRequest, } from '@/lib/infrastructure/data/view-model/create-rule.d'; -import { DIDType } from '@/lib/core/entity/rucio'; +import { DIDLong, DIDType } from '@/lib/core/entity/rucio'; import { twMerge } from 'tailwind-merge'; import { SamplingTag } from '../../Tags/SamplingTag'; import { CreateRuleDIDTable } from './CreateRuleDIDTable'; @@ -36,6 +37,7 @@ import { didToScopename } from '../../StreamedTables/helpers'; import { CreateRuleRSETable } from './CreateRuleRSETable'; import { RSEAccountUsageLimitViewModel } from '@/lib/infrastructure/data/view-model/rse'; import { DIDLongViewModel } from '@/lib/infrastructure/data/view-model/did'; +import { RuleSummaryViewModel } from '@/lib/infrastructure/data/view-model/rule'; export interface CreateRulePageProps { // Page 0.0 - DID Search` @@ -44,8 +46,16 @@ export interface CreateRulePageProps { didValidation: (didValidationQuery: TypedDIDValidationQuery) => Promise, // Page 1 - RSE Selection rseListComDOM: UseComDOM, + // Page 2 - Summary + fetchSummary: ( + query: TFetchCreateRuleSummaryRequest, + setSummaryViewModel: (viewModel: RuleSummaryViewModel) => void, + setActivePage: (int: number) => void, + setError: (error: string) => void, + ) => void, // Page 3 - Sendoff - onSubmit: (createRuleQuery: CreateRuleQuery) => Promise + onSubmit: (createRuleQuery: TCreateRuleRequest) => Promise + } // can assume that DIDs are unique, hence SET can be used later @@ -239,13 +249,14 @@ export const CreateRule = ( }) /* ================================================= - * Page 3 + * Page 3 : Summary page * ================================================= */ - const page3submitFunction = (event: any) => { - // build query - const CreateRuleQuery: CreateRuleQuery = { - DIDList: Page0State.typedDIDs.concat(didToScopename(Page0State.searchDIDSelection)), - RSEList: Page1State.RSESelection.map(element => element.rse), + const [summaryViewModel, setSummaryViewModel] = useState() + + const loadRuleSummaryPage = () => { + const fetchSummaryRequest: TFetchCreateRuleSummaryRequest = { + RSEViewModels: Page1State.RSESelection, + DIDViewModels: Page0State.searchDIDSelection, expirydate: Page2State.expiryDate, notifications: Page2State.enableNotifications, asynchronousMode: Page2State.asynchronousMode, @@ -255,9 +266,29 @@ export const CreateRule = ( comment: Page2State.freeComment, approval: Page2State.approval } + props.fetchSummary(fetchSummaryRequest, setSummaryViewModel, setActivePage, (error: string) => { console.log(error) }) + } + + + const page3submitFunction = (event: any) => { // execute query - const response = props.onSubmit(CreateRuleQuery) + // TODO : Use summary view model to create the query + const createRulesRequest: TCreateRuleRequest = { + DIDList: Page0State.typedDIDs.concat(didToScopename(Page0State.searchDIDSelection)), + RSEList: Page1State.RSESelection.map((element) => element.rse), + RSEViewModels: Page1State.RSESelection, + DIDViewModels: Page0State.searchDIDSelection, + expirydate: Page2State.expiryDate, + notifications: Page2State.enableNotifications, + asynchronousMode: Page2State.asynchronousMode, + numcopies: Page2State.numcopies, + numsamples: Page2State.numsamples, + groupby: Page2State.groupBy, + comment: Page2State.freeComment, + approval: Page2State.approval + } + const response = props.onSubmit(createRulesRequest) response.then((response) => { console.log("response: ", response) }) @@ -311,8 +342,10 @@ export const CreateRule = ( + {/* TODO: delayed */}
- + + {/* { @@ -337,7 +370,7 @@ export const CreateRule = (

DID {element.DID} has Errorcodes {element.ErrorCodes}

) })} -
+ */}
@@ -371,7 +404,7 @@ export const CreateRule = ( - { setActivePage(activePage + 1) }} onPrev={pagePrevFunction}> + { loadRuleSummaryPage() }} onPrev={pagePrevFunction}>
@@ -484,17 +517,21 @@ export const CreateRule = (
- element.rse), - expirydate: Page2State.expiryDate, - notifications: Page2State.enableNotifications, - asynchronousMode: Page2State.asynchronousMode, - numcopies: Page2State.numcopies, - numsamples: Page2State.numsamples, - groupby: Page2State.groupBy, - comment: Page2State.freeComment, - approval: Page2State.approval + diff --git a/src/component-library/Pages/Rule/CreateRuleRSETable.tsx b/src/component-library/Pages/Rule/CreateRuleRSETable.tsx index 668aa246..638d986c 100644 --- a/src/component-library/Pages/Rule/CreateRuleRSETable.tsx +++ b/src/component-library/Pages/Rule/CreateRuleRSETable.tsx @@ -33,7 +33,7 @@ export const CreateRuleRSETable = ( type="checkbox" disabled={!info.row.getCanSelect()} checked={info.row.getIsSelected()} - onChange={e => { + onClick={e => { info.row.toggleSelected() }} /> diff --git a/src/component-library/Pages/Rule/SummaryPage.stories.tsx b/src/component-library/Pages/Rule/SummaryPage.stories.tsx index ed96a2ae..e1b02e86 100644 --- a/src/component-library/Pages/Rule/SummaryPage.stories.tsx +++ b/src/component-library/Pages/Rule/SummaryPage.stories.tsx @@ -1,4 +1,5 @@ -import { CreateRuleQuery } from '@/lib/infrastructure/data/view-model/create-rule' +import { TCreateRuleRequest } from '@/lib/infrastructure/data/view-model/create-rule' +import { RuleSummaryViewModel } from '@/lib/infrastructure/data/view-model/rule' import { StoryFn, Meta } from '@storybook/react' import { SummaryPage as SP } from './SummaryPage' @@ -12,6 +13,7 @@ const Template: StoryFn = args => export const SummaryPage = Template.bind({}) SummaryPage.args = { data: { + status: 'success', DIDList: [ 'user.AndrewJenkins:dataset-dBDUMqZWnMImKbhZCJUA', 'user.SandraOrtiz:file-SxbkaPRbmlZezztEiAZl', @@ -42,5 +44,5 @@ SummaryPage.args = { numsamples: -1, groupby: "File", comment: "", - } as CreateRuleQuery, + } as RuleSummaryViewModel, } \ No newline at end of file diff --git a/src/component-library/Pages/Rule/SummaryPage.tsx b/src/component-library/Pages/Rule/SummaryPage.tsx index 8279ae1d..4f219e26 100644 --- a/src/component-library/Pages/Rule/SummaryPage.tsx +++ b/src/component-library/Pages/Rule/SummaryPage.tsx @@ -1,10 +1,11 @@ -import { CreateRuleQuery } from "@/lib/infrastructure/data/view-model/create-rule" +import { TCreateRuleRequest } from "@/lib/infrastructure/data/view-model/create-rule" import { BoolTag } from "../../Tags/BoolTag" import { twMerge } from "tailwind-merge" -import FC from "react" +import FC, { useEffect } from "react" import { DIDTypeTag } from "../../Tags/DIDTypeTag" import { HiQuestionMarkCircle } from "react-icons/hi" import { SamplingTag } from "../../Tags/SamplingTag" +import { RuleSummaryViewModel } from "@/lib/infrastructure/data/view-model/rule" var format = require("date-format") @@ -82,7 +83,7 @@ const OptionTD = (props: {children: any}): JSX.Element => export const SummaryPage = ( props: { - data: CreateRuleQuery + data: RuleSummaryViewModel } ) => { return ( @@ -110,7 +111,7 @@ export const SummaryPage = ( )} > - + rse.rse_id)} title="RSEs" />
+ DIDViewModels: Array + expirydate: Date + notifications: boolean + asynchronousMode: boolean + numcopies: number + numsamples: number + groupby: DIDType + comment: string + approval: boolean +} + +export interface TCreateRuleRequest { DIDList: Array RSEList: Array + RSEViewModels: Array + DIDViewModels: Array expirydate: Date notifications: boolean asynchronousMode: boolean diff --git a/src/lib/infrastructure/data/view-model/list-did.d.ts b/src/lib/infrastructure/data/view-model/list-did.d.ts index a39266c8..34355b5d 100644 --- a/src/lib/infrastructure/data/view-model/list-did.d.ts +++ b/src/lib/infrastructure/data/view-model/list-did.d.ts @@ -1,8 +1,5 @@ import { BaseViewModel } from "@/lib/sdk/view-models"; import { ListDIDsResponse } from "@/lib/core/usecase-models/list-dids-usecase-models"; -import { DID } from "@/lib/core/entity/rucio"; +import { DID, DIDLong } from "@/lib/core/entity/rucio"; -export interface ListDIDsViewModel extends DID, BaseViewModel { - bytes: number; - length: number; -} \ No newline at end of file +export interface ListDIDsViewModel extends DIDLong, BaseViewModel {} \ No newline at end of file diff --git a/src/lib/infrastructure/data/view-model/rule.d.ts b/src/lib/infrastructure/data/view-model/rule.d.ts index 2b14b054..5580685d 100644 --- a/src/lib/infrastructure/data/view-model/rule.d.ts +++ b/src/lib/infrastructure/data/view-model/rule.d.ts @@ -4,4 +4,18 @@ import { BaseViewModel } from "@/lib/sdk/view-models"; export interface RuleViewModel extends Rule, BaseViewModel {} export interface RulePageLockEntryViewModel extends RulePageLockEntry, BaseViewModel {} -export interface RuleMetaViewModel extends RuleMeta, BaseViewModel {} \ No newline at end of file +export interface RuleMetaViewModel extends RuleMeta, BaseViewModel {} +export interface RuleSummaryViewModel extends BaseViewModel { + DIDList: Array + RSEList: Array + RSEViewModels: Array + DIDViewModels: Array + expirydate: Date + notifications: boolean + asynchronousMode: boolean + numcopies: number + numsamples: number + groupby: DIDType + comment: string + approval: boolean +} diff --git a/test/component/CreateRule.test.tsx b/test/component/CreateRule.test.tsx index 7a25e30d..08fb4198 100644 --- a/test/component/CreateRule.test.tsx +++ b/test/component/CreateRule.test.tsx @@ -4,7 +4,7 @@ import { CreateRule } from "@/component-library/Pages/Rule/CreateRule"; import { - CreateRuleQuery, DIDSearchQuery, + TCreateRuleRequest, DIDSearchQuery, TypedDIDValidationQuery, TypedDIDValidationResponse, RSESearchQuery } from '@/lib/infrastructure/data/view-model/create-rule' @@ -16,7 +16,7 @@ jest.mock('next/navigation') let user: any // user input let F: any // fixtures -const onSubmit = (query: CreateRuleQuery) => { +const onSubmit = (query: TCreateRuleRequest) => { return Promise.resolve({ success: true, })