123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- import {
- addErrorMessage,
- addLoadingMessage,
- addSuccessMessage,
- } from 'sentry/actionCreators/indicator';
- import type {RequestOptions} from 'sentry/api';
- import {Client} from 'sentry/api';
- import {t} from 'sentry/locale';
- import PluginsStore from 'sentry/stores/pluginsStore';
- import type {Plugin} from 'sentry/types/integrations';
- const activeFetch: Record<string, Promise<any> | null> = {};
- // PluginsStore always exists, so api client should be independent of component lifecycle
- const api = new Client();
- type Slugs = {
- /**
- * Organization slug
- */
- orgId: string;
- /**
- * Plugin slug
- */
- pluginId: string;
- /**
- * Project slug
- */
- projectId: string;
- };
- type DoUpdateParams = Slugs & {
- update: Partial<Plugin>;
- } & Partial<RequestOptions>;
- function doUpdate({orgId, projectId, pluginId, update, ...params}: DoUpdateParams) {
- PluginsStore.onUpdate(pluginId, update);
- const request = api.requestPromise(
- `/projects/${orgId}/${projectId}/plugins/${pluginId}/`,
- {
- ...params,
- }
- );
- // This is intentionally not chained because we want the unhandled promise to be returned
- request
- .then(() => {
- PluginsStore.onUpdateSuccess(pluginId);
- })
- .catch(resp => {
- const err =
- typeof resp?.responseJSON?.detail === 'string'
- ? new Error(resp.responseJSON.detail)
- : new Error('Unable to update plugin');
- PluginsStore.onUpdateError(pluginId, err);
- });
- return request;
- }
- type FetchPluginsOptions = {
- /**
- * Reset will set loading state = true
- */
- resetLoading?: boolean;
- };
- /**
- * Fetches list of available plugins for a project
- */
- export function fetchPlugins(
- {orgId, projectId}: Pick<Slugs, 'orgId' | 'projectId'>,
- options?: FetchPluginsOptions
- ): Promise<Plugin[]> {
- const path = `/projects/${orgId}/${projectId}/plugins/`;
- // Make sure we throttle fetches
- if (activeFetch[path]) {
- return activeFetch[path];
- }
- PluginsStore.onFetchAll(options);
- const request = api.requestPromise(path, {
- method: 'GET',
- includeAllArgs: true,
- });
- activeFetch[path] = request;
- // This is intentionally not chained because we want the unhandled promise to be returned
- request
- .then(([data, _, resp]) => {
- PluginsStore.onFetchAllSuccess(data, {
- pageLinks: resp?.getResponseHeader('Link') ?? undefined,
- });
- return data;
- })
- .catch(err => {
- PluginsStore.onFetchAllError(err);
- throw new Error('Unable to fetch plugins');
- })
- .then(() => (activeFetch[path] = null));
- return request;
- }
- type EnableDisablePluginParams = Slugs;
- /**
- * Enables a plugin
- */
- export function enablePlugin(params: EnableDisablePluginParams) {
- addLoadingMessage(t('Enabling...'));
- return doUpdate({...params, update: {enabled: true}, method: 'POST'})
- .then(() => addSuccessMessage(t('Plugin was enabled')))
- .catch(() => addErrorMessage(t('Unable to enable plugin')));
- }
- /**
- * Disables a plugin
- */
- export function disablePlugin(params: EnableDisablePluginParams) {
- addLoadingMessage(t('Disabling...'));
- return doUpdate({...params, update: {enabled: false}, method: 'DELETE'})
- .then(() => addSuccessMessage(t('Plugin was disabled')))
- .catch(() => addErrorMessage(t('Unable to disable plugin')));
- }
|