@ynput/ayon-frontend-shared 0.3.55 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/index.cjs4.js +1 -1
- package/dist/_virtual/index.cjs5.js +1 -1
- package/dist/_virtual/index.cjs6.js +1 -1
- package/dist/_virtual/index.cjs8.js +1 -1
- package/dist/_virtual/index.cjs9.js +1 -1
- package/dist/_virtual/index.es15.js +2 -2
- package/dist/_virtual/index.es4.js +5 -2
- package/dist/_virtual/index.es4.js.map +1 -1
- package/dist/_virtual/index.es5.js +2 -5
- package/dist/_virtual/index.es5.js.map +1 -1
- package/dist/_virtual/index.es6.js +2 -2
- package/dist/_virtual/index.es8.js +2 -5
- package/dist/_virtual/index.es8.js.map +1 -1
- package/dist/_virtual/index.es9.js +5 -2
- package/dist/_virtual/index.es9.js.map +1 -1
- package/dist/api.cjs.js +1 -1
- package/dist/api.es.js +193 -192
- package/dist/node_modules/match-sorter/dist/match-sorter.esm.cjs.js +1 -1
- package/dist/node_modules/match-sorter/dist/match-sorter.esm.es.js +1 -1
- package/dist/node_modules/parse-numeric-range/index.cjs.js +1 -1
- package/dist/node_modules/parse-numeric-range/index.es.js +1 -1
- package/dist/node_modules/remove-accents/index.cjs.js +1 -1
- package/dist/node_modules/remove-accents/index.cjs.js.map +1 -1
- package/dist/node_modules/remove-accents/index.es.js +1 -1
- package/dist/shared/node_modules/@module-federation/error-codes/dist/index.cjs.js +1 -1
- package/dist/shared/node_modules/@module-federation/error-codes/dist/index.es.js +1 -1
- package/dist/shared/node_modules/@module-federation/runtime/dist/index.cjs.js +1 -1
- package/dist/shared/node_modules/@module-federation/runtime/dist/index.es.js +1 -1
- package/dist/shared/node_modules/@module-federation/runtime-core/dist/index.cjs.js +1 -1
- package/dist/shared/node_modules/@module-federation/runtime-core/dist/index.es.js +1 -1
- package/dist/shared/node_modules/prop-types/index.cjs.js +1 -1
- package/dist/shared/node_modules/prop-types/index.cjs.js.map +1 -1
- package/dist/shared/node_modules/prop-types/index.es.js +1 -1
- package/dist/shared/node_modules/react-is/index.cjs.js +1 -1
- package/dist/shared/node_modules/react-is/index.es.js +1 -1
- package/dist/shared/node_modules/react-transition-group/esm/CSSTransition.cjs.js +1 -1
- package/dist/shared/node_modules/react-transition-group/esm/CSSTransition.es.js +1 -1
- package/dist/shared/node_modules/react-transition-group/esm/Transition.cjs.js +1 -1
- package/dist/shared/node_modules/react-transition-group/esm/Transition.es.js +1 -1
- package/dist/shared/node_modules/react-transition-group/esm/utils/PropTypes.cjs.js +1 -1
- package/dist/shared/node_modules/react-transition-group/esm/utils/PropTypes.es.js +1 -1
- package/dist/shared/src/api/generated/graphql.cjs.js +4 -0
- package/dist/shared/src/api/generated/graphql.cjs.js.map +1 -1
- package/dist/shared/src/api/generated/graphql.es.js +4 -0
- package/dist/shared/src/api/generated/graphql.es.js.map +1 -1
- package/dist/shared/src/api/generated/graphqlLinks.cjs.js.map +1 -1
- package/dist/shared/src/api/generated/graphqlLinks.es.js.map +1 -1
- package/dist/shared/src/api/queries/entities/transformDetailsPanelData.cjs.js +1 -1
- package/dist/shared/src/api/queries/entities/transformDetailsPanelData.cjs.js.map +1 -1
- package/dist/shared/src/api/queries/entities/transformDetailsPanelData.es.js +17 -16
- package/dist/shared/src/api/queries/entities/transformDetailsPanelData.es.js.map +1 -1
- package/dist/shared/src/api/queries/entityLists/getLists.cjs.js +1 -1
- package/dist/shared/src/api/queries/entityLists/getLists.cjs.js.map +1 -1
- package/dist/shared/src/api/queries/entityLists/getLists.es.js +47 -47
- package/dist/shared/src/api/queries/entityLists/getLists.es.js.map +1 -1
- package/dist/shared/src/api/queries/folders/getFolders.cjs.js +1 -1
- package/dist/shared/src/api/queries/folders/getFolders.cjs.js.map +1 -1
- package/dist/shared/src/api/queries/folders/getFolders.es.js +20 -22
- package/dist/shared/src/api/queries/folders/getFolders.es.js.map +1 -1
- package/dist/shared/src/api/queries/overview/getOverview.cjs.js +1 -1
- package/dist/shared/src/api/queries/overview/getOverview.cjs.js.map +1 -1
- package/dist/shared/src/api/queries/overview/getOverview.es.js +92 -89
- package/dist/shared/src/api/queries/overview/getOverview.es.js.map +1 -1
- package/dist/shared/src/api/queries/project/getProject.cjs.js +1 -1
- package/dist/shared/src/api/queries/project/getProject.cjs.js.map +1 -1
- package/dist/shared/src/api/queries/project/getProject.es.js +1 -1
- package/dist/shared/src/api/queries/project/getProject.es.js.map +1 -1
- package/dist/shared/src/api/queries/users/getUsers.cjs.js +1 -1
- package/dist/shared/src/api/queries/users/getUsers.cjs.js.map +1 -1
- package/dist/shared/src/api/queries/users/getUsers.es.js +1 -1
- package/dist/shared/src/api/queries/users/getUsers.es.js.map +1 -1
- package/dist/shared/src/api/queries/versions/getVersionsProducts.cjs.js +1 -1
- package/dist/shared/src/api/queries/versions/getVersionsProducts.cjs.js.map +1 -1
- package/dist/shared/src/api/queries/versions/getVersionsProducts.es.js +23 -23
- package/dist/shared/src/api/queries/versions/getVersionsProducts.es.js.map +1 -1
- package/dist/shared/src/api/queries/versions/getVersionsProductsUtils.cjs.js +1 -1
- package/dist/shared/src/api/queries/versions/getVersionsProductsUtils.cjs.js.map +1 -1
- package/dist/shared/src/api/queries/versions/getVersionsProductsUtils.es.js +13 -13
- package/dist/shared/src/api/queries/versions/getVersionsProductsUtils.es.js.map +1 -1
- package/dist/shared/src/components/DetailsPanelAttributes/components/RenderFieldWidget.cjs.js +3 -3
- package/dist/shared/src/components/DetailsPanelAttributes/components/RenderFieldWidget.cjs.js.map +1 -1
- package/dist/shared/src/components/DetailsPanelAttributes/components/RenderFieldWidget.es.js +51 -50
- package/dist/shared/src/components/DetailsPanelAttributes/components/RenderFieldWidget.es.js.map +1 -1
- package/dist/shared/src/components/RemotePage/ProjectPageRemote.cjs.js +1 -1
- package/dist/shared/src/components/RemotePage/ProjectPageRemote.cjs.js.map +1 -1
- package/dist/shared/src/components/RemotePage/ProjectPageRemote.es.js +26 -24
- package/dist/shared/src/components/RemotePage/ProjectPageRemote.es.js.map +1 -1
- package/dist/shared/src/components/RemotePage/RemotePageWrapper.cjs.js +1 -1
- package/dist/shared/src/components/RemotePage/RemotePageWrapper.cjs.js.map +1 -1
- package/dist/shared/src/components/RemotePage/RemotePageWrapper.es.js +31 -18
- package/dist/shared/src/components/RemotePage/RemotePageWrapper.es.js.map +1 -1
- package/dist/shared/src/containers/ListTable/ListTableWidgets.cjs.js +1 -1
- package/dist/shared/src/containers/ListTable/ListTableWidgets.cjs.js.map +1 -1
- package/dist/shared/src/containers/ListTable/ListTableWidgets.es.js +62 -58
- package/dist/shared/src/containers/ListTable/ListTableWidgets.es.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.cjs.js +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.cjs.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.es.js +21 -20
- package/dist/shared/src/containers/ProjectTreeTable/buildTreeTableColumns.es.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildGroupByTableData.cjs.js +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildGroupByTableData.cjs.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildGroupByTableData.es.js +25 -24
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildGroupByTableData.es.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildProjectDataTable.cjs.js +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildProjectDataTable.cjs.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildProjectDataTable.es.js +20 -19
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useBuildProjectDataTable.es.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useUpdateTableData.cjs.js +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useUpdateTableData.cjs.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useUpdateTableData.es.js +152 -133
- package/dist/shared/src/containers/ProjectTreeTable/hooks/useUpdateTableData.es.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/widgets/CellWidget.cjs.js +2 -2
- package/dist/shared/src/containers/ProjectTreeTable/widgets/CellWidget.cjs.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/widgets/CellWidget.es.js +75 -73
- package/dist/shared/src/containers/ProjectTreeTable/widgets/CellWidget.es.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/widgets/DateWidget.cjs.js +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/widgets/DateWidget.cjs.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/widgets/DateWidget.es.js +21 -19
- package/dist/shared/src/containers/ProjectTreeTable/widgets/DateWidget.es.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/widgets/DateWidgetInput.cjs.js +2 -2
- package/dist/shared/src/containers/ProjectTreeTable/widgets/DateWidgetInput.cjs.js.map +1 -1
- package/dist/shared/src/containers/ProjectTreeTable/widgets/DateWidgetInput.es.js +58 -43
- package/dist/shared/src/containers/ProjectTreeTable/widgets/DateWidgetInput.es.js.map +1 -1
- package/dist/types/api/generated/graphql.d.ts +5 -0
- package/dist/types/api/generated/graphqlLinks.d.ts +1 -0
- package/dist/types/api/queries/entities/transformDetailsPanelData.d.ts +1 -0
- package/dist/types/api/queries/overview/getOverview.d.ts +2 -1
- package/dist/types/components/RemotePage/RemotePageWrapper.d.ts +25 -1
- package/dist/types/containers/ProjectTreeTable/types/table.d.ts +3 -1
- package/dist/types/containers/ProjectTreeTable/widgets/CellWidget.d.ts +1 -0
- package/dist/types/containers/ProjectTreeTable/widgets/DateWidget.d.ts +1 -0
- package/dist/types/containers/ProjectTreeTable/widgets/DateWidgetInput.d.ts +1 -0
- package/package.json +1 -1
|
@@ -61,7 +61,7 @@ import "../config/getConfig.es.js";
|
|
|
61
61
|
import "../config/updateConfig.es.js";
|
|
62
62
|
import "../entities/getEntity.es.js";
|
|
63
63
|
import "../entities/getEntityPanel.es.js";
|
|
64
|
-
import {
|
|
64
|
+
import { parseJSONField as N } from "../overview/getOverview.es.js";
|
|
65
65
|
import "../overview/updateOverview.es.js";
|
|
66
66
|
import "../versions/getVersionsProducts.es.js";
|
|
67
67
|
import "../links/getEntityLinks.es.js";
|
|
@@ -98,14 +98,14 @@ import "../views/getViews.es.js";
|
|
|
98
98
|
import "../views/updateViews.es.js";
|
|
99
99
|
import "../watchers/getWatchers.es.js";
|
|
100
100
|
import "../uris/getUris.es.js";
|
|
101
|
-
import { createRealtimeBatcher as
|
|
102
|
-
import
|
|
101
|
+
import { createRealtimeBatcher as j, getSupportedEntityPatch as v, waitForRealtimeJitter as G, REALTIME_REST_CALL_LIMIT as U } from "../../../util/realtimeUpdatesUtils.es.js";
|
|
102
|
+
import T from "../../../util/pubsub.es.js";
|
|
103
103
|
const x = P.enhanceEndpoints({
|
|
104
104
|
endpoints: {
|
|
105
105
|
GetUpdatedAndNewFolders: {
|
|
106
106
|
transformResponse: (f) => f.project.folders.edges.map(({ node: e }) => ({
|
|
107
107
|
...e,
|
|
108
|
-
attrib:
|
|
108
|
+
attrib: N(e.allAttrib),
|
|
109
109
|
path: e.path ?? "",
|
|
110
110
|
parentId: e.parentId ?? void 0,
|
|
111
111
|
label: e.label ?? void 0,
|
|
@@ -128,19 +128,19 @@ const x = P.enhanceEndpoints({
|
|
|
128
128
|
{ type: "folder", id: y }
|
|
129
129
|
],
|
|
130
130
|
async onCacheEntryAdded(f, { cacheDataLoaded: e, cacheEntryRemoved: y, updateCachedData: a, getCacheEntry: _, dispatch: L }) {
|
|
131
|
-
const { projectName:
|
|
131
|
+
const { projectName: E } = f || {}, R = ["status", "tags", "folderType"], g = {
|
|
132
132
|
"entity.folder.label_changed": "label",
|
|
133
133
|
"entity.folder.renamed": "name",
|
|
134
134
|
"entity.folder.type_changed": "folderType",
|
|
135
135
|
"entity.folder.status_changed": "status",
|
|
136
136
|
"entity.folder.tags_changed": "tags",
|
|
137
137
|
"entity.folder.attrib_changed": "attrib"
|
|
138
|
-
}, M = ["entity.folder"], w = [], b =
|
|
138
|
+
}, M = ["entity.folder"], w = [], b = j(
|
|
139
139
|
async (d) => {
|
|
140
|
-
if (!
|
|
140
|
+
if (!E) return;
|
|
141
141
|
const m = /* @__PURE__ */ new Set(), o = _().data;
|
|
142
142
|
o && Array.isArray(o.folders) && o.folders.forEach((t) => m.add(t.id));
|
|
143
|
-
const s = [], c = [], l = /* @__PURE__ */ new Map(),
|
|
143
|
+
const s = [], c = [], l = /* @__PURE__ */ new Map(), F = [];
|
|
144
144
|
d.forEach((t) => {
|
|
145
145
|
const i = t.summary?.entityId;
|
|
146
146
|
if (!i) return;
|
|
@@ -153,12 +153,12 @@ const x = P.enhanceEndpoints({
|
|
|
153
153
|
return;
|
|
154
154
|
}
|
|
155
155
|
if (!m.has(i)) return;
|
|
156
|
-
const p =
|
|
156
|
+
const p = v(
|
|
157
157
|
g[t.topic],
|
|
158
158
|
t.summary,
|
|
159
159
|
R
|
|
160
160
|
);
|
|
161
|
-
if (p)
|
|
161
|
+
if (p) F.push({ folderId: i, ...p });
|
|
162
162
|
else {
|
|
163
163
|
const n = g[t.topic];
|
|
164
164
|
if (!n) return;
|
|
@@ -167,20 +167,18 @@ const x = P.enhanceEndpoints({
|
|
|
167
167
|
}
|
|
168
168
|
}), s.length && a((t) => {
|
|
169
169
|
!t || !Array.isArray(t.folders) || (t.folders = t.folders.filter((i) => !s.includes(i.id)));
|
|
170
|
-
}),
|
|
171
|
-
!t || !Array.isArray(t.folders) ||
|
|
170
|
+
}), F.length && a((t) => {
|
|
171
|
+
!t || !Array.isArray(t.folders) || F.forEach(({ folderId: i, field: p, value: n }) => {
|
|
172
172
|
const r = t.folders.find((h) => h.id === i);
|
|
173
173
|
r && (r[p] = n);
|
|
174
174
|
});
|
|
175
175
|
});
|
|
176
|
-
const u = [
|
|
177
|
-
.../* @__PURE__ */ new Set([...c, ...l.keys()])
|
|
178
|
-
];
|
|
176
|
+
const u = [.../* @__PURE__ */ new Set([...c, ...l.keys()])];
|
|
179
177
|
if (!(u.length > B) && u.length) {
|
|
180
|
-
await
|
|
178
|
+
await G();
|
|
181
179
|
const t = await L(
|
|
182
180
|
x.endpoints.GetUpdatedAndNewFolders.initiate({
|
|
183
|
-
projectName:
|
|
181
|
+
projectName: E,
|
|
184
182
|
folderIds: u,
|
|
185
183
|
first: u.length
|
|
186
184
|
})
|
|
@@ -191,9 +189,9 @@ const x = P.enhanceEndpoints({
|
|
|
191
189
|
t.filter(Boolean).map((r) => [r.id, r])
|
|
192
190
|
);
|
|
193
191
|
p.folders.forEach((r, h) => {
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
r[
|
|
192
|
+
const I = n.get(r.id);
|
|
193
|
+
I && (i.has(r.id) ? p.folders[h] = { ...r, ...I } : (l.get(r.id) || /* @__PURE__ */ new Set()).forEach((S) => {
|
|
194
|
+
r[S] = I[S];
|
|
197
195
|
}), n.delete(r.id));
|
|
198
196
|
}), n.forEach((r, h) => {
|
|
199
197
|
i.has(h) && p.folders.push(r);
|
|
@@ -223,10 +221,10 @@ const x = P.enhanceEndpoints({
|
|
|
223
221
|
const d = (m, o) => {
|
|
224
222
|
o?.summary?.entityId && b.add({ ...o, topic: m });
|
|
225
223
|
};
|
|
226
|
-
M.forEach((m) => w.push(
|
|
224
|
+
M.forEach((m) => w.push(T.subscribe(m, d)));
|
|
227
225
|
} catch {
|
|
228
226
|
}
|
|
229
|
-
await y, b.clear(), w.forEach((d) =>
|
|
227
|
+
await y, b.clear(), w.forEach((d) => T.unsubscribe(d)), A && A(), b.clear();
|
|
230
228
|
}
|
|
231
229
|
}
|
|
232
230
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFolders.es.js","sources":["../../../../../../src/api/queries/folders/getFolders.ts"],"sourcesContent":["import {\n FolderListItem,\n foldersApi,\n GetUpdatedAndNewFoldersQuery,\n gqlApi,\n} from '@shared/api/generated'\nimport {\n getSupportedEntityPatch,\n createRealtimeBatcher,\n REALTIME_REST_CALL_LIMIT,\n waitForRealtimeJitter,\n PubSub,\n subscribeToThumbnailUpdates,\n ThumbnailUpdateMessage,\n SupportedEntityPatchField,\n} from '@shared/util'\n\nimport { DefinitionsFromApi, OverrideResultType, TagTypesFromApi } from '@reduxjs/toolkit/query'\nimport { parseAllAttribs } from '../overview'\n\ntype GetUpdatedAndNewFoldersResult = FolderListItem[]\n\n// HELPER QUERIES FOR REALTIME UPDATES\ntype Definitions = DefinitionsFromApi<typeof gqlApi>\ntype TagTypes = TagTypesFromApi<typeof gqlApi>\n// update the definitions to include the new types\ntype UpdatedDefinitions = Omit<Definitions, 'GetUpdatedAndNewFolders'> & {\n GetUpdatedAndNewFolders: OverrideResultType<\n Definitions['GetUpdatedAndNewFolders'],\n GetUpdatedAndNewFoldersResult\n >\n}\n\nconst graphqlFolders = gqlApi.enhanceEndpoints<TagTypes, UpdatedDefinitions>({\n endpoints: {\n GetUpdatedAndNewFolders: {\n transformResponse: (response: GetUpdatedAndNewFoldersQuery): GetUpdatedAndNewFoldersResult =>\n response.project.folders.edges.map(({ node }) => ({\n ...node,\n attrib: parseAllAttribs(node.allAttrib),\n path: node.path ?? '',\n parentId: node.parentId ?? undefined,\n label: node.label ?? undefined,\n taskNames: [],\n createdAt: String(node.createdAt),\n updatedAt: String(node.updatedAt),\n })),\n },\n },\n})\n\n// the max number of folder to process in a single batch\n// TODO: Use this limit to trigger the reload button\nexport const MAX_FOLDER_UPDATE_REST_CALLS = REALTIME_REST_CALL_LIMIT\n\nconst enhancedApi = foldersApi.enhanceEndpoints({\n endpoints: {\n getFolderHierarchy: {\n providesTags: ['hierarchy'],\n },\n getFolderList: {\n providesTags: (result, _e, { projectName }) => [\n 'hierarchy',\n { type: 'folder', id: 'LIST' },\n ...(result?.folders.map(({ id }) => ({ type: 'folder', id })) || []),\n { type: 'folder', id: projectName },\n ],\n async onCacheEntryAdded(\n args,\n { cacheDataLoaded, cacheEntryRemoved, updateCachedData, getCacheEntry, dispatch },\n ) {\n const { projectName } = args || {}\n const supportedFolderFields = ['status', 'tags', 'folderType']\n const topicFieldMap: Record<string, string> = {\n 'entity.folder.label_changed': 'label',\n 'entity.folder.renamed': 'name',\n 'entity.folder.type_changed': 'folderType',\n 'entity.folder.status_changed': 'status',\n 'entity.folder.tags_changed': 'tags',\n 'entity.folder.attrib_changed': 'attrib',\n }\n\n const topics = ['entity.folder']\n const tokens: (string | undefined)[] = []\n\n // handle a batch of messages, updating the cache and fetching missing data as needed\n const batchProcessMessages = async (messages: any[]) => {\n if (!projectName) return\n\n const cachedFolderIds = new Set<string>()\n const cachedFolders = getCacheEntry().data\n if (cachedFolders && Array.isArray(cachedFolders.folders)) {\n cachedFolders.folders.forEach((folder: any) => cachedFolderIds.add(folder.id))\n }\n\n const deletedIds: string[] = []\n const createdIds: string[] = []\n const unsupportedFields = new Map<string, Set<string>>()\n const summaryPatches: {\n folderId: string\n field: SupportedEntityPatchField\n value: string | string[]\n }[] = []\n\n // for each message, check it's type and then add it to the appropriate list for processing\n messages.forEach((message) => {\n const folderId = message.summary?.entityId\n if (!folderId) return\n\n // delete: remove from cache - no additional API calls\n if (message.topic === 'entity.folder.deleted') {\n deletedIds.push(folderId)\n return\n }\n\n // create: add to cache - will fetch the full folder data later\n if (message.topic === 'entity.folder.created') {\n createdIds.push(folderId)\n return\n }\n\n // for updates, check if the folder is in the cache\n // no point updating a folder that does not exist for the user\n if (!cachedFolderIds.has(folderId)) return\n\n // check if the updated field data is in the summary (status, tags etc)\n // if it is, we can update the cache directly, otherwise we will need to fetch the full folder data later\n const patch = getSupportedEntityPatch(\n topicFieldMap[message.topic],\n message.summary,\n supportedFolderFields,\n )\n if (patch) summaryPatches.push({ folderId, ...patch })\n else {\n const field = topicFieldMap[message.topic]\n if (!field) return\n\n const fields = unsupportedFields.get(folderId) || new Set<string>()\n fields.add(field)\n unsupportedFields.set(folderId, fields)\n }\n })\n\n // DELETED: remove deleted folders from cache\n if (deletedIds.length) {\n updateCachedData((draft: any) => {\n if (!draft || !Array.isArray(draft.folders)) return\n draft.folders = draft.folders.filter((folder: any) => !deletedIds.includes(folder.id))\n })\n }\n\n // UPDATED: update cached folders with summary data from the message, if available\n if (summaryPatches.length) {\n updateCachedData((draft: any) => {\n if (!draft || !Array.isArray(draft.folders)) return\n summaryPatches.forEach(({ folderId, field, value }) => {\n const folder = draft.folders.find((item: any) => item.id === folderId)\n if (folder) folder[field] = value\n })\n })\n }\n\n // Fetch created and unsupported folders in one request.\n // This is to avoid overwhelming the API with too many requests at once, and to prevent potential performance issues in the frontend.\n const foldersToFetch = [\n ...new Set([...createdIds, ...unsupportedFields.keys()]),\n ]\n if (foldersToFetch.length > MAX_FOLDER_UPDATE_REST_CALLS) return\n\n if (foldersToFetch.length) {\n await waitForRealtimeJitter()\n const fetchedFolders = await dispatch(\n graphqlFolders.endpoints.GetUpdatedAndNewFolders.initiate({\n projectName,\n folderIds: foldersToFetch,\n first: foldersToFetch.length,\n }),\n )\n .unwrap()\n .catch(() => [])\n\n const createdFolderIds = new Set(createdIds)\n updateCachedData((draft: any) => {\n if (!draft || !Array.isArray(draft.folders)) return\n const fetchedById = new Map(\n fetchedFolders.filter(Boolean).map((folder: any) => [folder.id, folder] as const),\n )\n\n draft.folders.forEach((folder: any, index: number) => {\n const fetchedFolder = fetchedById.get(folder.id)\n if (!fetchedFolder) return\n\n if (createdFolderIds.has(folder.id)) {\n draft.folders[index] = { ...folder, ...fetchedFolder }\n } else {\n const fields = unsupportedFields.get(folder.id) || new Set<string>()\n fields.forEach((field) => {\n folder[field] = fetchedFolder[field]\n })\n }\n fetchedById.delete(folder.id)\n })\n\n fetchedById.forEach((folder, folderId) => {\n if (createdFolderIds.has(folderId)) draft.folders.push(folder)\n })\n })\n }\n }\n\n // create a batcher to process messages in batches\n const batcher = createRealtimeBatcher(\n batchProcessMessages,\n (message: any) => message.summary.entityId,\n )\n\n let unsubscribeThumbnails: (() => void) | undefined\n\n try {\n await cacheDataLoaded\n\n unsubscribeThumbnails = subscribeToThumbnailUpdates(\n (messages: ThumbnailUpdateMessage[]) => {\n updateCachedData((draft: any) => {\n if (!draft || !Array.isArray(draft.folders)) return\n messages.forEach((message) => {\n if (message.summary.entityType === 'folder' && message.summary.thumbnailHash) {\n const idx = draft.folders.findIndex(\n (f: any) => f.id === message.summary.entityId,\n )\n if (idx !== -1) {\n draft.folders[idx].thumbnailHash = message.summary.thumbnailHash\n }\n }\n })\n })\n },\n ['folder'],\n )\n\n const handlePubSub = (topic: string, message: any) => {\n const entityId = message?.summary?.entityId\n if (!entityId) return\n\n // add update to the batcher\n batcher.add({ ...message, topic })\n }\n\n topics.forEach((t) => tokens.push(PubSub.subscribe(t, handlePubSub)))\n } catch {\n // silent\n }\n\n await cacheEntryRemoved\n batcher.clear()\n tokens.forEach((t) => PubSub.unsubscribe(t))\n if (unsubscribeThumbnails) unsubscribeThumbnails()\n batcher.clear()\n },\n },\n },\n})\n\nexport const { useGetFolderHierarchyQuery, useGetFolderListQuery } = enhancedApi\nexport { enhancedApi as foldersQueries }\n"],"names":["graphqlFolders","gqlApi","response","node","parseAllAttribs","MAX_FOLDER_UPDATE_REST_CALLS","REALTIME_REST_CALL_LIMIT","enhancedApi","foldersApi","result","_e","projectName","id","args","cacheDataLoaded","cacheEntryRemoved","updateCachedData","getCacheEntry","dispatch","supportedFolderFields","topicFieldMap","topics","tokens","batcher","createRealtimeBatcher","messages","cachedFolderIds","cachedFolders","folder","deletedIds","createdIds","unsupportedFields","summaryPatches","message","folderId","patch","getSupportedEntityPatch","field","fields","draft","value","item","foldersToFetch","waitForRealtimeJitter","fetchedFolders","createdFolderIds","fetchedById","index","fetchedFolder","unsubscribeThumbnails","subscribeToThumbnailUpdates","idx","f","handlePubSub","topic","t","PubSub","useGetFolderHierarchyQuery","useGetFolderListQuery"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAMA,IAAiBC,EAAO,iBAA+C;AAAA,EAC3E,WAAW;AAAA,IACT,yBAAyB;AAAA,MACvB,mBAAmB,CAACC,MAClBA,EAAS,QAAQ,QAAQ,MAAM,IAAI,CAAC,EAAE,MAAAC,SAAY;AAAA,QAChD,GAAGA;AAAA,QACH,QAAQC,EAAgBD,EAAK,SAAS;AAAA,QACtC,MAAMA,EAAK,QAAQ;AAAA,QACnB,UAAUA,EAAK,YAAY;AAAA,QAC3B,OAAOA,EAAK,SAAS;AAAA,QACrB,WAAW,CAAA;AAAA,QACX,WAAW,OAAOA,EAAK,SAAS;AAAA,QAChC,WAAW,OAAOA,EAAK,SAAS;AAAA,MAAA,EAChC;AAAA,IAAA;AAAA,EACN;AAEJ,CAAC,GAIYE,IAA+BC,GAEtCC,IAAcC,EAAW,iBAAiB;AAAA,EAC9C,WAAW;AAAA,IACT,oBAAoB;AAAA,MAClB,cAAc,CAAC,WAAW;AAAA,IAAA;AAAA,IAE5B,eAAe;AAAA,MACb,cAAc,CAACC,GAAQC,GAAI,EAAE,aAAAC,QAAkB;AAAA,QAC7C;AAAA,QACA,EAAE,MAAM,UAAU,IAAI,OAAA;AAAA,QACtB,GAAIF,GAAQ,QAAQ,IAAI,CAAC,EAAE,IAAAG,EAAA,OAAU,EAAE,MAAM,UAAU,IAAAA,EAAA,EAAK,KAAK,CAAA;AAAA,QACjE,EAAE,MAAM,UAAU,IAAID,EAAA;AAAA,MAAY;AAAA,MAEpC,MAAM,kBACJE,GACA,EAAE,iBAAAC,GAAiB,mBAAAC,GAAmB,kBAAAC,GAAkB,eAAAC,GAAe,UAAAC,KACvE;AACA,cAAM,EAAE,aAAAP,MAAgBE,KAAQ,CAAA,GAC1BM,IAAwB,CAAC,UAAU,QAAQ,YAAY,GACvDC,IAAwC;AAAA,UAC5C,+BAA+B;AAAA,UAC/B,yBAAyB;AAAA,UACzB,8BAA8B;AAAA,UAC9B,gCAAgC;AAAA,UAChC,8BAA8B;AAAA,UAC9B,gCAAgC;AAAA,QAAA,GAG5BC,IAAS,CAAC,eAAe,GACzBC,IAAiC,CAAA,GAgIjCC,IAAUC;AAAA,UA7Ha,OAAOC,MAAoB;AACtD,gBAAI,CAACd,EAAa;AAElB,kBAAMe,wBAAsB,IAAA,GACtBC,IAAgBV,IAAgB;AACtC,YAAIU,KAAiB,MAAM,QAAQA,EAAc,OAAO,KACtDA,EAAc,QAAQ,QAAQ,CAACC,MAAgBF,EAAgB,IAAIE,EAAO,EAAE,CAAC;AAG/E,kBAAMC,IAAuB,CAAA,GACvBC,IAAuB,CAAA,GACvBC,wBAAwB,IAAA,GACxBC,IAIA,CAAA;AAGN,YAAAP,EAAS,QAAQ,CAACQ,MAAY;AAC5B,oBAAMC,IAAWD,EAAQ,SAAS;AAClC,kBAAI,CAACC,EAAU;AAGf,kBAAID,EAAQ,UAAU,yBAAyB;AAC7C,gBAAAJ,EAAW,KAAKK,CAAQ;AACxB;AAAA,cACF;AAGA,kBAAID,EAAQ,UAAU,yBAAyB;AAC7C,gBAAAH,EAAW,KAAKI,CAAQ;AACxB;AAAA,cACF;AAIA,kBAAI,CAACR,EAAgB,IAAIQ,CAAQ,EAAG;AAIpC,oBAAMC,IAAQC;AAAA,gBACZhB,EAAca,EAAQ,KAAK;AAAA,gBAC3BA,EAAQ;AAAA,gBACRd;AAAA,cAAA;AAEF,kBAAIgB,EAAO,CAAAH,EAAe,KAAK,EAAE,UAAAE,GAAU,GAAGC,GAAO;AAAA,mBAChD;AACH,sBAAME,IAAQjB,EAAca,EAAQ,KAAK;AACzC,oBAAI,CAACI,EAAO;AAEZ,sBAAMC,IAASP,EAAkB,IAAIG,CAAQ,yBAAS,IAAA;AACtD,gBAAAI,EAAO,IAAID,CAAK,GAChBN,EAAkB,IAAIG,GAAUI,CAAM;AAAA,cACxC;AAAA,YACF,CAAC,GAGGT,EAAW,UACbb,EAAiB,CAACuB,MAAe;AAC/B,cAAI,CAACA,KAAS,CAAC,MAAM,QAAQA,EAAM,OAAO,MAC1CA,EAAM,UAAUA,EAAM,QAAQ,OAAO,CAACX,MAAgB,CAACC,EAAW,SAASD,EAAO,EAAE,CAAC;AAAA,YACvF,CAAC,GAICI,EAAe,UACjBhB,EAAiB,CAACuB,MAAe;AAC/B,cAAI,CAACA,KAAS,CAAC,MAAM,QAAQA,EAAM,OAAO,KAC1CP,EAAe,QAAQ,CAAC,EAAE,UAAAE,GAAU,OAAAG,GAAO,OAAAG,QAAY;AACrD,sBAAMZ,IAASW,EAAM,QAAQ,KAAK,CAACE,MAAcA,EAAK,OAAOP,CAAQ;AACrE,gBAAIN,MAAQA,EAAOS,CAAK,IAAIG;AAAA,cAC9B,CAAC;AAAA,YACH,CAAC;AAKH,kBAAME,IAAiB;AAAA,cACrB,GAAG,oBAAI,IAAI,CAAC,GAAGZ,GAAY,GAAGC,EAAkB,MAAM,CAAC;AAAA,YAAA;AAEzD,gBAAI,EAAAW,EAAe,SAASrC,MAExBqC,EAAe,QAAQ;AACzB,oBAAMC,EAAA;AACN,oBAAMC,IAAiB,MAAM1B;AAAA,gBAC3BlB,EAAe,UAAU,wBAAwB,SAAS;AAAA,kBACxD,aAAAW;AAAA,kBACA,WAAW+B;AAAA,kBACX,OAAOA,EAAe;AAAA,gBAAA,CACvB;AAAA,cAAA,EAEA,OAAA,EACA,MAAM,MAAM,EAAE,GAEXG,IAAmB,IAAI,IAAIf,CAAU;AAC3C,cAAAd,EAAiB,CAACuB,MAAe;AAC/B,oBAAI,CAACA,KAAS,CAAC,MAAM,QAAQA,EAAM,OAAO,EAAG;AAC7C,sBAAMO,IAAc,IAAI;AAAA,kBACtBF,EAAe,OAAO,OAAO,EAAE,IAAI,CAAChB,MAAgB,CAACA,EAAO,IAAIA,CAAM,CAAU;AAAA,gBAAA;AAGlF,gBAAAW,EAAM,QAAQ,QAAQ,CAACX,GAAamB,MAAkB;AACpD,wBAAMC,IAAgBF,EAAY,IAAIlB,EAAO,EAAE;AAC/C,kBAAKoB,MAEDH,EAAiB,IAAIjB,EAAO,EAAE,IAChCW,EAAM,QAAQQ,CAAK,IAAI,EAAE,GAAGnB,GAAQ,GAAGoB,EAAA,KAExBjB,EAAkB,IAAIH,EAAO,EAAE,yBAAS,IAAA,GAChD,QAAQ,CAACS,MAAU;AACxB,oBAAAT,EAAOS,CAAK,IAAIW,EAAcX,CAAK;AAAA,kBACrC,CAAC,GAEHS,EAAY,OAAOlB,EAAO,EAAE;AAAA,gBAC9B,CAAC,GAEDkB,EAAY,QAAQ,CAAClB,GAAQM,MAAa;AACxC,kBAAIW,EAAiB,IAAIX,CAAQ,KAAGK,EAAM,QAAQ,KAAKX,CAAM;AAAA,gBAC/D,CAAC;AAAA,cACH,CAAC;AAAA,YACH;AAAA,UACF;AAAA,UAKE,CAACK,MAAiBA,EAAQ,QAAQ;AAAA,QAAA;AAGpC,YAAIgB;AAEJ,YAAI;AACF,gBAAMnC,GAENmC,IAAwBC;AAAA,YACtB,CAACzB,MAAuC;AACtC,cAAAT,EAAiB,CAACuB,MAAe;AAC/B,gBAAI,CAACA,KAAS,CAAC,MAAM,QAAQA,EAAM,OAAO,KAC1Cd,EAAS,QAAQ,CAACQ,MAAY;AAC5B,sBAAIA,EAAQ,QAAQ,eAAe,YAAYA,EAAQ,QAAQ,eAAe;AAC5E,0BAAMkB,IAAMZ,EAAM,QAAQ;AAAA,sBACxB,CAACa,MAAWA,EAAE,OAAOnB,EAAQ,QAAQ;AAAA,oBAAA;AAEvC,oBAAIkB,MAAQ,OACVZ,EAAM,QAAQY,CAAG,EAAE,gBAAgBlB,EAAQ,QAAQ;AAAA,kBAEvD;AAAA,gBACF,CAAC;AAAA,cACH,CAAC;AAAA,YACH;AAAA,YACA,CAAC,QAAQ;AAAA,UAAA;AAGX,gBAAMoB,IAAe,CAACC,GAAerB,MAAiB;AAEpD,YADiBA,GAAS,SAAS,YAInCV,EAAQ,IAAI,EAAE,GAAGU,GAAS,OAAAqB,GAAO;AAAA,UACnC;AAEA,UAAAjC,EAAO,QAAQ,CAACkC,MAAMjC,EAAO,KAAKkC,EAAO,UAAUD,GAAGF,CAAY,CAAC,CAAC;AAAA,QACtE,QAAQ;AAAA,QAER;AAEA,cAAMtC,GACNQ,EAAQ,MAAA,GACRD,EAAO,QAAQ,CAACiC,MAAMC,EAAO,YAAYD,CAAC,CAAC,GACvCN,KAAuBA,EAAA,GAC3B1B,EAAQ,MAAA;AAAA,MACV;AAAA,IAAA;AAAA,EACF;AAEJ,CAAC,GAEY,EAAE,4BAAAkC,IAA4B,uBAAAC,OAA0BnD;"}
|
|
1
|
+
{"version":3,"file":"getFolders.es.js","sources":["../../../../../../src/api/queries/folders/getFolders.ts"],"sourcesContent":["import {\n FolderListItem,\n foldersApi,\n GetUpdatedAndNewFoldersQuery,\n gqlApi,\n} from '@shared/api/generated'\nimport {\n getSupportedEntityPatch,\n createRealtimeBatcher,\n REALTIME_REST_CALL_LIMIT,\n waitForRealtimeJitter,\n PubSub,\n subscribeToThumbnailUpdates,\n ThumbnailUpdateMessage,\n SupportedEntityPatchField,\n} from '@shared/util'\n\nimport { DefinitionsFromApi, OverrideResultType, TagTypesFromApi } from '@reduxjs/toolkit/query'\nimport { parseJSONField } from '../overview'\n\ntype GetUpdatedAndNewFoldersResult = FolderListItem[]\n\n// HELPER QUERIES FOR REALTIME UPDATES\ntype Definitions = DefinitionsFromApi<typeof gqlApi>\ntype TagTypes = TagTypesFromApi<typeof gqlApi>\n// update the definitions to include the new types\ntype UpdatedDefinitions = Omit<Definitions, 'GetUpdatedAndNewFolders'> & {\n GetUpdatedAndNewFolders: OverrideResultType<\n Definitions['GetUpdatedAndNewFolders'],\n GetUpdatedAndNewFoldersResult\n >\n}\n\nconst graphqlFolders = gqlApi.enhanceEndpoints<TagTypes, UpdatedDefinitions>({\n endpoints: {\n GetUpdatedAndNewFolders: {\n transformResponse: (response: GetUpdatedAndNewFoldersQuery): GetUpdatedAndNewFoldersResult =>\n response.project.folders.edges.map(({ node }) => ({\n ...node,\n attrib: parseJSONField(node.allAttrib),\n path: node.path ?? '',\n parentId: node.parentId ?? undefined,\n label: node.label ?? undefined,\n taskNames: [],\n createdAt: String(node.createdAt),\n updatedAt: String(node.updatedAt),\n })),\n },\n },\n})\n\n// the max number of folder to process in a single batch\n// TODO: Use this limit to trigger the reload button\nexport const MAX_FOLDER_UPDATE_REST_CALLS = REALTIME_REST_CALL_LIMIT\n\nconst enhancedApi = foldersApi.enhanceEndpoints({\n endpoints: {\n getFolderHierarchy: {\n providesTags: ['hierarchy'],\n },\n getFolderList: {\n providesTags: (result, _e, { projectName }) => [\n 'hierarchy',\n { type: 'folder', id: 'LIST' },\n ...(result?.folders.map(({ id }) => ({ type: 'folder', id })) || []),\n { type: 'folder', id: projectName },\n ],\n async onCacheEntryAdded(\n args,\n { cacheDataLoaded, cacheEntryRemoved, updateCachedData, getCacheEntry, dispatch },\n ) {\n const { projectName } = args || {}\n const supportedFolderFields = ['status', 'tags', 'folderType']\n const topicFieldMap: Record<string, string> = {\n 'entity.folder.label_changed': 'label',\n 'entity.folder.renamed': 'name',\n 'entity.folder.type_changed': 'folderType',\n 'entity.folder.status_changed': 'status',\n 'entity.folder.tags_changed': 'tags',\n 'entity.folder.attrib_changed': 'attrib',\n }\n\n const topics = ['entity.folder']\n const tokens: (string | undefined)[] = []\n\n // handle a batch of messages, updating the cache and fetching missing data as needed\n const batchProcessMessages = async (messages: any[]) => {\n if (!projectName) return\n\n const cachedFolderIds = new Set<string>()\n const cachedFolders = getCacheEntry().data\n if (cachedFolders && Array.isArray(cachedFolders.folders)) {\n cachedFolders.folders.forEach((folder: any) => cachedFolderIds.add(folder.id))\n }\n\n const deletedIds: string[] = []\n const createdIds: string[] = []\n const unsupportedFields = new Map<string, Set<string>>()\n const summaryPatches: {\n folderId: string\n field: SupportedEntityPatchField\n value: string | string[]\n }[] = []\n\n // for each message, check it's type and then add it to the appropriate list for processing\n messages.forEach((message) => {\n const folderId = message.summary?.entityId\n if (!folderId) return\n\n // delete: remove from cache - no additional API calls\n if (message.topic === 'entity.folder.deleted') {\n deletedIds.push(folderId)\n return\n }\n\n // create: add to cache - will fetch the full folder data later\n if (message.topic === 'entity.folder.created') {\n createdIds.push(folderId)\n return\n }\n\n // for updates, check if the folder is in the cache\n // no point updating a folder that does not exist for the user\n if (!cachedFolderIds.has(folderId)) return\n\n // check if the updated field data is in the summary (status, tags etc)\n // if it is, we can update the cache directly, otherwise we will need to fetch the full folder data later\n const patch = getSupportedEntityPatch(\n topicFieldMap[message.topic],\n message.summary,\n supportedFolderFields,\n )\n if (patch) summaryPatches.push({ folderId, ...patch })\n else {\n const field = topicFieldMap[message.topic]\n if (!field) return\n\n const fields = unsupportedFields.get(folderId) || new Set<string>()\n fields.add(field)\n unsupportedFields.set(folderId, fields)\n }\n })\n\n // DELETED: remove deleted folders from cache\n if (deletedIds.length) {\n updateCachedData((draft: any) => {\n if (!draft || !Array.isArray(draft.folders)) return\n draft.folders = draft.folders.filter((folder: any) => !deletedIds.includes(folder.id))\n })\n }\n\n // UPDATED: update cached folders with summary data from the message, if available\n if (summaryPatches.length) {\n updateCachedData((draft: any) => {\n if (!draft || !Array.isArray(draft.folders)) return\n summaryPatches.forEach(({ folderId, field, value }) => {\n const folder = draft.folders.find((item: any) => item.id === folderId)\n if (folder) folder[field] = value\n })\n })\n }\n\n // Fetch created and unsupported folders in one request.\n // This is to avoid overwhelming the API with too many requests at once, and to prevent potential performance issues in the frontend.\n const foldersToFetch = [...new Set([...createdIds, ...unsupportedFields.keys()])]\n if (foldersToFetch.length > MAX_FOLDER_UPDATE_REST_CALLS) return\n\n if (foldersToFetch.length) {\n await waitForRealtimeJitter()\n const fetchedFolders = await dispatch(\n graphqlFolders.endpoints.GetUpdatedAndNewFolders.initiate({\n projectName,\n folderIds: foldersToFetch,\n first: foldersToFetch.length,\n }),\n )\n .unwrap()\n .catch(() => [])\n\n const createdFolderIds = new Set(createdIds)\n updateCachedData((draft: any) => {\n if (!draft || !Array.isArray(draft.folders)) return\n const fetchedById = new Map(\n fetchedFolders.filter(Boolean).map((folder: any) => [folder.id, folder] as const),\n )\n\n draft.folders.forEach((folder: any, index: number) => {\n const fetchedFolder = fetchedById.get(folder.id)\n if (!fetchedFolder) return\n\n if (createdFolderIds.has(folder.id)) {\n draft.folders[index] = { ...folder, ...fetchedFolder }\n } else {\n const fields = unsupportedFields.get(folder.id) || new Set<string>()\n fields.forEach((field) => {\n folder[field] = fetchedFolder[field]\n })\n }\n fetchedById.delete(folder.id)\n })\n\n fetchedById.forEach((folder, folderId) => {\n if (createdFolderIds.has(folderId)) draft.folders.push(folder)\n })\n })\n }\n }\n\n // create a batcher to process messages in batches\n const batcher = createRealtimeBatcher(\n batchProcessMessages,\n (message: any) => message.summary.entityId,\n )\n\n let unsubscribeThumbnails: (() => void) | undefined\n\n try {\n await cacheDataLoaded\n\n unsubscribeThumbnails = subscribeToThumbnailUpdates(\n (messages: ThumbnailUpdateMessage[]) => {\n updateCachedData((draft: any) => {\n if (!draft || !Array.isArray(draft.folders)) return\n messages.forEach((message) => {\n if (message.summary.entityType === 'folder' && message.summary.thumbnailHash) {\n const idx = draft.folders.findIndex(\n (f: any) => f.id === message.summary.entityId,\n )\n if (idx !== -1) {\n draft.folders[idx].thumbnailHash = message.summary.thumbnailHash\n }\n }\n })\n })\n },\n ['folder'],\n )\n\n const handlePubSub = (topic: string, message: any) => {\n const entityId = message?.summary?.entityId\n if (!entityId) return\n\n // add update to the batcher\n batcher.add({ ...message, topic })\n }\n\n topics.forEach((t) => tokens.push(PubSub.subscribe(t, handlePubSub)))\n } catch {\n // silent\n }\n\n await cacheEntryRemoved\n batcher.clear()\n tokens.forEach((t) => PubSub.unsubscribe(t))\n if (unsubscribeThumbnails) unsubscribeThumbnails()\n batcher.clear()\n },\n },\n },\n})\n\nexport const { useGetFolderHierarchyQuery, useGetFolderListQuery } = enhancedApi\nexport { enhancedApi as foldersQueries }\n"],"names":["graphqlFolders","gqlApi","response","node","parseJSONField","MAX_FOLDER_UPDATE_REST_CALLS","REALTIME_REST_CALL_LIMIT","enhancedApi","foldersApi","result","_e","projectName","id","args","cacheDataLoaded","cacheEntryRemoved","updateCachedData","getCacheEntry","dispatch","supportedFolderFields","topicFieldMap","topics","tokens","batcher","createRealtimeBatcher","messages","cachedFolderIds","cachedFolders","folder","deletedIds","createdIds","unsupportedFields","summaryPatches","message","folderId","patch","getSupportedEntityPatch","field","fields","draft","value","item","foldersToFetch","waitForRealtimeJitter","fetchedFolders","createdFolderIds","fetchedById","index","fetchedFolder","unsubscribeThumbnails","subscribeToThumbnailUpdates","idx","f","handlePubSub","topic","t","PubSub","useGetFolderHierarchyQuery","useGetFolderListQuery"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("../../base/client.cjs.js");const K=require("../../generated/graphql.cjs.js");require("../../generated/graphqlLinks.cjs.js");require("../../generated/access.cjs.js");require("../../generated/actions.cjs.js");require("../../generated/activityFeed.cjs.js");require("../../generated/addons.cjs.js");require("../../generated/anatomy.cjs.js");require("../../generated/attributes.cjs.js");require("../../generated/authentication.cjs.js");require("../../generated/bundles.cjs.js");require("../../generated/configuration.cjs.js");require("../../generated/dataImport.cjs.js");require("../../generated/desktop.cjs.js");require("../../generated/entityLists.cjs.js");require("../../generated/events.cjs.js");require("../../generated/files.cjs.js");const X=require("../../generated/folders.cjs.js");require("../../generated/inbox.cjs.js");require("../../generated/links.cjs.js");require("../../generated/market.cjs.js");require("../../generated/onboarding.cjs.js");require("../../generated/operations.cjs.js");require("../../generated/products.cjs.js");require("../../generated/projectDashboard.cjs.js");require("../../generated/projects.cjs.js");require("../../generated/projectFolders.cjs.js");require("../../generated/reviewables.cjs.js");require("../../generated/services.cjs.js");require("../../generated/system.cjs.js");require("../../generated/tasks.cjs.js");require("../../generated/teams.cjs.js");require("../../generated/thumbnails.cjs.js");require("../../generated/uRIs.cjs.js");require("../../generated/users.cjs.js");require("../../generated/versions.cjs.js");require("../../generated/workfiles.cjs.js");require("../../generated/ynputCloud.cjs.js");require("../../generated/grouping.cjs.js");require("../../generated/views.cjs.js");const N=require("../../../util/pubsub.cjs.js");require("lodash");require("react-toastify");require("uuid");const H=require("../../../util/thumbnailWebsocket.cjs.js");require("../actions/getActions.cjs.js");require("../activities/getActivities.cjs.js");require("../activities/updateReaction.cjs.js");require("../activities/getMentions.cjs.js");require("../activities/getCategories.cjs.js");require("../addons/getAddons.cjs.js");require("../addons/updateAddons.cjs.js");require("../attributes/getAttributes.cjs.js");require("../attributes/updateAttributes.cjs.js");require("../authentication/getAuthentication.cjs.js");require("../bundles/getBundles.cjs.js");require("../bundles/updateBundles.cjs.js");require("../cloud/cloud.cjs.js");const A=require("../columnStats/columnStats.cjs.js"),U=require("../columnStats/metricTargets.cjs.js");require("../columnStats/groupCounts.cjs.js");require("../config/getConfig.cjs.js");require("../config/updateConfig.cjs.js");require("../entities/getEntity.cjs.js");require("../entities/getEntityPanel.cjs.js");require("./updateOverview.cjs.js");require("../versions/getVersionsProducts.cjs.js");require("../links/getEntityLinks.cjs.js");require("../entities/updateEntity.cjs.js");require("../entityLists/getLists.cjs.js");require("../entityLists/updateLists.cjs.js");require("../entityLists/getListsAttributes.cjs.js");require("../entityLists/listItemsColumnStats.cjs.js");require("../entityLists/updateListsAttributes.cjs.js");require("../entityLists/listFolders.cjs.js");require("../folders/getFolders.cjs.js");require("../folders/getFolderDeleteInfo.cjs.js");require("../grouping/getGrouping.cjs.js");require("../links/updateLinks.cjs.js");require("../links/getLinks.cjs.js");require("../permissions/getPermissions.cjs.js");require("../products/createProduct.cjs.js");require("../products/getFolderProducts.cjs.js");require("../project/getProject.cjs.js");require("../project/updateProject.cjs.js");require("../projectFolders/projectFolders.cjs.js");require("../review/getReview.cjs.js");require("../review/updateReview.cjs.js");require("../share/share.cjs.js");require("../system/getSystem.cjs.js");require("../tasks/getTasks.cjs.js");require("../tasks/updateTasks.cjs.js");require("../teams/getTeams.cjs.js");require("../userDashboard/getUserDashboard.cjs.js");require("../users/getUsers.cjs.js");require("../users/updateUsers.cjs.js");require("../users/guests.cjs.js");require("../versions/updateVersions.cjs.js");require("../views/getViews.cjs.js");require("../views/updateViews.cjs.js");require("../watchers/getWatchers.cjs.js");require("../uris/getUris.cjs.js");const C=10,D=r=>{try{return JSON.parse(r)}catch{return{}}},z=r=>{if(!r.project)return[];const e=[];for(const{node:s}of r.project.tasks.edges)e.push({...s,folderId:s.folderId||"root",attrib:D(s.allAttrib),entityId:s.id,entityType:"task",links:[]});return e},P=(r=[],e,s)=>{const i=r?.map(c=>({type:"overviewTask",id:c.id}))||[],a=s?(Array.isArray(s)?s:[s]).map(c=>({type:"overviewTask",id:c})):[];return[...i,...a,{type:"overviewTask",id:e},{type:"overviewTask",id:"LIST"}]},_=K.api.enhanceEndpoints({endpoints:{GetTasksByParent:{transformResponse:r=>({pageInfo:r?.project?.tasks?.pageInfo??{hasNextPage:!1,endCursor:null},tasks:z(r)}),providesTags:(r,e,{parentIds:s,projectName:i})=>P(r?.tasks||[],i,s),keepUnusedDataFor:C},GetTasksList:{transformResponse:r=>({tasks:z(r),pageInfo:r.project.tasks.pageInfo}),providesTags:(r,e,{projectName:s})=>P(r?.tasks||[],s),keepUnusedDataFor:C},GetFolderColumnStats:{transformResponse:r=>A.normalizeFieldStats(r?.project?.folders?.fieldStats??[]),transformErrorResponse:r=>A.transformStatsError(r,"folder"),serializeQueryArgs:({queryArgs:{targets:r,...e}})=>e,merge:(r,e)=>A.mergeFieldStats(e,r),forceRefetch:({currentArg:r,previousArg:e})=>U.hasNewTargetFields(r,e),providesTags:(r,e,{projectName:s})=>[{type:"folderColumnStats",id:s}],keepUnusedDataFor:C},GetTaskColumnStats:{transformResponse:r=>A.normalizeFieldStats(r?.project?.tasks?.fieldStats??[]),transformErrorResponse:r=>A.transformStatsError(r,"task"),serializeQueryArgs:({queryArgs:{targets:r,...e}})=>e,merge:(r,e)=>A.mergeFieldStats(e,r),forceRefetch:({currentArg:r,previousArg:e})=>U.hasNewTargetFields(r,e),providesTags:(r,e,{projectName:s})=>[{type:"taskColumnStats",id:s}],keepUnusedDataFor:C}}}),V=X.api.enhanceEndpoints({endpoints:{searchFolders:{}}}),x=100,R={},j=(r,e,s,i,a)=>JSON.stringify({projectName:r,filter:e,folderFilter:s,search:i,showComments:a}),$=(r,e)=>{R[r]||(R[r]=new Set),e.forEach(s=>R[r].add(s))},Y=r=>R[r]||new Set,O=_.injectEndpoints({endpoints:r=>({getOverviewTasksByFolders:r.query({async queryFn({projectName:e,parentIds:s,filter:i,folderFilter:a,search:c,showComments:T},{dispatch:I,getState:w,forced:b}){try{const g=w(),k={projectName:e,filter:i,folderFilter:a,search:c,showComments:T},S=O.endpoints.getOverviewTasksByFolders.select(k)(g)?.data||[],q=j(e,i,a,c,T),t=Y(q),o=b?s:s.filter(n=>!t.has(n));if(o.length===0)return{data:S};const l=[],u=100,p=20,d=10,f=1e3,y=u*p;if(o.length>f)throw new Error(`Exceeded maximum folders count limit ${f} (${o.length}). Please reduce the number of expanded folders.`);for(let n=0;n<o.length;n+=u){const v=o.slice(n,n+u);let E=!0,L,G=0;for(;E&&G<d;){if(G++,G===d)throw new Error(`Exceeded maximum tasks count limit ${d*y}.`);const Q=await I(_.endpoints.GetTasksByParent.initiate({projectName:e,parentIds:v,filter:i,folderFilter:a,search:c,showComments:!!T,first:y,after:L},{forceRefetch:!0}));if(Q.error)throw Q.error;const M=Q.data,J=M?.tasks||[];l.push(...J);const B=M?.pageInfo;E=B?.hasNextPage||!1,L=B?.endCursor||void 0}}$(q,o);const m=[...S,...l],h=new Map(m.map(n=>[n.id,n]));return{data:Array.from(h.values())}}catch(g){return console.error(g),{error:{status:"FETCH_ERROR",error:g.message||g.data?.message||JSON.stringify(g)||"Unknown Fetch Error"}}}},serializeQueryArgs:({queryArgs:{parentIds:e,...s}})=>({...s}),forceRefetch({currentArg:e,previousArg:s}){return JSON.stringify(e)!==JSON.stringify(s)},providesTags:(e,s,{parentIds:i,projectName:a})=>P(e,a,i),async onCacheEntryAdded({projectName:e,parentIds:s,filter:i,folderFilter:a,search:c,showComments:T},{cacheDataLoaded:I,cacheEntryRemoved:w,updateCachedData:b,dispatch:g}){let k;const F=new Set,S=100,q=500;let t=!1;const o=()=>{t||(t=!0,setTimeout(l,q))},l=async()=>{if(t=!1,!F.size)return;const d=Array.from(F).slice(0,S);d.forEach(f=>F.delete(f));try{const y=(await g(_.endpoints.GetTasksList.initiate({projectName:e,taskIds:d,showComments:!!T},{forceRefetch:!0})).unwrap()).tasks||[],m=new Map(y.map(h=>[h.id,h]));b(h=>{for(const n of y){const v=h.findIndex(E=>E.id===n.id);v>-1?h[v]=n:h.push(n)}for(const n of d)if(!m.has(n)){const v=h.findIndex(E=>E.id===n);v>-1&&h.splice(v,1)}})}catch(f){console.error("Realtime overview batch update failed",f)}finally{F.size&&o()}};let u;try{await I,u=H.subscribeToThumbnailUpdates(f=>{b(y=>{f.forEach(m=>{if(m.summary.entityType==="task"&&m.summary.thumbnailHash){const h=y.findIndex(n=>n.id===m.summary.entityId);h>-1&&(y[h].thumbnailHash=m.summary.thumbnailHash)}})})},["task"]);const d=async(f,y)=>{const m=y?.summary?.entityId,h=y?.summary?.parentId;!m||!h||s.includes(h)&&(F.add(m),o())};k=N.subscribe("entity.task",d)}catch{}await w;const p=j(e,i,a,c,T);delete R[p],k&&N.unsubscribe(k),u&&u()},keepUnusedDataFor:C}),getSearchFolders:r.query({async queryFn({projectName:e,folderSearchRequest:s},{dispatch:i}){try{return{data:(await i(V.endpoints.searchFolders.initiate({projectName:e,folderSearchRequest:s}))).data?.folderIds||[]}}catch(a){return console.error(a),{error:{status:"FETCH_ERROR",error:a.message}}}},providesTags:(e,s,{projectName:i})=>[{type:"tasksFolder",id:i}],keepUnusedDataFor:C}),getTasksListInfinite:r.infiniteQuery({infiniteQueryOptions:{initialPageParam:{cursor:"",desc:!1},getNextPageParam:(e,s,i,a)=>{const c=e.pageInfo;if(!(!(i.desc?c.hasPreviousPage:c.hasNextPage)||!c.endCursor))return{cursor:c.endCursor,desc:i.desc}}},queryFn:async({queryArg:e,pageParam:s},i)=>{try{const{projectName:a,filter:c,folderFilter:T,search:I,folderIds:w,taskIds:b,sortBy:g,desc:k,showComments:F,includeFolderChildren:S}=e,{cursor:q}=s,t={projectName:a,filter:c,folderFilter:T,search:I,folderIds:w,taskIds:b,showComments:!!F,includeFolderChildren:S!==!1};g?(t.sortBy=g,k?(t.before=q||void 0,t.last=x):(t.after=q||void 0,t.first=x)):(t.after=q||void 0,t.first=x);const o=await i.dispatch(_.endpoints.GetTasksList.initiate(t,{forceRefetch:!0}));if(o.error)throw o.error;const l={tasks:[],pageInfo:{hasNextPage:!1,endCursor:null,startCursor:null,hasPreviousPage:!1}};return{data:o.data||l}}catch(a){return console.error("Error in getTasksListInfinite queryFn:",a),{error:{status:"FETCH_ERROR",error:a.message}}}},providesTags:(e,s,{projectName:i})=>P(e?.pages.flatMap(a=>a.tasks)||[],i),async onCacheEntryAdded(e,{cacheDataLoaded:s,cacheEntryRemoved:i,updateCachedData:a,dispatch:c}){let T;const I=new Set,w=100,b=500;let g=!1;const k=()=>{g||(g=!0,setTimeout(F,b))},F=async()=>{if(g=!1,!I.size)return;const q=Array.from(I).slice(0,w);q.forEach(t=>I.delete(t));try{const o=(await c(_.endpoints.GetTasksList.initiate({projectName:e.projectName,taskIds:q,folderIds:e.folderIds,showComments:!!e.showComments},{forceRefetch:!0})).unwrap()).tasks||[],l=new Map(o.map(u=>[u.id,u]));a(u=>{for(const p of o){let d=!1;for(const f of u.pages){const y=f.tasks.findIndex(m=>m.id===p.id);if(y!==-1){f.tasks[y]=p,d=!0;break}}d||(u.pages.length?u.pages[0].tasks.unshift(p):u.pages.push({tasks:[p],pageInfo:{startCursor:null,endCursor:null,hasNextPage:!1,hasPreviousPage:!1}}))}for(const p of q)if(!l.has(p))for(const d of u.pages){const f=d.tasks.findIndex(y=>y.id===p);if(f!==-1){d.tasks.splice(f,1);break}}})}catch(t){console.error("Realtime infinite tasks batch update failed",t)}finally{I.size&&k()}};let S;try{await s,S=H.subscribeToThumbnailUpdates(t=>{a(o=>{t.forEach(l=>{if(l.summary.entityType==="task"&&l.summary.thumbnailHash)for(const u of o.pages){const p=u.tasks.findIndex(d=>d.id===l.summary.entityId);if(p>-1){u.tasks[p].thumbnailHash=l.summary.thumbnailHash;break}}})})},["task"]);const q=async(t,o)=>{const l=o?.summary?.entityId;l&&(I.add(l),k())};T=N.subscribe("entity.task",q)}catch{}await i,T&&N.unsubscribe(T),S&&S()},keepUnusedDataFor:C}),getGroupedTasksList:r.query({queryFn:async({projectName:e,groups:s,search:i,folderFilter:a,folderIds:c,desc:T,sortBy:I,groupCount:w,showComments:b},g)=>{try{let k=[];const F=new Set(["folderType"]);for(const t of s){const o=w||t.count||500;let l=t.filter,u=a;if(t.filter)try{const f=JSON.parse(t.filter),y=f.conditions||[],m=y.filter(n=>!F.has(n.key)),h=y.filter(n=>F.has(n.key));if(h.length>0){l=m.length?JSON.stringify({...f,conditions:m}):void 0;const n=a?JSON.parse(a):null,E=[...n&&Array.isArray(n.conditions)?n.conditions:[],...h];u=JSON.stringify(n?{...n,conditions:E}:{conditions:E})}}catch{}const p={projectName:e,filter:l,folderFilter:u,search:i,folderIds:c,sortBy:I,showComments:!!b,group:t.value};T?p.last=o:p.first=o;const d=g.dispatch(_.endpoints.GetTasksList.initiate(p,{forceRefetch:!0}));k.push(d)}const S=await Promise.all(k),q=[];for(const t of S){if(t.error)throw t.error;const o=t.originalArgs?.group,l=t.data?.pageInfo?.hasNextPage||t.data?.pageInfo?.hasPreviousPage||!1,u=t.data?.tasks.map((p,d,f)=>({...p,groups:[{value:o,hasNextPage:d===f.length-1&&l?o:void 0}]}))||[];q.push(...u)}return{data:{tasks:q}}}catch(k){return console.error("Error in getGroupedTasksList queryFn:",k),{error:{status:"FETCH_ERROR",error:k.message}}}},providesTags:(e,s,{projectName:i})=>P(e?.tasks,i),keepUnusedDataFor:C})})}),{useGetOverviewTasksByFoldersQuery:W,useGetSearchFoldersQuery:Z,useGetTasksListQuery:ee,useGetTasksListInfiniteInfiniteQuery:re,useLazyGetTasksByParentQuery:se,useGetGroupedTasksListQuery:te,useGetFolderColumnStatsQuery:ie,useGetTaskColumnStatsQuery:ae}=O;exports.TASKS_INFINITE_QUERY_COUNT=x;exports.default=O;exports.parseAllAttribs=D;exports.useGetFolderColumnStatsQuery=ie;exports.useGetGroupedTasksListQuery=te;exports.useGetOverviewTasksByFoldersQuery=W;exports.useGetSearchFoldersQuery=Z;exports.useGetTaskColumnStatsQuery=ae;exports.useGetTasksListInfiniteInfiniteQuery=re;exports.useGetTasksListQuery=ee;exports.useLazyGetTasksByParentQuery=se;
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});require("../../base/client.cjs.js");const K=require("../../generated/graphql.cjs.js");require("../../generated/graphqlLinks.cjs.js");require("../../generated/access.cjs.js");require("../../generated/actions.cjs.js");require("../../generated/activityFeed.cjs.js");require("../../generated/addons.cjs.js");require("../../generated/anatomy.cjs.js");require("../../generated/attributes.cjs.js");require("../../generated/authentication.cjs.js");require("../../generated/bundles.cjs.js");require("../../generated/configuration.cjs.js");require("../../generated/dataImport.cjs.js");require("../../generated/desktop.cjs.js");require("../../generated/entityLists.cjs.js");require("../../generated/events.cjs.js");require("../../generated/files.cjs.js");const X=require("../../generated/folders.cjs.js");require("../../generated/inbox.cjs.js");require("../../generated/links.cjs.js");require("../../generated/market.cjs.js");require("../../generated/onboarding.cjs.js");require("../../generated/operations.cjs.js");require("../../generated/products.cjs.js");require("../../generated/projectDashboard.cjs.js");require("../../generated/projects.cjs.js");require("../../generated/projectFolders.cjs.js");require("../../generated/reviewables.cjs.js");require("../../generated/services.cjs.js");require("../../generated/system.cjs.js");require("../../generated/tasks.cjs.js");require("../../generated/teams.cjs.js");require("../../generated/thumbnails.cjs.js");require("../../generated/uRIs.cjs.js");require("../../generated/users.cjs.js");require("../../generated/versions.cjs.js");require("../../generated/workfiles.cjs.js");require("../../generated/ynputCloud.cjs.js");require("../../generated/grouping.cjs.js");require("../../generated/views.cjs.js");const N=require("../../../util/pubsub.cjs.js");require("lodash");require("react-toastify");require("uuid");const U=require("../../../util/thumbnailWebsocket.cjs.js");require("../actions/getActions.cjs.js");require("../activities/getActivities.cjs.js");require("../activities/updateReaction.cjs.js");require("../activities/getMentions.cjs.js");require("../activities/getCategories.cjs.js");require("../addons/getAddons.cjs.js");require("../addons/updateAddons.cjs.js");require("../attributes/getAttributes.cjs.js");require("../attributes/updateAttributes.cjs.js");require("../authentication/getAuthentication.cjs.js");require("../bundles/getBundles.cjs.js");require("../bundles/updateBundles.cjs.js");require("../cloud/cloud.cjs.js");const A=require("../columnStats/columnStats.cjs.js"),z=require("../columnStats/metricTargets.cjs.js");require("../columnStats/groupCounts.cjs.js");require("../config/getConfig.cjs.js");require("../config/updateConfig.cjs.js");require("../entities/getEntity.cjs.js");require("../entities/getEntityPanel.cjs.js");require("./updateOverview.cjs.js");require("../versions/getVersionsProducts.cjs.js");require("../links/getEntityLinks.cjs.js");require("../entities/updateEntity.cjs.js");require("../entityLists/getLists.cjs.js");require("../entityLists/updateLists.cjs.js");require("../entityLists/getListsAttributes.cjs.js");require("../entityLists/listItemsColumnStats.cjs.js");require("../entityLists/updateListsAttributes.cjs.js");require("../entityLists/listFolders.cjs.js");require("../folders/getFolders.cjs.js");require("../folders/getFolderDeleteInfo.cjs.js");require("../grouping/getGrouping.cjs.js");require("../links/updateLinks.cjs.js");require("../links/getLinks.cjs.js");require("../permissions/getPermissions.cjs.js");require("../products/createProduct.cjs.js");require("../products/getFolderProducts.cjs.js");require("../project/getProject.cjs.js");require("../project/updateProject.cjs.js");require("../projectFolders/projectFolders.cjs.js");require("../review/getReview.cjs.js");require("../review/updateReview.cjs.js");require("../share/share.cjs.js");require("../system/getSystem.cjs.js");require("../tasks/getTasks.cjs.js");require("../tasks/updateTasks.cjs.js");require("../teams/getTeams.cjs.js");require("../userDashboard/getUserDashboard.cjs.js");require("../users/getUsers.cjs.js");require("../users/updateUsers.cjs.js");require("../users/guests.cjs.js");require("../versions/updateVersions.cjs.js");require("../views/getViews.cjs.js");require("../views/updateViews.cjs.js");require("../watchers/getWatchers.cjs.js");require("../uris/getUris.cjs.js");const C=10,G=r=>{if(!r)return{};try{return JSON.parse(r)}catch{return{}}},V=G,J=r=>{if(!r.project)return[];const e=[];for(const{node:s}of r.project.tasks.edges)e.push({...s,folderId:s.folderId||"root",attrib:G(s.allAttrib),data:G(s.data),entityId:s.id,entityType:"task",links:[]});return e},P=(r=[],e,s)=>{const i=r?.map(c=>({type:"overviewTask",id:c.id}))||[],a=s?(Array.isArray(s)?s:[s]).map(c=>({type:"overviewTask",id:c})):[];return[...i,...a,{type:"overviewTask",id:e},{type:"overviewTask",id:"LIST"}]},_=K.api.enhanceEndpoints({endpoints:{GetTasksByParent:{transformResponse:r=>({pageInfo:r?.project?.tasks?.pageInfo??{hasNextPage:!1,endCursor:null},tasks:J(r)}),providesTags:(r,e,{parentIds:s,projectName:i})=>P(r?.tasks||[],i,s),keepUnusedDataFor:C},GetTasksList:{transformResponse:r=>({tasks:J(r),pageInfo:r.project.tasks.pageInfo}),providesTags:(r,e,{projectName:s})=>P(r?.tasks||[],s),keepUnusedDataFor:C},GetFolderColumnStats:{transformResponse:r=>A.normalizeFieldStats(r?.project?.folders?.fieldStats??[]),transformErrorResponse:r=>A.transformStatsError(r,"folder"),serializeQueryArgs:({queryArgs:{targets:r,...e}})=>e,merge:(r,e)=>A.mergeFieldStats(e,r),forceRefetch:({currentArg:r,previousArg:e})=>z.hasNewTargetFields(r,e),providesTags:(r,e,{projectName:s})=>[{type:"folderColumnStats",id:s}],keepUnusedDataFor:C},GetTaskColumnStats:{transformResponse:r=>A.normalizeFieldStats(r?.project?.tasks?.fieldStats??[]),transformErrorResponse:r=>A.transformStatsError(r,"task"),serializeQueryArgs:({queryArgs:{targets:r,...e}})=>e,merge:(r,e)=>A.mergeFieldStats(e,r),forceRefetch:({currentArg:r,previousArg:e})=>z.hasNewTargetFields(r,e),providesTags:(r,e,{projectName:s})=>[{type:"taskColumnStats",id:s}],keepUnusedDataFor:C}}}),$=X.api.enhanceEndpoints({endpoints:{searchFolders:{}}}),x=100,R={},j=(r,e,s,i,a)=>JSON.stringify({projectName:r,filter:e,folderFilter:s,search:i,showComments:a}),Y=(r,e)=>{R[r]||(R[r]=new Set),e.forEach(s=>R[r].add(s))},W=r=>R[r]||new Set,L=_.injectEndpoints({endpoints:r=>({getOverviewTasksByFolders:r.query({async queryFn({projectName:e,parentIds:s,filter:i,folderFilter:a,search:c,showComments:T},{dispatch:F,getState:w,forced:b}){try{const g=w(),k={projectName:e,filter:i,folderFilter:a,search:c,showComments:T},S=L.endpoints.getOverviewTasksByFolders.select(k)(g)?.data||[],q=j(e,i,a,c,T),t=W(q),o=b?s:s.filter(n=>!t.has(n));if(o.length===0)return{data:S};const l=[],u=100,p=20,d=10,f=1e3,y=u*p;if(o.length>f)throw new Error(`Exceeded maximum folders count limit ${f} (${o.length}). Please reduce the number of expanded folders.`);for(let n=0;n<o.length;n+=u){const v=o.slice(n,n+u);let E=!0,M,O=0;for(;E&&O<d;){if(O++,O===d)throw new Error(`Exceeded maximum tasks count limit ${d*y}.`);const Q=await F(_.endpoints.GetTasksByParent.initiate({projectName:e,parentIds:v,filter:i,folderFilter:a,search:c,showComments:!!T,first:y,after:M},{forceRefetch:!0}));if(Q.error)throw Q.error;const B=Q.data,D=B?.tasks||[];l.push(...D);const H=B?.pageInfo;E=H?.hasNextPage||!1,M=H?.endCursor||void 0}}Y(q,o);const m=[...S,...l],h=new Map(m.map(n=>[n.id,n]));return{data:Array.from(h.values())}}catch(g){return console.error(g),{error:{status:"FETCH_ERROR",error:g.message||g.data?.message||JSON.stringify(g)||"Unknown Fetch Error"}}}},serializeQueryArgs:({queryArgs:{parentIds:e,...s}})=>({...s}),forceRefetch({currentArg:e,previousArg:s}){return JSON.stringify(e)!==JSON.stringify(s)},providesTags:(e,s,{parentIds:i,projectName:a})=>P(e,a,i),async onCacheEntryAdded({projectName:e,parentIds:s,filter:i,folderFilter:a,search:c,showComments:T},{cacheDataLoaded:F,cacheEntryRemoved:w,updateCachedData:b,dispatch:g}){let k;const I=new Set,S=100,q=500;let t=!1;const o=()=>{t||(t=!0,setTimeout(l,q))},l=async()=>{if(t=!1,!I.size)return;const d=Array.from(I).slice(0,S);d.forEach(f=>I.delete(f));try{const y=(await g(_.endpoints.GetTasksList.initiate({projectName:e,taskIds:d,showComments:!!T},{forceRefetch:!0})).unwrap()).tasks||[],m=new Map(y.map(h=>[h.id,h]));b(h=>{for(const n of y){const v=h.findIndex(E=>E.id===n.id);v>-1?h[v]=n:h.push(n)}for(const n of d)if(!m.has(n)){const v=h.findIndex(E=>E.id===n);v>-1&&h.splice(v,1)}})}catch(f){console.error("Realtime overview batch update failed",f)}finally{I.size&&o()}};let u;try{await F,u=U.subscribeToThumbnailUpdates(f=>{b(y=>{f.forEach(m=>{if(m.summary.entityType==="task"&&m.summary.thumbnailHash){const h=y.findIndex(n=>n.id===m.summary.entityId);h>-1&&(y[h].thumbnailHash=m.summary.thumbnailHash)}})})},["task"]);const d=async(f,y)=>{const m=y?.summary?.entityId,h=y?.summary?.parentId;!m||!h||s.includes(h)&&(I.add(m),o())};k=N.subscribe("entity.task",d)}catch{}await w;const p=j(e,i,a,c,T);delete R[p],k&&N.unsubscribe(k),u&&u()},keepUnusedDataFor:C}),getSearchFolders:r.query({async queryFn({projectName:e,folderSearchRequest:s},{dispatch:i}){try{return{data:(await i($.endpoints.searchFolders.initiate({projectName:e,folderSearchRequest:s}))).data?.folderIds||[]}}catch(a){return console.error(a),{error:{status:"FETCH_ERROR",error:a.message}}}},providesTags:(e,s,{projectName:i})=>[{type:"tasksFolder",id:i}],keepUnusedDataFor:C}),getTasksListInfinite:r.infiniteQuery({infiniteQueryOptions:{initialPageParam:{cursor:"",desc:!1},getNextPageParam:(e,s,i,a)=>{const c=e.pageInfo;if(!(!(i.desc?c.hasPreviousPage:c.hasNextPage)||!c.endCursor))return{cursor:c.endCursor,desc:i.desc}}},queryFn:async({queryArg:e,pageParam:s},i)=>{try{const{projectName:a,filter:c,folderFilter:T,search:F,folderIds:w,taskIds:b,sortBy:g,desc:k,showComments:I,includeFolderChildren:S}=e,{cursor:q}=s,t={projectName:a,filter:c,folderFilter:T,search:F,folderIds:w,taskIds:b,showComments:!!I,includeFolderChildren:S!==!1};g?(t.sortBy=g,k?(t.before=q||void 0,t.last=x):(t.after=q||void 0,t.first=x)):(t.after=q||void 0,t.first=x);const o=await i.dispatch(_.endpoints.GetTasksList.initiate(t,{forceRefetch:!0}));if(o.error)throw o.error;const l={tasks:[],pageInfo:{hasNextPage:!1,endCursor:null,startCursor:null,hasPreviousPage:!1}};return{data:o.data||l}}catch(a){return console.error("Error in getTasksListInfinite queryFn:",a),{error:{status:"FETCH_ERROR",error:a.message}}}},providesTags:(e,s,{projectName:i})=>P(e?.pages.flatMap(a=>a.tasks)||[],i),async onCacheEntryAdded(e,{cacheDataLoaded:s,cacheEntryRemoved:i,updateCachedData:a,dispatch:c}){let T;const F=new Set,w=100,b=500;let g=!1;const k=()=>{g||(g=!0,setTimeout(I,b))},I=async()=>{if(g=!1,!F.size)return;const q=Array.from(F).slice(0,w);q.forEach(t=>F.delete(t));try{const o=(await c(_.endpoints.GetTasksList.initiate({projectName:e.projectName,taskIds:q,folderIds:e.folderIds,showComments:!!e.showComments},{forceRefetch:!0})).unwrap()).tasks||[],l=new Map(o.map(u=>[u.id,u]));a(u=>{for(const p of o){let d=!1;for(const f of u.pages){const y=f.tasks.findIndex(m=>m.id===p.id);if(y!==-1){f.tasks[y]=p,d=!0;break}}d||(u.pages.length?u.pages[0].tasks.unshift(p):u.pages.push({tasks:[p],pageInfo:{startCursor:null,endCursor:null,hasNextPage:!1,hasPreviousPage:!1}}))}for(const p of q)if(!l.has(p))for(const d of u.pages){const f=d.tasks.findIndex(y=>y.id===p);if(f!==-1){d.tasks.splice(f,1);break}}})}catch(t){console.error("Realtime infinite tasks batch update failed",t)}finally{F.size&&k()}};let S;try{await s,S=U.subscribeToThumbnailUpdates(t=>{a(o=>{t.forEach(l=>{if(l.summary.entityType==="task"&&l.summary.thumbnailHash)for(const u of o.pages){const p=u.tasks.findIndex(d=>d.id===l.summary.entityId);if(p>-1){u.tasks[p].thumbnailHash=l.summary.thumbnailHash;break}}})})},["task"]);const q=async(t,o)=>{const l=o?.summary?.entityId;l&&(F.add(l),k())};T=N.subscribe("entity.task",q)}catch{}await i,T&&N.unsubscribe(T),S&&S()},keepUnusedDataFor:C}),getGroupedTasksList:r.query({queryFn:async({projectName:e,groups:s,search:i,folderFilter:a,folderIds:c,desc:T,sortBy:F,groupCount:w,showComments:b},g)=>{try{let k=[];const I=new Set(["folderType"]);for(const t of s){const o=w||t.count||500;let l=t.filter,u=a;if(t.filter)try{const f=JSON.parse(t.filter),y=f.conditions||[],m=y.filter(n=>!I.has(n.key)),h=y.filter(n=>I.has(n.key));if(h.length>0){l=m.length?JSON.stringify({...f,conditions:m}):void 0;const n=a?JSON.parse(a):null,E=[...n&&Array.isArray(n.conditions)?n.conditions:[],...h];u=JSON.stringify(n?{...n,conditions:E}:{conditions:E})}}catch{}const p={projectName:e,filter:l,folderFilter:u,search:i,folderIds:c,sortBy:F,showComments:!!b,group:t.value};T?p.last=o:p.first=o;const d=g.dispatch(_.endpoints.GetTasksList.initiate(p,{forceRefetch:!0}));k.push(d)}const S=await Promise.all(k),q=[];for(const t of S){if(t.error)throw t.error;const o=t.originalArgs?.group,l=t.data?.pageInfo?.hasNextPage||t.data?.pageInfo?.hasPreviousPage||!1,u=t.data?.tasks.map((p,d,f)=>({...p,groups:[{value:o,hasNextPage:d===f.length-1&&l?o:void 0}]}))||[];q.push(...u)}return{data:{tasks:q}}}catch(k){return console.error("Error in getGroupedTasksList queryFn:",k),{error:{status:"FETCH_ERROR",error:k.message}}}},providesTags:(e,s,{projectName:i})=>P(e?.tasks,i),keepUnusedDataFor:C})})}),{useGetOverviewTasksByFoldersQuery:Z,useGetSearchFoldersQuery:ee,useGetTasksListQuery:re,useGetTasksListInfiniteInfiniteQuery:se,useLazyGetTasksByParentQuery:te,useGetGroupedTasksListQuery:ie,useGetFolderColumnStatsQuery:ae,useGetTaskColumnStatsQuery:ne}=L;exports.TASKS_INFINITE_QUERY_COUNT=x;exports.default=L;exports.parseAllAttribs=V;exports.parseJSONField=G;exports.useGetFolderColumnStatsQuery=ae;exports.useGetGroupedTasksListQuery=ie;exports.useGetOverviewTasksByFoldersQuery=Z;exports.useGetSearchFoldersQuery=ee;exports.useGetTaskColumnStatsQuery=ne;exports.useGetTasksListInfiniteInfiniteQuery=se;exports.useGetTasksListQuery=re;exports.useLazyGetTasksByParentQuery=te;
|
|
2
2
|
//# sourceMappingURL=getOverview.cjs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getOverview.cjs.js","sources":["../../../../../../src/api/queries/overview/getOverview.ts"],"sourcesContent":["import {\n gqlApi,\n GetTasksByParentQuery,\n GetTasksListQuery,\n GetFolderColumnStatsQuery,\n GetTaskColumnStatsQuery,\n foldersApi,\n SearchFoldersApiArg,\n GetTasksListQueryVariables,\n} from '@shared/api/generated'\nimport PubSub from '@shared/util/pubsub'\nimport { subscribeToThumbnailUpdates, ThumbnailUpdateMessage } from '@shared/util'\nimport { EditorTaskNode } from '@shared/containers/ProjectTreeTable'\nimport type { FieldStats } from '../columnStats'\nimport {\n normalizeFieldStats,\n mergeFieldStats,\n hasNewTargetFields,\n transformStatsError,\n} from '../columnStats'\nimport {\n DefinitionsFromApi,\n FetchBaseQueryError,\n OverrideResultType,\n TagTypesFromApi,\n} from '@reduxjs/toolkit/query'\n\nconst CACHE_TIME = 10 // seconds\n\n// parse attribs JSON string to object\nexport const parseAllAttribs = (allAttrib: string) => {\n try {\n return JSON.parse(allAttrib)\n } catch (e) {\n return {}\n }\n}\n\nconst transformFilteredEntitiesByParent = (response: GetTasksByParentQuery): EditorTaskNode[] => {\n if (!response.project) {\n return []\n }\n\n const tasks: EditorTaskNode[] = []\n for (const { node: taskNode } of response.project.tasks.edges) {\n tasks.push({\n ...taskNode,\n folderId: taskNode.folderId || 'root',\n attrib: parseAllAttribs(taskNode.allAttrib),\n entityId: taskNode.id,\n entityType: 'task',\n links: [],\n })\n }\n\n return tasks\n}\n\nconst getOverviewTaskTags = (\n result: EditorTaskNode[] | undefined = [],\n projectName: string,\n parentIds?: string | string[],\n) => {\n const taskTags = result?.map((task) => ({ type: 'overviewTask', id: task.id })) || []\n\n const parentTags = parentIds\n ? (Array.isArray(parentIds) ? parentIds : [parentIds]).map((id) => ({\n type: 'overviewTask',\n id,\n }))\n : []\n\n return [\n ...taskTags,\n ...parentTags,\n { type: 'overviewTask', id: projectName },\n { type: 'overviewTask', id: 'LIST' },\n ]\n}\n\nexport type GetTasksListResult = {\n pageInfo: GetTasksListQuery['project']['tasks']['pageInfo']\n tasks: EditorTaskNode[]\n}\nexport type GetTasksByParentResult = {\n pageInfo: GetTasksByParentQuery['project']['tasks']['pageInfo']\n tasks: EditorTaskNode[]\n}\n\nexport type GetTasksListArgs = {\n projectName: string\n filter?: string\n folderFilter?: string\n search?: string\n folderIds?: string[]\n taskIds?: string[]\n desc?: boolean\n sortBy?: string\n showComments?: boolean\n includeFolderChildren?: boolean\n}\n\nexport type GetGroupedTasksListResult = {\n tasks: EditorTaskNode[]\n}\n\nexport type GetGroupedTasksListArgs = {\n projectName: string\n groups: { filter: string; count: number; value: string }[]\n search?: string\n folderFilter?: string\n folderIds?: string[]\n desc?: boolean\n sortBy?: string\n groupCount?: number // optional override for all groups\n showComments?: boolean\n}\n\n// Define the page param type for infinite query\ntype TasksListPageParam = {\n cursor: string\n desc?: boolean\n}\n\ntype Definitions = DefinitionsFromApi<typeof gqlApi>\ntype TagTypes = TagTypesFromApi<typeof gqlApi>\ntype UpdatedDefinitions = Omit<Definitions, 'GetFilteredEntities'> & {\n GetTasksByParent: OverrideResultType<Definitions['GetTasksByParent'], GetTasksByParentResult>\n GetTasksList: OverrideResultType<Definitions['GetTasksList'], GetTasksListResult>\n GetFolderColumnStats: OverrideResultType<Definitions['GetFolderColumnStats'], FieldStats[]>\n GetTaskColumnStats: OverrideResultType<Definitions['GetTaskColumnStats'], FieldStats[]>\n}\n\n// GRAPHQL API\nconst enhancedApi = gqlApi.enhanceEndpoints<TagTypes, UpdatedDefinitions>({\n endpoints: {\n // This gets tasks for all parent folders provided\n // But in this case it will only ever receive one parent folder from the getOverviewTasksByFolders query\n // It is only used by getOverviewTasksByFolders in this file\n GetTasksByParent: {\n transformResponse: (res: GetTasksByParentQuery) => ({\n pageInfo: res?.project?.tasks?.pageInfo ?? { hasNextPage: false, endCursor: null },\n tasks: transformFilteredEntitiesByParent(res),\n }),\n providesTags: (result, _e, { parentIds, projectName }) =>\n getOverviewTaskTags(result?.tasks || [], projectName, parentIds),\n keepUnusedDataFor: CACHE_TIME,\n },\n GetTasksList: {\n transformResponse: (result: GetTasksListQuery) => ({\n tasks: transformFilteredEntitiesByParent(result),\n pageInfo: result.project.tasks.pageInfo,\n }),\n providesTags: (result, _e, { projectName }) =>\n getOverviewTaskTags(result?.tasks || [], projectName),\n keepUnusedDataFor: CACHE_TIME,\n },\n // footer stats: `targets` excluded from cache key + responses merged,\n // so column toggles reuse cache and only added targets refetch\n GetFolderColumnStats: {\n transformResponse: (res: GetFolderColumnStatsQuery) =>\n normalizeFieldStats(res?.project?.folders?.fieldStats ?? []),\n transformErrorResponse: (error: any) => transformStatsError(error, 'folder'),\n serializeQueryArgs: ({ queryArgs: { targets: _t, ...rest } }) => rest,\n merge: (cache, incoming) => mergeFieldStats(incoming, cache),\n forceRefetch: ({ currentArg, previousArg }) => hasNewTargetFields(currentArg, previousArg),\n providesTags: (_r, _e, { projectName }) => [{ type: 'folderColumnStats', id: projectName }],\n keepUnusedDataFor: CACHE_TIME,\n },\n GetTaskColumnStats: {\n transformResponse: (res: GetTaskColumnStatsQuery) =>\n normalizeFieldStats(res?.project?.tasks?.fieldStats ?? []),\n transformErrorResponse: (error: any) => transformStatsError(error, 'task'),\n serializeQueryArgs: ({ queryArgs: { targets: _t, ...rest } }) => rest,\n merge: (cache, incoming) => mergeFieldStats(incoming, cache),\n forceRefetch: ({ currentArg, previousArg }) => hasNewTargetFields(currentArg, previousArg),\n providesTags: (_r, _e, { projectName }) => [{ type: 'taskColumnStats', id: projectName }],\n keepUnusedDataFor: CACHE_TIME,\n },\n },\n})\n\n// REST FOLDERS API\nconst foldersApiEnhanced = foldersApi.enhanceEndpoints({\n endpoints: {\n searchFolders: {},\n },\n})\n\nexport const TASKS_INFINITE_QUERY_COUNT = 100 // Number of items to fetch per page\n\n// --- TRACKING REGISTRY FOR EMPTY FOLDERS (FILTER-AWARE) ---\nconst queriedFoldersRegistry: Record<string, Set<string>> = {}\n\nconst getCacheKey = (\n projectName: string,\n filter?: string,\n folderFilter?: string,\n search?: string,\n showComments?: boolean,\n) => {\n return JSON.stringify({ projectName, filter, folderFilter, search, showComments })\n}\n\nconst markFoldersAsQueried = (cacheKey: string, folderIds: string[]) => {\n if (!queriedFoldersRegistry[cacheKey]) {\n queriedFoldersRegistry[cacheKey] = new Set()\n }\n folderIds.forEach((id) => queriedFoldersRegistry[cacheKey].add(id))\n}\n\nconst getQueriedFolders = (cacheKey: string): Set<string> => {\n return queriedFoldersRegistry[cacheKey] || new Set()\n}\n\nconst injectedApi = enhancedApi.injectEndpoints({\n endpoints: (build) => ({\n // Each project has one cache for all the tasks of the expanded folders\n // Changing the expanded folders will trigger a refetch but not a new cache\n // Each expanded folder has it's own query that is looped over here\n // When new folders are expanded, the new tasks are fetched and we use the cache for the rest\n // This also solves the pagination issue of getting all tasks in one query, splitting it up in multiple queries to avoid pagination limits\n getOverviewTasksByFolders: build.query<\n EditorTaskNode[],\n {\n projectName: string\n parentIds: string[]\n filter?: string\n folderFilter?: string\n search?: string\n showComments?: boolean\n }\n >({\n async queryFn(\n { projectName, parentIds, filter, folderFilter, search, showComments },\n { dispatch, getState, forced },\n ) {\n try {\n const state = getState()\n const cacheArgs = { projectName, filter, folderFilter, search, showComments }\n\n // Select current flat cache state\n const currentCache = (injectedApi.endpoints as any).getOverviewTasksByFolders.select(\n cacheArgs,\n )(state)\n const cacheData: EditorTaskNode[] = currentCache?.data || []\n\n // 1. Generate a stable cache key matching RTK Query's serialization\n const cacheKey = getCacheKey(projectName, filter, folderFilter, search, showComments)\n\n // 2. Fetch our registry specific to THIS combination of search/filters\n const alreadyQueriedFolders = getQueriedFolders(cacheKey)\n\n // 3. Diffing: Only request folders that haven't hit the network under these specific filters\n // If forced, we ignore the registry and fetch all folders again, like a refresh\n const newFolderIds = forced\n ? parentIds\n : parentIds.filter((id) => !alreadyQueriedFolders.has(id))\n\n // Short-circuit if all expanded folders have been evaluated for this filter setup\n if (newFolderIds.length === 0) {\n return { data: cacheData }\n }\n\n const allNewTasks: EditorTaskNode[] = []\n const BATCH_SIZE = 100\n const TASK_PER_FOLDER = 20\n const MAX_PAGES_PER_BATCH = 10\n const MAX_FOLDERS = 1000\n const TASKS_PER_PAGE = BATCH_SIZE * TASK_PER_FOLDER\n\n if (newFolderIds.length > MAX_FOLDERS) {\n throw new Error(\n `Exceeded maximum folders count limit ${MAX_FOLDERS} (${newFolderIds.length}). Please reduce the number of expanded folders.`,\n )\n }\n\n // 5. Batch folder IDs into groups and process them sequentially\n for (let i = 0; i < newFolderIds.length; i += BATCH_SIZE) {\n const batchFolderIds = newFolderIds.slice(i, i + BATCH_SIZE)\n\n let hasNextPage = true\n let cursor: string | undefined = undefined\n let pageCount = 0\n\n while (hasNextPage && pageCount < MAX_PAGES_PER_BATCH) {\n pageCount++\n\n if (pageCount === MAX_PAGES_PER_BATCH) {\n throw new Error(\n `Exceeded maximum tasks count limit ${MAX_PAGES_PER_BATCH * TASKS_PER_PAGE}.`,\n )\n }\n\n const result = await dispatch(\n enhancedApi.endpoints.GetTasksByParent.initiate(\n {\n projectName,\n parentIds: batchFolderIds,\n filter,\n folderFilter,\n search,\n showComments: !!showComments,\n first: TASKS_PER_PAGE,\n after: cursor,\n },\n { forceRefetch: true },\n ),\n )\n\n if (result.error) throw result.error\n const data = result.data as GetTasksByParentResult\n\n const fetchedTasks = data?.tasks || []\n allNewTasks.push(...fetchedTasks)\n\n const pageInfo = data?.pageInfo\n hasNextPage = pageInfo?.hasNextPage || false\n cursor = pageInfo?.endCursor || undefined\n }\n }\n\n // 4. Only mark folders as queried if the network loops complete successfully\n markFoldersAsQueried(cacheKey, newFolderIds)\n\n // 5. Append new tasks to the existing flat array cache with task ID deduplication\n const finalTasks = [...cacheData, ...allNewTasks]\n const uniqueTasksMap = new Map(finalTasks.map((task) => [task.id, task]))\n\n return {\n data: Array.from(uniqueTasksMap.values()),\n }\n } catch (e: any) {\n console.error(e)\n const errorMessage =\n e.message || e.data?.message || JSON.stringify(e) || 'Unknown Fetch Error'\n return { error: { status: 'FETCH_ERROR', error: errorMessage } as FetchBaseQueryError }\n }\n },\n // keep one cache per project\n serializeQueryArgs: ({ queryArgs: { parentIds, ...rest } }) => ({\n ...rest,\n }),\n // Refetch when the page arg changes\n forceRefetch({ currentArg, previousArg }) {\n return JSON.stringify(currentArg) !== JSON.stringify(previousArg)\n },\n providesTags: (result, _e, { parentIds, projectName }) =>\n getOverviewTaskTags(result, projectName, parentIds),\n async onCacheEntryAdded(\n { projectName, parentIds, filter, folderFilter, search, showComments },\n { cacheDataLoaded, cacheEntryRemoved, updateCachedData, dispatch },\n ) {\n let token: any\n const pendingTaskIds = new Set<string>()\n const MAX_BATCH = 100\n const INTERVAL = 500\n let scheduled = false\n\n const schedule = () => {\n if (scheduled) return\n scheduled = true\n setTimeout(flush, INTERVAL)\n }\n\n const flush = async () => {\n scheduled = false\n if (!pendingTaskIds.size) return\n const batchIds = Array.from(pendingTaskIds).slice(0, MAX_BATCH)\n batchIds.forEach((id) => pendingTaskIds.delete(id))\n try {\n const res = await dispatch(\n enhancedApi.endpoints.GetTasksList.initiate(\n {\n projectName,\n taskIds: batchIds,\n showComments: !!showComments,\n } as any,\n { forceRefetch: true },\n ),\n ).unwrap()\n const returned = res.tasks || []\n const returnedMap = new Map(returned.map((t: EditorTaskNode) => [t.id, t]))\n\n updateCachedData((draft: EditorTaskNode[]) => {\n // update or add\n for (const task of returned) {\n const idx = draft.findIndex((t) => t.id === task.id)\n if (idx > -1) draft[idx] = task\n else draft.push(task)\n }\n // remove missing\n for (const id of batchIds) {\n if (!returnedMap.has(id)) {\n const idx = draft.findIndex((t) => t.id === id)\n if (idx > -1) draft.splice(idx, 1)\n }\n }\n })\n } catch (err) {\n console.error('Realtime overview batch update failed', err)\n } finally {\n if (pendingTaskIds.size) schedule()\n }\n }\n let unsubscribeThumbnails: (() => void) | undefined\n try {\n await cacheDataLoaded\n\n unsubscribeThumbnails = subscribeToThumbnailUpdates(\n (messages: ThumbnailUpdateMessage[]) => {\n updateCachedData((draft: EditorTaskNode[]) => {\n messages.forEach((message) => {\n if (message.summary.entityType === 'task' && message.summary.thumbnailHash) {\n const idx = draft.findIndex((t) => t.id === message.summary.entityId)\n if (idx > -1) {\n draft[idx].thumbnailHash = message.summary.thumbnailHash\n }\n }\n })\n })\n },\n ['task'],\n )\n\n const handlePubSub = async (_topic: string, message: any) => {\n const taskId = message?.summary?.entityId\n const parentId = message?.summary?.parentId\n if (!taskId || !parentId) return\n // Only react if the parent folder is part of the current expanded set\n if (!parentIds.includes(parentId)) return\n pendingTaskIds.add(taskId)\n schedule()\n }\n\n // Subscribe to task entity updates\n // NOTE: backend emits topics like 'entity.task.assignees_changed'.\n // Assuming PubSub supports prefix matching when subscribing without the suffix.\n token = PubSub.subscribe('entity.task', handlePubSub)\n } catch (e) {\n // cache entry removed before loaded - ignore\n }\n\n await cacheEntryRemoved\n\n // Evict tracking map memory entry completely when this RTK Query cache entry expires\n const deadCacheKey = getCacheKey(projectName, filter, folderFilter, search, showComments)\n delete queriedFoldersRegistry[deadCacheKey]\n\n if (token) PubSub.unsubscribe(token)\n if (unsubscribeThumbnails) unsubscribeThumbnails()\n },\n keepUnusedDataFor: CACHE_TIME,\n }),\n // searchFolders is a post so it's a bit annoying to consume\n // we wrap it in a queryFn to make it easier to consume as a query hook\n getSearchFolders: build.query<string[], SearchFoldersApiArg>({\n async queryFn({ projectName, folderSearchRequest }, { dispatch }) {\n try {\n const result = await dispatch(\n foldersApiEnhanced.endpoints.searchFolders.initiate({\n projectName,\n folderSearchRequest,\n }),\n )\n\n const data = result.data?.folderIds || []\n\n return { data }\n } catch (e: any) {\n console.error(e)\n const error = { status: 'FETCH_ERROR', error: e.message } as FetchBaseQueryError\n return { error }\n }\n },\n providesTags: (_r, _e, { projectName }) => [{ type: 'tasksFolder', id: projectName }],\n keepUnusedDataFor: CACHE_TIME,\n }),\n // Add new infinite query endpoint for tasks list\n getTasksListInfinite: build.infiniteQuery<\n GetTasksListResult,\n GetTasksListArgs,\n TasksListPageParam\n >({\n infiniteQueryOptions: {\n initialPageParam: { cursor: '', desc: false },\n // Calculate the next page param based on current page response and params\n getNextPageParam: (lastPage, _allPages, lastPageParam, _allPageParams) => {\n // Use the endCursor from the query as the next page param\n const pageInfo = lastPage.pageInfo\n const desc = lastPageParam.desc\n const hasNextPage = desc ? pageInfo.hasPreviousPage : pageInfo.hasNextPage\n\n if (!hasNextPage || !pageInfo.endCursor) return undefined\n\n return {\n cursor: pageInfo.endCursor,\n desc: lastPageParam.desc,\n }\n },\n },\n queryFn: async ({ queryArg, pageParam }, api) => {\n try {\n const {\n projectName,\n filter,\n folderFilter,\n search,\n folderIds,\n taskIds,\n sortBy,\n desc,\n showComments,\n includeFolderChildren,\n } = queryArg\n const { cursor } = pageParam\n\n // Build the query parameters for GetTasksList\n const queryParams: any = {\n projectName,\n filter,\n folderFilter,\n search,\n folderIds,\n taskIds,\n showComments: !!showComments,\n includeFolderChildren: includeFolderChildren !== false, // default to true\n }\n\n // Add cursor-based pagination\n if (sortBy) {\n queryParams.sortBy = sortBy\n if (desc) {\n queryParams.before = cursor || undefined\n queryParams.last = TASKS_INFINITE_QUERY_COUNT\n } else {\n queryParams.after = cursor || undefined\n queryParams.first = TASKS_INFINITE_QUERY_COUNT\n }\n } else {\n queryParams.after = cursor || undefined\n queryParams.first = TASKS_INFINITE_QUERY_COUNT\n }\n\n // Call the existing GetTasksList endpoint\n const result = await api.dispatch(\n enhancedApi.endpoints.GetTasksList.initiate(queryParams, { forceRefetch: true }),\n )\n\n if (result.error) throw result.error\n const fallback = {\n tasks: [],\n pageInfo: {\n hasNextPage: false,\n endCursor: null,\n startCursor: null,\n hasPreviousPage: false,\n },\n }\n\n // Return the tasks directly as required by the infinite query format\n return {\n data: result.data || fallback,\n }\n } catch (e: any) {\n console.error('Error in getTasksListInfinite queryFn:', e)\n return { error: { status: 'FETCH_ERROR', error: e.message } as FetchBaseQueryError }\n }\n },\n providesTags: (result, _e, { projectName }) =>\n getOverviewTaskTags(result?.pages.flatMap((p) => p.tasks) || [], projectName),\n async onCacheEntryAdded(\n arg,\n { cacheDataLoaded, cacheEntryRemoved, updateCachedData, dispatch },\n ) {\n let token: any\n const pendingTaskIds = new Set<string>()\n const MAX_BATCH = 100\n const INTERVAL = 500\n let scheduled = false\n\n const schedule = () => {\n if (scheduled) return\n scheduled = true\n setTimeout(flush, INTERVAL)\n }\n\n const flush = async () => {\n scheduled = false\n if (!pendingTaskIds.size) return\n const batchIds = Array.from(pendingTaskIds).slice(0, MAX_BATCH)\n batchIds.forEach((id) => pendingTaskIds.delete(id))\n try {\n const res = await dispatch(\n enhancedApi.endpoints.GetTasksList.initiate(\n {\n projectName: arg.projectName,\n taskIds: batchIds,\n folderIds: arg.folderIds,\n showComments: !!arg.showComments,\n } as any,\n { forceRefetch: true },\n ),\n ).unwrap()\n\n const returned = res.tasks || []\n const returnedMap = new Map(returned.map((t: EditorTaskNode) => [t.id, t]))\n\n updateCachedData((draft: { pages: GetTasksListResult[]; pageParams: any[] }) => {\n // update/insert\n for (const task of returned) {\n let located = false\n for (const page of draft.pages) {\n const idx = page.tasks.findIndex((t) => t.id === task.id)\n if (idx !== -1) {\n page.tasks[idx] = task\n located = true\n break\n }\n }\n if (!located) {\n if (draft.pages.length) draft.pages[0].tasks.unshift(task)\n else\n draft.pages.push({\n tasks: [task],\n pageInfo: {\n startCursor: null,\n endCursor: null,\n hasNextPage: false,\n hasPreviousPage: false,\n },\n })\n }\n }\n // remove any requested but missing tasks\n for (const id of batchIds) {\n if (returnedMap.has(id)) continue\n for (const page of draft.pages) {\n const idx = page.tasks.findIndex((t) => t.id === id)\n if (idx !== -1) {\n page.tasks.splice(idx, 1)\n break\n }\n }\n }\n })\n } catch (err) {\n console.error('Realtime infinite tasks batch update failed', err)\n } finally {\n if (pendingTaskIds.size) schedule()\n }\n }\n let unsubscribeThumbnails: (() => void) | undefined\n try {\n await cacheDataLoaded\n\n unsubscribeThumbnails = subscribeToThumbnailUpdates(\n (messages: ThumbnailUpdateMessage[]) => {\n updateCachedData((draft: { pages: GetTasksListResult[]; pageParams: any[] }) => {\n messages.forEach((message) => {\n if (message.summary.entityType === 'task' && message.summary.thumbnailHash) {\n for (const page of draft.pages) {\n const idx = page.tasks.findIndex((t) => t.id === message.summary.entityId)\n if (idx > -1) {\n page.tasks[idx].thumbnailHash = message.summary.thumbnailHash\n break\n }\n }\n }\n })\n })\n },\n ['task'],\n )\n\n const handlePubSub = async (_topic: string, message: any) => {\n const taskId = message?.summary?.entityId\n if (!taskId) return\n pendingTaskIds.add(taskId)\n schedule()\n }\n\n token = PubSub.subscribe('entity.task', handlePubSub)\n } catch (_) {\n // ignore\n }\n await cacheEntryRemoved\n if (token) PubSub.unsubscribe(token)\n if (unsubscribeThumbnails) unsubscribeThumbnails()\n },\n keepUnusedDataFor: CACHE_TIME,\n }),\n getGroupedTasksList: build.query<GetGroupedTasksListResult, GetGroupedTasksListArgs>({\n queryFn: async (\n {\n projectName,\n groups,\n search,\n folderFilter,\n folderIds,\n desc,\n sortBy,\n groupCount,\n showComments,\n },\n api,\n ) => {\n try {\n let promises = []\n // Folder-level filter keys that must go in folderFilter, not task filter\n const folderFilterKeys = new Set(['folderType'])\n\n for (const group of groups) {\n // Determine count for this group - use argument override, else group count, else default\n const count = groupCount || group.count || 500\n\n // Separate folder-level conditions from task-level conditions in the group filter\n let taskFilter: string | undefined = group.filter\n let mergedFolderFilter = folderFilter\n if (group.filter) {\n try {\n const parsed = JSON.parse(group.filter)\n const conditions = parsed.conditions || []\n const taskConditions = conditions.filter((c: any) => !folderFilterKeys.has(c.key))\n const folderConditions = conditions.filter((c: any) => folderFilterKeys.has(c.key))\n\n if (folderConditions.length > 0) {\n taskFilter = taskConditions.length\n ? JSON.stringify({ ...parsed, conditions: taskConditions })\n : undefined\n // Merge folder conditions with existing folderFilter, preserving metadata\n const existingFolderFilter = folderFilter ? JSON.parse(folderFilter) : null\n const existingConditions =\n existingFolderFilter && Array.isArray(existingFolderFilter.conditions)\n ? existingFolderFilter.conditions\n : []\n const allFolderConditions = [...existingConditions, ...folderConditions]\n mergedFolderFilter = JSON.stringify(\n existingFolderFilter\n ? { ...existingFolderFilter, conditions: allFolderConditions }\n : { conditions: allFolderConditions },\n )\n }\n } catch {\n // If parsing fails, use the original filter as-is\n }\n }\n\n const queryParams: GetTasksListQueryVariables = {\n projectName,\n filter: taskFilter,\n folderFilter: mergedFolderFilter,\n search,\n folderIds,\n sortBy: sortBy,\n showComments: !!showComments,\n // @ts-expect-error - we know group does not exist on query variables but we need it for later\n group: group.value,\n }\n if (desc) {\n queryParams.last = count\n } else {\n queryParams.first = count\n }\n\n const promise = api.dispatch(\n enhancedApi.endpoints.GetTasksList.initiate(queryParams, { forceRefetch: true }),\n )\n promises.push(promise)\n }\n\n const result = await Promise.all(promises)\n const tasks: EditorTaskNode[] = []\n for (const res of result) {\n if (res.error) throw res.error\n // get group value\n // @ts-expect-error - we know group does exist on res.originalArgs from line 319\n const groupValue = res.originalArgs?.group as string\n\n const hasNextPage =\n res.data?.pageInfo?.hasNextPage || res.data?.pageInfo?.hasPreviousPage || false\n const groupTasks =\n res.data?.tasks.map((task, i, a) => ({\n ...task,\n groups: [\n {\n value: groupValue,\n hasNextPage: i === a.length - 1 && hasNextPage ? groupValue : undefined, // Only add hasNextPage to the last task in the group\n },\n ],\n })) || []\n\n tasks.push(...groupTasks)\n }\n\n // Return the tasks directly as required by the query format\n return {\n data: {\n tasks,\n },\n }\n } catch (error: any) {\n console.error('Error in getGroupedTasksList queryFn:', error)\n return { error: { status: 'FETCH_ERROR', error: error.message } as FetchBaseQueryError }\n }\n },\n providesTags: (result, _e, { projectName }) =>\n getOverviewTaskTags(result?.tasks, projectName),\n keepUnusedDataFor: CACHE_TIME,\n }),\n }),\n})\n\nexport const {\n useGetOverviewTasksByFoldersQuery,\n useGetSearchFoldersQuery,\n useGetTasksListQuery,\n useGetTasksListInfiniteInfiniteQuery,\n useLazyGetTasksByParentQuery,\n useGetGroupedTasksListQuery,\n useGetFolderColumnStatsQuery,\n useGetTaskColumnStatsQuery,\n} = injectedApi\nexport default injectedApi\n"],"names":["CACHE_TIME","parseAllAttribs","allAttrib","transformFilteredEntitiesByParent","response","tasks","taskNode","getOverviewTaskTags","result","projectName","parentIds","taskTags","task","parentTags","id","enhancedApi","gqlApi","res","_e","normalizeFieldStats","error","transformStatsError","_t","rest","cache","incoming","mergeFieldStats","currentArg","previousArg","hasNewTargetFields","_r","foldersApiEnhanced","foldersApi","TASKS_INFINITE_QUERY_COUNT","queriedFoldersRegistry","getCacheKey","filter","folderFilter","search","showComments","markFoldersAsQueried","cacheKey","folderIds","getQueriedFolders","injectedApi","build","dispatch","getState","forced","state","cacheArgs","cacheData","alreadyQueriedFolders","newFolderIds","allNewTasks","BATCH_SIZE","TASK_PER_FOLDER","MAX_PAGES_PER_BATCH","MAX_FOLDERS","TASKS_PER_PAGE","i","batchFolderIds","hasNextPage","cursor","pageCount","data","fetchedTasks","pageInfo","finalTasks","uniqueTasksMap","e","cacheDataLoaded","cacheEntryRemoved","updateCachedData","token","pendingTaskIds","MAX_BATCH","INTERVAL","scheduled","schedule","flush","batchIds","returned","returnedMap","t","draft","idx","err","unsubscribeThumbnails","subscribeToThumbnailUpdates","messages","message","handlePubSub","_topic","taskId","parentId","PubSub","deadCacheKey","folderSearchRequest","lastPage","_allPages","lastPageParam","_allPageParams","queryArg","pageParam","api","taskIds","sortBy","desc","includeFolderChildren","queryParams","fallback","p","arg","located","page","groups","groupCount","promises","folderFilterKeys","group","count","taskFilter","mergedFolderFilter","parsed","conditions","taskConditions","c","folderConditions","existingFolderFilter","allFolderConditions","promise","groupValue","groupTasks","a","useGetOverviewTasksByFoldersQuery","useGetSearchFoldersQuery","useGetTasksListQuery","useGetTasksListInfiniteInfiniteQuery","useLazyGetTasksByParentQuery","useGetGroupedTasksListQuery","useGetFolderColumnStatsQuery","useGetTaskColumnStatsQuery"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"getOverview.cjs.js","sources":["../../../../../../src/api/queries/overview/getOverview.ts"],"sourcesContent":["import {\n gqlApi,\n GetTasksByParentQuery,\n GetTasksListQuery,\n GetFolderColumnStatsQuery,\n GetTaskColumnStatsQuery,\n foldersApi,\n SearchFoldersApiArg,\n GetTasksListQueryVariables,\n} from '@shared/api/generated'\nimport PubSub from '@shared/util/pubsub'\nimport { subscribeToThumbnailUpdates, ThumbnailUpdateMessage } from '@shared/util'\nimport { EditorTaskNode } from '@shared/containers/ProjectTreeTable'\nimport type { FieldStats } from '../columnStats'\nimport {\n normalizeFieldStats,\n mergeFieldStats,\n hasNewTargetFields,\n transformStatsError,\n} from '../columnStats'\nimport {\n DefinitionsFromApi,\n FetchBaseQueryError,\n OverrideResultType,\n TagTypesFromApi,\n} from '@reduxjs/toolkit/query'\n\nconst CACHE_TIME = 10 // seconds\n\n// parse attribs JSON string to object\nexport const parseJSONField = (allAttrib: string | null | undefined): Record<string, unknown> => {\n if (!allAttrib) return {}\n try {\n return JSON.parse(allAttrib)\n } catch (e) {\n return {}\n }\n}\n// backwards compatibility for old API\nexport const parseAllAttribs = parseJSONField\n\nconst transformFilteredEntitiesByParent = (response: GetTasksByParentQuery): EditorTaskNode[] => {\n if (!response.project) {\n return []\n }\n\n const tasks: EditorTaskNode[] = []\n for (const { node: taskNode } of response.project.tasks.edges) {\n tasks.push({\n ...taskNode,\n folderId: taskNode.folderId || 'root',\n attrib: parseJSONField(taskNode.allAttrib),\n data: parseJSONField(taskNode.data),\n entityId: taskNode.id,\n entityType: 'task',\n links: [],\n })\n }\n\n return tasks\n}\n\nconst getOverviewTaskTags = (\n result: EditorTaskNode[] | undefined = [],\n projectName: string,\n parentIds?: string | string[],\n) => {\n const taskTags = result?.map((task) => ({ type: 'overviewTask', id: task.id })) || []\n\n const parentTags = parentIds\n ? (Array.isArray(parentIds) ? parentIds : [parentIds]).map((id) => ({\n type: 'overviewTask',\n id,\n }))\n : []\n\n return [\n ...taskTags,\n ...parentTags,\n { type: 'overviewTask', id: projectName },\n { type: 'overviewTask', id: 'LIST' },\n ]\n}\n\nexport type GetTasksListResult = {\n pageInfo: GetTasksListQuery['project']['tasks']['pageInfo']\n tasks: EditorTaskNode[]\n}\nexport type GetTasksByParentResult = {\n pageInfo: GetTasksByParentQuery['project']['tasks']['pageInfo']\n tasks: EditorTaskNode[]\n}\n\nexport type GetTasksListArgs = {\n projectName: string\n filter?: string\n folderFilter?: string\n search?: string\n folderIds?: string[]\n taskIds?: string[]\n desc?: boolean\n sortBy?: string\n showComments?: boolean\n includeFolderChildren?: boolean\n}\n\nexport type GetGroupedTasksListResult = {\n tasks: EditorTaskNode[]\n}\n\nexport type GetGroupedTasksListArgs = {\n projectName: string\n groups: { filter: string; count: number; value: string }[]\n search?: string\n folderFilter?: string\n folderIds?: string[]\n desc?: boolean\n sortBy?: string\n groupCount?: number // optional override for all groups\n showComments?: boolean\n}\n\n// Define the page param type for infinite query\ntype TasksListPageParam = {\n cursor: string\n desc?: boolean\n}\n\ntype Definitions = DefinitionsFromApi<typeof gqlApi>\ntype TagTypes = TagTypesFromApi<typeof gqlApi>\ntype UpdatedDefinitions = Omit<Definitions, 'GetFilteredEntities'> & {\n GetTasksByParent: OverrideResultType<Definitions['GetTasksByParent'], GetTasksByParentResult>\n GetTasksList: OverrideResultType<Definitions['GetTasksList'], GetTasksListResult>\n GetFolderColumnStats: OverrideResultType<Definitions['GetFolderColumnStats'], FieldStats[]>\n GetTaskColumnStats: OverrideResultType<Definitions['GetTaskColumnStats'], FieldStats[]>\n}\n\n// GRAPHQL API\nconst enhancedApi = gqlApi.enhanceEndpoints<TagTypes, UpdatedDefinitions>({\n endpoints: {\n // This gets tasks for all parent folders provided\n // But in this case it will only ever receive one parent folder from the getOverviewTasksByFolders query\n // It is only used by getOverviewTasksByFolders in this file\n GetTasksByParent: {\n transformResponse: (res: GetTasksByParentQuery) => ({\n pageInfo: res?.project?.tasks?.pageInfo ?? { hasNextPage: false, endCursor: null },\n tasks: transformFilteredEntitiesByParent(res),\n }),\n providesTags: (result, _e, { parentIds, projectName }) =>\n getOverviewTaskTags(result?.tasks || [], projectName, parentIds),\n keepUnusedDataFor: CACHE_TIME,\n },\n GetTasksList: {\n transformResponse: (result: GetTasksListQuery) => ({\n tasks: transformFilteredEntitiesByParent(result),\n pageInfo: result.project.tasks.pageInfo,\n }),\n providesTags: (result, _e, { projectName }) =>\n getOverviewTaskTags(result?.tasks || [], projectName),\n keepUnusedDataFor: CACHE_TIME,\n },\n // footer stats: `targets` excluded from cache key + responses merged,\n // so column toggles reuse cache and only added targets refetch\n GetFolderColumnStats: {\n transformResponse: (res: GetFolderColumnStatsQuery) =>\n normalizeFieldStats(res?.project?.folders?.fieldStats ?? []),\n transformErrorResponse: (error: any) => transformStatsError(error, 'folder'),\n serializeQueryArgs: ({ queryArgs: { targets: _t, ...rest } }) => rest,\n merge: (cache, incoming) => mergeFieldStats(incoming, cache),\n forceRefetch: ({ currentArg, previousArg }) => hasNewTargetFields(currentArg, previousArg),\n providesTags: (_r, _e, { projectName }) => [{ type: 'folderColumnStats', id: projectName }],\n keepUnusedDataFor: CACHE_TIME,\n },\n GetTaskColumnStats: {\n transformResponse: (res: GetTaskColumnStatsQuery) =>\n normalizeFieldStats(res?.project?.tasks?.fieldStats ?? []),\n transformErrorResponse: (error: any) => transformStatsError(error, 'task'),\n serializeQueryArgs: ({ queryArgs: { targets: _t, ...rest } }) => rest,\n merge: (cache, incoming) => mergeFieldStats(incoming, cache),\n forceRefetch: ({ currentArg, previousArg }) => hasNewTargetFields(currentArg, previousArg),\n providesTags: (_r, _e, { projectName }) => [{ type: 'taskColumnStats', id: projectName }],\n keepUnusedDataFor: CACHE_TIME,\n },\n },\n})\n\n// REST FOLDERS API\nconst foldersApiEnhanced = foldersApi.enhanceEndpoints({\n endpoints: {\n searchFolders: {},\n },\n})\n\nexport const TASKS_INFINITE_QUERY_COUNT = 100 // Number of items to fetch per page\n\n// --- TRACKING REGISTRY FOR EMPTY FOLDERS (FILTER-AWARE) ---\nconst queriedFoldersRegistry: Record<string, Set<string>> = {}\n\nconst getCacheKey = (\n projectName: string,\n filter?: string,\n folderFilter?: string,\n search?: string,\n showComments?: boolean,\n) => {\n return JSON.stringify({ projectName, filter, folderFilter, search, showComments })\n}\n\nconst markFoldersAsQueried = (cacheKey: string, folderIds: string[]) => {\n if (!queriedFoldersRegistry[cacheKey]) {\n queriedFoldersRegistry[cacheKey] = new Set()\n }\n folderIds.forEach((id) => queriedFoldersRegistry[cacheKey].add(id))\n}\n\nconst getQueriedFolders = (cacheKey: string): Set<string> => {\n return queriedFoldersRegistry[cacheKey] || new Set()\n}\n\nconst injectedApi = enhancedApi.injectEndpoints({\n endpoints: (build) => ({\n // Each project has one cache for all the tasks of the expanded folders\n // Changing the expanded folders will trigger a refetch but not a new cache\n // Each expanded folder has it's own query that is looped over here\n // When new folders are expanded, the new tasks are fetched and we use the cache for the rest\n // This also solves the pagination issue of getting all tasks in one query, splitting it up in multiple queries to avoid pagination limits\n getOverviewTasksByFolders: build.query<\n EditorTaskNode[],\n {\n projectName: string\n parentIds: string[]\n filter?: string\n folderFilter?: string\n search?: string\n showComments?: boolean\n }\n >({\n async queryFn(\n { projectName, parentIds, filter, folderFilter, search, showComments },\n { dispatch, getState, forced },\n ) {\n try {\n const state = getState()\n const cacheArgs = { projectName, filter, folderFilter, search, showComments }\n\n // Select current flat cache state\n const currentCache = (injectedApi.endpoints as any).getOverviewTasksByFolders.select(\n cacheArgs,\n )(state)\n const cacheData: EditorTaskNode[] = currentCache?.data || []\n\n // 1. Generate a stable cache key matching RTK Query's serialization\n const cacheKey = getCacheKey(projectName, filter, folderFilter, search, showComments)\n\n // 2. Fetch our registry specific to THIS combination of search/filters\n const alreadyQueriedFolders = getQueriedFolders(cacheKey)\n\n // 3. Diffing: Only request folders that haven't hit the network under these specific filters\n // If forced, we ignore the registry and fetch all folders again, like a refresh\n const newFolderIds = forced\n ? parentIds\n : parentIds.filter((id) => !alreadyQueriedFolders.has(id))\n\n // Short-circuit if all expanded folders have been evaluated for this filter setup\n if (newFolderIds.length === 0) {\n return { data: cacheData }\n }\n\n const allNewTasks: EditorTaskNode[] = []\n const BATCH_SIZE = 100\n const TASK_PER_FOLDER = 20\n const MAX_PAGES_PER_BATCH = 10\n const MAX_FOLDERS = 1000\n const TASKS_PER_PAGE = BATCH_SIZE * TASK_PER_FOLDER\n\n if (newFolderIds.length > MAX_FOLDERS) {\n throw new Error(\n `Exceeded maximum folders count limit ${MAX_FOLDERS} (${newFolderIds.length}). Please reduce the number of expanded folders.`,\n )\n }\n\n // 5. Batch folder IDs into groups and process them sequentially\n for (let i = 0; i < newFolderIds.length; i += BATCH_SIZE) {\n const batchFolderIds = newFolderIds.slice(i, i + BATCH_SIZE)\n\n let hasNextPage = true\n let cursor: string | undefined = undefined\n let pageCount = 0\n\n while (hasNextPage && pageCount < MAX_PAGES_PER_BATCH) {\n pageCount++\n\n if (pageCount === MAX_PAGES_PER_BATCH) {\n throw new Error(\n `Exceeded maximum tasks count limit ${MAX_PAGES_PER_BATCH * TASKS_PER_PAGE}.`,\n )\n }\n\n const result = await dispatch(\n enhancedApi.endpoints.GetTasksByParent.initiate(\n {\n projectName,\n parentIds: batchFolderIds,\n filter,\n folderFilter,\n search,\n showComments: !!showComments,\n first: TASKS_PER_PAGE,\n after: cursor,\n },\n { forceRefetch: true },\n ),\n )\n\n if (result.error) throw result.error\n const data = result.data as GetTasksByParentResult\n\n const fetchedTasks = data?.tasks || []\n allNewTasks.push(...fetchedTasks)\n\n const pageInfo = data?.pageInfo\n hasNextPage = pageInfo?.hasNextPage || false\n cursor = pageInfo?.endCursor || undefined\n }\n }\n\n // 4. Only mark folders as queried if the network loops complete successfully\n markFoldersAsQueried(cacheKey, newFolderIds)\n\n // 5. Append new tasks to the existing flat array cache with task ID deduplication\n const finalTasks = [...cacheData, ...allNewTasks]\n const uniqueTasksMap = new Map(finalTasks.map((task) => [task.id, task]))\n\n return {\n data: Array.from(uniqueTasksMap.values()),\n }\n } catch (e: any) {\n console.error(e)\n const errorMessage =\n e.message || e.data?.message || JSON.stringify(e) || 'Unknown Fetch Error'\n return { error: { status: 'FETCH_ERROR', error: errorMessage } as FetchBaseQueryError }\n }\n },\n // keep one cache per project\n serializeQueryArgs: ({ queryArgs: { parentIds, ...rest } }) => ({\n ...rest,\n }),\n // Refetch when the page arg changes\n forceRefetch({ currentArg, previousArg }) {\n return JSON.stringify(currentArg) !== JSON.stringify(previousArg)\n },\n providesTags: (result, _e, { parentIds, projectName }) =>\n getOverviewTaskTags(result, projectName, parentIds),\n async onCacheEntryAdded(\n { projectName, parentIds, filter, folderFilter, search, showComments },\n { cacheDataLoaded, cacheEntryRemoved, updateCachedData, dispatch },\n ) {\n let token: any\n const pendingTaskIds = new Set<string>()\n const MAX_BATCH = 100\n const INTERVAL = 500\n let scheduled = false\n\n const schedule = () => {\n if (scheduled) return\n scheduled = true\n setTimeout(flush, INTERVAL)\n }\n\n const flush = async () => {\n scheduled = false\n if (!pendingTaskIds.size) return\n const batchIds = Array.from(pendingTaskIds).slice(0, MAX_BATCH)\n batchIds.forEach((id) => pendingTaskIds.delete(id))\n try {\n const res = await dispatch(\n enhancedApi.endpoints.GetTasksList.initiate(\n {\n projectName,\n taskIds: batchIds,\n showComments: !!showComments,\n } as any,\n { forceRefetch: true },\n ),\n ).unwrap()\n const returned = res.tasks || []\n const returnedMap = new Map(returned.map((t: EditorTaskNode) => [t.id, t]))\n\n updateCachedData((draft: EditorTaskNode[]) => {\n // update or add\n for (const task of returned) {\n const idx = draft.findIndex((t) => t.id === task.id)\n if (idx > -1) draft[idx] = task\n else draft.push(task)\n }\n // remove missing\n for (const id of batchIds) {\n if (!returnedMap.has(id)) {\n const idx = draft.findIndex((t) => t.id === id)\n if (idx > -1) draft.splice(idx, 1)\n }\n }\n })\n } catch (err) {\n console.error('Realtime overview batch update failed', err)\n } finally {\n if (pendingTaskIds.size) schedule()\n }\n }\n let unsubscribeThumbnails: (() => void) | undefined\n try {\n await cacheDataLoaded\n\n unsubscribeThumbnails = subscribeToThumbnailUpdates(\n (messages: ThumbnailUpdateMessage[]) => {\n updateCachedData((draft: EditorTaskNode[]) => {\n messages.forEach((message) => {\n if (message.summary.entityType === 'task' && message.summary.thumbnailHash) {\n const idx = draft.findIndex((t) => t.id === message.summary.entityId)\n if (idx > -1) {\n draft[idx].thumbnailHash = message.summary.thumbnailHash\n }\n }\n })\n })\n },\n ['task'],\n )\n\n const handlePubSub = async (_topic: string, message: any) => {\n const taskId = message?.summary?.entityId\n const parentId = message?.summary?.parentId\n if (!taskId || !parentId) return\n // Only react if the parent folder is part of the current expanded set\n if (!parentIds.includes(parentId)) return\n pendingTaskIds.add(taskId)\n schedule()\n }\n\n // Subscribe to task entity updates\n // NOTE: backend emits topics like 'entity.task.assignees_changed'.\n // Assuming PubSub supports prefix matching when subscribing without the suffix.\n token = PubSub.subscribe('entity.task', handlePubSub)\n } catch (e) {\n // cache entry removed before loaded - ignore\n }\n\n await cacheEntryRemoved\n\n // Evict tracking map memory entry completely when this RTK Query cache entry expires\n const deadCacheKey = getCacheKey(projectName, filter, folderFilter, search, showComments)\n delete queriedFoldersRegistry[deadCacheKey]\n\n if (token) PubSub.unsubscribe(token)\n if (unsubscribeThumbnails) unsubscribeThumbnails()\n },\n keepUnusedDataFor: CACHE_TIME,\n }),\n // searchFolders is a post so it's a bit annoying to consume\n // we wrap it in a queryFn to make it easier to consume as a query hook\n getSearchFolders: build.query<string[], SearchFoldersApiArg>({\n async queryFn({ projectName, folderSearchRequest }, { dispatch }) {\n try {\n const result = await dispatch(\n foldersApiEnhanced.endpoints.searchFolders.initiate({\n projectName,\n folderSearchRequest,\n }),\n )\n\n const data = result.data?.folderIds || []\n\n return { data }\n } catch (e: any) {\n console.error(e)\n const error = { status: 'FETCH_ERROR', error: e.message } as FetchBaseQueryError\n return { error }\n }\n },\n providesTags: (_r, _e, { projectName }) => [{ type: 'tasksFolder', id: projectName }],\n keepUnusedDataFor: CACHE_TIME,\n }),\n // Add new infinite query endpoint for tasks list\n getTasksListInfinite: build.infiniteQuery<\n GetTasksListResult,\n GetTasksListArgs,\n TasksListPageParam\n >({\n infiniteQueryOptions: {\n initialPageParam: { cursor: '', desc: false },\n // Calculate the next page param based on current page response and params\n getNextPageParam: (lastPage, _allPages, lastPageParam, _allPageParams) => {\n // Use the endCursor from the query as the next page param\n const pageInfo = lastPage.pageInfo\n const desc = lastPageParam.desc\n const hasNextPage = desc ? pageInfo.hasPreviousPage : pageInfo.hasNextPage\n\n if (!hasNextPage || !pageInfo.endCursor) return undefined\n\n return {\n cursor: pageInfo.endCursor,\n desc: lastPageParam.desc,\n }\n },\n },\n queryFn: async ({ queryArg, pageParam }, api) => {\n try {\n const {\n projectName,\n filter,\n folderFilter,\n search,\n folderIds,\n taskIds,\n sortBy,\n desc,\n showComments,\n includeFolderChildren,\n } = queryArg\n const { cursor } = pageParam\n\n // Build the query parameters for GetTasksList\n const queryParams: any = {\n projectName,\n filter,\n folderFilter,\n search,\n folderIds,\n taskIds,\n showComments: !!showComments,\n includeFolderChildren: includeFolderChildren !== false, // default to true\n }\n\n // Add cursor-based pagination\n if (sortBy) {\n queryParams.sortBy = sortBy\n if (desc) {\n queryParams.before = cursor || undefined\n queryParams.last = TASKS_INFINITE_QUERY_COUNT\n } else {\n queryParams.after = cursor || undefined\n queryParams.first = TASKS_INFINITE_QUERY_COUNT\n }\n } else {\n queryParams.after = cursor || undefined\n queryParams.first = TASKS_INFINITE_QUERY_COUNT\n }\n\n // Call the existing GetTasksList endpoint\n const result = await api.dispatch(\n enhancedApi.endpoints.GetTasksList.initiate(queryParams, { forceRefetch: true }),\n )\n\n if (result.error) throw result.error\n const fallback = {\n tasks: [],\n pageInfo: {\n hasNextPage: false,\n endCursor: null,\n startCursor: null,\n hasPreviousPage: false,\n },\n }\n\n // Return the tasks directly as required by the infinite query format\n return {\n data: result.data || fallback,\n }\n } catch (e: any) {\n console.error('Error in getTasksListInfinite queryFn:', e)\n return { error: { status: 'FETCH_ERROR', error: e.message } as FetchBaseQueryError }\n }\n },\n providesTags: (result, _e, { projectName }) =>\n getOverviewTaskTags(result?.pages.flatMap((p) => p.tasks) || [], projectName),\n async onCacheEntryAdded(\n arg,\n { cacheDataLoaded, cacheEntryRemoved, updateCachedData, dispatch },\n ) {\n let token: any\n const pendingTaskIds = new Set<string>()\n const MAX_BATCH = 100\n const INTERVAL = 500\n let scheduled = false\n\n const schedule = () => {\n if (scheduled) return\n scheduled = true\n setTimeout(flush, INTERVAL)\n }\n\n const flush = async () => {\n scheduled = false\n if (!pendingTaskIds.size) return\n const batchIds = Array.from(pendingTaskIds).slice(0, MAX_BATCH)\n batchIds.forEach((id) => pendingTaskIds.delete(id))\n try {\n const res = await dispatch(\n enhancedApi.endpoints.GetTasksList.initiate(\n {\n projectName: arg.projectName,\n taskIds: batchIds,\n folderIds: arg.folderIds,\n showComments: !!arg.showComments,\n } as any,\n { forceRefetch: true },\n ),\n ).unwrap()\n\n const returned = res.tasks || []\n const returnedMap = new Map(returned.map((t: EditorTaskNode) => [t.id, t]))\n\n updateCachedData((draft: { pages: GetTasksListResult[]; pageParams: any[] }) => {\n // update/insert\n for (const task of returned) {\n let located = false\n for (const page of draft.pages) {\n const idx = page.tasks.findIndex((t) => t.id === task.id)\n if (idx !== -1) {\n page.tasks[idx] = task\n located = true\n break\n }\n }\n if (!located) {\n if (draft.pages.length) draft.pages[0].tasks.unshift(task)\n else\n draft.pages.push({\n tasks: [task],\n pageInfo: {\n startCursor: null,\n endCursor: null,\n hasNextPage: false,\n hasPreviousPage: false,\n },\n })\n }\n }\n // remove any requested but missing tasks\n for (const id of batchIds) {\n if (returnedMap.has(id)) continue\n for (const page of draft.pages) {\n const idx = page.tasks.findIndex((t) => t.id === id)\n if (idx !== -1) {\n page.tasks.splice(idx, 1)\n break\n }\n }\n }\n })\n } catch (err) {\n console.error('Realtime infinite tasks batch update failed', err)\n } finally {\n if (pendingTaskIds.size) schedule()\n }\n }\n let unsubscribeThumbnails: (() => void) | undefined\n try {\n await cacheDataLoaded\n\n unsubscribeThumbnails = subscribeToThumbnailUpdates(\n (messages: ThumbnailUpdateMessage[]) => {\n updateCachedData((draft: { pages: GetTasksListResult[]; pageParams: any[] }) => {\n messages.forEach((message) => {\n if (message.summary.entityType === 'task' && message.summary.thumbnailHash) {\n for (const page of draft.pages) {\n const idx = page.tasks.findIndex((t) => t.id === message.summary.entityId)\n if (idx > -1) {\n page.tasks[idx].thumbnailHash = message.summary.thumbnailHash\n break\n }\n }\n }\n })\n })\n },\n ['task'],\n )\n\n const handlePubSub = async (_topic: string, message: any) => {\n const taskId = message?.summary?.entityId\n if (!taskId) return\n pendingTaskIds.add(taskId)\n schedule()\n }\n\n token = PubSub.subscribe('entity.task', handlePubSub)\n } catch (_) {\n // ignore\n }\n await cacheEntryRemoved\n if (token) PubSub.unsubscribe(token)\n if (unsubscribeThumbnails) unsubscribeThumbnails()\n },\n keepUnusedDataFor: CACHE_TIME,\n }),\n getGroupedTasksList: build.query<GetGroupedTasksListResult, GetGroupedTasksListArgs>({\n queryFn: async (\n {\n projectName,\n groups,\n search,\n folderFilter,\n folderIds,\n desc,\n sortBy,\n groupCount,\n showComments,\n },\n api,\n ) => {\n try {\n let promises = []\n // Folder-level filter keys that must go in folderFilter, not task filter\n const folderFilterKeys = new Set(['folderType'])\n\n for (const group of groups) {\n // Determine count for this group - use argument override, else group count, else default\n const count = groupCount || group.count || 500\n\n // Separate folder-level conditions from task-level conditions in the group filter\n let taskFilter: string | undefined = group.filter\n let mergedFolderFilter = folderFilter\n if (group.filter) {\n try {\n const parsed = JSON.parse(group.filter)\n const conditions = parsed.conditions || []\n const taskConditions = conditions.filter((c: any) => !folderFilterKeys.has(c.key))\n const folderConditions = conditions.filter((c: any) => folderFilterKeys.has(c.key))\n\n if (folderConditions.length > 0) {\n taskFilter = taskConditions.length\n ? JSON.stringify({ ...parsed, conditions: taskConditions })\n : undefined\n // Merge folder conditions with existing folderFilter, preserving metadata\n const existingFolderFilter = folderFilter ? JSON.parse(folderFilter) : null\n const existingConditions =\n existingFolderFilter && Array.isArray(existingFolderFilter.conditions)\n ? existingFolderFilter.conditions\n : []\n const allFolderConditions = [...existingConditions, ...folderConditions]\n mergedFolderFilter = JSON.stringify(\n existingFolderFilter\n ? { ...existingFolderFilter, conditions: allFolderConditions }\n : { conditions: allFolderConditions },\n )\n }\n } catch {\n // If parsing fails, use the original filter as-is\n }\n }\n\n const queryParams: GetTasksListQueryVariables = {\n projectName,\n filter: taskFilter,\n folderFilter: mergedFolderFilter,\n search,\n folderIds,\n sortBy: sortBy,\n showComments: !!showComments,\n // @ts-expect-error - we know group does not exist on query variables but we need it for later\n group: group.value,\n }\n if (desc) {\n queryParams.last = count\n } else {\n queryParams.first = count\n }\n\n const promise = api.dispatch(\n enhancedApi.endpoints.GetTasksList.initiate(queryParams, { forceRefetch: true }),\n )\n promises.push(promise)\n }\n\n const result = await Promise.all(promises)\n const tasks: EditorTaskNode[] = []\n for (const res of result) {\n if (res.error) throw res.error\n // get group value\n // @ts-expect-error - we know group does exist on res.originalArgs from line 319\n const groupValue = res.originalArgs?.group as string\n\n const hasNextPage =\n res.data?.pageInfo?.hasNextPage || res.data?.pageInfo?.hasPreviousPage || false\n const groupTasks =\n res.data?.tasks.map((task, i, a) => ({\n ...task,\n groups: [\n {\n value: groupValue,\n hasNextPage: i === a.length - 1 && hasNextPage ? groupValue : undefined, // Only add hasNextPage to the last task in the group\n },\n ],\n })) || []\n\n tasks.push(...groupTasks)\n }\n\n // Return the tasks directly as required by the query format\n return {\n data: {\n tasks,\n },\n }\n } catch (error: any) {\n console.error('Error in getGroupedTasksList queryFn:', error)\n return { error: { status: 'FETCH_ERROR', error: error.message } as FetchBaseQueryError }\n }\n },\n providesTags: (result, _e, { projectName }) =>\n getOverviewTaskTags(result?.tasks, projectName),\n keepUnusedDataFor: CACHE_TIME,\n }),\n }),\n})\n\nexport const {\n useGetOverviewTasksByFoldersQuery,\n useGetSearchFoldersQuery,\n useGetTasksListQuery,\n useGetTasksListInfiniteInfiniteQuery,\n useLazyGetTasksByParentQuery,\n useGetGroupedTasksListQuery,\n useGetFolderColumnStatsQuery,\n useGetTaskColumnStatsQuery,\n} = injectedApi\nexport default injectedApi\n"],"names":["CACHE_TIME","parseJSONField","allAttrib","parseAllAttribs","transformFilteredEntitiesByParent","response","tasks","taskNode","getOverviewTaskTags","result","projectName","parentIds","taskTags","task","parentTags","id","enhancedApi","gqlApi","res","_e","normalizeFieldStats","error","transformStatsError","_t","rest","cache","incoming","mergeFieldStats","currentArg","previousArg","hasNewTargetFields","_r","foldersApiEnhanced","foldersApi","TASKS_INFINITE_QUERY_COUNT","queriedFoldersRegistry","getCacheKey","filter","folderFilter","search","showComments","markFoldersAsQueried","cacheKey","folderIds","getQueriedFolders","injectedApi","build","dispatch","getState","forced","state","cacheArgs","cacheData","alreadyQueriedFolders","newFolderIds","allNewTasks","BATCH_SIZE","TASK_PER_FOLDER","MAX_PAGES_PER_BATCH","MAX_FOLDERS","TASKS_PER_PAGE","i","batchFolderIds","hasNextPage","cursor","pageCount","data","fetchedTasks","pageInfo","finalTasks","uniqueTasksMap","e","cacheDataLoaded","cacheEntryRemoved","updateCachedData","token","pendingTaskIds","MAX_BATCH","INTERVAL","scheduled","schedule","flush","batchIds","returned","returnedMap","t","draft","idx","err","unsubscribeThumbnails","subscribeToThumbnailUpdates","messages","message","handlePubSub","_topic","taskId","parentId","PubSub","deadCacheKey","folderSearchRequest","lastPage","_allPages","lastPageParam","_allPageParams","queryArg","pageParam","api","taskIds","sortBy","desc","includeFolderChildren","queryParams","fallback","p","arg","located","page","groups","groupCount","promises","folderFilterKeys","group","count","taskFilter","mergedFolderFilter","parsed","conditions","taskConditions","c","folderConditions","existingFolderFilter","allFolderConditions","promise","groupValue","groupTasks","a","useGetOverviewTasksByFoldersQuery","useGetSearchFoldersQuery","useGetTasksListQuery","useGetTasksListInfiniteInfiniteQuery","useLazyGetTasksByParentQuery","useGetGroupedTasksListQuery","useGetFolderColumnStatsQuery","useGetTaskColumnStatsQuery"],"mappings":"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"}
|