Skip to content

Commit

Permalink
create page layout & toolbar
Browse files Browse the repository at this point in the history
  • Loading branch information
jpinsonneau committed Mar 10, 2022
1 parent 46b3211 commit c88c876
Show file tree
Hide file tree
Showing 23 changed files with 287 additions and 143 deletions.
46 changes: 25 additions & 21 deletions web/locales/en/plugin__network-observability-plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@
"Compact": "Compact",
"Normal": "Normal",
"Large": "Large",
"Source": "Source",
"Destination": "Destination",
"Both": "Both",
"Match all columns": "Match all columns",
"Match any column": "Match any column",
"Every flow can be reported from the source node and/or the destination node. For in-cluster traffic, usually both source and destination nodes report flows, resulting in duplicated data. Cluster ingress traffic is only reported by destination nodes, and cluster egress by source nodes.": "Every flow can be reported from the source node and/or the destination node. For in-cluster traffic, usually both source and destination nodes report flows, resulting in duplicated data. Cluster ingress traffic is only reported by destination nodes, and cluster egress by source nodes.",
"Reporter node": "Reporter node",
"Whether each query result has to match all the filters or just any of them": "Whether each query result has to match all the filters or just any of them",
"Match filters": "Match filters",
"Limit": "Limit",
"Query Options": "Query Options",
"Refresh off": "Refresh off",
"{{count}} second": "{{count}} second",
"{{count}} second_plural": "{{count}} second",
"{{count}} minute": "{{count}} minute",
"{{count}} minute_plural": "{{count}} minute",
"{{count}} hour": "{{count}} hour",
"{{count}} hour_plural": "{{count}} hour",
"{{count}} day": "{{count}} day",
"{{count}} day_plural": "{{count}} day",
"Column must be selected": "Column must be selected",
"Value is empty": "Value is empty",
"Unknown port": "Unknown port",
Expand Down Expand Up @@ -48,8 +68,6 @@
"Export": "Export",
"Following query will be exported as CSV format:": "Following query will be exported as CSV format:",
"Time Range": "Time Range",
"Reporter node": "Reporter node",
"Limit": "Limit",
"Close": "Close",
"Export all datas": "Export all datas",
"Use this option to export every fields and labels from flows.": "Use this option to export every fields and labels from flows.",
Expand All @@ -70,27 +88,13 @@
"Unable to get flows": "Unable to get flows",
"No results found": "No results found",
"Clear all filters and try again.": "Clear all filters and try again.",
"Network Traffic": "Network Traffic",
"Unable to get topology": "Unable to get topology",
"TODO": "TODO",
"Flow Table": "Flow Table",
"Topology": "Topology",
"Column management": "Column management",
"Export management": "Export management",
"Source": "Source",
"Destination": "Destination",
"Both": "Both",
"Match all columns": "Match all columns",
"Match any column": "Match any column",
"Every flow can be reported from the source node and/or the destination node. For in-cluster traffic, usually both source and destination nodes report flows, resulting in duplicated data. Cluster ingress traffic is only reported by destination nodes, and cluster egress by source nodes.": "Every flow can be reported from the source node and/or the destination node. For in-cluster traffic, usually both source and destination nodes report flows, resulting in duplicated data. Cluster ingress traffic is only reported by destination nodes, and cluster egress by source nodes.",
"Whether each query result has to match all the filters or just any of them": "Whether each query result has to match all the filters or just any of them",
"Match filters": "Match filters",
"Query Options": "Query Options",
"Refresh off": "Refresh off",
"{{count}} second": "{{count}} second",
"{{count}} second_plural": "{{count}} second",
"{{count}} minute": "{{count}} minute",
"{{count}} minute_plural": "{{count}} minute",
"{{count}} hour": "{{count}} hour",
"{{count}} hour_plural": "{{count}} hour",
"{{count}} day": "{{count}} day",
"{{count}} day_plural": "{{count}} day",
"Network Traffic": "Network Traffic",
"Date & time": "Date & time",
"Name": "Name",
"Kind": "Kind",
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/__tests__/filters-toolbar.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe('<FiltersToolbar />', () => {
const wrapper = shallow(<FiltersToolbar {...props} />);
expect(wrapper.find(FiltersToolbar)).toBeTruthy();
expect(wrapper.find(Toolbar)).toBeTruthy();
expect(wrapper.find(ToolbarItem)).toHaveLength(3);
expect(wrapper.find(ToolbarItem)).toHaveLength(2);
expect(wrapper.find(Dropdown)).toBeTruthy();
expect(wrapper.find(Button)).toBeTruthy();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Radio, Select } from '@patternfly/react-core';
import { shallow } from 'enzyme';
import { act } from 'react-dom/test-utils';
import QueryOptionsDropdown, { QueryOptionsDropdownProps, QueryOptionsPanel } from '../query-options-dropdown';
import { QueryOptions } from '../../model/query-options';
import { QueryOptions } from '../../../model/query-options';

describe('<QueryOptionsDropdown />', () => {
const props: QueryOptionsDropdownProps = {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Radio, Select, Tooltip } from '@patternfly/react-core';
import { InfoAltIcon } from '@patternfly/react-icons';
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { Match, QueryOptions, Reporter } from '../model/query-options';
import { Match, QueryOptions, Reporter } from '../../model/query-options';

export interface QueryOptionsDropdownProps {
options: QueryOptions;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { Dropdown, DropdownToggle, DropdownItem } from '@patternfly/react-core';
import * as _ from 'lodash';
import { parseDuration, formatDuration } from '../utils/duration';
import { parseDuration, formatDuration } from '../../utils/duration';

export type RefreshDropdownProps = {
interval?: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { Dropdown, DropdownToggle, DropdownItem } from '@patternfly/react-core';
import { parseDuration, formatDuration, getDateMsInSeconds, getDateSInMiliseconds } from '../utils/duration';
import { getTimeRangeOptions } from '../utils/datetime';
import { parseDuration, formatDuration, getDateMsInSeconds, getDateSInMiliseconds } from '../../utils/duration';
import { getTimeRangeOptions } from '../../utils/datetime';
import * as _ from 'lodash';

export type TimeRangeDropdownProps = {
Expand Down
5 changes: 5 additions & 0 deletions web/src/components/filters-toolbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,9 @@ button.pf-c-button.pf-m-link.pf-m-inline:empty {
/* stick "Learn more" text */
#more {
padding: 5px 0px 0px 5px;
}

/* force new row for forced filters group*/
#forced-filters {
flex-basis: 100%;
}
70 changes: 34 additions & 36 deletions web/src/components/filters-toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
Toolbar,
ToolbarContent,
ToolbarFilter,
ToolbarGroup,
ToolbarItem,
Tooltip,
ValidatedOptions
Expand All @@ -43,7 +44,7 @@ import {
import './filters-toolbar.css';
import { validateIPFilter } from '../utils/ip';
import { QueryOptions } from '../model/query-options';
import { QueryOptionsDropdown } from './query-options-dropdown';
import { QueryOptionsDropdown } from './dropdowns/query-options-dropdown';
import { getPathWithParams, NETFLOW_TRAFFIC_PATH } from '../utils/router';
import { useHistory } from 'react-router-dom';
import { validateLabel } from '../utils/label';
Expand Down Expand Up @@ -404,8 +405,8 @@ export const FiltersToolbar: React.FC<FiltersToolbarProps> = ({
<ToolbarItem className="flex-start">
<QueryOptionsDropdown options={props.queryOptions} setOptions={props.setQueryOptions} />
</ToolbarItem>
<ToolbarItem className="flex-start">
{_.isEmpty(forcedFilters) ? (
{_.isEmpty(forcedFilters) && (
<ToolbarItem className="flex-start">
<Tooltip
//css hide tooltip here to avoid render issue
className={`filters-tooltip${_.isEmpty(message) ? '-empty' : ''}`}
Expand Down Expand Up @@ -459,39 +460,9 @@ export const FiltersToolbar: React.FC<FiltersToolbarProps> = ({
{getHint()}
</div>
</Tooltip>
) : (
forcedFilters &&
forcedFilters.map((forcedFilter, ffIndex) => (
<ChipGroup
key={ffIndex}
isClosable={false}
categoryName={getFullColumnName(columns.find(c => c.id === forcedFilter.colId))}
>
{forcedFilter.values.map((forcedValue, fvIndex) => (
<Chip key={fvIndex} isReadOnly={true}>
{forcedValue.display ? forcedValue.display : forcedValue.v}
</Chip>
))}
</ChipGroup>
))
)}
</ToolbarItem>
{!_.isEmpty(forcedFilters) && (
<ToolbarItem className="flex-start">
<OverflowMenu breakpoint="md">
<OverflowMenuGroup groupType="button" isPersistent>
<Button onClick={() => push(getPathWithParams(NETFLOW_TRAFFIC_PATH))}>{t('Edit filters')}</Button>
</OverflowMenuGroup>
</OverflowMenu>
</ToolbarItem>
)}
<ToolbarItem className="flex-start">
<OverflowMenu breakpoint="md">
<OverflowMenuGroup groupType="button" isPersistent>
{props.children}
</OverflowMenuGroup>
</OverflowMenu>
</ToolbarItem>
{props.children && <ToolbarItem className="flex-start">{props.children}</ToolbarItem>}
{actions && (
<ToolbarItem className="flex-start" alignment={{ default: 'alignRight' }}>
<OverflowMenu breakpoint="md">
Expand All @@ -501,7 +472,7 @@ export const FiltersToolbar: React.FC<FiltersToolbarProps> = ({
</OverflowMenu>
</ToolbarItem>
)}
{_.isEmpty(forcedFilters) &&
{_.isEmpty(forcedFilters) ? (
filters &&
filters.map((filter, index) => (
<ToolbarFilter
Expand All @@ -525,7 +496,34 @@ export const FiltersToolbar: React.FC<FiltersToolbarProps> = ({
<div></div>
}
</ToolbarFilter>
))}
))
) : (
<ToolbarGroup id="forced-filters" variant="filter-group">
<ToolbarItem className="flex-start">
{forcedFilters &&
forcedFilters.map((forcedFilter, ffIndex) => (
<ChipGroup
key={ffIndex}
isClosable={false}
categoryName={getFullColumnName(columns.find(c => c.id === forcedFilter.colId))}
>
{forcedFilter.values.map((forcedValue, fvIndex) => (
<Chip key={fvIndex} isReadOnly={true}>
{forcedValue.display ? forcedValue.display : forcedValue.v}
</Chip>
))}
</ChipGroup>
))}
</ToolbarItem>
<ToolbarItem className="flex-start">
<OverflowMenu breakpoint="md">
<OverflowMenuGroup groupType="button" isPersistent>
<Button onClick={() => push(getPathWithParams(NETFLOW_TRAFFIC_PATH))}>{t('Edit filters')}</Button>
</OverflowMenuGroup>
</OverflowMenu>
</ToolbarItem>
</ToolbarGroup>
)}
{/* TODO : NETOBSERV-104
<ToolbarItem variant="pagination">
<Pagination
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Button } from '@patternfly/react-core';
import RecordField, { RecordFieldFilter } from '../record-field';
import { DefaultColumns } from '../../__tests-data__/columns';
import { FlowsSample } from '../../__tests-data__/flows';
import { Size } from '../../display-dropdown';
import { Size } from '../../dropdowns/display-dropdown';

describe('<RecordField />', () => {
const filterMock: RecordFieldFilter = {
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/netflow-record/record-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { FlowDirection, Record } from '../../api/ipfix';
import { Column, ColumnsId, getFullColumnName } from '../../utils/columns';
import { formatPort } from '../../utils/port';
import { formatProtocol } from '../../utils/protocol';
import { Size } from '../display-dropdown';
import { Size } from '../dropdowns/display-dropdown';
import './record-field.css';

export type RecordFieldFilter = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import NetflowTableRow from '../netflow-table-row';
import { Record } from '../../../api/ipfix';
import { DefaultColumns } from '../../__tests-data__/columns';
import { FlowsSample } from '../../__tests-data__/flows';
import { Size } from '../../display-dropdown';
import { Size } from '../../dropdowns/display-dropdown';

describe('<NetflowTableRow />', () => {
let flows: Record[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { NetflowTableHeader } from '../netflow-table-header';

import { ShuffledDefaultColumns } from '../../__tests-data__/columns';
import { FlowsSample } from '../../__tests-data__/flows';
import { Size } from '../../display-dropdown';
import { Size } from '../../dropdowns/display-dropdown';

const errorStateQuery = `EmptyState[data-test="error-state"]`;
const loadingContentsQuery = `Bullseye[data-test="loading-contents"]`;
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/netflow-table/netflow-table-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Td, Tr } from '@patternfly/react-table';
import * as React from 'react';
import { Record } from '../../api/ipfix';
import { Column } from '../../utils/columns';
import { Size } from '../display-dropdown';
import { Size } from '../dropdowns/display-dropdown';
import { RecordField } from '../netflow-record/record-field';
import './netflow-table-row.css';
import CSSTransition from 'react-transition-group/CSSTransition';
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/netflow-table/netflow-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { Record } from '../../api/ipfix';
import { NetflowTableHeader } from './netflow-table-header';
import NetflowTableRow from './netflow-table-row';
import { Column } from '../../utils/columns';
import { Size } from '../display-dropdown';
import { Size } from '../dropdowns/display-dropdown';

const NetflowTable: React.FC<{
flows: Record[];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { shallow } from 'enzyme';
import * as React from 'react';
import NetflowTopology from '../netflow-topology';

describe('<NetflowTopology />', () => {
it('should render component', async () => {
const wrapper = shallow(<NetflowTopology />);
expect(wrapper.find(NetflowTopology)).toBeTruthy();
});
});
31 changes: 31 additions & 0 deletions web/src/components/netflow-topology/netflow-topology.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Bullseye, EmptyState, EmptyStateBody, EmptyStateVariant, Spinner, Title } from '@patternfly/react-core';
import * as React from 'react';
import { useTranslation } from 'react-i18next';

const NetflowTopology: React.FC<{
loading?: boolean;
error?: string;
}> = ({ error, loading }) => {
const { t } = useTranslation('plugin__network-observability-plugin');

if (error) {
return (
<EmptyState data-test="error-state" variant={EmptyStateVariant.small}>
<Title headingLevel="h2" size="lg">
{t('Unable to get topology')}
</Title>
<EmptyStateBody>{error}</EmptyStateBody>
</EmptyState>
);
} else if (loading) {
return (
<Bullseye data-test="loading-contents">
<Spinner size="xl" />
</Bullseye>
);
}

return <div>{t('TODO')}</div>;
};

export default NetflowTopology;
19 changes: 19 additions & 0 deletions web/src/components/netflow-traffic.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
.actions {
display: flex;
flex-direction: row;
align-items: baseline;
}

/*hack to keep refresh button size while loading*/

.co-action-refresh-button {
Expand All @@ -16,6 +22,7 @@ span.pf-c-button__icon.pf-m-start {
from {
transform: rotate(0deg);
}

to {
transform: rotate(360deg);
}
Expand All @@ -36,4 +43,16 @@ span.pf-c-button__icon.pf-m-start {

#drawer {
z-index: 0;
}

/* flex page header */
#pageHeader {
display: flex;
flex-direction: row;
margin-bottom: 10px;
padding-right: var(--pf-global--spacer--md);
}

.flex {
flex: 1;
}
Loading

0 comments on commit c88c876

Please sign in to comment.