Skip to content

Commit f45108e

Browse files
authored
fix: create and organise CheckList page folder with dependent components (#998)
* refactor: moved routing components to own high-level folder * fix: local mocks to routers.test rather than global * refactor: create checklist page folder and move associated components * fix: move routing.consts to routing folder * fix: upstream merge changes * refactor: split uninitialisedRouter * fix: updated bulkActionsModal export name * fix: reparent ROUTES type to routing/types * fix: create test/helpers folder * fix: flatten checklist components folder. rename checklist items so adhere to file nesting * fix: update gren
1 parent edbf7a7 commit f45108e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+387
-385
lines changed

‎CONTRIBUTING.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,24 @@ Grafana configuration can be adjusted using the `custom.ini` file located in `/d
5555
Grafana Enterprise adds features which the plugin takes advantage of (e.g. RBAC). To run the development environment with Grafana Enterprise features enabled you need to add a valid Grafana Enterprise license by updating `dev/license.jwt`. It has been added to our `.gitignore` file to ensure your license doesn't get added to any pull requests (we wouldn't want that happening again...).
5656

5757
When running `yarn server` if `dev/license.jwt` doesn't exist it will create it for you with no content present. You are free to update this file with your own license.
58+
59+
### IDE setup
60+
61+
We make no distinction of what IDE you should be using, however we do have some recommendations that if your IDE allows, you should enable:
62+
63+
#### Format on save
64+
65+
We use both [prettier](https://prettier.io/) and [eslint](https://eslint.org/) with the [@grafana/eslint-config package](https://www.npmjs.com/package/@grafana/eslint-config) which [we have chosen to extend](./.eslintrc.js). Our CI/CD pipelines expect these rules to be adherred to and will fail any submitted PRs if not. We recommend you enable format on save to ensure you are always adhering to these rules with as little friction as possible.
66+
67+
#### File nesting
68+
69+
We use the file nesting feature to help manage the growing number of files in the project. We recommend you enable this feature in your IDE to help keep your project organized and add the following rule (example is for VSCode):
70+
71+
```json
72+
"explorer.fileNesting.enabled": true,
73+
"explorer.fileNesting.patterns": {
74+
"*.tsx": "${capture}.constants.ts, ${capture}.hooks.ts, ${capture}.test.tsx, ${capture}.types.ts, ${capture}.utils.ts"
75+
}
76+
```
77+
78+

‎src/__mocks__/MockFormWrapper.tsx

Lines changed: 0 additions & 11 deletions
This file was deleted.

‎src/__mocks__/raw-loader.js

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { AddNewCheckButton } from './AddNewCheckButton';

‎src/components/AlertSensitivityBadge/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

‎src/components/AlertStatus/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

‎src/components/BulkEditModal/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

‎src/components/CheckList/CheckListViewSwitcher.tsx

Lines changed: 0 additions & 22 deletions
This file was deleted.

‎src/components/CheckListItem/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

‎src/components/constants.ts

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@ import {
66
AlertSeverity,
77
BrowserCheck,
88
Check,
9-
CheckEnabledStatus,
10-
CheckListViewType,
11-
CheckSort,
129
CheckType,
1310
DNSCheck,
1411
DnsProtocol,
@@ -443,52 +440,6 @@ export const getDefaultAlertAnnotations = (percentage: number) => ({
443440
summary: `check success below ${percentage}%`,
444441
});
445442

446-
export const CHECK_LIST_SORT_OPTIONS = [
447-
{
448-
label: 'A-Z',
449-
value: CheckSort.AToZ,
450-
},
451-
{
452-
label: 'Z-A',
453-
value: CheckSort.ZToA,
454-
},
455-
{
456-
label: 'Asc. Reachability ',
457-
value: CheckSort.ReachabilityAsc,
458-
},
459-
{
460-
label: 'Desc. Reachability ',
461-
value: CheckSort.ReachabilityDesc,
462-
},
463-
{
464-
label: 'Asc. Executions ',
465-
value: CheckSort.ExecutionsAsc,
466-
},
467-
{
468-
label: 'Desc. Executions ',
469-
value: CheckSort.ExecutionsDesc,
470-
},
471-
];
472-
473-
export const CHECK_LIST_STATUS_OPTIONS: Array<SelectableValue<CheckEnabledStatus>> = [
474-
{ label: 'All', value: CheckEnabledStatus.All },
475-
{ label: 'Enabled', value: CheckEnabledStatus.Enabled },
476-
{ label: 'Disabled', value: CheckEnabledStatus.Disabled },
477-
];
478-
479-
export const CHECK_LIST_VIEW_TYPE_OPTIONS = [
480-
{ description: 'Card view', value: CheckListViewType.Card, icon: 'check-square' },
481-
{ description: 'List view', value: CheckListViewType.List, icon: 'list-ul' },
482-
{ description: 'Visualization view', value: CheckListViewType.Viz, icon: 'gf-grid' },
483-
];
484-
485-
export const CHECKS_PER_PAGE_CARD = 15;
486-
export const CHECKS_PER_PAGE_LIST = 50;
487-
488-
export const CHECK_LIST_VIEW_TYPE_LS_KEY = 'grafana.sm.checklist.viewType';
489-
490-
export const CHECK_LIST_ICON_OVERLAY_LS_KEY = 'grafana.sm.checklist.iconOverlay';
491-
492443
export const HTTP_COMPRESSION_ALGO_OPTIONS = [
493444
{ label: 'none', value: HTTPCompressionAlgo.none },
494445
{ label: 'identity', value: HTTPCompressionAlgo.identity },
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { SelectableValue } from '@grafana/data';
2+
3+
import { CheckEnabledStatus } from 'types';
4+
5+
export const CHECK_LIST_STATUS_OPTIONS: Array<SelectableValue<CheckEnabledStatus>> = [
6+
{ label: 'All', value: CheckEnabledStatus.All },
7+
{ label: 'Enabled', value: CheckEnabledStatus.Enabled },
8+
{ label: 'Disabled', value: CheckEnabledStatus.Disabled },
9+
];

‎src/hooks/useCheckFilters.ts renamed to ‎src/page/CheckList/CheckList.hooks.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import { SelectableValue } from '@grafana/data';
22
import { capitalize } from 'lodash';
33

4-
import { CheckEnabledStatus, CheckType, CheckTypeFilter, ProbeFilter } from 'types';
4+
import { CheckTypeFilter, ProbeFilter } from 'page/CheckList/CheckList.types';
5+
import { CheckEnabledStatus, CheckType } from 'types';
56
import { useProbes } from 'data/useProbes';
6-
import { defaultFilters } from 'components/CheckFilters';
7-
8-
import { useQueryParametersState } from './useQueryParametersState';
9-
10-
export type FilterType = 'search' | 'labels' | 'type' | 'status' | 'probes';
7+
import { useQueryParametersState } from 'hooks/useQueryParametersState';
8+
import { defaultFilters } from 'page/CheckList/CheckList.utils';
119

1210
interface CheckFiltersProps {
1311
search: [state: string, update: (value: string | null) => void];

‎src/components/CheckList/CheckList.tsx renamed to ‎src/page/CheckList/CheckList.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,24 @@ import { Pagination, useStyles2 } from '@grafana/ui';
55
import { css } from '@emotion/css';
66
import { getTotalChecksPerMonth } from 'checkUsageCalc';
77

8-
import { Check, CheckEnabledStatus, CheckFiltersType, CheckListViewType, CheckSort, CheckType, Label } from 'types';
8+
import { CheckFiltersType, CheckListViewType, FilterType } from 'page/CheckList/CheckList.types';
9+
import { Check, CheckEnabledStatus, CheckSort, CheckType, Label } from 'types';
910
import { MetricCheckSuccess, Time } from 'datasource/responses.types';
1011
import { useSuspenseChecks } from 'data/useChecks';
1112
import { useChecksReachabilitySuccessRate } from 'data/useSuccessRates';
1213
import { findCheckinMetrics } from 'data/utils';
13-
import { FilterType, useCheckFilters } from 'hooks/useCheckFilters';
1414
import { useQueryParametersState } from 'hooks/useQueryParametersState';
15-
import { CHECK_LIST_STATUS_OPTIONS, CHECKS_PER_PAGE_CARD, CHECKS_PER_PAGE_LIST } from 'components/constants';
1615
import { QueryErrorBoundary } from 'components/QueryErrorBoundary';
17-
18-
import { CheckListItem } from '../CheckListItem';
19-
import { matchesAllFilters } from './checkFilters';
20-
import { CheckListHeader } from './CheckListHeader';
21-
import { CheckListScene } from './CheckListScene';
22-
import { EmptyCheckList } from './EmptyCheckList';
16+
import { CHECK_LIST_STATUS_OPTIONS } from 'page/CheckList/CheckList.constants';
17+
import { useCheckFilters } from 'page/CheckList/CheckList.hooks';
18+
import { matchesAllFilters } from 'page/CheckList/CheckList.utils';
19+
import { CheckListHeader } from 'page/CheckList/components/CheckListHeader';
20+
import { CheckListItem } from 'page/CheckList/components/CheckListItem';
21+
import { CheckListScene } from 'page/CheckList/components/CheckListScene';
22+
import { EmptyCheckList } from 'page/CheckList/components/EmptyCheckList';
23+
24+
const CHECKS_PER_PAGE_CARD = 15;
25+
const CHECKS_PER_PAGE_LIST = 50;
2326

2427
export const CheckList = () => {
2528
const [viewType, setViewType] = useQueryParametersState<CheckListViewType>({

‎src/page/CheckList/CheckList.types.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { SelectableValue } from '@grafana/data';
2+
3+
import { Check, CheckEnabledStatus, CheckType, DashboardSceneAppConfig } from 'types';
4+
5+
export enum CheckListViewType {
6+
Card = 'card',
7+
List = 'list',
8+
Viz = 'viz',
9+
}
10+
11+
export type ProbeFilter = {
12+
label: string;
13+
value: number;
14+
};
15+
16+
export type CheckTypeFilter = CheckType | 'all';
17+
18+
export type FilterType = 'search' | 'labels' | 'type' | 'status' | 'probes';
19+
20+
export interface CheckFiltersType {
21+
[key: string]: any;
22+
23+
search: string;
24+
labels: string[];
25+
type: CheckTypeFilter;
26+
status: SelectableValue<CheckEnabledStatus>;
27+
probes: Array<SelectableValue<ProbeFilter>>;
28+
}
29+
30+
export interface VizViewSceneAppConfig extends DashboardSceneAppConfig {
31+
checkFilters: CheckFiltersType;
32+
checks: Check[];
33+
onReset: () => void;
34+
onFilterChange: (filters: CheckFiltersType, type: FilterType) => void;
35+
}

‎src/components/CheckList/checkFilters.ts renamed to ‎src/page/CheckList/CheckList.utils.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { SelectableValue } from '@grafana/data';
22

3-
import { Check, CheckEnabledStatus, CheckFiltersType, CheckTypeFilter } from 'types';
3+
import { CheckFiltersType, CheckTypeFilter } from 'page/CheckList/CheckList.types';
4+
import { Check, CheckEnabledStatus } from 'types';
45
import { getCheckType, matchStrings } from 'utils';
6+
import { CHECK_LIST_STATUS_OPTIONS } from 'page/CheckList/CheckList.constants';
57

68
const matchesFilterType = (check: Check, typeFilter: CheckTypeFilter) => {
79
if (typeFilter === 'all') {
@@ -71,3 +73,15 @@ export const matchesAllFilters = (check: Check, checkFilters: CheckFiltersType)
7173
matchesSelectedProbes(check, probes)
7274
);
7375
};
76+
77+
export const defaultFilters: CheckFiltersType = {
78+
search: '',
79+
labels: [],
80+
type: 'all',
81+
status: CHECK_LIST_STATUS_OPTIONS[0],
82+
probes: [],
83+
};
84+
85+
export const getDefaultFilters = (): CheckFiltersType => {
86+
return defaultFilters;
87+
};

‎src/components/AlertStatus/AlertStatus.tsx renamed to ‎src/page/CheckList/components/AlertStatus.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { ROUTES } from 'routing/types';
88
import { getRoute } from 'routing/utils';
99
import { useAlertRules } from 'hooks/useAlertRules';
1010
import { useMetricsDS } from 'hooks/useMetricsDS';
11-
import { AlertSensitivityBadge } from 'components/AlertSensitivityBadge';
1211
import { Toggletip } from 'components/Toggletip';
12+
import { AlertSensitivityBadge } from 'page/CheckList/components/AlertSensitivityBadge';
1313

1414
type AlertStatusProps = {
1515
check: Check;

‎src/components/CheckList/BulkActions.tsx renamed to ‎src/page/CheckList/components/BulkActions.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ import { css } from '@emotion/css';
66
import { Check } from 'types';
77
import { useBulkDeleteChecks, useBulkUpdateChecks } from 'data/useChecks';
88
import { useCanWriteSM } from 'hooks/useDSPermission';
9-
import { BulkEditModal } from 'components/BulkEditModal';
9+
import { BulkActionsModal } from 'page/CheckList/components/BulkActionsModal';
1010

11-
type BulkActionsProps = {
11+
interface BulkActionsProps {
1212
checks: Check[];
1313
onResolved: () => void;
14-
};
14+
}
1515

16-
export enum BulkAction {
16+
enum BulkAction {
1717
Add = `add`,
1818
Remove = `remove`,
1919
}
@@ -89,7 +89,7 @@ export const BulkActions = ({ checks, onResolved }: BulkActionsProps) => {
8989
</Button>
9090
</div>
9191
{bulkEditAction && (
92-
<BulkEditModal
92+
<BulkActionsModal
9393
checks={checks}
9494
onDismiss={() => setBulkEditAction(null)}
9595
action={bulkEditAction}

‎src/components/BulkEditModal/BulkEditModal.test.tsx renamed to ‎src/page/CheckList/components/BulkActionsModal.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import { server } from 'test/server';
88

99
import { Check } from 'types';
1010

11-
import { BulkEditModal } from './BulkEditModal';
11+
import { BulkActionsModal } from './BulkActionsModal';
1212

1313
const onDismiss = jest.fn();
1414

1515
const renderBulkEditModal = (action: 'add' | 'remove', checks: Check[]) => {
16-
return render(<BulkEditModal onDismiss={onDismiss} checks={checks} action={action} isOpen={true} />);
16+
return render(<BulkActionsModal onDismiss={onDismiss} checks={checks} action={action} isOpen={true} />);
1717
};
1818

1919
test('shows the modal', async () => {

‎src/components/BulkEditModal/BulkEditModal.tsx renamed to ‎src/page/CheckList/components/BulkActionsModal.tsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import { Check, Probe } from 'types';
88
import { useBulkUpdateChecks } from 'data/useChecks';
99
import { useProbes } from 'data/useProbes';
1010
import { QueryErrorBoundary } from 'components/QueryErrorBoundary';
11-
12-
import { ProbesByRegion } from './ProbesByRegion';
11+
import { ProbesByRegion } from 'page/CheckList/components/ProbesByRegion';
1312

1413
const actionTypeMap = {
1514
add: {
@@ -24,26 +23,26 @@ const actionTypeMap = {
2423
},
2524
};
2625

27-
interface BulkEditModalProps {
26+
interface BulkActionModalProps {
2827
onDismiss: () => void;
2928
checks: Check[];
3029
action: 'add' | 'remove';
3130
isOpen: boolean;
3231
}
3332

34-
export const BulkEditModal = (props: BulkEditModalProps) => {
33+
export const BulkActionsModal = (props: BulkActionModalProps) => {
3534
if (!props.action) {
3635
return null;
3736
}
3837

3938
return (
4039
<QueryErrorBoundary>
41-
<BulkEditModalContent {...props} />
40+
<BulkActionsModalContent {...props} />
4241
</QueryErrorBoundary>
4342
);
4443
};
4544

46-
const BulkEditModalContent = ({ onDismiss, isOpen, checks, action }: BulkEditModalProps) => {
45+
const BulkActionsModalContent = ({ onDismiss, isOpen, checks, action }: BulkActionModalProps) => {
4746
const { data: probes = [] } = useProbes();
4847
const { mutate: bulkUpdateChecks, isPending } = useBulkUpdateChecks({ onSuccess: onDismiss });
4948
const [probeIds, setProbeIds] = useState<number[]>([]);

‎src/components/CheckCardLabel.tsx renamed to ‎src/page/CheckList/components/CheckCardLabel.tsx

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,24 @@ import { css, cx } from '@emotion/css';
55

66
import { Label } from 'types';
77

8-
interface Props {
8+
interface CheckCardLabelProps {
99
label: Label;
1010
onLabelSelect: (label: Label) => void;
1111
className?: string;
1212
}
1313

14+
export const CheckCardLabel = ({ label, onLabelSelect, className }: CheckCardLabelProps) => {
15+
const styles = useStyles2(getStyles);
16+
17+
return (
18+
<Tag
19+
onClick={() => onLabelSelect(label)}
20+
name={`${label.name}: ${label.value}`}
21+
className={cx(styles.container, className)}
22+
/>
23+
);
24+
};
25+
1426
const getStyles = (theme: GrafanaTheme2) => ({
1527
container: css`
1628
background-color: #9933cc;
@@ -21,14 +33,3 @@ const getStyles = (theme: GrafanaTheme2) => ({
2133
text-overflow: ellipsis;
2234
`,
2335
});
24-
25-
export const CheckCardLabel = ({ label, onLabelSelect, className }: Props) => {
26-
const styles = useStyles2(getStyles);
27-
return (
28-
<Tag
29-
onClick={() => onLabelSelect(label)}
30-
name={`${label.name}: ${label.value}`}
31-
className={cx(styles.container, className)}
32-
/>
33-
);
34-
};

0 commit comments

Comments
 (0)