indicatorStore.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import {createStore} from 'reflux';
  2. import {Indicator} from 'sentry/actionCreators/indicator';
  3. import {t} from 'sentry/locale';
  4. import {CommonStoreDefinition} from './types';
  5. interface InternalDefinition {
  6. items: any[];
  7. lastId: number;
  8. }
  9. interface IndicatorStoreDefinition
  10. extends CommonStoreDefinition<Indicator[]>,
  11. InternalDefinition {
  12. /**
  13. * When this method is called directly via older parts of the application,
  14. * we want to maintain the old behavior in that it is replaced (and not queued up)
  15. *
  16. * @param message Toast message to be displayed
  17. * @param type One of ['error', 'success', '']
  18. * @param options Options object
  19. */
  20. add(
  21. message: React.ReactNode,
  22. type?: Indicator['type'],
  23. options?: Indicator['options']
  24. ): Indicator;
  25. addError(message?: string): Indicator;
  26. /**
  27. * Alias for add()
  28. */
  29. addMessage(
  30. message: React.ReactNode,
  31. type: Indicator['type'],
  32. options?: Indicator['options']
  33. ): Indicator;
  34. addSuccess(message: string): Indicator;
  35. /**
  36. * Appends a message to be displayed in list of indicators
  37. *
  38. * @param message Toast message to be displayed
  39. * @param type One of ['error', 'success', '']
  40. * @param options Options object
  41. */
  42. append(
  43. message: React.ReactNode,
  44. type: Indicator['type'],
  45. options?: Indicator['options']
  46. ): Indicator;
  47. /**
  48. * Remove all current indicators.
  49. */
  50. clear(): void;
  51. init(): void;
  52. /**
  53. * Remove an indicator
  54. */
  55. remove(indicator: Indicator): void;
  56. }
  57. const storeConfig: IndicatorStoreDefinition = {
  58. items: [],
  59. lastId: 0,
  60. init() {
  61. this.items = [];
  62. this.lastId = 0;
  63. },
  64. addSuccess(message) {
  65. return this.add(message, 'success', {duration: 2000});
  66. },
  67. addError(message = t('An error occurred')) {
  68. return this.add(message, 'error', {duration: 2000});
  69. },
  70. addMessage(message, type, {append, ...options} = {}) {
  71. const indicator: Indicator = {
  72. id: this.lastId++,
  73. message,
  74. type,
  75. options,
  76. clearId: null,
  77. };
  78. if (options.duration) {
  79. indicator.clearId = window.setTimeout(() => {
  80. this.remove(indicator);
  81. }, options.duration);
  82. }
  83. const newItems = append ? [...this.items, indicator] : [indicator];
  84. this.items = newItems;
  85. this.trigger(this.items);
  86. return indicator;
  87. },
  88. append(message, type, options) {
  89. return this.addMessage(message, type, {
  90. ...options,
  91. append: true,
  92. });
  93. },
  94. add(message, type = 'loading', options = {}) {
  95. return this.addMessage(message, type, {
  96. ...options,
  97. append: false,
  98. });
  99. },
  100. clear() {
  101. this.items = [];
  102. this.trigger(this.items);
  103. },
  104. remove(indicator) {
  105. if (!indicator) {
  106. return;
  107. }
  108. this.items = this.items.filter(item => item !== indicator);
  109. if (indicator.clearId) {
  110. window.clearTimeout(indicator.clearId);
  111. indicator.clearId = null;
  112. }
  113. this.trigger(this.items);
  114. },
  115. getState() {
  116. return this.items;
  117. },
  118. };
  119. const IndicatorStore = createStore(storeConfig);
  120. export default IndicatorStore;