From ced624c2ff87702685d24890847a4379a0b0341b Mon Sep 17 00:00:00 2001 From: Taloth Saldono Date: Thu, 24 Dec 2020 23:11:03 +0100 Subject: [PATCH] Small helper in UI to access Radarr API more easily (cherry picked from commit 090cdc364ef335fbfea8cf540696af813f6ecea4) --- frontend/src/Diag/ConsoleApi.js | 120 ++++++++++++++++++++++++++++++++ frontend/src/bootstrap.tsx | 2 + 2 files changed, 122 insertions(+) create mode 100644 frontend/src/Diag/ConsoleApi.js diff --git a/frontend/src/Diag/ConsoleApi.js b/frontend/src/Diag/ConsoleApi.js new file mode 100644 index 000000000..8398b9f16 --- /dev/null +++ b/frontend/src/Diag/ConsoleApi.js @@ -0,0 +1,120 @@ +import createAjaxRequest from 'Utilities/createAjaxRequest'; + +// This file contains some helpers for power users in a browser console + +let hasWarned = false; + +function checkActivationWarning() { + if (!hasWarned) { + console.log('Activated RadarrApi console helpers.'); + console.warn('Be warned: There will be no further confirmation checks.'); + hasWarned = true; + } +} + +function attachAsyncActions(promise) { + promise.filter = function() { + const args = arguments; + const res = this.then((d) => d.filter(...args)); + attachAsyncActions(res); + return res; + }; + + promise.map = function() { + const args = arguments; + const res = this.then((d) => d.map(...args)); + attachAsyncActions(res); + return res; + }; + + promise.all = function() { + const res = this.then((d) => Promise.all(d)); + attachAsyncActions(res); + return res; + }; + + promise.forEach = function(action) { + const res = this.then((d) => Promise.all(d.map(action))); + attachAsyncActions(res); + return res; + }; +} + +class ResourceApi { + constructor(api, url) { + this.api = api; + this.url = url; + } + + single(id) { + return this.api.fetch(`${this.url}/${id}`); + } + + all() { + return this.api.fetch(this.url); + } + + filter(pred) { + return this.all().filter(pred); + } + + update(resource) { + return this.api.fetch(`${this.url}/${resource.id}`, { method: 'PUT', data: resource }); + } + + delete(resource) { + if (typeof resource === 'object' && resource !== null && resource.id) { + resource = resource.id; + } + + if (!resource || !Number.isInteger(resource)) { + throw Error('Invalid resource', resource); + } + + return this.api.fetch(`${this.url}/${resource}`, { method: 'DELETE' }); + } + + fetch(url, options) { + return this.api.fetch(`${this.url}${url}`, options); + } +} + +class ConsoleApi { + constructor() { + this.movie = new ResourceApi(this, '/movie'); + } + + resource(url) { + return new ResourceApi(this, url); + } + + fetch(url, options) { + checkActivationWarning(); + + options = options || {}; + + const req = { + url, + method: options.method || 'GET' + }; + + if (options.data) { + req.dataType = 'json'; + req.data = JSON.stringify(options.data); + } + + const promise = createAjaxRequest(req).request; + + promise.fail((xhr) => { + console.error(`Failed to fetch ${url}`, xhr); + }); + + attachAsyncActions(promise); + + return promise; + } +} + +window.RadarrApi = new ConsoleApi(); + +export default ConsoleApi; diff --git a/frontend/src/bootstrap.tsx b/frontend/src/bootstrap.tsx index 5e9985ba3..6a6d7fc67 100644 --- a/frontend/src/bootstrap.tsx +++ b/frontend/src/bootstrap.tsx @@ -4,6 +4,8 @@ import { render } from 'react-dom'; import createAppStore from 'Store/createAppStore'; import App from './App/App'; +import 'Diag/ConsoleApi'; + export async function bootstrap() { const history = createBrowserHistory(); const store = createAppStore(history);