@cdc/dashboard 4.25.8 → 4.25.11

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 (88) hide show
  1. package/dist/{cdcdashboard-fce76882.es.js → cdcdashboard-BnB1QM5d.es.js} +6 -13
  2. package/dist/{cdcdashboard-c55ac1ea.es.js → cdcdashboard-D6CG2-Hb.es.js} +5 -12
  3. package/dist/{cdcdashboard-31a33da1.es.js → cdcdashboard-MXgURbdZ.es.js} +6 -13
  4. package/dist/{cdcdashboard-1a1724a1.es.js → cdcdashboard-dgT_1dIT.es.js} +136 -151
  5. package/dist/cdcdashboard.js +80040 -75976
  6. package/examples/api-test/categories.json +18 -0
  7. package/examples/api-test/chart-data.json +602 -0
  8. package/examples/api-test/topics.json +47 -0
  9. package/examples/api-test/years.json +22 -0
  10. package/examples/markup-axis-label.json +4167 -0
  11. package/examples/private/DEV-10538.json +407 -0
  12. package/examples/private/DEV-11405.json +39112 -0
  13. package/examples/private/big-dashboard.json +39112 -0
  14. package/examples/private/brfs-2.json +1532 -0
  15. package/examples/private/brfs.json +2128 -2138
  16. package/examples/private/clade-2.json +430 -0
  17. package/examples/private/delete.json +32919 -0
  18. package/examples/private/diabetes.json +5582 -0
  19. package/examples/private/example-2.json +49796 -0
  20. package/examples/private/group-legend-test.json +328 -0
  21. package/examples/private/map.json +1211 -0
  22. package/examples/private/markup-footer/burden_toolkit_mortality_diabetes_attributable_deaths_data.csv +14041 -0
  23. package/examples/private/markup-footer/burden_toolkit_mortality_diabetes_attributable_deaths_per_100000_data.csv +14041 -0
  24. package/examples/private/markup-footer/burden_toolkit_mortality_qaly_data.csv +18721 -0
  25. package/examples/private/markup-footer/burden_toolkit_mortality_yll_data.csv +18721 -0
  26. package/examples/private/markup-footer/mortality-deaths-footnotes-age.csv +3 -0
  27. package/examples/private/markup-variables.json +1451 -0
  28. package/examples/private/markup.json +5471 -0
  29. package/examples/private/mpox.json +38128 -0
  30. package/examples/private/north-dakota.json +1132 -0
  31. package/examples/private/ophdst.json +38754 -0
  32. package/examples/private/pedro.json +1 -0
  33. package/examples/private/pivot.json +683 -0
  34. package/examples/private/reset.json +32920 -0
  35. package/examples/private/sewershed.json +435 -0
  36. package/examples/private/tobacco.json +1938 -0
  37. package/examples/test-api-filter-reset.json +132 -0
  38. package/index.html +2 -2
  39. package/package.json +16 -10
  40. package/src/CdcDashboard.tsx +1 -3
  41. package/src/CdcDashboardComponent.tsx +34 -16
  42. package/src/DashboardContext.tsx +5 -1
  43. package/src/_stories/Dashboard.API.stories.tsx +62 -0
  44. package/src/_stories/Dashboard.stories.tsx +492 -472
  45. package/src/_stories/_mock/api/cessation.json +1 -0
  46. package/src/_stories/_mock/api/data-explorer.json +1 -0
  47. package/src/_stories/_mock/api/explore-by-location.json +1 -0
  48. package/src/_stories/_mock/api/explore-by-topic.json +1 -0
  49. package/src/_stories/_mock/api/legislation.json +1 -0
  50. package/src/_stories/_mock/api/oral-health-data.json +1 -0
  51. package/src/_stories/_mock/custom-order-new-values.json +116 -0
  52. package/src/components/CollapsibleVisualizationRow.tsx +1 -1
  53. package/src/components/DashboardFilters/DashboardFilters.tsx +34 -23
  54. package/src/components/DashboardFilters/DashboardFiltersEditor/DashboardFiltersEditor.tsx +29 -12
  55. package/src/components/DashboardFilters/DashboardFiltersEditor/components/FilterEditor.tsx +81 -112
  56. package/src/components/DashboardFilters/DashboardFiltersEditor/components/NestedDropDownDashboard.tsx +82 -52
  57. package/src/components/DashboardFilters/DashboardFiltersWrapper.tsx +130 -31
  58. package/src/components/DashboardFilters/_stories/DashboardFilters.stories.tsx +80 -21
  59. package/src/components/DataDesignerModal.tsx +227 -210
  60. package/src/components/Header/Header.tsx +13 -12
  61. package/src/components/Toggle/Toggle.tsx +48 -47
  62. package/src/components/VisualizationRow.tsx +13 -6
  63. package/src/components/VisualizationsPanel/VisualizationsPanel.tsx +2 -0
  64. package/src/components/Widget/Widget.tsx +47 -18
  65. package/src/helpers/addValuesToDashboardFilters.ts +111 -60
  66. package/src/helpers/apiFilterHelpers.ts +190 -166
  67. package/src/helpers/filterData.ts +52 -7
  68. package/src/helpers/filterResetHelpers.ts +102 -0
  69. package/src/helpers/formatConfigBeforeSave.ts +137 -0
  70. package/src/helpers/getVizConfig.ts +36 -18
  71. package/src/helpers/loadAPIFilters.ts +109 -99
  72. package/src/helpers/reloadURLHelpers.ts +1 -1
  73. package/src/helpers/tests/filterResetHelpers.test.ts +532 -0
  74. package/src/helpers/tests/formatConfigBeforeSave.test.ts +69 -0
  75. package/src/index.tsx +1 -1
  76. package/src/scss/editor-panel.scss +3 -431
  77. package/src/scss/grid.scss +7 -5
  78. package/src/scss/main.scss +1 -24
  79. package/src/store/errorMessage/errorMessage.reducer.ts +1 -1
  80. package/src/types/DashboardFilters.ts +9 -8
  81. package/src/types/InitialState.ts +12 -12
  82. package/vite.config.js +1 -1
  83. package/vitest.config.ts +16 -0
  84. package/src/coreStyles_dashboard.scss +0 -3
  85. package/src/helpers/getAutoLoadVisualization.ts +0 -11
  86. package/src/scss/mixins.scss +0 -47
  87. package/src/scss/variables.scss +0 -5
  88. /package/dist/{cdcdashboard-548642e6.es.js → cdcdashboard-Ct2SB0vL.es.js} +0 -0
