useSortAccessibility.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import {useCallback, useMemo} from 'react';
  2. import type {HydratedA11yFrame} from 'sentry/utils/replays/hydrateA11yFrame';
  3. import useUrlParams from 'sentry/utils/useUrlParams';
  4. interface SortConfig {
  5. asc: boolean;
  6. by: keyof HydratedA11yFrame | string;
  7. getValue: (row: HydratedA11yFrame) => any;
  8. }
  9. const IMPACT_SORT = {
  10. minor: 0,
  11. moderate: 1,
  12. serious: 2,
  13. critical: 3,
  14. };
  15. const SortStrategies: Record<string, (row) => any> = {
  16. impact: row => IMPACT_SORT[row.impact],
  17. id: row => row.id,
  18. element: row => row.element,
  19. timestampMs: row => row.timestampMs,
  20. };
  21. const DEFAULT_ASC = 'false';
  22. const DEFAULT_BY = 'impact';
  23. type Opts = {items: HydratedA11yFrame[]};
  24. function useSortAccessibility({items}: Opts) {
  25. const {getParamValue: getSortAsc, setParamValue: setSortAsc} = useUrlParams(
  26. 's_a_asc',
  27. DEFAULT_ASC
  28. );
  29. const {getParamValue: getSortBy, setParamValue: setSortBy} = useUrlParams(
  30. 's_a_by',
  31. DEFAULT_BY
  32. );
  33. const {setParamValue: setDetailRow} = useUrlParams('a_detail_row', '');
  34. const sortAsc = getSortAsc();
  35. const sortBy = getSortBy();
  36. const sortConfig = useMemo(
  37. () =>
  38. ({
  39. asc: sortAsc === 'true',
  40. by: sortBy,
  41. getValue: SortStrategies[sortBy],
  42. }) as SortConfig,
  43. [sortAsc, sortBy]
  44. );
  45. const sortedItems = useMemo(
  46. () => sortAccessibility(items, sortConfig),
  47. [items, sortConfig]
  48. );
  49. const handleSort = useCallback(
  50. (fieldName: keyof typeof SortStrategies) => {
  51. if (sortConfig.by === fieldName) {
  52. setSortAsc(sortConfig.asc ? 'false' : 'true');
  53. } else {
  54. setSortAsc('true');
  55. setSortBy(fieldName);
  56. }
  57. setDetailRow('');
  58. },
  59. [sortConfig, setSortAsc, setSortBy, setDetailRow]
  60. );
  61. return {
  62. handleSort,
  63. items: sortedItems,
  64. sortConfig,
  65. };
  66. }
  67. function sortAccessibility(
  68. accessibility: HydratedA11yFrame[],
  69. sortConfig: SortConfig
  70. ): HydratedA11yFrame[] {
  71. return [...accessibility].sort((a, b) => {
  72. let valueA = sortConfig.getValue(a);
  73. let valueB = sortConfig.getValue(b);
  74. valueA = typeof valueA === 'string' ? valueA.toUpperCase() : valueA;
  75. valueB = typeof valueB === 'string' ? valueB.toUpperCase() : valueB;
  76. // if the values are not defined, we want to push them to the bottom of the list
  77. if (valueA === undefined) {
  78. return 1;
  79. }
  80. if (valueB === undefined) {
  81. return -1;
  82. }
  83. if (valueA === valueB) {
  84. return 0;
  85. }
  86. if (sortConfig.asc) {
  87. return valueA > valueB ? 1 : -1;
  88. }
  89. return valueB > valueA ? 1 : -1;
  90. });
  91. }
  92. export default useSortAccessibility;