import {createStore, StoreDefinition} from 'reflux'; import PluginActions from 'sentry/actions/pluginActions'; import {Plugin} from 'sentry/types'; import {makeSafeRefluxStore} from 'sentry/utils/makeSafeRefluxStore'; interface PluginStoreDefinition extends StoreDefinition { plugins: Map | null; state: { error: Error | null; loading: boolean; pageLinks: string | null; plugins: Plugin[]; }; updating: Map; } const defaultState = { loading: true, plugins: [], error: null, pageLinks: null, }; const storeConfig: PluginStoreDefinition = { plugins: null, state: {...defaultState}, updating: new Map(), unsubscribeListeners: [], reset() { // reset our state this.plugins = null; this.state = {...defaultState}; this.updating = new Map(); return this.state; }, getInitialState() { return this.getState(); }, getState() { const {plugins: _plugins, ...state} = this.state; return { ...state, plugins: this.plugins ? Array.from(this.plugins.values()) : [], }; }, init() { this.reset(); this.unsubscribeListeners.push( this.listenTo(PluginActions.fetchAll, this.onFetchAll) ); this.unsubscribeListeners.push( this.listenTo(PluginActions.fetchAllSuccess, this.onFetchAllSuccess) ); this.unsubscribeListeners.push( this.listenTo(PluginActions.fetchAllError, this.onFetchAllError) ); this.unsubscribeListeners.push(this.listenTo(PluginActions.update, this.onUpdate)); this.unsubscribeListeners.push( this.listenTo(PluginActions.updateSuccess, this.onUpdateSuccess) ); this.unsubscribeListeners.push( this.listenTo(PluginActions.updateError, this.onUpdateError) ); }, triggerState() { this.trigger(this.getState()); }, onFetchAll({resetLoading}: {resetLoading?: boolean} = {}) { if (resetLoading) { this.state.loading = true; this.state.error = null; this.plugins = null; } this.triggerState(); }, onFetchAllSuccess(data: Plugin[], {pageLinks}: {pageLinks?: string}) { this.plugins = new Map(data.map(plugin => [plugin.id, plugin])); this.state.pageLinks = pageLinks || null; this.state.loading = false; this.triggerState(); }, onFetchAllError(err) { this.plugins = null; this.state.loading = false; this.state.error = err; this.triggerState(); }, onUpdate(id: string, updateObj: Partial) { if (!this.plugins) { return; } const plugin = this.plugins.get(id); if (!plugin) { return; } const newPlugin = { ...plugin, ...updateObj, }; this.plugins.set(id, newPlugin); this.updating.set(id, plugin); this.triggerState(); }, onUpdateSuccess(id: string, _updateObj: Partial) { this.updating.delete(id); }, onUpdateError(id: string, _updateObj: Partial, err) { const origPlugin = this.updating.get(id); if (!origPlugin || !this.plugins) { return; } this.plugins.set(id, origPlugin); this.updating.delete(id); this.state.error = err; this.triggerState(); }, }; const PluginStore = createStore(makeSafeRefluxStore(storeConfig)); export default PluginStore;