@genspectrum/dashboard-components 0.4.4 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/custom-elements.json +107 -12
  2. package/dist/dashboard-components.js +186 -145
  3. package/dist/dashboard-components.js.map +1 -1
  4. package/dist/genspectrum-components.d.ts +24 -0
  5. package/package.json +1 -1
  6. package/src/preact/aggregatedData/aggregate-table.tsx +3 -2
  7. package/src/preact/aggregatedData/aggregate.stories.tsx +2 -0
  8. package/src/preact/aggregatedData/aggregate.tsx +8 -3
  9. package/src/preact/components/table.stories.tsx +51 -1
  10. package/src/preact/components/table.tsx +4 -3
  11. package/src/preact/locationFilter/location-filter.stories.tsx +12 -1
  12. package/src/preact/locationFilter/location-filter.tsx +10 -3
  13. package/src/preact/mutationComparison/mutation-comparison-table.tsx +7 -2
  14. package/src/preact/mutationComparison/mutation-comparison.stories.tsx +3 -0
  15. package/src/preact/mutationComparison/mutation-comparison.tsx +25 -3
  16. package/src/preact/mutations/mutations-grid.tsx +8 -2
  17. package/src/preact/mutations/mutations-insertions-table.tsx +3 -2
  18. package/src/preact/mutations/mutations-table.tsx +3 -2
  19. package/src/preact/mutations/mutations.stories.tsx +3 -0
  20. package/src/preact/mutations/mutations.tsx +16 -6
  21. package/src/preact/prevalenceOverTime/prevalence-over-time-table.tsx +3 -2
  22. package/src/preact/prevalenceOverTime/prevalence-over-time.stories.tsx +4 -0
  23. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +8 -1
  24. package/src/web-components/input/gs-location-filter.stories.ts +11 -0
  25. package/src/web-components/input/gs-location-filter.tsx +14 -1
  26. package/src/web-components/visualization/gs-aggregate.stories.ts +4 -0
  27. package/src/web-components/visualization/gs-aggregate.tsx +8 -0
  28. package/src/web-components/visualization/gs-mutation-comparison.stories.ts +4 -0
  29. package/src/web-components/visualization/gs-mutation-comparison.tsx +8 -0
  30. package/src/web-components/visualization/gs-mutations.stories.ts +4 -0
  31. package/src/web-components/visualization/gs-mutations.tsx +8 -0
  32. package/src/web-components/visualization/gs-prevalence-over-time.stories.ts +5 -0
  33. package/src/web-components/visualization/gs-prevalence-over-time.tsx +12 -4
@@ -66,6 +66,11 @@ export declare class AggregateComponent extends PreactLitAdapterWithGridJsStyles
66
66
  * The initial sort direction of the table.
67
67
  */
68
68
  initialSortDirection: 'ascending' | 'descending';
69
+ /**
70
+ * The maximum number of rows to display in the table view.
71
+ * Set to `false` to disable pagination. Set to `true` to enable pagination with a default limit (10).
72
+ */
73
+ pageSize: boolean | number;
69
74
  render(): JSX_2.Element;
70
75
  }
71
76
 
@@ -228,6 +233,10 @@ export declare class LocationFilterComponent extends PreactLitAdapter {
228
233
  * Visit https://genspectrum.github.io/dashboards/?path=/docs/components-size-of-components--docs for more information.
229
234
  */
230
235
  width: string;
236
+ /**
237
+ * The placeholder text to display in the input field, if it is empty.
238
+ */
239
+ placeholderText: string;
231
240
  render(): JSX_2.Element;
232
241
  }
233
242
 
@@ -296,6 +305,11 @@ export declare class MutationComparisonComponent extends PreactLitAdapterWithGri
296
305
  * The headline of the component. Set to an empty string to hide the headline.
297
306
  */
298
307
  headline: string;
308
+ /**
309
+ * The maximum number of rows to display in the table view.
310
+ * Set to `false` to disable pagination. Set to `true` to enable pagination with a default limit (10).
311
+ */
312
+ pageSize: boolean | number;
299
313
  render(): JSX_2.Element;
300
314
  }
301
315
 