@@ -1,472 +1,492 @@
1
- import type { Meta, StoryObj } from '@storybook/react'
2
- import { faker } from '@faker-js/faker'
3
- import APIFiltersMapData from './_mock/api-filter-map.json'
4
- import APIFiltersChartData from './_mock/api-filter-chart.json'
5
- import APIFilterErrorConfig from './_mock/api-filter-error.json'
6
- import ExampleConfig_1 from './_mock/dashboard-gallery.json'
7
- import ExampleConfig_2 from './_mock/dashboard-2.json'
8
- import ExampleConfig_3 from './_mock/dashboard_no_filter.json'
9
- import SingleStateDashboardFilters from './_mock/single-state-dashboard-filters.json'
10
- import Dashboard_Filter from './_mock/dashboard-filter.json'
11
- import MultiVizConfig from './_mock/multi-viz.json'
12
- import MultiDashboardConfig from './_mock/multi-dashboards.json'
13
- import Dashboard from '../CdcDashboard'
14
- import StandaloneTable from './_mock/standalone-table.json'
15
- import GroupPivotConfig from './_mock/group-pivot-filter.json'
16
- import PivotFitlerConfig from './_mock/pivot-filter.json'
17
- import { type DashboardConfig as Config } from '../types/DashboardConfig'
18
- import { userEvent, within } from '@storybook/testing-library'
19
- import ToggleExampleConfig from './_mock/toggle-example.json'
20
- import _ from 'lodash'
21
- import { footnotesSymbols } from '@cdc/core/helpers/footnoteSymbols'
22
- import FootnotesConfig from '@cdc/core/types/Footnotes'
23
- import { ConfigRow } from '../types/ConfigRow'
24
- import BumpChartConfig from './_mock/bump-chart.json'
25
- import MethodologyConfig from './_mock/methodology.json'
26
- import methodologyAPI from './_mock/methodologyAPI'
27
- import TopSpacing_1 from './_mock/data-bite-dash-test.json'
28
- import TopSpacing_2 from './_mock/data-bite-dash-test_1.json'
29
- import TopSpacing_3 from './_mock/data-bite-dash-test_1_1.json'
30
- import TopSpacing_4 from './_mock/data-bite-dash-test_1_1_1.json'
31
-
32
- // Dashboard Filter Updates for Ascending, Descending, and Custom Order
33
- import DashboardFilterAsc from './_mock/dashboard-filter-asc.json'
34
- const DashboardFilterDesc = _.cloneDeep(DashboardFilterAsc)
35
- const DashboardFilterCust = _.cloneDeep(DashboardFilterAsc)
36
- DashboardFilterDesc.dashboard.sharedFilters[0].order = 'desc'
37
- DashboardFilterCust.dashboard.sharedFilters[0].order = 'cust'
38
-
39
- // On DashboardFilterCust change the sharedFilters[0].values and orderedValues to be in a custom order
40
- const customOrder = ['American Samoa', 'Alaska', 'Alabama', 'Arizona', 'Arkansas']
41
-
42
- const meta: Meta<typeof Dashboard> = {
43
- title: 'Components/Pages/Dashboard',
44
- component: Dashboard
45
- }
46
-
47
- type Story = StoryObj<typeof Dashboard>
48
-
49
- export const Dashboard_Filter_Asc: Story = {
50
- args: {
51
- config: DashboardFilterAsc,
52
- isEditor: false
53
- }
54
- }
55
-
56
- export const Dashboard_Filter_Desc: Story = {
57
- args: {
58
- config: DashboardFilterDesc,
59
- isEditor: false
60
- }
61
- }
62
-
63
- export const Dashboard_Filter_Cust: Story = {
64
- args: {
65
- config: DashboardFilterCust,
66
- isEditor: false
67
- }
68
- }
69
-
70
- export const Example_1: Story = {
71
- args: {
72
- config: ExampleConfig_1,
73
- isEditor: false
74
- }
75
- }
76
-
77
- export const Example_2: Story = {
78
- args: {
79
- config: ExampleConfig_2,
80
- isEditor: false
81
- }
82
- }
83
-
84
- export const Example_3: Story = {
85
- args: {
86
- config: ExampleConfig_3,
87
- isEditor: false
88
- }
89
- }
90
-
91
- export const Bump_Chart_Dashboard: Story = {
92
- args: {
93
- config: BumpChartConfig,
94
- isEditor: false
95
- }
96
- }
97
-
98
- export const Dashboard_Filters: Story = {
99
- args: {
100
- config: Dashboard_Filter,
101
- isEditor: false
102
- }
103
- }
104
-
105
- export const API_Filter_Error: Story = {
106
- args: {
107
- config: APIFilterErrorConfig,
108
- isEditor: false
109
- }
110
- }
111
-
112
- export const StandAloneTable: Story = {
113
- args: {
114
- config: StandaloneTable,
115
- isEditor: false
116
- }
117
- }
118
-
119
- export const ToggleExample: Story = {
120
- args: {
121
- config: ToggleExampleConfig,
122
- isEditor: false
123
- }
124
- }
125
-
126
- export const PivotFilter: Story = {
127
- args: {
128
- config: PivotFitlerConfig,
129
- isEditor: false
130
- }
131
- }
132
-
133
- export const GroupPivotFilter: Story = {
134
- args: {
135
- config: GroupPivotConfig,
136
- isEditor: false
137
- }
138
- }
139
-
140
- export const SingleStateDashboardWithFilters: Story = {
141
- args: {
142
- config: SingleStateDashboardFilters,
143
- isEditor: false
144
- }
145
- }
146
-
147
- faker.seed(123)
148
-
149
- const countries = _.times(5, faker.location.country)
150
- const categories = _.times(3, val => `category-${val + 1}`)
151
-
152
- const data = []
153
- countries.forEach((country, i) => {
154
- categories.forEach((category, j) => {
155
- if ((i + j) % 3 === 0) return
156
- data.push({
157
- Country: country,
158
- 'Sample Categories': category,
159
- Data: faker.number.int({ min: 5, max: 50 })
160
- })
161
- })
162
- })
163
-
164
- const footnoteData = countries.map((country, i) => {
165
- return { Country: country, symbol: footnotesSymbols[i][0], text: faker.lorem.sentence() }
166
- })
167
-
168
- const multiVizData = {
169
- 'valid-world-data.json': { data },
170
- 'footnote-data.json': { data: footnoteData }
171
- }
172
-
173
- export const MultiDashboard: Story = {
174
- args: {
175
- config: MultiDashboardConfig,
176
- isEditor: false
177
- }
178
- }
179
-
180
- const FNrows: ConfigRow[] = [{ ...MultiVizConfig.rows[0], footnotesId: 'footnote123' }]
181
- const footnoteConfig: Partial<FootnotesConfig> = {
182
- dataKey: 'footnote-data.json',
183
- dynamicFootnotes: { symbolColumn: 'symbol', textColumn: 'text' },
184
- staticFootnotes: [{ symbol: '**', text: 'This is a static Footnote' }]
185
- }
186
- const FNViz = { ...MultiVizConfig.visualizations, footnote123: footnoteConfig }
187
- export const Footnotes: Story = {
188
- args: {
189
- config: { ...MultiVizConfig, datasets: multiVizData, rows: FNrows, visualizations: FNViz },
190
- isEditor: false
191
- }
192
- }
193
-
194
- const sleep = ms => {
195
- return new Promise(r => setTimeout(r, ms))
196
- }
197
-
198
- const fetchMock = {
199
- debug: true,
200
- mocks: [
201
- {
202
- matcher: {
203
- name: 'topicsFilter',
204
- url: 'path:/api/poc/topics'
205
- },
206
- response: {
207
- status: 200,
208
- body: [{ TopicID: 'topicId', Topic: 'Some Topic' }]
209
- }
210
- },
211
- {
212
- matcher: {
213
- name: 'indicatorsFilter',
214
- url: 'path:/api/poc/indicators'
215
- },
216
- response: {
217
- status: 200,
218
- body: [{ IndicatorID: 'indicatorID', Indicator: 'Some Indicator' }]
219
- }
220
- },
221
- ...['Year', 'DataValueType', 'StratificationCategory', 'Stratification'].map(filter => {
222
- return {
223
- matcher: {
224
- name: 'filters' + filter,
225
- url: 'path:/api/POC/Filters/' + filter
226
- },
227
- response: {
228
- status: 200,
229
- body: _.times(5, i => ({ [filter]: `Some ${filter} ${i}` }))
230
- }
231
- }
232
- }),
233
- {
234
- matcher: {
235
- name: 'locations',
236
- url: 'path:/api/poc/locations'
237
- },
238
- response: {
239
- status: 200,
240
- body: [
241
- {
242
- LocationAbbr: 'MS',
243
- LocationDesc: 'Mississippi'
244
- }
245
- ]
246
- }
247
- },
248
- {
249
- matcher: {
250
- name: 'tableData',
251
- url: 'path:/api/POC/TableData'
252
- },
253
- response: {
254
- status: 200,
255
- body: [
256
- {
257
- LocationAbbr: 'MS',
258
- LocationDesc: 'Mississippi',
259
- Indicator: 'Some Indicator',
260
- IndicatorID: 'ALC04',
261
- Topic: 'Some Topic',
262
- TopicID: 'ALC',
263
- DataSource: null,
264
- StratificationCategory: 'Overall',
265
- Stratification: 'Overall',
266
- StratificationId1: 'OVR',
267
- StratificationCategoryId: 'OVERALL',
268
- YearStart: null,
269
- YearEnd: 2019,
270
- DataValue: 2,
271
- DataValueUnit: 'Number',
272
- LowConfidenceLimit: 1.6,
273
- HighConfidenceLimit: 2.9,
274
- DataValueType: null,
275
- DataValueTypeID: 'CRDMEDN'
276
- }
277
- ]
278
- }
279
- },
280
- {
281
- matcher: {
282
- name: 'methodologyYear',
283
- url: 'path:/methodology',
284
- query: {
285
- $select: 'distinct year'
286
- }
287
- },
288
- response: {
289
- status: 200,
290
- body: methodologyAPI('distinct year')
291
- }
292
- },
293
- ...['a', 'b'].map(methodology => {
294
- return {
295
- matcher: {
296
- name: 'methodology' + methodology,
297
- url: 'path:/methodology',
298
- query: {
299
- methodology: `"${methodology}"`
300
- }
301
- },
302
- response: {
303
- status: 200,
304
- body: methodologyAPI('*', ['methodology', methodology])
305
- }
306
- }
307
- }),
308
- ...[1999, 2000, 2012, 2013].map(year => {
309
- return {
310
- matcher: {
311
- name: 'methodology' + year,
312
- url: 'path:/methodology',
313
- query: {
314
- $select: 'distinct methodology',
315
- year
316
- }
317
- },
318
- response: {
319
- status: 200,
320
- body: methodologyAPI('distinct methodology', ['year', year])
321
- }
322
- }
323
- })
324
- ]
325
- }
326
-
327
- export const RegressionAPIFiltersMap: Story = {
328
- args: {
329
- config: APIFiltersMapData as unknown as Config,
330
- isEditor: false
331
- },
332
- parameters: {
333
- fetchMock
334
- },
335
- play: async ({ canvasElement }) => {
336
- const canvas = within(canvasElement)
337
- const user = userEvent.setup()
338
- // play is running before full rendering is complete so sleep function
339
- // is needed to delay the execution.
340
- // possible related bug: https://github.com/storybookjs/storybook/issues/18258
341
- await sleep(1000)
342
- const topicsFilter = canvas.getByLabelText('Category', { selector: 'select' })
343
- await user.selectOptions(topicsFilter, ['topicId'])
344
- await sleep(1000)
345
-
346
- const indicatorsFilter = canvas.getByLabelText('Indicator', { selector: 'select' })
347
- await user.selectOptions(indicatorsFilter, ['indicatorID'])
348
- const yearsFilter = canvas.getByLabelText('Year', { selector: 'select' })
349
- await user.selectOptions(yearsFilter, ['Some Year 0'])
350
- const stratCategoryFilter = canvas.getByLabelText('View By', { selector: 'select' })
351
- await user.selectOptions(stratCategoryFilter, ['Some StratificationCategory 0'])
352
- const stratFilter = canvas.getByLabelText('Stratification', { selector: 'select' })
353
- await user.selectOptions(stratFilter, ['Some Stratification 0'])
354
- await user.click(canvas.getByText('GO!'))
355
- }
356
- }
357
-
358
- export const RegressionAPIFiltersChart: Story = {
359
- args: {
360
- config: APIFiltersChartData as unknown as Config,
361
- isEditor: false
362
- },
363
- parameters: {
364
- fetchMock
365
- },
366
- play: async ({ canvasElement }) => {
367
- const canvas = within(canvasElement)
368
- const user = userEvent.setup()
369
- // play is running before full rendering is complete so sleep function
370
- // is needed to delay the execution.
371
- // possible related bug: https://github.com/storybookjs/storybook/issues/18258
372
- await sleep(1000)
373
- const locationFilter = canvas.getByLabelText('Location', { selector: 'select' })
374
- await user.selectOptions(locationFilter, ['MS'])
375
- const topicsFilter = canvas.getByLabelText('Category', { selector: 'select' })
376
- await user.selectOptions(topicsFilter, ['topicId'])
377
- const indicatorsFilter = canvas.getByLabelText('Indicator', { selector: 'select' })
378
- await user.selectOptions(indicatorsFilter, ['indicatorID'])
379
- await user.click(canvas.getByText('GO!'))
380
- await sleep(1000)
381
- const yearFilter = canvas.getByLabelText('Year', { selector: 'select' })
382
- await user.selectOptions(yearFilter, ['Some Year 1'])
383
- }
384
- }
385
-
386
- export const RegressionHiddenFilter: Story = {
387
- args: {
388
- config: MethodologyConfig,
389
- isEditor: false
390
- },
391
- parameters: {
392
- fetchMock
393
- },
394
- play: async ({ canvasElement }) => {
395
- const canvas = within(canvasElement)
396
- const user = userEvent.setup()
397
- // play is running before full rendering is complete so sleep function
398
- // is needed to delay the execution.
399
- // possible related bug: https://github.com/storybookjs/storybook/issues/18258
400
- await sleep(1000)
401
- const yearFilter = canvas.getByLabelText('Year', { selector: 'select' })
402
- await user.selectOptions(yearFilter, ['1999'])
403
- await user.click(canvas.getByText('GO!'))
404
- await sleep(500)
405
- canvas.getAllByText('alabama')
406
- canvas.getAllByText('alaska')
407
- canvas.getAllByText('arizona')
408
- await user.selectOptions(yearFilter, ['2012'])
409
- await user.click(canvas.getByText('GO!'))
410
- await sleep(500)
411
- canvas.getAllByText('new york')
412
- canvas.getAllByText('new jersey')
413
- canvas.getAllByText('new mexico')
414
- }
415
- }
416
-
417
- export const RegressionMultiVisualization: Story = {
418
- args: {
419
- config: { ...MultiVizConfig, datasets: multiVizData },
420
- isEditor: false
421
- },
422
- play: async ({ canvasElement }) => {
423
- const canvas = within(canvasElement)
424
- const user = userEvent.setup()
425
- // play is running before full rendering is complete so sleep function
426
- // is needed to delay the execution.
427
- // possible related bug: https://github.com/storybookjs/storybook/issues/18258
428
- await sleep(1000)
429
- const categoryFilter = canvas.getByLabelText('Category', { selector: 'select' })
430
- canvas.getAllByText('Paraguay')
431
- canvas.getAllByText('Poland')
432
- canvas.getAllByText('Iraq')
433
- await user.selectOptions(categoryFilter, ['category-3'])
434
- canvas.getAllByText('Paraguay')
435
- canvas.getAllByText('Ethiopia')
436
- canvas.getAllByText('Iraq')
437
- await user.selectOptions(categoryFilter, ['category-1'])
438
- canvas.getAllByText('Poland')
439
- canvas.getAllByText('Ethiopia')
440
- canvas.getAllByText('Curacao')
441
- }
442
- }
443
-
444
- export const Top_Spacing_1: Story = {
445
- args: {
446
- config: TopSpacing_1,
447
- isEditor: false
448
- }
449
- }
450
-
451
- export const Top_Spacing_2: Story = {
452
- args: {
453
- config: TopSpacing_2,
454
- isEditor: false
455
- }
456
- }
457
-
458
- export const Top_Spacing_3: Story = {
459
- args: {
460
- config: TopSpacing_3,
461
- isEditor: false
462
- }
463
- }
464
-
465
- export const Top_Spacing_4: Story = {
466
- args: {
467
- config: TopSpacing_4,
468
- isEditor: false
469
- }
470
- }
471
-
472
- export default meta
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import { faker } from '@faker-js/faker'
3
+ import APIFiltersMapData from './_mock/api-filter-map.json'
4
+ import APIFiltersChartData from './_mock/api-filter-chart.json'
5
+ import APIFilterErrorConfig from './_mock/api-filter-error.json'
6
+ import ExampleConfig_1 from './_mock/dashboard-gallery.json'
7
+ import ExampleConfig_2 from './_mock/dashboard-2.json'
8
+ import ExampleConfig_3 from './_mock/dashboard_no_filter.json'
9
+ import SingleStateDashboardFilters from './_mock/single-state-dashboard-filters.json'
10
+ import Dashboard_Filter from './_mock/dashboard-filter.json'
11
+ import MultiVizConfig from './_mock/multi-viz.json'
12
+ import MultiDashboardConfig from './_mock/multi-dashboards.json'
13
+ import Dashboard from '../CdcDashboard'
14
+ import StandaloneTable from './_mock/standalone-table.json'
15
+ import GroupPivotConfig from './_mock/group-pivot-filter.json'
16
+ import PivotFitlerConfig from './_mock/pivot-filter.json'
17
+ import { type DashboardConfig as Config } from '../types/DashboardConfig'
18
+ import { userEvent, within } from 'storybook/test'
19
+ import ToggleExampleConfig from './_mock/toggle-example.json'
20
+ import _ from 'lodash'
21
+ import { footnotesSymbols } from '@cdc/core/helpers/footnoteSymbols'
22
+ import FootnotesConfig from '@cdc/core/types/Footnotes'
23
+ import { ConfigRow } from '../types/ConfigRow'
24
+ import BumpChartConfig from './_mock/bump-chart.json'
25
+ import MethodologyConfig from './_mock/methodology.json'
26
+ import methodologyAPI from './_mock/methodologyAPI'
27
+ import TopSpacing_1 from './_mock/data-bite-dash-test.json'
28
+ import TopSpacing_2 from './_mock/data-bite-dash-test_1.json'
29
+ import TopSpacing_3 from './_mock/data-bite-dash-test_1_1.json'
30
+ import TopSpacing_4 from './_mock/data-bite-dash-test_1_1_1.json'
31
+ import CustomOrderNewValues from './_mock/custom-order-new-values.json'
32
+ import APIFilterResetConfig from '../../examples/test-api-filter-reset.json'
33
+
34
+ // Dashboard Filter Updates for Ascending, Descending, and Custom Order
35
+ import DashboardFilterAsc from './_mock/dashboard-filter-asc.json'
36
+ const DashboardFilterDesc = _.cloneDeep(DashboardFilterAsc)
37
+ const DashboardFilterCust = _.cloneDeep(DashboardFilterAsc)
38
+ DashboardFilterDesc.dashboard.sharedFilters[0].order = 'desc'
39
+ DashboardFilterCust.dashboard.sharedFilters[0].order = 'cust'
40
+
41
+ // On DashboardFilterCust change the sharedFilters[0].values and orderedValues to be in a custom order
42
+ const customOrder = ['American Samoa', 'Alaska', 'Alabama', 'Arizona', 'Arkansas']
43
+ DashboardFilterCust.dashboard.sharedFilters[0].orderedValues = customOrder
44
+
45
+ const meta: Meta<typeof Dashboard> = {
46
+ title: 'Components/Pages/Dashboard',
47
+ component: Dashboard
48
+ }
49
+
50
+ type Story = StoryObj<typeof Dashboard>
51
+
52
+ export const Dashboard_Filter_Asc: Story = {
53
+ args: {
54
+ config: DashboardFilterAsc,
55
+ isEditor: false
56
+ }
57
+ }
58
+
59
+ export const Dashboard_Filter_Desc: Story = {
60
+ args: {
61
+ config: DashboardFilterDesc,
62
+ isEditor: false
63
+ }
64
+ }
65
+
66
+ export const Dashboard_Filter_Cust: Story = {
67
+ args: {
68
+ config: DashboardFilterCust,
69
+ isEditor: false
70
+ }
71
+ }
72
+
73
+ export const CustomOrder_NewValues_AutoAppend: Story = {
74
+ args: {
75
+ config: CustomOrderNewValues,
76
+ isEditor: false
77
+ }
78
+ }
79
+
80
+ export const Example_1: Story = {
81
+ args: {
82
+ config: ExampleConfig_1,
83
+ isEditor: false
84
+ }
85
+ }
86
+
87
+ export const Example_2: Story = {
88
+ args: {
89
+ config: ExampleConfig_2,
90
+ isEditor: false
91
+ }
92
+ }
93
+
94
+ export const Example_3: Story = {
95
+ args: {
96
+ config: ExampleConfig_3,
97
+ isEditor: false
98
+ }
99
+ }
100
+
101
+ export const Bump_Chart_Dashboard: Story = {
102
+ args: {
103
+ config: BumpChartConfig,
104
+ isEditor: false
105
+ }
106
+ }
107
+
108
+ export const Dashboard_Filters: Story = {
109
+ args: {
110
+ config: Dashboard_Filter,
111
+ isEditor: false
112
+ }
113
+ }
114
+
115
+ export const API_Filter_Error: Story = {
116
+ args: {
117
+ config: APIFilterErrorConfig,
118
+ isEditor: false
119
+ }
120
+ }
121
+
122
+ export const StandAloneTable: Story = {
123
+ args: {
124
+ config: StandaloneTable,
125
+ isEditor: false
126
+ }
127
+ }
128
+
129
+ export const ToggleExample: Story = {
130
+ args: {
131
+ config: ToggleExampleConfig,
132
+ isEditor: false
133
+ }
134
+ }
135
+
136
+ export const PivotFilter: Story = {
137
+ args: {
138
+ config: PivotFitlerConfig,
139
+ isEditor: false
140
+ }
141
+ }
142
+
143
+ export const GroupPivotFilter: Story = {
144
+ args: {
145
+ config: GroupPivotConfig,
146
+ isEditor: false
147
+ }
148
+ }
149
+
150
+ export const SingleStateDashboardWithFilters: Story = {
151
+ args: {
152
+ config: SingleStateDashboardFilters,
153
+ isEditor: false
154
+ }
155
+ }
156
+
157
+ faker.seed(123)
158
+
159
+ const countries = _.times(5, faker.location.country)
160
+ const categories = _.times(3, val => `category-${val + 1}`)
161
+
162
+ const data = []
163
+ countries.forEach((country, i) => {
164
+ categories.forEach((category, j) => {
165
+ if ((i + j) % 3 === 0) return
166
+ data.push({
167
+ Country: country,
168
+ 'Sample Categories': category,
169
+ Data: faker.number.int({ min: 5, max: 50 })
170
+ })
171
+ })
172
+ })
173
+
174
+ const footnoteData = countries.map((country, i) => {
175
+ return { Country: country, symbol: footnotesSymbols[i][0], text: faker.lorem.sentence() }
176
+ })
177
+
178
+ const multiVizData = {
179
+ 'valid-world-data.json': { data },
180
+ 'footnote-data.json': { data: footnoteData }
181
+ }
182
+
183
+ export const MultiDashboard: Story = {
184
+ args: {
185
+ config: MultiDashboardConfig,
186
+ isEditor: false
187
+ }
188
+ }
189
+
190
+ const FNrows: ConfigRow[] = [{ ...MultiVizConfig.rows[0], footnotesId: 'footnote123' }]
191
+ const footnoteConfig: Partial<FootnotesConfig> = {
192
+ dataKey: 'footnote-data.json',
193
+ dynamicFootnotes: { symbolColumn: 'symbol', textColumn: 'text' },
194
+ staticFootnotes: [{ symbol: '**', text: 'This is a static Footnote' }]
195
+ }
196
+ const FNViz = { ...MultiVizConfig.visualizations, footnote123: footnoteConfig }
197
+ export const Footnotes: Story = {
198
+ args: {
199
+ config: { ...MultiVizConfig, datasets: multiVizData, rows: FNrows, visualizations: FNViz },
200
+ isEditor: false
201
+ }
202
+ }
203
+
204
+ const sleep = ms => {
205
+ return new Promise(r => setTimeout(r, ms))
206
+ }
207
+
208
+ const fetchMock = {
209
+ debug: true,
210
+ mocks: [
211
+ {
212
+ matcher: {
213
+ name: 'topicsFilter',
214
+ url: 'path:/api/poc/topics'
215
+ },
216
+ response: {
217
+ status: 200,
218
+ body: [{ TopicID: 'topicId', Topic: 'Some Topic' }]
219
+ }
220
+ },
221
+ {
222
+ matcher: {
223
+ name: 'indicatorsFilter',
224
+ url: 'path:/api/poc/indicators'
225
+ },
226
+ response: {
227
+ status: 200,
228
+ body: [{ IndicatorID: 'indicatorID', Indicator: 'Some Indicator' }]
229
+ }
230
+ },
231
+ ...['Year', 'DataValueType', 'StratificationCategory', 'Stratification'].map(filter => {
232
+ return {
233
+ matcher: {
234
+ name: 'filters' + filter,
235
+ url: 'path:/api/POC/Filters/' + filter
236
+ },
237
+ response: {
238
+ status: 200,
239
+ body: _.times(5, i => ({ [filter]: `Some ${filter} ${i}` }))
240
+ }
241
+ }
242
+ }),
243
+ {
244
+ matcher: {
245
+ name: 'locations',
246
+ url: 'path:/api/poc/locations'
247
+ },
248
+ response: {
249
+ status: 200,
250
+ body: [
251
+ {
252
+ LocationAbbr: 'MS',
253
+ LocationDesc: 'Mississippi'
254
+ }
255
+ ]
256
+ }
257
+ },
258
+ {
259
+ matcher: {
260
+ name: 'tableData',
261
+ url: 'path:/api/POC/TableData'
262
+ },
263
+ response: {
264
+ status: 200,
265
+ body: [
266
+ {
267
+ LocationAbbr: 'MS',
268
+ LocationDesc: 'Mississippi',
269
+ Indicator: 'Some Indicator',
270
+ IndicatorID: 'ALC04',
271
+ Topic: 'Some Topic',
272
+ TopicID: 'ALC',
273
+ DataSource: null,
274
+ StratificationCategory: 'Overall',
275
+ Stratification: 'Overall',
276
+ StratificationId1: 'OVR',
277
+ StratificationCategoryId: 'OVERALL',
278
+ YearStart: null,
279
+ YearEnd: 2019,
280
+ DataValue: 2,
281
+ DataValueUnit: 'Number',
282
+ LowConfidenceLimit: 1.6,
283
+ HighConfidenceLimit: 2.9,
284
+ DataValueType: null,
285
+ DataValueTypeID: 'CRDMEDN'
286
+ }
287
+ ]
288
+ }
289
+ },
290
+ {
291
+ matcher: {
292
+ name: 'methodologyYear',
293
+ url: 'path:/methodology',
294
+ query: {
295
+ $select: 'distinct year'
296
+ }
297
+ },
298
+ response: {
299
+ status: 200,
300
+ body: methodologyAPI('distinct year')
301
+ }
302
+ },
303
+ ...['a', 'b'].map(methodology => {
304
+ return {
305
+ matcher: {
306
+ name: 'methodology' + methodology,
307
+ url: 'path:/methodology',
308
+ query: {
309
+ methodology: `"${methodology}"`
310
+ }
311
+ },
312
+ response: {
313
+ status: 200,
314
+ body: methodologyAPI('*', ['methodology', methodology])
315
+ }
316
+ }
317
+ }),
318
+ ...[1999, 2000, 2012, 2013].map(year => {
319
+ return {
320
+ matcher: {
321
+ name: 'methodology' + year,
322
+ url: 'path:/methodology',
323
+ query: {
324
+ $select: 'distinct methodology',
325
+ year
326
+ }
327
+ },
328
+ response: {
329
+ status: 200,
330
+ body: methodologyAPI('distinct methodology', ['year', year])
331
+ }
332
+ }
333
+ })
334
+ ]
335
+ }
336
+
337
+ export const RegressionAPIFiltersMap: Story = {
338
+ args: {
339
+ config: APIFiltersMapData as unknown as Config,
340
+ isEditor: false
341
+ },
342
+ parameters: {
343
+ fetchMock
344
+ }
345
+ // TODO: Re-enable play function when fetch-mock is fully compatible with Storybook 9 + Vitest
346
+ // play: async ({ canvasElement }) => {
347
+ // const canvas = within(canvasElement)
348
+ // const user = userEvent.setup()
349
+ // // play is running before full rendering is complete so sleep function
350
+ // // is needed to delay the execution.
351
+ // // possible related bug: https://github.com/storybookjs/storybook/issues/18258
352
+ // await sleep(1000)
353
+ // const topicsFilter = canvas.getByLabelText('Category', { selector: 'select' })
354
+ // await user.selectOptions(topicsFilter, ['topicId'])
355
+ // await sleep(1000)
356
+
357
+ // const indicatorsFilter = canvas.getByLabelText('Indicator', { selector: 'select' })
358
+ // await user.selectOptions(indicatorsFilter, ['indicatorID'])
359
+ // const yearsFilter = canvas.getByLabelText('Year', { selector: 'select' })
360
+ // await user.selectOptions(yearsFilter, ['Some Year 0'])
361
+ // const stratCategoryFilter = canvas.getByLabelText('View By', { selector: 'select' })
362
+ // await user.selectOptions(stratCategoryFilter, ['Some StratificationCategory 0'])
363
+ // const stratFilter = canvas.getByLabelText('Stratification', { selector: 'select' })
364
+ // await user.selectOptions(stratFilter, ['Some Stratification 0'])
365
+ // await user.click(canvas.getByText('GO!'))
366
+ // }
367
+ }
368
+
369
+ export const RegressionAPIFiltersChart: Story = {
370
+ args: {
371
+ config: APIFiltersChartData as unknown as Config,
372
+ isEditor: false
373
+ },
374
+ parameters: {
375
+ fetchMock
376
+ }
377
+ // TODO: Re-enable play function when fetch-mock is fully compatible with Storybook 9 + Vitest
378
+ // play: async ({ canvasElement }) => {
379
+ // const canvas = within(canvasElement)
380
+ // const user = userEvent.setup()
381
+ // // play is running before full rendering is complete so sleep function
382
+ // // is needed to delay the execution.
383
+ // // possible related bug: https://github.com/storybookjs/storybook/issues/18258
384
+ // await sleep(1000)
385
+ // const locationFilter = canvas.getByLabelText('Location', { selector: 'select' })
386
+ // await user.selectOptions(locationFilter, ['MS'])
387
+ // const topicsFilter = canvas.getByLabelText('Category', { selector: 'select' })
388
+ // await user.selectOptions(topicsFilter, ['topicId'])
389
+ // const indicatorsFilter = canvas.getByLabelText('Indicator', { selector: 'select' })
390
+ // await user.selectOptions(indicatorsFilter, ['indicatorID'])
391
+ // await user.click(canvas.getByText('GO!'))
392
+ // await sleep(1000)
393
+ // const yearFilter = canvas.getByLabelText('Year', { selector: 'select' })
394
+ // await user.selectOptions(yearFilter, ['Some Year 1'])
395
+ // }
396
+ }
397
+
398
+ export const RegressionHiddenFilter: Story = {
399
+ args: {
400
+ config: MethodologyConfig,
401
+ isEditor: false
402
+ },
403
+ parameters: {
404
+ fetchMock
405
+ }
406
+ // TODO: Re-enable play function when fetch-mock is fully compatible with Storybook 9 + Vitest
407
+ // play: async ({ canvasElement }) => {
408
+ // const canvas = within(canvasElement)
409
+ // const user = userEvent.setup()
410
+ // // play is running before full rendering is complete so sleep function
411
+ // // is needed to delay the execution.
412
+ // // possible related bug: https://github.com/storybookjs/storybook/issues/18258
413
+ // await sleep(1000)
414
+ // const yearFilter = canvas.getByLabelText('Year', { selector: 'select' })
415
+ // await user.selectOptions(yearFilter, ['1999'])
416
+ // await user.click(canvas.getByText('GO!'))
417
+ // await sleep(500)
418
+ // canvas.getAllByText('alabama')
419
+ // canvas.getAllByText('alaska')
420
+ // canvas.getAllByText('arizona')
421
+ // await user.selectOptions(yearFilter, ['2012'])
422
+ // await user.click(canvas.getByText('GO!'))
423
+ // await sleep(500)
424
+ // canvas.getAllByText('new york')
425
+ // canvas.getAllByText('new jersey')
426
+ // canvas.getAllByText('new mexico')
427
+ // }
428
+ }
429
+
430
+ export const RegressionMultiVisualizationTests: Story = {
431
+ args: {
432
+ config: { ...MultiVizConfig, datasets: multiVizData },
433
+ isEditor: false
434
+ },
435
+ play: async ({ canvasElement }) => {
436
+ const canvas = within(canvasElement)
437
+ const user = userEvent.setup()
438
+ // play is running before full rendering is complete so sleep function
439
+ // is needed to delay the execution.
440
+ // possible related bug: https://github.com/storybookjs/storybook/issues/18258
441
+ await sleep(1000)
442
+ const categoryFilter = canvas.getByLabelText('Category', { selector: 'select' })
443
+ canvas.getAllByText('Paraguay')
444
+ canvas.getAllByText('Poland')
445
+ canvas.getAllByText('Iraq')
446
+ await user.selectOptions(categoryFilter, ['category-3'])
447
+ canvas.getAllByText('Paraguay')
448
+ canvas.getAllByText('Ethiopia')
449
+ canvas.getAllByText('Iraq')
450
+ await user.selectOptions(categoryFilter, ['category-1'])
451
+ canvas.getAllByText('Poland')
452
+ canvas.getAllByText('Ethiopia')
453
+ canvas.getAllByText('Curacao')
454
+ }
455
+ }
456
+
457
+ export const Top_Spacing_1: Story = {
458
+ args: {
459
+ config: TopSpacing_1,
460
+ isEditor: false
461
+ }
462
+ }
463
+
464
+ export const Top_Spacing_2: Story = {
465
+ args: {
466
+ config: TopSpacing_2,
467
+ isEditor: false
468
+ }
469
+ }
470
+
471
+ export const Top_Spacing_3: Story = {
472
+ args: {
473
+ config: TopSpacing_3,
474
+ isEditor: false
475
+ }
476
+ }
477
+
478
+ export const Top_Spacing_4: Story = {
479
+ args: {
480
+ config: TopSpacing_4,
481
+ isEditor: false
482
+ }
483
+ }
484
+
485
+ export const Clear_Filters_Button: Story = {
486
+ args: {
487
+ config: APIFilterResetConfig as unknown as Config,
488
+ isEditor: false
489
+ }
490
+ }
491
+
492
+ export default meta