From 71ce74e1d18b1ed955969ba0a293cbe71ea8a8db Mon Sep 17 00:00:00 2001 From: Kiwi Date: Tue, 27 Nov 2018 22:49:40 +0100 Subject: [PATCH] feat: batch admin configure mutations (#2089) --- .../configure/containers/ConfigureContainer.tsx | 17 ++++++++++++----- .../sections/auth/containers/AuthContainer.tsx | 2 +- .../auth/containers/OIDCConfigListContainer.tsx | 16 ++++++++++------ .../configure/submitHook/SubmitHookContext.tsx | 7 ++++++- .../framework/lib/network/createNetwork.ts | 3 ++- 5 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/core/client/admin/routes/configure/containers/ConfigureContainer.tsx b/src/core/client/admin/routes/configure/containers/ConfigureContainer.tsx index 3d2257881..e8f9aa8c1 100644 --- a/src/core/client/admin/routes/configure/containers/ConfigureContainer.tsx +++ b/src/core/client/admin/routes/configure/containers/ConfigureContainer.tsx @@ -56,25 +56,32 @@ class ConfigureContainer extends React.Component { ) => { let cancelled = false; let formErrors: Record = {}; + const executeCallbacks: Array<() => Promise> = []; const cancel = (errors: Record) => { cancelled = true; formErrors = { ...errors, ...formErrors }; }; + const onExecute = (cb: () => Promise) => { + executeCallbacks.push(cb); + }; try { // Call submit hooks, that can manipulate what // we send as the mutation. let nextData = data; for (const hook of this.submitHooks) { - const result = await hook(nextData, cancel); - if (cancelled) { - return formErrors; - } + const result = await hook(nextData, { cancel, onExecute }); if (result) { nextData = result; } } + if (cancelled) { + return formErrors; + } - await this.props.updateSettings({ settings: nextData }); + executeCallbacks.push(() => + this.props.updateSettings({ settings: nextData }) + ); + await Promise.all(executeCallbacks.map(cb => cb())); form.initialize(data); } catch (error) { if (error instanceof BadUserInputError) { diff --git a/src/core/client/admin/routes/configure/sections/auth/containers/AuthContainer.tsx b/src/core/client/admin/routes/configure/sections/auth/containers/AuthContainer.tsx index ec1875d3b..e32bb4ff8 100644 --- a/src/core/client/admin/routes/configure/sections/auth/containers/AuthContainer.tsx +++ b/src/core/client/admin/routes/configure/sections/auth/containers/AuthContainer.tsx @@ -43,7 +43,7 @@ export default class AuthContainer extends React.Component { this.removeSubmitHook(); } - private submitHook: SubmitHook = async (data, cancel) => { + private submitHook: SubmitHook = async (data, { cancel }) => { const integrations = [ get(data, "auth.integrations.google"), get(data, "auth.integrations.facebook"), diff --git a/src/core/client/admin/routes/configure/sections/auth/containers/OIDCConfigListContainer.tsx b/src/core/client/admin/routes/configure/sections/auth/containers/OIDCConfigListContainer.tsx index 9b7a4b6d2..4f4879f25 100644 --- a/src/core/client/admin/routes/configure/sections/auth/containers/OIDCConfigListContainer.tsx +++ b/src/core/client/admin/routes/configure/sections/auth/containers/OIDCConfigListContainer.tsx @@ -43,19 +43,23 @@ class OIDCConfigListContainer extends React.Component { this.removeSubmitHook(); } - private submitHook: SubmitHook = async (data: any) => { + private submitHook: SubmitHook = async (data: any, { onExecute }) => { const cloned = cloneDeep(data); const oidc = cloned.auth.integrations.oidc; delete cloned.auth.integrations.oidc; if (this.props.auth.integrations.oidc.length === 0) { if (oidc[0].enabled) { - await this.props.createOIDCAuthIntegration({ configuration: oidc[0] }); + onExecute(() => + this.props.createOIDCAuthIntegration({ configuration: oidc[0] }) + ); } } else { - await this.props.updateOIDCAuthIntegration({ - configuration: oidc[0], - id: this.props.authReadOnly.integrations.oidc[0].id, - }); + onExecute(() => + this.props.updateOIDCAuthIntegration({ + configuration: oidc[0], + id: this.props.authReadOnly.integrations.oidc[0].id, + }) + ); } return cloned; }; diff --git a/src/core/client/admin/routes/configure/submitHook/SubmitHookContext.tsx b/src/core/client/admin/routes/configure/submitHook/SubmitHookContext.tsx index 046546628..65565c49b 100644 --- a/src/core/client/admin/routes/configure/submitHook/SubmitHookContext.tsx +++ b/src/core/client/admin/routes/configure/submitHook/SubmitHookContext.tsx @@ -3,7 +3,12 @@ import React from "react"; export type SubmitHook = ( data: any, - cancel: (errors?: Record) => void + actions: { + // Callback will be called after all validations has passed and + // the submit has not been cancelled. + onExecute: (cb: () => Promise) => void; + cancel: (errors?: Record) => void; + } ) => Promise | any; export type RemoveSubmitHook = () => void; export type AddSubmitHook = (hook: SubmitHook) => RemoveSubmitHook; diff --git a/src/core/client/framework/lib/network/createNetwork.ts b/src/core/client/framework/lib/network/createNetwork.ts index effd45b99..d67b56ae1 100644 --- a/src/core/client/framework/lib/network/createNetwork.ts +++ b/src/core/client/framework/lib/network/createNetwork.ts @@ -26,7 +26,8 @@ export default function createNetwork(tokenGetter: TokenGetter) { }), batchMiddleware({ batchUrl: (requestMap: any) => Promise.resolve(graphqlURL), - batchTimeout: 10, + batchTimeout: 0, + allowMutations: true, }), retryMiddleware({ fetchTimeout: 15000,