import Reflux from 'reflux'; import OrganizationActions from 'sentry/actions/organizationActions'; import ReleaseActions from 'sentry/actions/releaseActions'; import {Deploy, Organization, Release} from 'sentry/types'; type StoreRelease = Map; type StoreDeploys = Map>; type StoreLoading = Map; type StoreError = Map; type ReleaseStoreInterface = { get( projectSlug: string, releaseVersion: string ): { deploys: Array | undefined; deploysError: Error | undefined; deploysLoading: boolean | undefined; release: Release | undefined; releaseError: Error | undefined; releaseLoading: boolean | undefined; }; loadDeploys(orgSlug: string, projectSlug: string, releaseVersion: string): void; loadDeploysError(projectSlug: string, releaseVersion: string, error: Error): void; loadDeploysSuccess(projectSlug: string, releaseVersion: string, data: Release): void; loadRelease(orgSlug: string, projectSlug: string, releaseVersion: string): void; loadReleaseError(projectSlug: string, releaseVersion: string, error: Error): void; loadReleaseSuccess(projectSlug: string, releaseVersion: string, data: Release): void; state: { deploys: StoreDeploys; deploysError: StoreError; deploysLoading: StoreLoading; orgSlug: string | undefined; release: StoreRelease; releaseError: StoreError; releaseLoading: StoreLoading; }; updateOrganization(org: Organization): void; }; export const getReleaseStoreKey = (projectSlug: string, releaseVersion: string) => `${projectSlug}${releaseVersion}`; const storeConfig: Reflux.StoreDefinition & ReleaseStoreInterface = { state: { orgSlug: undefined, release: new Map() as StoreRelease, releaseLoading: new Map() as StoreLoading, releaseError: new Map() as StoreError, deploys: new Map() as StoreDeploys, deploysLoading: new Map() as StoreLoading, deploysError: new Map() as StoreError, }, listenables: ReleaseActions, init() { this.listenTo(OrganizationActions.update, this.updateOrganization); this.reset(); }, reset() { this.state = { orgSlug: undefined, release: new Map() as StoreRelease, releaseLoading: new Map() as StoreLoading, releaseError: new Map() as StoreError, deploys: new Map() as StoreDeploys, deploysLoading: new Map() as StoreLoading, deploysError: new Map() as StoreError, }; this.trigger(this.state); }, updateOrganization(org: Organization) { this.reset(); this.state.orgSlug = org.slug; this.trigger(this.state); }, loadRelease(orgSlug: string, projectSlug: string, releaseVersion: string) { // Wipe entire store if the user switched organizations if (!this.orgSlug || this.orgSlug !== orgSlug) { this.reset(); this.orgSlug = orgSlug; } const releaseKey = getReleaseStoreKey(projectSlug, releaseVersion); const {releaseLoading, releaseError, ...state} = this.state; this.state = { ...state, releaseLoading: { ...releaseLoading, [releaseKey]: true, }, releaseError: { ...releaseError, [releaseKey]: undefined, }, }; this.trigger(this.state); }, loadReleaseError(projectSlug: string, releaseVersion: string, error: Error) { const releaseKey = getReleaseStoreKey(projectSlug, releaseVersion); const {releaseLoading, releaseError, ...state} = this.state; this.state = { ...state, releaseLoading: { ...releaseLoading, [releaseKey]: false, }, releaseError: { ...releaseError, [releaseKey]: error, }, }; this.trigger(this.state); }, loadReleaseSuccess(projectSlug: string, releaseVersion: string, data: Release) { const releaseKey = getReleaseStoreKey(projectSlug, releaseVersion); const {release, releaseLoading, releaseError, ...state} = this.state; this.state = { ...state, release: { ...release, [releaseKey]: data, }, releaseLoading: { ...releaseLoading, [releaseKey]: false, }, releaseError: { ...releaseError, [releaseKey]: undefined, }, }; this.trigger(this.state); }, loadDeploys(orgSlug: string, projectSlug: string, releaseVersion: string) { // Wipe entire store if the user switched organizations if (!this.orgSlug || this.orgSlug !== orgSlug) { this.reset(); this.orgSlug = orgSlug; } const releaseKey = getReleaseStoreKey(projectSlug, releaseVersion); const {deploysLoading, deploysError, ...state} = this.state; this.state = { ...state, deploysLoading: { ...deploysLoading, [releaseKey]: true, }, deploysError: { ...deploysError, [releaseKey]: undefined, }, }; this.trigger(this.state); }, loadDeploysError(projectSlug: string, releaseVersion: string, error: Error) { const releaseKey = getReleaseStoreKey(projectSlug, releaseVersion); const {deploysLoading, deploysError, ...state} = this.state; this.state = { ...state, deploysLoading: { ...deploysLoading, [releaseKey]: false, }, deploysError: { ...deploysError, [releaseKey]: error, }, }; this.trigger(this.state); }, loadDeploysSuccess(projectSlug: string, releaseVersion: string, data: Release) { const releaseKey = getReleaseStoreKey(projectSlug, releaseVersion); const {deploys, deploysLoading, deploysError, ...state} = this.state; this.state = { ...state, deploys: { ...deploys, [releaseKey]: data, }, deploysLoading: { ...deploysLoading, [releaseKey]: false, }, deploysError: { ...deploysError, [releaseKey]: undefined, }, }; this.trigger(this.state); }, get(projectSlug: string, releaseVersion: string) { const releaseKey = getReleaseStoreKey(projectSlug, releaseVersion); return { release: this.state.release[releaseKey], releaseLoading: this.state.releaseLoading[releaseKey], releaseError: this.state.releaseError[releaseKey], deploys: this.state.deploys[releaseKey], deploysLoading: this.state.deploysLoading[releaseKey], deploysError: this.state.deploysError[releaseKey], }; }, }; const ReleaseStore = Reflux.createStore(storeConfig) as Reflux.Store & ReleaseStoreInterface; export default ReleaseStore;