@@ -433,6 +447,11 @@ export declare class MutationsComponent extends PreactLitAdapterWithGridJsStyles
433
447
  * The headline of the component. Set to an empty string to hide the headline.
434
448
  */
435
449
  headline: string;
450
+ /**
451
+ * The maximum number of rows to display in the table view.
452
+ * Set to `false` to disable pagination. Set to `true` to enable pagination with a default limit (10).
453
+ */
454
+ pageSize: boolean | number;
436
455
  render(): JSX_2.Element;
437
456
  }
438
457
 
@@ -555,6 +574,11 @@ export declare class PrevalenceOverTimeComponent extends PreactLitAdapterWithGri
555
574
  * Must be a field of type `date` in LAPIS.
556
575
  */
557
576
  lapisDateField: string;
577
+ /**
578
+ * The maximum number of rows to display in the table view.
579
+ * Set to `false` to disable pagination. Set to `true` to enable pagination with a default limit (10).
580
+ */
581
+ pageSize: boolean | number;
558
582
  render(): JSX_2.Element;
559
583
  }
560
584
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genspectrum/dashboard-components",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "GenSpectrum web components for building dashboards",
5
5
  "type": "module",
6
6
  "license": "AGPL-3.0-only",
@@ -7,9 +7,10 @@ import { formatProportion } from '../shared/table/formatProportion';
7
7
  type AggregateTableProps = {
8
8
  fields: string[];
9
9
  data: AggregateData;
10
+ pageSize: boolean | number;
10
11
  };
11
12
 
