Skip to content

Commit

Permalink
HMS-1623 feat: add detail page
Browse files Browse the repository at this point in the history
WIP This feature display the details for a given domain.

Signed-off-by: Alejandro Visiedo <[email protected]>
  • Loading branch information
avisiedo committed Oct 24, 2023
1 parent 7642a0f commit 7d491d2
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Components/DomainList/DomainList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export const DomainList = () => {
<>
<Tr key={domain.domain_id}>
<Td>
<Link to="/domains/{domain.domain_id}">{domain.title}</Link>
<Link to={'/details/' + domain.domain_id}>{domain.title}</Link>
</Td>
<Td>
<DomainListFieldType domain_type={domain.domain_type} />
Expand Down
2 changes: 2 additions & 0 deletions src/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Navigate, Route, Routes } from 'react-router-dom';

import { Bullseye, Spinner } from '@patternfly/react-core';
import WizardPage from './Routes/WizardPage/WizardPage';
import DetailPage from './Routes/DetailPage/DetailPage';

const DefaultPage = lazy(() => import(/* webpackChunkName: "DefaultPage" */ './Routes/DefaultPage/DefaultPage'));
const OopsPage = lazy(() => import(/* webpackChunkName: "OopsPage" */ './Routes/OopsPage/OopsPage'));
Expand All @@ -26,6 +27,7 @@ const DomainRegistryRoutes = () => (
>
<Routes>
<Route path="/domains" Component={DefaultPage} />
<Route path="/details/:domain_id" Component={DetailPage} />
<Route path="/domains/wizard" Component={WizardPage} />
<Route path="/oops" Component={OopsPage} />
<Route path="/no-permissions" Component={NoPermissionsPage} />
Expand Down
1 change: 1 addition & 0 deletions src/Routes/DetailPage/DetailPage.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import '~@redhat-cloud-services/frontend-components-utilities/styles/variables';
213 changes: 213 additions & 0 deletions src/Routes/DetailPage/DetailPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import { useNavigate, useParams } from 'react-router-dom';
import React, { useContext, useEffect, useState } from 'react';

import {
Button,
Drawer,
DrawerContent,
DrawerContentBody,
DrawerHead,
DrawerPanelContent,
Flex,
FlexItem,
Tab,
Tabs,
Text,
TextContent,
TextVariants,
} from '@patternfly/react-core';
import { PageHeader, PageHeaderTitle } from '@redhat-cloud-services/frontend-components/PageHeader';

import './DetailPage.scss';
import { Domain, ResourcesApiFactory } from '../../Api/api';
import { AppContext } from '../../AppContext';
import { TableComposable, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table';

interface DetailHeaderProps {
domain: Domain | undefined;
}

const DetailHeader = (props: DetailHeaderProps) => {
const base_url = '/api/idmsvc/v1';
const resources_api = ResourcesApiFactory(undefined, base_url, undefined);
const navigate = useNavigate();

const onDeleteHandler = () => {
// TODO Add delete handler
navigate('/domains');
return;
};

const [joinable, setJoinable] = useState(props.domain?.auto_enrollment_enabled);

const onJoinableHandler = (value: boolean) => {
console.log(`clicked on Enable/Disable, on ${props.domain?.domain_id}`);
if (props.domain?.domain_id) {
resources_api
.updateDomainUser(props.domain?.domain_id, {
auto_enrollment_enabled: value,
})
.then((response) => {
if (response.status == 200) {
setJoinable(value);
} else {
// TODO show-up notification with error message
}
})
.catch((error) => {
// TODO show-up notification with error message
console.log('error onClose: ' + error);
});
}
};

return (
<>
<PageHeader>
<Flex>
<FlexItem className="pf-u-mr-auto">
<PageHeaderTitle title={props.domain?.domain_name} />
<TextContent>{props.domain?.description}</TextContent>
</FlexItem>
<FlexItem>
<Button variant="secondary">Edit</Button>{' '}
<Button variant="secondary" onClick={onDeleteHandler}>
Delete
</Button>{' '}
<Button variant="secondary" isDisabled={joinable} onClick={() => onJoinableHandler(true)}>
Enable
</Button>{' '}
<Button variant="secondary" isDisabled={!joinable} onClick={() => onJoinableHandler(false)}>
Disable
</Button>
</FlexItem>
</Flex>
</PageHeader>
</>
);
};

interface DetailContentProps extends React.HTMLProps<HTMLDivElement> {
domain: Domain | undefined;
}

const DetailContent = (props: DetailContentProps) => {
const appContext = useContext(AppContext);

Check warning on line 95 in src/Routes/DetailPage/DetailPage.tsx

View workflow job for this annotation

GitHub Actions / validate

'appContext' is assigned a value but never used
const navigate = useNavigate();

Check warning on line 96 in src/Routes/DetailPage/DetailPage.tsx

View workflow job for this annotation

GitHub Actions / validate

'navigate' is assigned a value but never used
const base_url = '/api/idmsvc/v1';
const resources_api = ResourcesApiFactory(undefined, base_url, undefined);

Check warning on line 98 in src/Routes/DetailPage/DetailPage.tsx

View workflow job for this annotation

GitHub Actions / validate

'resources_api' is assigned a value but never used

// States
const [activeTabKey, setActiveTabKey] = React.useState<string | number>(0);

// Events
const handleTabClick = (event: React.MouseEvent<any> | React.KeyboardEvent | MouseEvent, tabIndex: string | number) => {

Check warning on line 104 in src/Routes/DetailPage/DetailPage.tsx

View workflow job for this annotation

GitHub Actions / validate

Unexpected any. Specify a different type
setActiveTabKey(tabIndex);
};

// Contents
const drawerContent = (
<>
<TableComposable>
<Thead>
<Tr>
<Th>Name</Th>
<Th>Category</Th>
<Th>UUID</Th>
</Tr>
</Thead>
<Tbody>
<Tr key={props.domain?.domain_id}>
<Td>{props.domain?.domain_name}</Td>
<Td>Domain</Td>
<Td>{props.domain?.domain_id}</Td>
</Tr>
{props.domain?.['rhel-idm']?.servers.map((server) => {
return (
<Tr key={server.subscription_manager_id}>
<Th>{server.fqdn}</Th>
<Th>Server</Th>
<Th>{server.subscription_manager_id}</Th>
</Tr>
);
})}
</Tbody>
</TableComposable>
</>
);
const panelContent = (
<>
<DrawerPanelContent isResizable minSize="300px" maxSize="400px" defaultSize="400px">
<DrawerHead>
<TextContent>
<Text component={TextVariants.h2}>{props.domain?.domain_name}</Text>
</TextContent>
</DrawerHead>
<Tabs activeKey={activeTabKey} onSelect={handleTabClick}>
<Tab title="General" eventKey={0}></Tab>
<Tab title="Additional" eventKey={1}></Tab>
</Tabs>
</DrawerPanelContent>
</>
);

return (
<>
<Drawer isStatic isExpanded={true}>
<DrawerContent panelContent={panelContent}>
<DrawerContentBody>{drawerContent}</DrawerContentBody>
</DrawerContent>
</Drawer>
</>
);
};

/**
* It represents the detail page to show the information about a
* registered domain.
* @see https://stackoverflow.com/questions/75522048/react-how-to-access-urls-parameters
* @see https://reactrouter.com/en/main/hooks/use-params
*/
const DetailPage = () => {
const appContext = useContext(AppContext);

Check warning on line 172 in src/Routes/DetailPage/DetailPage.tsx

View workflow job for this annotation

GitHub Actions / validate

'appContext' is assigned a value but never used
const base_url = '/api/idmsvc/v1';
const resources_api = ResourcesApiFactory(undefined, base_url, undefined);

// Params
const { domain_id } = useParams();

// States
const [domain, setDomain] = useState<Domain>();

console.log('INFO:DetailPage render:domain_id=' + domain_id);

// TODO Extract in a hook
useEffect(() => {
if (domain_id) {
resources_api
.readDomain(domain_id)
.then((res) => {
if (res.status === 200) {
setDomain(res.data);
}
})
.catch((reason) => {
// TODO Send error notification to chrome
console.log(reason);
});
}

return () => {
// Finalizer
};
}, [domain_id]);

return (
<>
<DetailHeader domain={domain} />
<DetailContent domain={domain} className="pt-u-mt-xs" />
</>
);
};

export default DetailPage;

0 comments on commit 7d491d2

Please sign in to comment.