indicatorStore.tsx 3.2 KB

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