12
- export const AggregateTable: FunctionComponent<AggregateTableProps> = ({ data, fields }) => {
13
+ export const AggregateTable: FunctionComponent<AggregateTableProps> = ({ data, fields, pageSize }) => {
13
14
  const headers = [
14
15
  ...fields.map((field) => {
15
16
  return {
@@ -28,5 +29,5 @@ export const AggregateTable: FunctionComponent<AggregateTableProps> = ({ data, f
28
29
  },
29
30
  ];
30
31
 
31
- return <Table data={data} columns={headers} pagination={true} />;
32
+ return <Table data={data} columns={headers} pageSize={pageSize} />;
32
33
  };
@@ -15,6 +15,7 @@ const meta: Meta<AggregateProps> = {
15
15
  headline: { control: 'text' },
16
16
  initialSortField: { control: 'text' },
17
17
  initialSortDirection: { control: 'radio', options: ['ascending', 'descending'] },
18
+ pageSize: { control: 'object' },
18
19
  },
19
20
  parameters: {
20
21
  fetchMock: {
@@ -57,5 +58,6 @@ export const Default: StoryObj<AggregateProps> = {
57
58
  headline: 'Aggregate',
58
59
  initialSortField: 'count',
59
60
  initialSortDirection: 'descending',
61
+ pageSize: 10,
60
62
  },
61
63
  };
@@ -31,6 +31,7 @@ export interface AggregateInnerProps {
31
31
  views: View[];
32
32
  initialSortField: string;
33
33
  initialSortDirection: 'ascending' | 'descending';
34
+ pageSize: boolean | number;
34
35
  }
35
36
 
36
37
  export const Aggregate: FunctionComponent<AggregateProps> = ({
@@ -40,6 +41,7 @@ export const Aggregate: FunctionComponent<AggregateProps> = ({
40
41
  headline = 'Mutations',
41
42
  filter,
42
43
  fields,
44
+ pageSize,
43
45
  initialSortField,
44
46
  initialSortDirection,
45
47
  }) => {
@@ -55,6 +57,7 @@ export const Aggregate: FunctionComponent<AggregateProps> = ({
55
57
  views={views}
56
58
  initialSortField={initialSortField}
57
59
  initialSortDirection={initialSortDirection}
60
+ pageSize={pageSize}
58
61
  />
59
62
  </Headline>
60
63
  </ResizeContainer>
@@ -68,6 +71,7 @@ export const AggregateInner: FunctionComponent<AggregateInnerProps> = ({
68
71
  filter,
69
72
  initialSortField,
70
73
  initialSortDirection,
74
+ pageSize,
71
75
  }) => {
72
76
  const lapis = useContext(LapisUrlContext);
73
77
 
@@ -87,22 +91,23 @@ export const AggregateInner: FunctionComponent<AggregateInnerProps> = ({
87
91
  return <NoDataDisplay />;
88
92
  }
89
93
 
90
- return <AggregatedDataTabs data={data} views={views} fields={fields} />;
94
+ return <AggregatedDataTabs data={data} views={views} fields={fields} pageSize={pageSize} />;
91
95
  };
92
96
 
93
97
  type AggregatedDataTabsProps = {
94
98
  data: AggregateData;
95
99
  fields: string[];
96
100
  views: View[];
101
+ pageSize: boolean | number;
97
102
  };
98
103
 
99
- const AggregatedDataTabs: FunctionComponent<AggregatedDataTabsProps> = ({ data, views, fields }) => {
104
+ const AggregatedDataTabs: FunctionComponent<AggregatedDataTabsProps> = ({ data, views, fields, pageSize }) => {
100
105
  const getTab = (view: View) => {
101
106
  switch (view) {
102
107
  case 'table':
103
108
  return {
104
109
  title: 'Table',
105
- content: <AggregateTable data={data} fields={fields} />,
110
+ content: <AggregateTable data={data} fields={fields} pageSize={pageSize} />,
106
111
  };
107
112
  }
108
113
  };
@@ -1,4 +1,5 @@
1
1
  import { type Meta, type StoryObj } from '@storybook/preact';
2
+ import { expect, userEvent, waitFor, within } from '@storybook/test';
2
3
 
3
4
  import { Table } from './table';
4
5
 
@@ -6,13 +7,51 @@ const meta: Meta = {
6
7
  title: 'Component/Table',
7
8
  component: Table,
8
9
  parameters: { fetchMock: {} },
10
+ argTypes: {
11
+ data: { control: 'object' },
12
+ columns: { control: 'object' },
13
+ pageSize: { control: 'object' },
14
+ },
9
15
  };
10
16
 
11
17
  export default meta;
12
18
 
13
19
  export const TableStory: StoryObj = {
14
20
  render: (args) => {
15
- return <Table data={args.data} columns={args.columns} pagination={false} />;
21
+ return <Table data={args.data} columns={args.columns} pageSize={args.pageSize} />;
22
+ },
23
+ args: {
24
+ data: [
25
+ ['John Do', 'john@example.com', '123-456-7890'],
26
+ ['Jane Doe', 'jane@example.com', '098-765-4321'],
27
+ ],
28
+ columns: [{ name: 'Name' }, { name: 'Email', sort: true }, { name: 'Phone Number' }],
29
+ pageSize: 1,
30
+ },
31
+ play: async ({ canvasElement, step }) => {
32
+ const canvas = within(canvasElement);
33
+
34
+ const firstRow = () => canvas.queryByText('John Do', { exact: true });
35
+ const secondRow = () => canvas.queryByText('Jane Doe', { exact: true });
36
+
37
+ await step('Expect first row to be visible and not second row', async () => {
38
+ await waitFor(() => expect(firstRow()).toBeVisible());
39
+ await expect(secondRow()).toBeNull();
40
+ });
41
+
42
+ await step('Expect second row to be visible and not first row after clicking next', async () => {
43
+ const nextButton = canvas.getByRole('button', { name: 'Next' });
44
+ await userEvent.click(nextButton);
45
+
46
+ await waitFor(() => expect(secondRow()).toBeVisible());
47
+ await expect(firstRow()).toBeNull();
48
+ });
49
+ },
50
+ };
51
+
52
+ export const TableStoryNoPagination: StoryObj = {
53
+ render: (args) => {
54
+ return <Table data={args.data} columns={args.columns} pageSize={args.pageSize} />;
16
55
  },
17
56
  args: {
18
57
  data: [
@@ -20,5 +59,16 @@ export const TableStory: StoryObj = {
20
59
  ['Jane Doe', 'jane@example.com', '098-765-4321'],
21
60
  ],
22
61
  columns: [{ name: 'Name' }, { name: 'Email', sort: true }, { name: 'Phone Number' }],
62
+ pageSize: false,
63
+ },
64
+ play: async ({ canvasElement }) => {
65
+ const canvas = within(canvasElement);
66
+
67
+ const firstRow = () => canvas.queryByText('John Do', { exact: true });
68
+ const secondRow = () => canvas.queryByText('Jane Doe', { exact: true });
69
+
70
+ await waitFor(() => expect(firstRow()).toBeVisible());
71
+ await expect(secondRow()).toBeVisible();
72
+ await waitFor(() => expect(canvas.queryByText('Next')).toBeNull());
23
73
  },
24
74
  };
@@ -1,6 +1,5 @@
1
1
  import { Grid } from 'gridjs';
2
2
  import { type OneDArray, type TColumn, type TData } from 'gridjs/dist/src/types';
3
- import { type PaginationConfig } from 'gridjs/dist/src/view/plugin/pagination';
4
3
  import { type ComponentChild } from 'preact';
5
4
  import { useEffect, useRef } from 'preact/hooks';
6
5
 
@@ -26,10 +25,12 @@ export const tableStyle = {
26
25
  interface TableProps {
27
26
  data: TData;
28
27
  columns: OneDArray<TColumn | string | ComponentChild>;
29
- pagination: PaginationConfig | boolean;
28
+ pageSize: number | boolean;
30
29
  }
31
30
 
32
- export const Table = ({ data, columns, pagination }: TableProps) => {
31
+ export const Table = ({ data, columns, pageSize }: TableProps) => {
32
+ const pagination = typeof pageSize === 'number' ? { limit: pageSize } : pageSize;
33
+
33
34
  const wrapper = useRef(null);
34
35
 
35
36
  useEffect(() => {
@@ -35,6 +35,7 @@ const meta: Meta<LocationFilterProps> = {
35
35
  width: '100%',
36
36
  fields: ['region', 'country', 'division', 'location'],
37
37
  initialValue: 'Europe',
38
+ placeholderText: 'Enter a location',
38
39
  },
39
40
  argTypes: {
40
41
  fields: {
@@ -52,6 +53,11 @@ const meta: Meta<LocationFilterProps> = {
52
53
  type: 'text',
53
54
  },
54
55
  },
56
+ placeholderText: {
57
+ control: {
58
+ type: 'text',
59
+ },
60
+ },
55
61
  },
56
62
  decorators: [withActions],
57
63
  };
@@ -61,7 +67,12 @@ export default meta;
61
67
  export const Primary: StoryObj<LocationFilterProps> = {
62
68
  render: (args) => (
63
69
  <LapisUrlContext.Provider value={LAPIS_URL}>
64
- <LocationFilter fields={args.fields} initialValue={args.initialValue} width={args.width} />
70
+ <LocationFilter
71
+ fields={args.fields}
72
+ initialValue={args.initialValue}
73
+ width={args.width}
74
+ placeholderText={args.placeholderText}
75
+ />
65
76
  </LapisUrlContext.Provider>
66
77
  ),
67
78
  };
@@ -12,6 +12,7 @@ import { useQuery } from '../useQuery';
12
12
 
13
13
  export interface LocationFilterInnerProps {
14
14
  initialValue?: string;
15
+ placeholderText?: string;
15
16
  fields: string[];
16
17
  }
17
18
 
@@ -19,19 +20,24 @@ export interface LocationFilterProps extends LocationFilterInnerProps {
19
20
  width: string;
20
21
  }
21
22
 
22
- export const LocationFilter: FunctionComponent<LocationFilterProps> = ({ width, initialValue, fields }) => {
23
+ export const LocationFilter: FunctionComponent<LocationFilterProps> = ({
24
+ width,
25
+ initialValue,
26
+ fields,
27
+ placeholderText,
28
+ }) => {
23
29
  const size = { width, height: '3rem' };
24
30
 
25
31
  return (
26
32
  <ErrorBoundary size={size}>
27
33
  <ResizeContainer size={size}>
28
- <LocationFilterInner initialValue={initialValue} fields={fields} />
34
+ <LocationFilterInner initialValue={initialValue} fields={fields} placeholderText={placeholderText} />
29
35
  </ResizeContainer>
30
36
  </ErrorBoundary>
31
37
  );
32
38
  };
33
39
 
34
- export const LocationFilterInner = ({ initialValue, fields }: LocationFilterInnerProps) => {
40
+ export const LocationFilterInner = ({ initialValue, fields, placeholderText }: LocationFilterInnerProps) => {
35
41
  const lapis = useContext(LapisUrlContext);
36
42
 
37
43
  const [value, setValue] = useState(initialValue ?? '');
@@ -77,6 +83,7 @@ export const LocationFilterInner = ({ initialValue, fields }: LocationFilterInne
77
83
  value={value}
78
84
  onInput={onInput}
79
85
  list='countries'
86
+ placeholder={placeholderText}
80
87
  />
81
88
  <datalist id='countries'>
82
89
  {data?.map((v) => {
@@ -12,9 +12,14 @@ import { formatProportion } from '../shared/table/formatProportion';
12
12
  export interface MutationsTableProps {
13
13
  data: Dataset<MutationData>;
14
14
  proportionInterval: ProportionInterval;
15
+ pageSize: boolean | number;
15
16
  }
16
17
 
17
- export const MutationComparisonTable: FunctionComponent<MutationsTableProps> = ({ data, proportionInterval }) => {
18
+ export const MutationComparisonTable: FunctionComponent<MutationsTableProps> = ({
19
+ data,
20
+ proportionInterval,
21
+ pageSize,
22
+ }) => {
18
23
  const headers = [
19
24
  {
20
25
  name: 'Mutation',
@@ -37,5 +42,5 @@ export const MutationComparisonTable: FunctionComponent<MutationsTableProps> = (
37
42
 
38
43
  const tableData = getMutationComparisonTableData(data, proportionInterval).map((row) => Object.values(row));
39
44
 
40
- return <Table data={tableData} columns={headers} pagination={true} />;
45
+ return <Table data={tableData} columns={headers} pageSize={pageSize} />;
41
46
  };
@@ -30,6 +30,7 @@ const meta: Meta<MutationComparisonProps> = {
30
30
  width: { control: 'text' },
31
31
  height: { control: 'text' },
32
32
  headline: { control: 'text' },
33
+ pageSize: { control: 'object' },
33
34
  },
34
35
  parameters: {
35
36
  fetchMock: {
@@ -85,6 +86,7 @@ const Template: StoryObj<MutationComparisonProps> = {
85
86
  width={args.width}
86
87
  height={args.height}
87
88
  headline={args.headline}
89
+ pageSize={args.pageSize}
88
90
  />
89
91
  </ReferenceGenomeContext.Provider>
90
92
  </LapisUrlContext.Provider>
@@ -114,6 +116,7 @@ export const TwoVariants: StoryObj<MutationComparisonProps> = {
114
116
  width: '100%',
115
117
  height: '700px',
116
118
  headline: 'Mutation comparison',
119
+ pageSize: 10,
117
120
  },
118
121
  };
119
122
 
@@ -34,6 +34,7 @@ export interface MutationComparisonInnerProps {
34
34
  variants: NamedLapisFilter[];
35
35
  sequenceType: SequenceType;
36
36
  views: View[];
37
+ pageSize: boolean | number;
37
38
  }
38
39
 
39
40
  export const MutationComparison: FunctionComponent<MutationComparisonProps> = ({
@@ -43,6 +44,7 @@ export const MutationComparison: FunctionComponent<MutationComparisonProps> = ({
43
44
  width,
44
45
  height,
45
46
  headline = 'Mutation comparison',
47
+ pageSize,
46
48
  }) => {
47
49
  const size = { height, width };
48
50
 
@@ -50,7 +52,12 @@ export const MutationComparison: FunctionComponent<MutationComparisonProps> = ({
50
52
  <ErrorBoundary size={size} headline={headline}>
51
53
  <ResizeContainer size={size}>
52
54
  <Headline heading={headline}>
53
- <MutationComparisonInner variants={variants} sequenceType={sequenceType} views={views} />
55
+ <MutationComparisonInner
56
+ variants={variants}
57
+ sequenceType={sequenceType}
58
+ views={views}
59
+ pageSize={pageSize}
60
+ />
54
61
  </Headline>
55
62
  </ResizeContainer>
56
63
  </ErrorBoundary>
@@ -61,6 +68,7 @@ export const MutationComparisonInner: FunctionComponent<MutationComparisonInnerP
61
68
  variants,
62
69
  sequenceType,
63
70
  views,
71
+ pageSize,
64
72
  }) => {
65
73
  const lapis = useContext(LapisUrlContext);
66
74
 
@@ -80,16 +88,29 @@ export const MutationComparisonInner: FunctionComponent<MutationComparisonInnerP
80
88
  return <NoDataDisplay />;
81
89
  }
82
90
 
83
- return <MutationComparisonTabs data={data.mutationData} sequenceType={sequenceType} views={views} />;
91
+ return (
92
+ <MutationComparisonTabs
93
+ data={data.mutationData}
94
+ sequenceType={sequenceType}
95
+ views={views}
96
+ pageSize={pageSize}
97
+ />
98
+ );
84
99
  };
85
100
 
86
101
  type MutationComparisonTabsProps = {
87
102
  data: MutationData[];
88
103
  views: View[];
89
104
  sequenceType: SequenceType;
105
+ pageSize: boolean | number;
90
106
  };
91
107
 
92
- const MutationComparisonTabs: FunctionComponent<MutationComparisonTabsProps> = ({ data, views, sequenceType }) => {
108
+ const MutationComparisonTabs: FunctionComponent<MutationComparisonTabsProps> = ({
109
+ data,
110
+ views,
111
+ sequenceType,
112
+ pageSize,
113
+ }) => {
93
114
  const [proportionInterval, setProportionInterval] = useState({ min: 0.5, max: 1 });
94
115
  const [displayedMutationTypes, setDisplayedMutationTypes] = useState<DisplayedMutationType[]>([
95
116
  { label: 'Substitutions', checked: true, type: 'substitution' },
@@ -111,6 +132,7 @@ const MutationComparisonTabs: FunctionComponent<MutationComparisonTabsProps> = (
111
132
  <MutationComparisonTable
112
133
  data={{ content: filteredData }}
113
134
  proportionInterval={proportionInterval}
135
+ pageSize={pageSize}
114
136
  />
115
137
  ),
116
138
  };
@@ -13,6 +13,7 @@ interface MutationsGridProps {
13
13
  data: SubstitutionOrDeletionEntry[];
14
14
  sequenceType: SequenceType;
15
15
  proportionInterval: ProportionInterval;
16
+ pageSize: boolean | number;
16
17
  }
17
18
 
18
19
  export type BaseCell = {
@@ -20,7 +21,12 @@ export type BaseCell = {
20
21
  isReference: boolean;
21
22
  };
22
23
 
23
- export const MutationsGrid: FunctionComponent<MutationsGridProps> = ({ data, sequenceType, proportionInterval }) => {
24
+ export const MutationsGrid: FunctionComponent<MutationsGridProps> = ({
25
+ data,
26
+ sequenceType,
27
+ proportionInterval,
28
+ pageSize,
29
+ }) => {
24
30
  const getHeaders = () => {
25
31
  return [
26
32
  {
@@ -80,5 +86,5 @@ export const MutationsGrid: FunctionComponent<MutationsGridProps> = ({ data, seq
80
86
 
81
87
  const tableData = getMutationsGridData(data, sequenceType, proportionInterval).map((row) => Object.values(row));
82
88
 
83
- return <Table data={tableData} columns={getHeaders()} pagination={true} />;
89
+ return <Table data={tableData} columns={getHeaders()} pageSize={pageSize} />;
84
90
  };
@@ -8,9 +8,10 @@ import { sortInsertions } from '../shared/sort/sortInsertions';
8
8
 
9
9
  export interface InsertionsTableProps {
10
10
  data: InsertionEntry[];
11
+ pageSize: boolean | number;
11
12
  }
12
13
 
13
- export const InsertionsTable: FunctionComponent<InsertionsTableProps> = ({ data }) => {
14
+ export const InsertionsTable: FunctionComponent<InsertionsTableProps> = ({ data, pageSize }) => {
14
15
  const getHeaders = () => {
15
16
  return [
16
17
  {
@@ -31,5 +32,5 @@ export const InsertionsTable: FunctionComponent<InsertionsTableProps> = ({ data
31
32
 
32
33
  const tableData = getInsertionsTableData(data).map((row) => Object.values(row));
33
34
 
34
- return <Table data={tableData} columns={getHeaders()} pagination={true} />;
35
+ return <Table data={tableData} columns={getHeaders()} pageSize={pageSize} />;
35
36
  };
@@ -11,9 +11,10 @@ import { formatProportion } from '../shared/table/formatProportion';
11
11
  export interface MutationsTableProps {
12
12
  data: SubstitutionOrDeletionEntry[];
13
13
  proportionInterval: ProportionInterval;
14
+ pageSize: boolean | number;
14
15
  }
15
16
 
16
- const MutationsTable: FunctionComponent<MutationsTableProps> = ({ data, proportionInterval }) => {
17
+ const MutationsTable: FunctionComponent<MutationsTableProps> = ({ data, proportionInterval, pageSize }) => {
17
18
  const getHeaders = () => {
18
19
  return [
19
20
  {
@@ -43,7 +44,7 @@ const MutationsTable: FunctionComponent<MutationsTableProps> = ({ data, proporti
43
44
 
44
45
  const tableData = getMutationsTableData(data, proportionInterval).map((row) => Object.values(row));
45
46
 
46
- return <Table data={tableData} columns={getHeaders()} pagination={true} />;
47
+ return <Table data={tableData} columns={getHeaders()} pageSize={pageSize} />;
47
48
  };
48
49
 
49
50
  export default MutationsTable;
@@ -25,6 +25,7 @@ const meta: Meta<MutationsProps> = {
25
25
  width: { control: 'text' },
26
26
  height: { control: 'text' },
27
27
  headline: { control: 'text' },
28
+ pageSize: { control: 'object' },
28
29
  },
29
30
  };
30
31
 
@@ -41,6 +42,7 @@ const Template = {
41
42
  width={args.width}
42
43
  height={args.height}
43
44
  headline={args.headline}
45
+ pageSize={args.pageSize}
44
46
  />
45
47
  </ReferenceGenomeContext.Provider>
46
48
  </LapisUrlContext.Provider>
@@ -56,6 +58,7 @@ export const Default: StoryObj<MutationsProps> = {
56
58
  width: '100%',
57
59
  height: '700px',
58
60
  headline: 'Mutations',
61
+ pageSize: 10,
59
62
  },
60
63
  parameters: {
61
64
  fetchMock: {
@@ -35,6 +35,7 @@ export interface MutationsInnerProps {
35
35
  variant: LapisFilter;
36
36
  sequenceType: SequenceType;
37
37
  views: View[];
38
+ pageSize: boolean | number;
38
39
  }
39
40
 
40
41
  export interface MutationsProps extends MutationsInnerProps {
@@ -50,6 +51,7 @@ export const Mutations: FunctionComponent<MutationsProps> = ({
50
51
  width,
51
52
  height,
52
53
  headline = 'Mutations',
54
+ pageSize,
53
55
  }) => {
54
56
  const size = { height, width };
55
57
 
@@ -57,14 +59,14 @@ export const Mutations: FunctionComponent<MutationsProps> = ({
57
59
  <ErrorBoundary size={size} headline={headline}>
58
60
  <ResizeContainer size={size}>
59
61
  <Headline heading={headline}>
60
- <MutationsInner variant={variant} sequenceType={sequenceType} views={views} />
62
+ <MutationsInner variant={variant} sequenceType={sequenceType} views={views} pageSize={pageSize} />
61
63
  </Headline>
62
64
  </ResizeContainer>
63
65
  </ErrorBoundary>
64
66
  );
65
67
  };
66
68
 
67
- export const MutationsInner: FunctionComponent<MutationsInnerProps> = ({ variant, sequenceType, views }) => {
69
+ export const MutationsInner: FunctionComponent<MutationsInnerProps> = ({ variant, sequenceType, views, pageSize }) => {
68
70
  const lapis = useContext(LapisUrlContext);
69
71
  const { data, error, isLoading } = useQuery(async () => {
70
72
  return queryMutationsData(variant, sequenceType, lapis);
@@ -82,16 +84,17 @@ export const MutationsInner: FunctionComponent<MutationsInnerProps> = ({ variant
82
84
  return <NoDataDisplay />;
83
85
  }
84
86
 
85
- return <MutationsTabs mutationsData={data} sequenceType={sequenceType} views={views} />;
87
+ return <MutationsTabs mutationsData={data} sequenceType={sequenceType} views={views} pageSize={pageSize} />;
86
88
  };
87
89
 
88
90
  type MutationTabsProps = {
89
91
  mutationsData: { insertions: InsertionEntry[]; substitutionsOrDeletions: SubstitutionOrDeletionEntry[] };
90
92
  sequenceType: SequenceType;
91
93
  views: View[];
94
+ pageSize: boolean | number;
92
95
  };
93
96
 
94
- const MutationsTabs: FunctionComponent<MutationTabsProps> = ({ mutationsData, sequenceType, views }) => {
97
+ const MutationsTabs: FunctionComponent<MutationTabsProps> = ({ mutationsData, sequenceType, views, pageSize }) => {
95
98
  const [proportionInterval, setProportionInterval] = useState({ min: 0.05, max: 1 });
96
99
 
97
100
  const [displayedSegments, setDisplayedSegments] = useDisplayedSegments(sequenceType);
@@ -107,7 +110,13 @@ const MutationsTabs: FunctionComponent<MutationTabsProps> = ({ mutationsData, se
107
110
  case 'table':
108
111
  return {
109
112
  title: 'Table',
110
- content: <MutationsTable data={filteredData.tableData} proportionInterval={proportionInterval} />,
113
+ content: (
114
+ <MutationsTable
115
+ data={filteredData.tableData}
116
+ proportionInterval={proportionInterval}
117
+ pageSize={pageSize}
118
+ />
119
+ ),
111
120
  };
112
121
  case 'grid':
113
122
  return {
@@ -117,13 +126,14 @@ const MutationsTabs: FunctionComponent<MutationTabsProps> = ({ mutationsData, se
117
126
  data={filteredData.gridData}
118
127
  sequenceType={sequenceType}
119
128
  proportionInterval={proportionInterval}
129
+ pageSize={pageSize}
120
130
  />
121
131
  ),
122
132
  };
123
133
  case 'insertions':
124
134
  return {
125
135
  title: 'Insertions',
126
- content: <InsertionsTable data={filteredData.insertions} />,
136
+ content: <InsertionsTable data={filteredData.insertions} pageSize={pageSize} />,
127
137
  };
128
138
  }
129
139
  };
@@ -7,9 +7,10 @@ import { formatProportion } from '../shared/table/formatProportion';
7
7
  interface PrevalenceOverTimeTableProps {
8
8
  data: PrevalenceOverTimeData;
9
9
  granularity: TemporalGranularity;
10
+ pageSize: boolean | number;
10
11
  }
11
12
 
12
- const PrevalenceOverTimeTable = ({ data, granularity }: PrevalenceOverTimeTableProps) => {
13
+ const PrevalenceOverTimeTable = ({ data, granularity, pageSize }: PrevalenceOverTimeTableProps) => {
13
14
  const getSplitColumns = (data: PrevalenceOverTimeData) => {
14
15
  return data.map((dataset) => ({
15
16
  name: dataset.displayName,
@@ -40,7 +41,7 @@ const PrevalenceOverTimeTable = ({ data, granularity }: PrevalenceOverTimeTableP
40
41
  return Object.values(dataByHeader).map((row) => Object.values(row));
41
42
  };
42
43
 
43
- return <Table data={getData(data, granularity)} columns={getColumns(data)} pagination={false} />;
44
+ return <Table data={getData(data, granularity)} columns={getColumns(data)} pageSize={pageSize} />;
44
45
  };
45
46
 
46
47
  export default PrevalenceOverTimeTable;