From 637f188ebec71fe4b0b80bbab4592d4c269d7d93 Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:46:06 +0200 Subject: [feature] Allow import/export/creation of domain allows via admin panel (#2264) * it's happening! * aaa * fix silly whoopsie * it's working pa! it's working ma! * model report parameters * shuffle some more stuff around * getting there * oo hoo * finish tidying up for now * aaa * fix use form submit errors * peepee poo poo * aaaaa * ffff * they see me typin', they hatin' * boop * aaa * oooo * typing typing tappa tappa * almost done typing * weee * alright * push it push it real good doo doo doo doo doo doo * thingy no worky * almost done * mutation modifers not quite right * hmm * it works * view blocks + allows nicely * it works! * typia install * the old linterino * linter plz --- web/source/settings/lib/query/query-modifiers.ts | 150 +++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 web/source/settings/lib/query/query-modifiers.ts (limited to 'web/source/settings/lib/query/query-modifiers.ts') diff --git a/web/source/settings/lib/query/query-modifiers.ts b/web/source/settings/lib/query/query-modifiers.ts new file mode 100644 index 000000000..d6bf0b6ae --- /dev/null +++ b/web/source/settings/lib/query/query-modifiers.ts @@ -0,0 +1,150 @@ +/* + GoToSocial + Copyright (C) GoToSocial Authors admin@gotosocial.org + SPDX-License-Identifier: AGPL-3.0-or-later + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +import { gtsApi } from "./gts-api"; + +import type { + Action, + CacheMutation, +} from "../types/query"; + +import { NoArg } from "../types/query"; + +/** + * Cache mutation creator for pessimistic updates. + * + * Feed it a function that you want to perform on the + * given draft and updated data, using the given parameters. + * + * https://redux-toolkit.js.org/rtk-query/api/createApi#onquerystarted + * https://redux-toolkit.js.org/rtk-query/usage/manual-cache-updates#pessimistic-updates + */ +function makeCacheMutation(action: Action): CacheMutation { + return function cacheMutation( + queryName: string | ((_arg: any) => string), + { key } = {}, + ) { + return { + onQueryStarted: async(mutationData, { dispatch, queryFulfilled }) => { + // queryName might be a function that returns + // a query name; trigger it if so. The returned + // queryName has to match one of the API endpoints + // we've defined. So if we have endpoints called + // (for example) `instanceV1` and `getPosts` then + // the queryName provided here has to line up with + // one of those in order to actually do anything. + if (typeof queryName !== "string") { + queryName = queryName(mutationData); + } + + if (queryName == "") { + throw ( + "provided queryName resolved to an empty string;" + + "double check your mutation definition!" + ); + } + + try { + // Wait for the mutation to finish (this + // is why it's a pessimistic update). + const { data: newData } = await queryFulfilled; + + // In order for `gtsApi.util.updateQueryData` to + // actually do something within a dispatch, the + // first two arguments passed into it have to line + // up with arguments that were used earlier to + // fetch the data whose cached version we're now + // trying to modify. + // + // So, if we earlier fetched all reports with + // queryName `getReports`, and arg `undefined`, + // then we now need match those parameters in + // `updateQueryData` in order to modify the cache. + // + // If you pass something like `null` or `""` here + // instead, then the cache will not get modified! + // Redux will just quietly discard the thunk action. + dispatch( + gtsApi.util.updateQueryData(queryName as any, NoArg, (draft) => { + if (key != undefined && typeof key !== "string") { + key = key(draft, newData); + } + action(draft, newData, { key }); + }) + ); + } catch (e) { + // eslint-disable-next-line no-console + console.error(`rolling back pessimistic update of ${queryName}: ${e}`); + } + } + }; + }; +} + +/** + * + */ +const replaceCacheOnMutation: CacheMutation = makeCacheMutation((draft, newData, _params) => { + Object.assign(draft, newData); +}); + +const appendCacheOnMutation: CacheMutation = makeCacheMutation((draft, newData, _params) => { + draft.push(newData); +}); + +const spliceCacheOnMutation: CacheMutation = makeCacheMutation((draft, _newData, { key }) => { + if (key === undefined) { + throw ("key undefined"); + } + + draft.splice(key, 1); +}); + +const updateCacheOnMutation: CacheMutation = makeCacheMutation((draft, newData, { key }) => { + if (key === undefined) { + throw ("key undefined"); + } + + if (typeof key !== "string") { + key = key(draft, newData); + } + + draft[key] = newData; +}); + +const removeFromCacheOnMutation: CacheMutation = makeCacheMutation((draft, newData, { key }) => { + if (key === undefined) { + throw ("key undefined"); + } + + if (typeof key !== "string") { + key = key(draft, newData); + } + + delete draft[key]; +}); + + +export { + replaceCacheOnMutation, + appendCacheOnMutation, + spliceCacheOnMutation, + updateCacheOnMutation, + removeFromCacheOnMutation, +}; -- cgit v1.2.3