123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- import Reflux from 'reflux';
- import OrganizationActions from 'app/actions/organizationActions';
- import ProjectActions from 'app/actions/projectActions';
- import TeamActions from 'app/actions/teamActions';
- import {ORGANIZATION_FETCH_ERROR_TYPES} from 'app/constants';
- import {Organization, Project, Team} from 'app/types';
- import RequestError from 'app/utils/requestError/requestError';
- type UpdateOptions = {
- replace?: boolean;
- };
- type OutputState = {
- organization: Organization | null;
- loading: boolean;
- dirty: boolean;
- errorType?: string | null;
- error?: RequestError | null;
- };
- type OrganizationStoreInterface = {
- init: () => void;
- reset: () => void;
- onUpdate: (org: Organization, options: UpdateOptions) => void;
- onFetchOrgError: (err: RequestError) => void;
- onProjectOrTeamChange: () => void;
- onLoadProjects: (projects: Project[]) => void;
- onLoadTeams: (teams: Team[]) => void;
- get: () => OutputState;
- };
- const storeConfig: Reflux.StoreDefinition & OrganizationStoreInterface = {
- init() {
- this.reset();
- this.listenTo(OrganizationActions.update, this.onUpdate);
- this.listenTo(OrganizationActions.fetchOrg, this.reset);
- this.listenTo(OrganizationActions.fetchOrgError, this.onFetchOrgError);
- // fill in teams and projects if they are loaded
- this.listenTo(ProjectActions.loadProjects, this.onLoadProjects);
- this.listenTo(TeamActions.loadTeams, this.onLoadTeams);
- // mark the store as dirty if projects or teams change
- this.listenTo(ProjectActions.createSuccess, this.onProjectOrTeamChange);
- this.listenTo(ProjectActions.updateSuccess, this.onProjectOrTeamChange);
- this.listenTo(ProjectActions.changeSlug, this.onProjectOrTeamChange);
- this.listenTo(ProjectActions.addTeamSuccess, this.onProjectOrTeamChange);
- this.listenTo(ProjectActions.removeTeamSuccess, this.onProjectOrTeamChange);
- this.listenTo(TeamActions.updateSuccess, this.onProjectOrTeamChange);
- this.listenTo(TeamActions.removeTeamSuccess, this.onProjectOrTeamChange);
- this.listenTo(TeamActions.createTeamSuccess, this.onProjectOrTeamChange);
- },
- reset() {
- this.loading = true;
- this.error = null;
- this.errorType = null;
- this.organization = null;
- this.dirty = false;
- this.trigger(this.get());
- },
- onUpdate(updatedOrg: Organization, {replace = false}: UpdateOptions = {}) {
- this.loading = false;
- this.error = null;
- this.errorType = null;
- this.organization = replace ? updatedOrg : {...this.organization, ...updatedOrg};
- this.dirty = false;
- this.trigger(this.get());
- },
- onFetchOrgError(err: RequestError) {
- this.organization = null;
- this.errorType = null;
- switch (err?.status) {
- case 401:
- this.errorType = ORGANIZATION_FETCH_ERROR_TYPES.ORG_NO_ACCESS;
- break;
- case 404:
- this.errorType = ORGANIZATION_FETCH_ERROR_TYPES.ORG_NOT_FOUND;
- break;
- default:
- }
- this.loading = false;
- this.error = err;
- this.dirty = false;
- this.trigger(this.get());
- },
- onProjectOrTeamChange() {
- // mark the store as dirty so the next fetch will trigger an org details refetch
- this.dirty = true;
- },
- onLoadProjects(projects: Project[]) {
- if (this.organization) {
- // sort projects to mimic how they are received from backend
- projects.sort((a, b) => a.slug.localeCompare(b.slug));
- this.organization = {...this.organization, projects};
- this.trigger(this.get());
- }
- },
- onLoadTeams(teams: Team[]) {
- if (this.organization) {
- // sort teams to mimic how they are received from backend
- teams.sort((a, b) => a.slug.localeCompare(b.slug));
- this.organization = {...this.organization, teams};
- this.trigger(this.get());
- }
- },
- get() {
- return {
- organization: this.organization,
- error: this.error,
- loading: this.loading,
- errorType: this.errorType,
- dirty: this.dirty,
- };
- },
- };
- type OrganizationStore = Reflux.Store & OrganizationStoreInterface;
- const OrganizationStore = Reflux.createStore(storeConfig) as OrganizationStore;
- export default OrganizationStore;
|