selectedGroupStore.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import {createStore, Store, StoreDefinition} from 'reflux';
  2. import GroupStore from 'sentry/stores/groupStore';
  3. import {makeSafeRefluxStore, SafeStoreDefinition} from 'sentry/utils/makeSafeRefluxStore';
  4. type SelectedGroupStoreInterface = {
  5. add(ids: string[]): void;
  6. allSelected(): boolean;
  7. anySelected(): boolean;
  8. deselectAll(): void;
  9. getSelectedIds(): Set<string>;
  10. init(): void;
  11. isSelected(itemId: string): boolean;
  12. multiSelected(): boolean;
  13. numSelected(): number;
  14. onGroupChange(itemIds: string[]): void;
  15. prune(): void;
  16. toggleSelect(itemId: string): void;
  17. toggleSelectAll(): void;
  18. };
  19. type Internals = {
  20. records: Record<string, boolean>;
  21. };
  22. const storeConfig: StoreDefinition &
  23. Internals &
  24. SelectedGroupStoreInterface &
  25. SafeStoreDefinition = {
  26. records: {},
  27. unsubscribeListeners: [],
  28. init() {
  29. this.records = {};
  30. this.unsubscribeListeners.push(
  31. this.listenTo(GroupStore, this.onGroupChange, this.onGroupChange)
  32. );
  33. },
  34. onGroupChange(itemIds) {
  35. this.prune();
  36. this.add(itemIds);
  37. this.trigger();
  38. },
  39. add(ids) {
  40. const allSelected = this.allSelected();
  41. ids.forEach(id => {
  42. if (!this.records.hasOwnProperty(id)) {
  43. this.records[id] = allSelected;
  44. }
  45. });
  46. },
  47. prune() {
  48. const existingIds = new Set(GroupStore.getAllItemIds());
  49. // Remove ids that no longer exist
  50. for (const itemId in this.records) {
  51. if (!existingIds.has(itemId)) {
  52. delete this.records[itemId];
  53. }
  54. }
  55. },
  56. allSelected() {
  57. const itemIds = this.getSelectedIds();
  58. const numRecords = this.numSelected();
  59. return itemIds.size > 0 && itemIds.size === numRecords;
  60. },
  61. numSelected() {
  62. return Object.keys(this.records).length;
  63. },
  64. anySelected() {
  65. const itemIds = this.getSelectedIds();
  66. return itemIds.size > 0;
  67. },
  68. multiSelected() {
  69. const itemIds = this.getSelectedIds();
  70. return itemIds.size > 1;
  71. },
  72. getSelectedIds() {
  73. const selected = new Set<string>();
  74. for (const itemId in this.records) {
  75. if (this.records[itemId]) {
  76. selected.add(itemId);
  77. }
  78. }
  79. return selected;
  80. },
  81. isSelected(itemId) {
  82. return this.records[itemId] === true;
  83. },
  84. deselectAll() {
  85. for (const itemId in this.records) {
  86. this.records[itemId] = false;
  87. }
  88. this.trigger();
  89. },
  90. toggleSelect(itemId) {
  91. if (!this.records.hasOwnProperty(itemId)) {
  92. return;
  93. }
  94. this.records[itemId] = !this.records[itemId];
  95. this.trigger();
  96. },
  97. toggleSelectAll() {
  98. const allSelected = !this.allSelected();
  99. for (const itemId in this.records) {
  100. this.records[itemId] = allSelected;
  101. }
  102. this.trigger();
  103. },
  104. };
  105. const SelectedGroupStore = createStore(makeSafeRefluxStore(storeConfig)) as Store &
  106. SelectedGroupStoreInterface;
  107. export default SelectedGroupStore;