@overmap-ai/core 1.0.71-procedures.2 → 1.0.71-project-file-improvements.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/overmap-core.js +2057 -3969
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +1262 -3174
- package/dist/overmap-core.umd.cjs.map +1 -1
- package/dist/sdk/services/AssetAttachmentService.d.ts +8 -32
- package/dist/sdk/services/AssetService.d.ts +1 -1
- package/dist/sdk/services/AssetStageService.d.ts +6 -4
- package/dist/sdk/services/AssetTypeAttachmentService.d.ts +9 -32
- package/dist/sdk/services/AssetTypeService.d.ts +1 -1
- package/dist/sdk/services/BaseAttachmentService.d.ts +20 -18
- package/dist/sdk/services/BaseUploadService.d.ts +1 -2
- package/dist/sdk/services/DocumentAttachmentService.d.ts +8 -30
- package/dist/sdk/services/FormService.d.ts +14 -11
- package/dist/sdk/services/FormSubmissionService.d.ts +28 -8
- package/dist/sdk/services/IssueAssociationService.d.ts +2 -2
- package/dist/sdk/services/IssueAttachmentService.d.ts +8 -31
- package/dist/sdk/services/IssueService.d.ts +3 -0
- package/dist/sdk/services/ProjectAttachmentService.d.ts +8 -31
- package/dist/sdk/services/ProjectFileService.d.ts +7 -7
- package/dist/sdk/services/index.d.ts +0 -17
- package/dist/store/slices/assetStageCompletionSlice.d.ts +4 -3
- package/dist/store/slices/assetStageSlice.d.ts +3 -2
- package/dist/store/slices/formRevisionSlice.d.ts +2 -1
- package/dist/store/slices/formSlice.d.ts +5 -1
- package/dist/store/slices/formSubmissionSlice.d.ts +6 -0
- package/dist/store/slices/index.d.ts +0 -14
- package/dist/store/slices/projectFileSlice.d.ts +34 -29
- package/dist/store/store.d.ts +3 -17
- package/dist/typings/files.d.ts +4 -8
- package/dist/typings/models/assets.d.ts +5 -44
- package/dist/typings/models/attachments.d.ts +6 -1
- package/dist/typings/models/forms.d.ts +29 -12
- package/dist/typings/models/geoImages.d.ts +2 -2
- package/dist/typings/models/index.d.ts +0 -1
- package/dist/typings/models/issues.d.ts +0 -15
- package/dist/typings/models/projects.d.ts +4 -1
- package/dist/typings/models/store.d.ts +1 -15
- package/dist/utils/file.d.ts +2 -2
- package/package.json +1 -1
- package/dist/sdk/services/AssetProcedureFieldValuesAttachmentService.d.ts +0 -15
- package/dist/sdk/services/AssetProcedureFieldValuesService.d.ts +0 -21
- package/dist/sdk/services/AssetProcedureFieldsAttachmentService.d.ts +0 -12
- package/dist/sdk/services/AssetProcedureFieldsService.d.ts +0 -8
- package/dist/sdk/services/AssetProcedureInstanceService.d.ts +0 -10
- package/dist/sdk/services/AssetProcedureService.d.ts +0 -10
- package/dist/sdk/services/AssetTypeFieldValuesAttachmentService.d.ts +0 -12
- package/dist/sdk/services/AssetTypeFieldValuesService.d.ts +0 -20
- package/dist/sdk/services/AssetTypeFieldsAttachmentService.d.ts +0 -12
- package/dist/sdk/services/AssetTypeFieldsService.d.ts +0 -8
- package/dist/sdk/services/FormRevisionAttachmentService.d.ts +0 -12
- package/dist/sdk/services/FormRevisionService.d.ts +0 -8
- package/dist/sdk/services/FormSubmissionAttachmentService.d.ts +0 -13
- package/dist/sdk/services/IssueTypeFieldValuesAttachmentService.d.ts +0 -13
- package/dist/sdk/services/IssueTypeFieldValuesService.d.ts +0 -10
- package/dist/sdk/services/IssueTypeFieldsAttachmentService.d.ts +0 -12
- package/dist/sdk/services/IssueTypeFieldsService.d.ts +0 -8
- package/dist/store/slices/assetProcedureFieldValuesAttachmentSlice.d.ts +0 -53
- package/dist/store/slices/assetProcedureFieldValuesSlice.d.ts +0 -53
- package/dist/store/slices/assetProcedureFieldsAttachmentSlice.d.ts +0 -52
- package/dist/store/slices/assetProcedureFieldsSlice.d.ts +0 -53
- package/dist/store/slices/assetProcedureInstanceSlice.d.ts +0 -54
- package/dist/store/slices/assetProcedureSlice.d.ts +0 -53
- package/dist/store/slices/assetTypeFieldValuesAttachmentSlice.d.ts +0 -53
- package/dist/store/slices/assetTypeFieldValuesSlice.d.ts +0 -53
- package/dist/store/slices/assetTypeFieldsAttachmentSlice.d.ts +0 -52
- package/dist/store/slices/assetTypeFieldsSlice.d.ts +0 -53
- package/dist/store/slices/issueTypeFieldValuesAttachmentSlice.d.ts +0 -53
- package/dist/store/slices/issueTypeFieldValuesSlice.d.ts +0 -52
- package/dist/store/slices/issueTypeFieldsAttachmentSlice.d.ts +0 -52
- package/dist/store/slices/issueTypeFieldsSlice.d.ts +0 -54
- package/dist/typings/models/fields.d.ts +0 -16
package/dist/overmap-core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overmap-core.js","sources":["../src/enums/api.ts","../src/enums/attachments.ts","../src/enums/issue.ts","../src/enums/access.ts","../src/enums/licenses.ts","../src/sdk/classes/OutboxCoordinator.ts","../src/sdk/errors.ts","../src/utils/coordinates.ts","../src/utils/file.ts","../src/utils/logging.ts","../src/utils/offline.ts","../src/utils/string.ts","../src/utils/utils.ts","../src/constants/defaults.ts","../src/constants/offline.ts","../src/constants/array.ts","../src/utils/optimization.ts","../src/utils/colors.ts","../src/utils/date.ts","../src/utils/async/DeferredPromise.ts","../node_modules/redux/es/redux.js","../src/store/migrations.ts","../src/sdk/globals.ts","../src/sdk/services/BaseService.ts","../src/store/slices/authSlice.ts","../src/store/adapter.ts","../src/store/slices/categorySlice.ts","../src/store/slices/assetSlice.ts","../src/store/slices/assetAttachmentSlice.ts","../src/store/slices/assetStageCompletionSlice.ts","../src/store/slices/assetStageSlice.ts","../src/store/slices/assetTypeSlice.ts","../src/store/slices/assetTypeAttachmentSlice.ts","../src/store/slices/issueSlice.ts","../src/store/slices/issueTypeSlice.ts","../src/store/slices/fileSlice.ts","../src/store/slices/userSlice.ts","../src/store/slices/organizationAccessSlice.ts","../src/store/slices/licenseSlice.ts","../src/store/slices/projectAccessSlice.ts","../src/store/slices/projectSlice.ts","../src/store/slices/organizationSlice.ts","../src/store/slices/outboxSlice.ts","../src/store/slices/projectFileSlice.ts","../src/store/slices/projectAttachmentSlice.ts","../src/store/slices/rehydratedSlice.ts","../src/utils/forms.ts","../src/store/slices/formRevisionSlice.ts","../src/store/slices/formSlice.ts","../src/store/slices/formSubmissionSlice.ts","../src/store/slices/formSubmissionAttachmentSlice.ts","../src/store/slices/formRevisionAttachmentSlice.ts","../src/store/slices/workspaceSlice.ts","../src/store/slices/emailDomainsSlice.ts","../src/store/slices/documentSlice.ts","../src/store/slices/documentAttachmentSlice.ts","../src/store/slices/teamSlice.ts","../src/store/slices/agentsSlice.ts","../src/store/slices/issueCommentSlice.ts","../src/store/slices/issueUpdateSlice.ts","../src/store/slices/issueAttachmentSlice.ts","../src/store/slices/versioningSlice.ts","../src/store/slices/geoImageSlice.ts","../src/store/slices/issueAssociationSlice.ts","../src/store/slices/issueTypeFieldValuesSlice.ts","../src/store/slices/issueTypeFieldsSlice.ts","../src/store/slices/issueTypeFieldsAttachmentSlice.ts","../src/store/slices/issueTypeFieldValuesAttachmentSlice.ts","../src/store/slices/assetTypeFieldsSlice.ts","../src/store/slices/assetTypeFieldValuesSlice.ts","../src/store/slices/assetTypeFieldsAttachmentSlice.ts","../src/store/slices/assetTypeFieldValuesAttachmentSlice.ts","../src/store/slices/assetProcedureSlice.ts","../src/store/slices/assetProcedureInstanceSlice.ts","../src/store/slices/assetProcedureFieldsSlice.ts","../src/store/slices/assetProcedureFieldValuesSlice.ts","../src/store/slices/assetProcedureFieldsAttachmentSlice.ts","../src/store/slices/assetProcedureFieldValuesAttachmentSlice.ts","../src/store/store.ts","../src/sdk/base.ts","../src/sdk/sdk.ts","../src/sdk/services/BaseAuthService.ts","../src/sdk/services/JWTAuthService.ts","../src/sdk/services/BaseApiService.ts","../src/sdk/services/CategoryService.ts","../src/utils/array.ts","../src/sdk/services/AssetService.ts","../src/sdk/services/AssetStageCompletionService.ts","../src/sdk/services/AssetStageService.ts","../src/sdk/services/BaseUploadService.ts","../src/sdk/services/BaseAttachmentService.ts","../src/sdk/services/AssetAttachmentService.ts","../src/sdk/services/AssetTypeService.ts","../src/sdk/services/AssetTypeAttachmentService.ts","../src/sdk/services/IssueCommentService.ts","../src/sdk/services/IssueUpdateService.ts","../src/sdk/services/IssueAttachmentService.ts","../src/sdk/services/IssueService.ts","../src/sdk/services/IssueTypeService.ts","../src/sdk/services/ProjectAccessService.ts","../src/sdk/services/ProjectFileService.ts","../src/sdk/services/ProjectAttachmentService.ts","../src/sdk/services/ProjectService.ts","../src/sdk/services/FormService.ts","../src/sdk/services/FormSubmissionService.ts","../src/sdk/services/WorkspaceService.ts","../src/sdk/services/OrganizationAccessService.ts","../src/sdk/services/FileService.ts","../src/sdk/services/EmailVerificationService.ts","../src/sdk/services/EmailDomainsService.ts","../src/sdk/services/OrganizationService.ts","../src/sdk/services/LicenseService.ts","../src/sdk/services/DocumentService.ts","../src/sdk/services/DocumentAttachmentService.ts","../src/sdk/services/AgentService.ts","../src/sdk/services/TeamService.ts","../src/sdk/services/UserService.ts","../src/sdk/services/GeoImageService.ts","../src/sdk/services/IssueAssociationService.ts","../src/sdk/services/FormRevisionAttachmentService.ts","../src/sdk/services/FormSubmissionAttachmentService.ts","../src/sdk/services/FormRevisionService.ts","../src/sdk/services/AssetTypeFieldsAttachmentService.ts","../src/sdk/services/AssetTypeFieldsService.ts","../src/sdk/services/AssetTypeFieldValuesService.ts","../src/sdk/services/AssetTypeFieldValuesAttachmentService.ts","../src/sdk/services/IssueTypeFieldsAttachmentService.ts","../src/sdk/services/IssueTypeFieldsService.ts","../src/sdk/services/IssueTypeFieldValuesAttachmentService.ts","../src/sdk/services/IssueTypeFieldValuesService.ts","../src/sdk/services/AssetProcedureInstanceService.ts","../src/sdk/services/AssetProcedureService.ts","../src/sdk/services/AssetProcedureFieldsAttachmentService.ts","../src/sdk/services/AssetProcedureFieldsService.ts","../src/sdk/services/AssetProcedureFieldValuesAttachmentService.ts","../src/sdk/services/AssetProcedureFieldValuesService.ts","../src/typings/models/emailVerification.ts"],"sourcesContent":["export const enum HttpMethod {\n\tGET = \"GET\",\n\tPOST = \"POST\",\n\tPATCH = \"PATCH\",\n\tPUT = \"PUT\",\n\tDELETE = \"DELETE\",\n\t// TODO: Add support\n\t// OPTIONS = \"OPTIONS\",\n}\n","export enum AttachmentModel {\n\tIssue = \"issue\",\n\tAsset = \"asset\",\n\tAssetType = \"asset_type\",\n\tProject = \"project\",\n\tDocument = \"document\",\n}\n","export enum IssuePriority {\n\tLOWEST = 0,\n\tLOW = 2,\n\tMEDIUM = 4,\n\tHIGH = 6,\n\tHIGHEST = 8,\n}\n\nexport enum IssueStatus {\n\tBACKLOG = 0,\n\tSELECTED = 2,\n\tDONE = 4,\n}\n\nexport enum IssueUpdateChange {\n\tSTATUS = \"status\",\n\tPRIORITY = \"priority\",\n\tCATEGORY = \"category\",\n\tDESCRIPTION = \"description\",\n\tTITLE = \"title\",\n\tASSIGNED_TO = \"assigned_to\",\n\tDUE_DATE = \"due_date\",\n}\n","export enum ProjectAccessLevel {\n\tBASIC = 0,\n\tADMIN = 2,\n}\n\nexport enum OrganizationAccessLevel {\n\tBASIC = 0,\n\tADMIN = 2,\n}\n","export enum PaddleCheckoutEvent {\n\tCOMPLETED = \"checkout.completed\",\n\tCLOSED = \"checkout.closed\",\n}\n\nexport enum LicenseLevel {\n\tPRO = 0,\n}\n\nexport enum LicenseStatus {\n\tACTIVE = 0,\n\tPAUSED = 2,\n\tCANCELLED = 4,\n\tINACTIVE = 6,\n\tPAST_DUE = 8,\n}\n","import { DepGraph } from \"dependency-graph\"\nimport type { FullOfflineAction } from \"../../store\"\nimport { Outbox } from \"@redux-offline/redux-offline/lib/types\"\n\n// TODO: Tests:\n// - Bulk-create components, then delete one of those components. Ensure the dependency to the bulk-create is found.\n\nexport class OutboxCoordinator {\n\tgraph: DepGraph<FullOfflineAction>\n\trequestAttemptCounter: Record<string, number>\n\n\tconstructor() {\n\t\tthis.graph = new DepGraph()\n\t\tthis.requestAttemptCounter = {}\n\t}\n\n\t/**\n\t * Used when the app is loaded. Reconstructs the dependency graph based on an outbox from the redux-offline store.\n\t */\n\tstatic _fromOutbox(outbox: Outbox): OutboxCoordinator {\n\t\tconst ret = new OutboxCoordinator()\n\n\t\tfor (let i = 0; i < outbox.length; i++) {\n\t\t\tconst outboxItem = outbox[i] as FullOfflineAction | undefined\n\t\t\tif (!outboxItem) {\n\t\t\t\tconsole.error(\"Outbox item was undefined\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tret.sneakRequest(outboxItem)\n\t\t\t// Add any dependencies to requests that were added before this one\n\t\t\tfor (let j = 0; j < i; j++) {\n\t\t\t\tconst previousOutboxItem = outbox[j] as FullOfflineAction | undefined\n\t\t\t\tif (!previousOutboxItem) {\n\t\t\t\t\tconsole.error(\"Previous outbox item was undefined\")\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (previousOutboxItem.payload.uuid === outboxItem.payload.uuid) {\n\t\t\t\t\tcontinue // Skip self\n\t\t\t\t}\n\t\t\t\tif (previousOutboxItem.payload.blocks.some((block) => outboxItem.payload.blockers.includes(block))) {\n\t\t\t\t\tOutboxCoordinator._addDependency(\n\t\t\t\t\t\toutboxItem.payload.uuid,\n\t\t\t\t\t\tpreviousOutboxItem.payload.uuid,\n\t\t\t\t\t\tret.graph,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret\n\t}\n\n\t_addDependency(from: string, to: string) {\n\t\tOutboxCoordinator._addDependency(from, to, this.graph)\n\t}\n\n\tstatic _addDependency(from: string, to: string, graph: DepGraph<FullOfflineAction>) {\n\t\tif (from === to) {\n\t\t\tthrow new Error(`Tried to add dependency from node to itself: ${from}`)\n\t\t}\n\t\tconst fromExists = graph.hasNode(from)\n\t\tif (!fromExists) {\n\t\t\tthrow new Error(`Tried to add dependency from non-existent node: ${from} (to node: ${to})`)\n\t\t}\n\t\tconst toExists = graph.hasNode(to)\n\t\tif (!toExists) {\n\t\t\tthrow new Error(`Tried to add dependency to non-existent node: ${to} (from node: ${from})`)\n\t\t}\n\t\tgraph.addDependency(from, to)\n\t}\n\n\t/**\n\t * If there are one or more nodes in the graph, we find all nodes that match a dependency of the request and add a\n\t * dependency from the new request node to that node.\n\t */\n\taddRequest(request: FullOfflineAction) {\n\t\tthis.graph.addNode(request.payload.uuid, request)\n\n\t\tif (request.payload.blockers.length === 0 || this.graph.size() === 1) {\n\t\t\t// The request has no dependencies, or there are no other nodes in the graph, so there are no dependencies\n\t\t\t// to create.\n\t\t\treturn\n\t\t}\n\n\t\t// Create dependencies according to the request's blockers\n\t\tfor (const node of this.graph.overallOrder()) {\n\t\t\tif (node === request.payload.uuid) continue // Skip the node we just added\n\t\t\tconst details = this.graph.getNodeData(node)\n\t\t\t// 1. Any node matching this request's offline_id\n\t\t\tif (request.payload.blockers.some((blocker) => details.payload.blocks.includes(blocker))) {\n\t\t\t\tthis._addDependency(request.payload.uuid, node)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Inserts a request at the beginning of the queue. This could be used for requests that were popped, then failed,\n\t * and need to be re-enqueued at the front of the queue. Any requests that were previously blocked by this request\n\t * will be blocked by this request again. No blockers will be added to this request because it is assumed that the\n\t * request was already unblocked when it was popped.\n\t * @param request The request to insert at the beginning of the queue.\n\t */\n\tinsertRequest(request: FullOfflineAction) {\n\t\tthis.graph.addNode(request.payload.uuid, request)\n\n\t\t// Create dependencies according to the request's blockers\n\t\tfor (const node of this.graph.overallOrder()) {\n\t\t\tif (node === request.payload.uuid) continue // Skip the request we just inserted\n\t\t\tconst details = this.graph.getNodeData(node)\n\t\t\t// 1. Any node matching this request's offline_id\n\t\t\tif (details.payload.blockers.some((blocker) => request.payload.blocks.includes(blocker))) {\n\t\t\t\tthis._addDependency(node, request.payload.uuid)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Sneaks a request into the dependency graph without creating any blockers. Useful for reconstructing the graph\n\t * (from the offline store's outbox state) when the app is loaded.\n\t */\n\tsneakRequest(request: FullOfflineAction) {\n\t\tthis.graph.addNode(request.payload.uuid, request)\n\t}\n\n\t/**\n\t * Returns the next node in line to be sent. This is the unblocked node with the fewest number of attempts. If there\n\t * are multiple nodes with the same number of attempts, the first one (by insertion order) will be returned.\n\t */\n\t_getNextNode(): string | undefined {\n\t\tconst leafNodes = this.graph.overallOrder(true)\n\t\tlet minAttempts = Infinity\n\t\tlet minAttemptsNode: string | undefined\n\t\tfor (const node of leafNodes) {\n\t\t\tconst attempts = this.requestAttemptCounter[node] || 0\n\t\t\tif (attempts < minAttempts) {\n\t\t\t\tminAttempts = attempts\n\t\t\t\tminAttemptsNode = node\n\t\t\t}\n\t\t}\n\t\treturn minAttemptsNode\n\t}\n\n\t/**\n\t * Returns the next request in line to be sent without removing it.\n\t */\n\tpeek(): FullOfflineAction | undefined {\n\t\tconst nextNode = this._getNextNode()\n\t\tif (!nextNode) return undefined\n\t\treturn this.graph.getNodeData(nextNode)\n\t}\n\n\t/**\n\t * Removes a request from the graph. This should be called when a request is successfully sent.\n\t * @param uuid The UUID of the request to remove.\n\t */\n\tremove(uuid: string): void {\n\t\tthis.graph.removeNode(uuid)\n\t\tdelete this.requestAttemptCounter[uuid]\n\t}\n\n\t/**\n\t * Returns the next request in line to be sent and removes it from the graph.\n\t */\n\tpop(): FullOfflineAction | undefined {\n\t\tconst nextRequestDetails = this.peek()\n\t\tif (nextRequestDetails) {\n\t\t\tthis.graph.removeNode(nextRequestDetails.payload.uuid)\n\t\t}\n\t\treturn nextRequestDetails\n\t}\n\n\t/**\n\t * Gets the current queue for the outbox. Should be called to get a new value for the outbox slice every time a\n\t * request is enqueued. It will be used to render the outbox items in a single lane.\n\t */\n\tgetQueue(): FullOfflineAction[] {\n\t\tconst ret = this.graph.overallOrder().map((nodeName) => this.graph.getNodeData(nodeName))\n\n\t\t// We will return the normal overall order, except we put the request with the fewest number of attempts at the\n\t\t// front of the queue, assuming it is not blocked.\n\t\tconst nextNode = this._getNextNode()\n\t\tif (nextNode) {\n\t\t\tconst nextRequestDetails = this.graph.getNodeData(nextNode)\n\t\t\tconst nextRequestIndex = ret.findIndex(\n\t\t\t\t(request) => request.payload.uuid === nextRequestDetails.payload.uuid,\n\t\t\t)\n\t\t\tif (nextRequestIndex !== -1) {\n\t\t\t\tret.splice(nextRequestIndex, 1)\n\t\t\t\tret.unshift(nextRequestDetails)\n\t\t\t}\n\t\t}\n\n\t\treturn ret\n\t}\n\n\t/**\n\t * Gets a list of requests that can currently be sent (requests with no unresolved dependencies). Used to process\n\t * the next ready request in case the request at the front of the queue is failing.\n\t */\n\tgetReady(): FullOfflineAction[] {\n\t\tlet ret = this.graph.overallOrder(true).map((nodeName) => this.graph.getNodeData(nodeName))\n\t\t// First, order by insertion order\n\t\tret = ret.sort((a, b) => {\n\t\t\treturn a.meta.offline.effect.timestamp.localeCompare(b.meta.offline.effect.timestamp)\n\t\t})\n\t\t// Then, order by number of attempts\n\t\tret = ret.sort((a, b) => {\n\t\t\tconst aAttempts = this.requestAttemptCounter[a.payload.uuid] || 0\n\t\t\tconst bAttempts = this.requestAttemptCounter[b.payload.uuid] || 0\n\t\t\t// If these are equal, we want to keep the insertion order, which should be maintained from the previous\n\t\t\t// sort if we return 0.\n\t\t\treturn aAttempts - bAttempts\n\t\t})\n\t\treturn ret\n\t}\n\n\tregisterRetry(uuid: string): void {\n\t\tthis.requestAttemptCounter[uuid] = (this.requestAttemptCounter[uuid] || 0) + 1\n\t}\n}\n\n// TODO: Consider auto-discovering UUIDs instead of (or in addition to) explicitly passing them to `enqueueRequest`\n/**\n * Given a request, returns an array of discovered UUIDs referenced in the request.\n * Discovers UUIDs in the URL, body, and query string.\n * @param request\n */\n/*\nfunction _discoverUuids(request: RequestDetails): Set<string> {\n\t// We need to consider:\n\t// 1. Any UUID in the URL\n\t// 2. Any UUID in the body\n\t// 3. Any UUID in the query parameters\n\n\tconst ret = new Set<string>()\n\n\tfunction discoverUuidsInArray(values: unknown[]): void {\n\t\tfor (const value of values) {\n\t\t\tif (typeof value === \"string\" && value.length === 36 && UUID_REGEX.test(value)) {\n\t\t\t\tret.add(value)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst urlParts = request.url.split(\"/\")\n\n\tdiscoverUuidsInArray(urlParts)\n\n\tif (request.payload) {\n\t\tdiscoverUuidsInArray(Object.values(request.payload))\n\t}\n\n\tif (request.queryParams) {\n\t\tdiscoverUuidsInArray(Object.values(request.queryParams))\n\t}\n\n\treturn ret\n}\n */\n","// Contains custom error classes used by the SDK\n\nimport request from \"superagent\"\n\nexport interface APIErrorOptions {\n\tresponse?: request.Response\n\tinnerError?: unknown // Most likely an Error\n\tmessage?: string\n\tdiscard?: boolean\n}\n\nconst UNKNOWN_ERROR_MESSAGE = \"An unknown error occurred\"\nconst MAX_ERROR_MESSAGE_LENGTH = 500\nconst _SPECIAL_KEYS = [\"non_field_errors\", \"detail\"]\n\n/**\n * Makes a best-effort attempt to extract an error message from a request.Response or an error object.\n * @param errorRes The response object from a request, if available\n * @param err The error object, if available\n */\nfunction extractErrorMessage(errorRes: request.Response | undefined, err: unknown): string | undefined {\n\tlet ret: string | undefined\n\tif (errorRes?.body) {\n\t\tif (typeof errorRes.body === \"object\") {\n\t\t\tconst responseBody = errorRes.body as {\n\t\t\t\terror?: string\n\t\t\t\tmessage?: string\n\t\t\t\tbody?: Record<string, string | string[]>\n\t\t\t}\n\t\t\tif (typeof responseBody.error === \"string\") {\n\t\t\t\tret = responseBody.error\n\t\t\t} else if (typeof responseBody.message === \"string\") {\n\t\t\t\tret = responseBody.message\n\t\t\t} else if (responseBody.body) {\n\t\t\t\t// The error message may be something like this:\n\t\t\t\t// \t\t{\n\t\t\t\t// \t\t\tname: [\"This name is already taken.\", \"This name is too short.\"],\n\t\t\t\t// \t\t\temail: \"This email is already taken\",\n\t\t\t\t//\t\t\tnon_field_errors: [\"This username is already taken.\"]\n\t\t\t\t// \t\t}\n\t\t\t\t// We want to convert this into:\n\t\t\t\t// \t\tName: This name is already taken.\n\t\t\t\t// \t\tName: This name is too short.\n\t\t\t\t// \t\tEmail: This email is already taken\n\t\t\t\t//\t\tThis username is already taken.\n\t\t\t\t// TODO: Support bold field names without using unsafe HTML\n\t\t\t\ttry {\n\t\t\t\t\tret = Object.entries(responseBody.body)\n\t\t\t\t\t\t.map(([key, value]) => {\n\t\t\t\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\t\t\t\tif (_SPECIAL_KEYS.includes(key)) return value\n\t\t\t\t\t\t\t\treturn `${key}: ${value}`\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t\t\t\tif (_SPECIAL_KEYS.includes(key)) return value.join(\"\\n\")\n\t\t\t\t\t\t\t\treturn value.map((v) => `${key}: ${v}`).join(\"\\n\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn `${key}: ${JSON.stringify(value)}`\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(\"\\n\")\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.error(\"Failed to extract error message from response body\", e)\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (typeof errorRes.body === \"string\") {\n\t\t\tret = errorRes.body\n\t\t}\n\t} else if (errorRes?.text) {\n\t\tret = errorRes.text\n\t} else if (err instanceof Error) {\n\t\tret = err.message\n\t}\n\n\t// Check the length of the message. If it's too long, show a generic message instead.\n\t// This can happen if the backend returns a document instead of a JSON object.\n\tif (!ret || ret.length > MAX_ERROR_MESSAGE_LENGTH) {\n\t\treturn UNKNOWN_ERROR_MESSAGE\n\t}\n\treturn ret\n}\n\nexport class APIError extends Error {\n\t// NOTE: Needs to conform to NetworkError in @redux-offline/redux-offline, which has `status` and `response`.\n\tstatus: number\n\tresponse: request.Response | undefined\n\tmessage: string\n\toptions: APIErrorOptions\n\n\tconstructor(options: APIErrorOptions) {\n\t\tsuper(UNKNOWN_ERROR_MESSAGE)\n\t\tconst { response, innerError } = options\n\t\tthis.message = options.message ?? extractErrorMessage(response, innerError) ?? UNKNOWN_ERROR_MESSAGE\n\t\tthis.status = response?.status ?? 0\n\t\tthis.response = response\n\t\toptions.discard = options.discard ?? false\n\t\tthis.options = options\n\t}\n}\n","import L from \"leaflet\"\nimport { Bounds, Coordinates, MultiPointGeometry, PointGeometry } from \"../typings\"\n\n// Convert our Coordinates type into a Leaflet LatLngLiteral\nexport const coordinatesToLiteral = (coordinates: Coordinates): L.LatLngLiteral => {\n\treturn { lng: coordinates[0], lat: coordinates[1] }\n}\n\n// Convert a Leaflet LatLngLiteral into our Coordinates type\nexport const literalToCoordinates = (literal: L.LatLngLiteral): Coordinates => {\n\treturn [literal.lng, literal.lat]\n}\n\n/**\n * Flip coordinates from [lng, lat] to [lat, lng]\n */\nexport const flipCoordinates = (coordinates: L.LatLngTuple): Coordinates => {\n\treturn [coordinates[1], coordinates[0]]\n}\n\nexport const flipBounds = (bounds: Bounds): Bounds => {\n\treturn [flipCoordinates(bounds[0]), flipCoordinates(bounds[1])]\n}\n\nexport function offsetPositionByMeters(\n\toriginalPosition: L.LatLng,\n\tlatMeters: number,\n\tlngMeters: number,\n): L.LatLngLiteral {\n\tconst { lat, lng } = originalPosition\n\tconst earthRadius = 6378137 // Earth's radius in meters.\n\tconst metersPerDegree = (2 * Math.PI * earthRadius) / 360\n\t// The significance of one degree decreases the closer you get to a pole. This accounts for that.\n\tconst newLng = lng + lngMeters / metersPerDegree / Math.cos((lat * Math.PI) / 180)\n\tconst newLat = lat - latMeters / metersPerDegree\n\treturn { lat: newLat, lng: newLng }\n}\n\nexport const createPointGeometry = (coordinates: Coordinates): PointGeometry => {\n\treturn {\n\t\ttype: \"Point\",\n\t\tcoordinates,\n\t}\n}\n\nexport const coordinatesAreEqual = (a: Coordinates, b: Coordinates): boolean => {\n\treturn a[0] === b[0] && a[1] === b[1]\n}\n\n// export const coordinatesAreNearlyEqual = (a: Coordinates, b: Coordinates, thresholdMeters: number): boolean => {\n// return a === b\n// TODO: Fix\n// const diffLat = Math.abs(a[1] - b[1])\n// Length in km of 1° of latitude = always 111.32 km\n// const diffLatMeters = diffLat * 111320\n// if (diffLatMeters < thresholdMeters) return true\n// Length in km of 1° of longitude = 40075 km * cos(latitude) / 360'\n// const aVal = a[0] // Optimization\n// const diffLong = Math.abs(aVal - b[0])\n// const diffLongMeters = diffLong * ((40075000 * Math.cos(aVal)) / 360)\n// return diffLongMeters < thresholdMeters\n// }\n\n// This converts a Coordinate [lng, lat] to \"lat, lng\" string format with an option to round the numbers\nexport const coordinatesToText = (coordinates: Coordinates | null | undefined, decimalPlaces?: number) => {\n\tif (!coordinates) return \"(No Location)\"\n\tconst { lat, lng } = coordinatesToLiteral(coordinates)\n\tif (decimalPlaces) return `${lat.toFixed(decimalPlaces)}, ${lng.toFixed(decimalPlaces)}`\n\treturn `${lat}, ${lng}`\n}\n\nexport const coordinatesToUrlText = (coordinates: Coordinates) => {\n\tconst { lat, lng } = coordinatesToLiteral(coordinates)\n\treturn `${lat}%2C${lng}`\n}\n\n// Opens coordinates in Google maps\nexport const openCoordsInGoogleMaps = (coordinates: Coordinates) => {\n\tconst url = `https://www.google.com/maps/search/?api=1&query=${coordinatesToUrlText(coordinates)}`\n\twindow.open(url)\n}\n\nexport const openDirectionsInGoogleMaps = (startingPoint: Coordinates, destination: Coordinates) => {\n\tconst startingPointUrl = coordinatesToUrlText(startingPoint)\n\tconst destinationUrl = coordinatesToUrlText(destination)\n\tconst url = `https://www.google.com/maps/dir/?api=1&origin=${startingPointUrl}&destination=${destinationUrl}`\n\twindow.open(url)\n}\n\nexport const worldBounds: MultiPointGeometry = {\n\ttype: \"MultiPoint\",\n\tcoordinates: [\n\t\t[90, -180],\n\t\t[-90, 180],\n\t],\n}\n\nexport const createMultiPointGeometry = (coordinates: [Coordinates, Coordinates]): MultiPointGeometry => {\n\treturn {\n\t\ttype: \"MultiPoint\",\n\t\tcoordinates,\n\t}\n}\n","import { saveAs } from \"file-saver\"\nimport type { FilePayload } from \"../typings\"\n\n// See: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string\nfunction hex(buffer: ArrayBufferLike): string {\n\tconst hashArray = new Uint8Array(buffer)\n\n\treturn hashArray.reduce((data, byte) => data + byte.toString(16).padStart(2, \"0\"), \"\")\n}\n\nexport const getFileS3Key = async (file: File, hash?: string) => {\n\tif (!hash) {\n\t\thash = await hashFile(file)\n\t}\n\tlet fileType = file.type\n\tif (fileType.includes(\"/\")) {\n\t\tfileType = fileType.split(\"/\")[1]!\n\t}\n\tif (!fileType) {\n\t\tthrow new Error(`Could not extract file type from ${file.type}`)\n\t}\n\treturn `${hash}.${fileType}`\n}\n\nexport function hashFile(file: Blob): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst reader = new FileReader()\n\t\t// Provide an onload callback for this instance of FileReader\n\t\t// This is called once reader.readAsArrayBuffer() is done\n\t\treader.onload = () => {\n\t\t\tconst fileResult = reader.result as ArrayBuffer | null\n\t\t\tif (!fileResult) {\n\t\t\t\treject()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tvoid crypto.subtle.digest(\"SHA-1\", fileResult).then((hash) => {\n\t\t\t\tconst sha1result = hex(hash)\n\t\t\t\tresolve(sha1result)\n\t\t\t})\n\t\t}\n\n\t\t// calling reader.readAsArrayBuffer and providing a file should trigger the callback above\n\t\t// as soon as readAsArrayBuffer is complete\n\t\treader.readAsArrayBuffer(file)\n\t})\n}\n\nexport function getFileIdentifier(file: File): string {\n\tif (!file.name || !file.type || !file.size) {\n\t\tconst message = \"File has no name, type, and/or size\"\n\t\tconsole.error(`${message}`, file)\n\t\tthrow new Error(`${message}.`)\n\t}\n\treturn `${file.name}&${file.type}${file.size}`\n}\n\nexport function getRenamedFile(file: File, newName: string): File & { name: string } {\n\treturn new File([file], newName, { type: file.type })\n}\n\nexport function downloadInMemoryFile(filename: string, text: string) {\n\tconst element = document.createElement(\"a\")\n\telement.setAttribute(\"href\", \"data:text/plain;charset=utf-8,\" + encodeURIComponent(text))\n\telement.setAttribute(\"download\", filename)\n\n\telement.style.display = \"none\"\n\tdocument.body.appendChild(element)\n\n\telement.click()\n\n\tdocument.body.removeChild(element)\n}\n\n// TODO: implement to not block ui when hashing https://developer.chrome.com/blog/introducing-scheduler-yield-origin-trial\nexport const constructUploadedFilePayloads = async (files: File[]): Promise<FilePayload[]> => {\n\tconst filePayloads: Record<string, FilePayload> = {}\n\tfor (const file of files) {\n\t\tconst sha1 = await hashFile(file)\n\t\tfilePayloads[sha1] = {\n\t\t\tsha1,\n\t\t\textension: file.name.split(\".\").pop() || \"\",\n\t\t\tfile_type: file.type,\n\t\t\tsize: file.size,\n\t\t}\n\t}\n\treturn Object.values(filePayloads)\n}\n\nexport const fileToBlob = async (dataUrl: string): Promise<Blob> => {\n\t// TODO: Is this as reliable and supported as this?\n\t// https://www.nixtu.info/2013/06/how-to-upload-canvas-data-to-server.html\n\treturn (await fetch(dataUrl)).blob()\n}\n\nexport const blobToBase64 = (blob: Blob): Promise<string> => {\n\treturn new Promise((resolve, _) => {\n\t\tconst reader = new FileReader()\n\t\treader.onloadend = () => {\n\t\t\tresolve(reader.result?.toString() || \"\")\n\t\t}\n\t\treader.readAsDataURL(blob)\n\t})\n}\n\n// TODO:\n/** Converts a profile `file` and `fileSha1` into an img src that can be rendered. This relies on an API request. */\n\nexport function downloadFile(file: File) {\n\tconst blob = new Blob([file])\n\tsaveAs(blob, file.name)\n}\n","const logCache: Record<string, Record<string, boolean> | undefined> = {}\n\n/**\n * Logging the same message over and over again in a loop takes a lot of resources and makes the app laggy. This utility\n * function accepts a log ID (e.g. \"issue-has-no-index-workspace\") and an object ID (e.g. the offline_id of an issue),\n * and only logs the message on the first call with the same combination of logId and objId.\n * @param logId An arbitrary but unique identifier for this \"type of message\".\n * @param objId A unique identifier for the object the message regards. Can be an arbitrary string, e.g. \"current-user\"\n * or an actual object ID, e.g. the offline_id of an issue.\n * @param level The log level to use. For example, \"debug\" means `console.debug` will be called.\n * @param args The arguments to pass to the console log method.\n */\nexport function logOnlyOnce(\n\tlogId: string,\n\tobjId: string,\n\tlevel: \"debug\" | \"info\" | \"warn\" | \"error\",\n\t...args: unknown[]\n) {\n\tconst thisLogIdCache = logCache[logId]\n\tlet shouldLog = false\n\tif (!thisLogIdCache) {\n\t\tlogCache[logId] = { [objId]: true }\n\t\tshouldLog = true\n\t} else {\n\t\tconst hasLoggedForThisObject = thisLogIdCache[objId]\n\t\tif (!hasLoggedForThisObject) {\n\t\t\tthisLogIdCache[objId] = true\n\t\t\tshouldLog = true\n\t\t}\n\t}\n\tif (shouldLog) {\n\t\tconsole[level](...args)\n\t}\n}\n","import { Offline, OfflineModel } from \"../typings\"\nimport { v4 as uuidv4 } from \"uuid\"\n\n/**\n * Adds a generated UUID to the \"offline_id\" key of the object.\n * @param draft The model data to add the offline_id to\n */\nexport function offline<T>(draft: T): Offline<T> {\n\treturn { ...draft, offline_id: uuidv4() } as Offline<T>\n}\n\n/**\n * Converts an array of OfflineModel objects to a Record<string, TModel>, mapping an offline ID to the object with that\n * offline ID.\n * @param array An array of offline model instances\n */\nexport function toOfflineIdRecord<TModel extends OfflineModel>(array: TModel[]): Record<string, TModel> {\n\tconst asMapping: Record<string, TModel> = {}\n\tfor (const item of array) {\n\t\tasMapping[item.offline_id] = item\n\t}\n\treturn asMapping\n}\n","/**\n * Returns a file-safe string from arbitrary text. Will return maximum 255 characters, which is the longest safe\n * Long File Name (LFN).\n * WARNING! May give poor performance in big loops.\n * @param str The string to make safe for file names.\n * @param extension An extension (not including a period) to be added after a period at the end of the string. The\n * character limit of the returned string includes the extension, meaning characters from str will be removed to\n * accommodate it if necessary.\n * @param maxLength The maximum length of the resulting file name. Defaults to 255.\n */\nexport function toFileNameSafeString(str: string, extension: string | undefined = undefined, maxLength = 255): string {\n\tlet ret = str.replace(/[^a-z0-9_\\-.]/gi, \"_\").replace(/_{2,}/g, \"_\")\n\tif (!extension) {\n\t\tconst parts = str.split(\".\")\n\t\tif (parts.length > 1) {\n\t\t\textension = parts[parts.length - 1]\n\t\t}\n\t}\n\tif (extension && !extension.startsWith(\".\")) {\n\t\textension = \".\" + extension\n\t}\n\tconst extensionLengthWithPeriod = extension ? extension.length : 0\n\n\tif (ret.length + extensionLengthWithPeriod > maxLength) {\n\t\tret = ret.slice(0, maxLength - extensionLengthWithPeriod) + (extension || \"\")\n\t}\n\treturn ret\n}\n\nexport function spacesToDashesLower(value: string): string {\n\treturn value.toLowerCase().replace(\" \", \"-\")\n}\n\nexport function slugify(str: string, underscore = false) {\n\treturn str\n\t\t.normalize(\"NFKD\")\n\t\t.toLowerCase()\n\t\t.replace(/[^\\w\\s-]/g, \"\")\n\t\t.trim()\n\t\t.replace(/[-\\s]+/g, underscore ? \"_\" : \"-\")\n}\n\n/**\n * Given a string, returns a truncated version of it with an ellipsis character at the end if it is longer than\n * maxLength. The resulting string will be no longer than maxLength. Note that the ellipsis is only one character long.\n * @param str The string to truncate.\n * @param maxLength The maximum length of the resulting string, including the ellipsis.\n */\nexport function truncate(str: string, maxLength: number) {\n\tif (str.length <= maxLength) {\n\t\treturn str\n\t}\n\t// -1 to account for the ellipsis character\n\tconst subString = str.slice(0, maxLength - 1)\n\treturn subString.slice(0, subString.lastIndexOf(\" \")) + \"…\"\n}\n","import { Coordinates, IssueAttachment, OfflineModel, OvermapRootState } from \"../typings\"\n\ntype MemoizedSelectorWithArgs<TArgs, TRet> = (state: OvermapRootState, args: TArgs) => TRet\n\n// makes the createSelector function fit the current pattern for selectors with arguments\nexport const restructureCreateSelectorWithArgs =\n\t<TArgs, TRet>(selector: MemoizedSelectorWithArgs<TArgs, TRet>) =>\n\t(args: TArgs) =>\n\t(state: OvermapRootState) =>\n\t\tselector(state, args)\n\nexport function onlyUniqueOfflineIds(value: OfflineModel, index: number, self: OfflineModel[]) {\n\treturn self.findIndex((v) => v.offline_id === value.offline_id) === index\n}\n\nexport function onlyUniqueHashes(value: IssueAttachment, index: number, self: IssueAttachment[]) {\n\treturn (\n\t\tself.findIndex((v: IssueAttachment) => {\n\t\t\treturn v.file_sha1 === value.file_sha1\n\t\t}) === index\n\t)\n}\n\n/**\n *\n * @param bounds order: [northEast, southWest]\n * @param coordinates\n */\nexport function boundsContainPoint(bounds: [Coordinates, Coordinates], coordinates: Coordinates): boolean {\n\t// TODO: this is flipped for Marker (Geometry)\n\treturn (\n\t\tbounds[0][0] > coordinates[0] &&\n\t\tbounds[1][0] < coordinates[0] &&\n\t\tbounds[0][1] > coordinates[1] &&\n\t\tbounds[1][1] < coordinates[1]\n\t)\n}\n\nexport const emailRegex = /^.+@.+\\..+$/\n","import { IssuePriority, IssueStatus } from \"../enums\"\n\nexport const DEFAULT_ISSUE_STATUS = IssueStatus.BACKLOG\nexport const DEFAULT_ISSUE_PRIORITY = IssuePriority.MEDIUM\n","export const OUTBOX_RETRY_DELAY = 60000 // milliseconds\n","// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nexport const EMPTY_ARRAY: any[] = Object.freeze([]) // eslint-disable-line @typescript-eslint/no-explicit-any\n","import { EMPTY_ARRAY } from \"../constants\"\n\nlet debug = false\n\nconst REACT_APP_DEBUG_MEMOIZATION = (import.meta.env.REACT_APP_DEBUG_MEMOIZATION as string | undefined) || \"\"\n\nif ([\"true\", \"1\"].includes(REACT_APP_DEBUG_MEMOIZATION.toLowerCase())) {\n\tdebug = true\n}\n\nexport function shallowEqual(objA: Record<string, unknown>, objB: Record<string, unknown>) {\n\t// Check if they're the same object (objA is objB) -- just a quick reference check\n\tif (objA === objB) return true\n\n\tif (typeof objA !== typeof objB) {\n\t\treturn false\n\t}\n\n\tconst keysA = Object.keys(objA)\n\tconst keysB = Object.keys(objB)\n\n\t// Only calculate this once\n\tconst keysALength = keysA.length\n\tif (keysALength !== keysB.length) return false\n\n\tfor (let i = 0; i < keysALength; i++) {\n\t\tconst key = keysA[i]!\n\t\tif (!Object.prototype.hasOwnProperty.call(objB, key) || objA[key] !== objB[key]) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nexport function memoize<T extends (...args: never[]) => unknown>(func: T): T {\n\t// Taken from https://www.sitepoint.com/implementing-memoization-in-javascript/\n\tconst memo = {}\n\n\treturn function () {\n\t\t// eslint-disable-next-line prefer-rest-params\n\t\tconst args = Array.prototype.slice.call(arguments) as never[]\n\n\t\t// SEE: https://stackoverflow.com/questions/10173956/how-to-use-array-as-key-in-javascript\n\n\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t// @ts-expect-error\n\t\tif (args in memo) {\n\t\t\tif (debug) {\n\t\t\t\tconsole.debug(`Memoization debug: Using memorized return value for ${func.toString()}(`, args, \")\")\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t\t// @ts-expect-error\n\t\t\treturn memo[args] as T\n\t\t} else {\n\t\t\tif (debug) {\n\t\t\t\tconsole.debug(`Memoization debug: Cache miss! Memoizing ${func.toString()}(`, args, \")\")\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t\t// @ts-expect-error\n\t\t\treturn (memo[args] = func.apply(this, args))\n\t\t}\n\t} as T\n}\n\n/**\n * Performs an equality check by contents in order.\n * Reference types like objects and arrays are compared by reference.\n */\nexport function areArraysEqual(first: unknown[], second: unknown[]) {\n\tif (first.length !== second.length) return false\n\tfor (let i = 0; i < first.length; i++) {\n\t\tif (first[i] !== second[i]) return false\n\t}\n\treturn true\n}\n\nexport const fallbackToEmptyArray = <T>(array: T[]) => {\n\treturn array.length === 0 ? (EMPTY_ARRAY as T[]) : array\n}\n","import { default as ColorCls } from \"color\"\nimport {\n\tamber,\n\tblue,\n\tbrown,\n\tcrimson,\n\tcyan,\n\tgold,\n\tgrass,\n\tgray,\n\tindigo,\n\tiris,\n\tjade,\n\tlime,\n\tmint,\n\torange,\n\tpink,\n\tplum,\n\tpurple,\n\tred,\n\tsky,\n\tviolet,\n\tyellow,\n} from \"@radix-ui/colors\"\nimport { CSSColor } from \"../typings\"\n\n// TODO: Move most of these constants into src/theme/variables.ts\nexport const primaryColor: CSSColor = \"#2D55E2\"\nexport const successColor: CSSColor = \"#349C55\"\nexport const warningColor: CSSColor = \"#FFA620\"\nexport const errorColor: CSSColor = \"#E24C4C\"\nexport const GREEN: CSSColor = \"#1fd155\"\nexport const YELLOW: CSSColor = \"#f5de14\"\nexport interface BadgeColors {\n\tbackgroundColor: CSSColor\n\ttextColor: CSSColor\n}\n\n// Colors used for color selection purposes\nexport const Colors: Record<string, CSSColor> = {\n\tgray: (gray as Record<string, CSSColor>).gray9!,\n\tgold: (gold as Record<string, CSSColor>).gold9!,\n\tbrown: (brown as Record<string, CSSColor>).brown9!,\n\tyellow: (yellow as Record<string, CSSColor>).yellow9!,\n\tamber: (amber as Record<string, CSSColor>).amber9!,\n\torange: (orange as Record<string, CSSColor>).orange9!,\n\tred: (red as Record<string, CSSColor>).red9!,\n\tcrimson: (crimson as Record<string, CSSColor>).crimson9!,\n\tpink: (pink as Record<string, CSSColor>).pink9!,\n\tplum: (plum as Record<string, CSSColor>).plum9!,\n\tpurple: (purple as Record<string, CSSColor>).purple9!,\n\tviolet: (violet as Record<string, CSSColor>).violet9!,\n\tiris: (iris as Record<string, CSSColor>).iris9!,\n\tindigo: (indigo as Record<string, CSSColor>).indigo9!,\n\tblue: (blue as Record<string, CSSColor>).blue9!,\n\tcyan: (cyan as Record<string, CSSColor>).cyan9!,\n\tjade: (jade as Record<string, CSSColor>).jade9!,\n\tgrass: (grass as Record<string, CSSColor>).grass9!,\n\tlime: (lime as Record<string, CSSColor>).lime9!,\n\tmint: (mint as Record<string, CSSColor>).mint9!,\n\tsky: (sky as Record<string, CSSColor>).sky9!,\n}\n\nexport const defaultBadgeColor: CSSColor = \"#868686\"\n\n// This function adjusts a given colour into two variations for use as badge colours\nexport const generateBadgeColors = (rawColor: CSSColor): BadgeColors => {\n\tconst color = ColorCls(rawColor)\n\tconst safety = ColorCls(YELLOW)\n\tconst backgroundColor: CSSColor = color.darken(0.09).hex() as CSSColor\n\t// If the color matches the special yellow safety color, make the text black\n\tconst textColor = color.hex() === safety.hex() ? \"#000000\" : \"#FFFFFF\"\n\t// Alternate style:\n\t// const backgroundColor = color.lighten(0.4).hex()\n\t// const textColor = color.darken(0.6).hex()\n\n\treturn { backgroundColor, textColor }\n}\n","import { memoize } from \"./optimization\"\n\n/** Only shows year if a past year */\nexport const getLocalDateString = memoize((date?: string | null | Date | number) => {\n\tif (!date) return \"\"\n\tconst asDate = new Date(date)\n\tconst isThisYear = asDate.getFullYear() === today.getFullYear()\n\tconst options: Intl.DateTimeFormatOptions = { day: \"numeric\", month: \"short\" }\n\tif (!isThisYear) options.year = \"numeric\"\n\treturn asDate.toLocaleDateString([], options)\n})\n\nconst relative = new Intl.RelativeTimeFormat([], { style: \"long\", numeric: \"auto\" })\nconst msInDay = 1000 * 86400\nconst today = new Date()\n\n/** Returns true if the given date is today */\nexport const isToday = (date: string | Date | number) => {\n\treturn new Date(date).toDateString() === today.toDateString()\n}\n\n/*\nDisplays a relative message \"in 2 days\" or \"today\" if within the given period (min, max)\nOtherwise, falls back to getLocalDateString()\n*/\nexport const getLocalRelativeDateString = memoize((date: string | Date | number, min: number, max: number) => {\n\tconst days = Math.round((new Date(date).getTime() - today.getTime()) / msInDay)\n\tif (days < min || days > max) return getLocalDateString(date)\n\treturn relative.format(days, \"days\")\n})\n","// https://gist.github.com/GFoley83/5877f6c09fbcfd62569c51dc91444cf0\n\n/**\n * A new instance of deferred is constructed by calling `new DeferredPromise<T>()`.\n * The purpose of the deferred object is to expose the associated Promise\n * instance APIs that can be used for signaling the successful\n * or unsuccessful completion, as well as the state of the task.\n * @export\n * @class DeferredPromise\n * @implements {Promise<T>}\n * @template T\n * @example\n * const deferred = new DeferredPromise<string>()\n * console.log(deferred.state) // \"pending\"\n *\n * deferred\n * .then(str => console.log(str))\n * .catch(err => console.error(err))\n *\n * deferred.resolve(\"Foo\")\n * console.log(deferred.state) // \"fulfilled\"\n * // deferred.reject(\"Bar\")\n */\nexport class DeferredPromise<T> implements Promise<T> {\n\t[Symbol.toStringTag] = \"Promise\"\n\n\tprivate _promise: Promise<T>\n\tprivate _resolve: null | ((value?: T | PromiseLike<T>) => void)\n\tprivate _reject: null | ((reason?: unknown) => void)\n\tprivate _state: \"pending\" | \"fulfilled\" | \"rejected\" = \"pending\"\n\n\tpublic get state(): \"pending\" | \"fulfilled\" | \"rejected\" {\n\t\treturn this._state\n\t}\n\n\tconstructor() {\n\t\tthis._resolve = null\n\t\tthis._reject = null\n\n\t\tthis._promise = new Promise<T>((resolve, reject) => {\n\t\t\tthis._resolve = resolve as (value?: T | PromiseLike<T>) => void\n\t\t\tthis._reject = reject\n\t\t})\n\t}\n\n\tpublic then<TResult1, TResult2>(\n\t\tonFulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>,\n\t\tonRejected?: (reason: unknown) => TResult2 | PromiseLike<TResult2>,\n\t): Promise<TResult1 | TResult2> {\n\t\treturn this._promise.then(onFulfilled, onRejected)\n\t}\n\n\tpublic catch<TResult>(onRejected?: (reason: unknown) => TResult | PromiseLike<TResult>): Promise<T | TResult> {\n\t\treturn this._promise.catch(onRejected)\n\t}\n\n\tpublic resolve(value?: T | PromiseLike<T>): void {\n\t\tif (!this._resolve) throw new Error(\"No resolve callback\")\n\t\tthis._resolve(value)\n\t\tthis._state = \"fulfilled\"\n\t}\n\n\tpublic reject(reason?: unknown): void {\n\t\tif (!this._reject) throw reason\n\t\tthis._reject(reason)\n\t\tthis._state = \"rejected\"\n\t}\n\n\tpublic finally(_onFinally?: (() => void) | undefined | null): Promise<T> {\n\t\tthrow new Error(\"`finally` not implemented\")\n\t}\n}\n","import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';\n\n/**\n * Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js\n *\n * Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes\n * during build.\n * @param {number} code\n */\nfunction formatProdErrorMessage(code) {\n return \"Minified Redux error #\" + code + \"; visit https://redux.js.org/Errors?code=\" + code + \" for the full message or \" + 'use the non-minified dev environment for full errors. ';\n}\n\n// Inlined version of the `symbol-observable` polyfill\nvar $$observable = (function () {\n return typeof Symbol === 'function' && Symbol.observable || '@@observable';\n})();\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nvar randomString = function randomString() {\n return Math.random().toString(36).substring(7).split('').join('.');\n};\n\nvar ActionTypes = {\n INIT: \"@@redux/INIT\" + randomString(),\n REPLACE: \"@@redux/REPLACE\" + randomString(),\n PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {\n return \"@@redux/PROBE_UNKNOWN_ACTION\" + randomString();\n }\n};\n\n/**\n * @param {any} obj The object to inspect.\n * @returns {boolean} True if the argument appears to be a plain object.\n */\nfunction isPlainObject(obj) {\n if (typeof obj !== 'object' || obj === null) return false;\n var proto = obj;\n\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n\n return Object.getPrototypeOf(obj) === proto;\n}\n\n// Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of\nfunction miniKindOf(val) {\n if (val === void 0) return 'undefined';\n if (val === null) return 'null';\n var type = typeof val;\n\n switch (type) {\n case 'boolean':\n case 'string':\n case 'number':\n case 'symbol':\n case 'function':\n {\n return type;\n }\n }\n\n if (Array.isArray(val)) return 'array';\n if (isDate(val)) return 'date';\n if (isError(val)) return 'error';\n var constructorName = ctorName(val);\n\n switch (constructorName) {\n case 'Symbol':\n case 'Promise':\n case 'WeakMap':\n case 'WeakSet':\n case 'Map':\n case 'Set':\n return constructorName;\n } // other\n\n\n return type.slice(8, -1).toLowerCase().replace(/\\s/g, '');\n}\n\nfunction ctorName(val) {\n return typeof val.constructor === 'function' ? val.constructor.name : null;\n}\n\nfunction isError(val) {\n return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number';\n}\n\nfunction isDate(val) {\n if (val instanceof Date) return true;\n return typeof val.toDateString === 'function' && typeof val.getDate === 'function' && typeof val.setDate === 'function';\n}\n\nfunction kindOf(val) {\n var typeOfVal = typeof val;\n\n if (process.env.NODE_ENV !== 'production') {\n typeOfVal = miniKindOf(val);\n }\n\n return typeOfVal;\n}\n\n/**\n * @deprecated\n *\n * **We recommend using the `configureStore` method\n * of the `@reduxjs/toolkit` package**, which replaces `createStore`.\n *\n * Redux Toolkit is our recommended approach for writing Redux logic today,\n * including store setup, reducers, data fetching, and more.\n *\n * **For more details, please read this Redux docs page:**\n * **https://redux.js.org/introduction/why-rtk-is-redux-today**\n *\n * `configureStore` from Redux Toolkit is an improved version of `createStore` that\n * simplifies setup and helps avoid common bugs.\n *\n * You should not be using the `redux` core package by itself today, except for learning purposes.\n * The `createStore` method from the core `redux` package will not be removed, but we encourage\n * all users to migrate to using Redux Toolkit for all Redux code.\n *\n * If you want to use `createStore` without this visual deprecation warning, use\n * the `legacy_createStore` import instead:\n *\n * `import { legacy_createStore as createStore} from 'redux'`\n *\n */\n\nfunction createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(0) : 'It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.');\n }\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(1) : \"Expected the enhancer to be a function. Instead, received: '\" + kindOf(enhancer) + \"'\");\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(2) : \"Expected the root reducer to be a function. Instead, received: '\" + kindOf(reducer) + \"'\");\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n /**\n * This makes a shallow copy of currentListeners so we can use\n * nextListeners as a temporary list while dispatching.\n *\n * This prevents any bugs around consumers calling\n * subscribe/unsubscribe in the middle of a dispatch.\n */\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n\n\n function getState() {\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(3) : 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.');\n }\n\n return currentState;\n }\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n\n\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(4) : \"Expected the listener to be a function. Instead, received: '\" + kindOf(listener) + \"'\");\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(5) : 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');\n }\n\n var isSubscribed = true;\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(6) : 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');\n }\n\n isSubscribed = false;\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n currentListeners = null;\n };\n }\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n\n\n function dispatch(action) {\n if (!isPlainObject(action)) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(7) : \"Actions must be plain objects. Instead, the actual type was: '\" + kindOf(action) + \"'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.\");\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(8) : 'Actions may not have an undefined \"type\" property. You may have misspelled an action type string constant.');\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(9) : 'Reducers may not dispatch actions.');\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n\n for (var i = 0; i < listeners.length; i++) {\n var listener = listeners[i];\n listener();\n }\n\n return action;\n }\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n\n\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(10) : \"Expected the nextReducer to be a function. Instead, received: '\" + kindOf(nextReducer));\n }\n\n currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT.\n // Any reducers that existed in both the new and old rootReducer\n // will receive the previous state. This effectively populates\n // the new state tree with any relevant data from the old one.\n\n dispatch({\n type: ActionTypes.REPLACE\n });\n }\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/tc39/proposal-observable\n */\n\n\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object' || observer === null) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(11) : \"Expected the observer to be an object. Instead, received: '\" + kindOf(observer) + \"'\");\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return {\n unsubscribe: unsubscribe\n };\n }\n }, _ref[$$observable] = function () {\n return this;\n }, _ref;\n } // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n\n\n dispatch({\n type: ActionTypes.INIT\n });\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[$$observable] = observable, _ref2;\n}\n/**\n * Creates a Redux store that holds the state tree.\n *\n * **We recommend using `configureStore` from the\n * `@reduxjs/toolkit` package**, which replaces `createStore`:\n * **https://redux.js.org/introduction/why-rtk-is-redux-today**\n *\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} [enhancer] The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\n\nvar legacy_createStore = createStore;\n\n/**\n * Prints a warning in the console if it exists.\n *\n * @param {String} message The warning message.\n * @returns {void}\n */\nfunction warning(message) {\n /* eslint-disable no-console */\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error(message);\n }\n /* eslint-enable no-console */\n\n\n try {\n // This error was thrown as a convenience so that if you enable\n // \"break on all exceptions\" in your console,\n // it would pause the execution at this line.\n throw new Error(message);\n } catch (e) {} // eslint-disable-line no-empty\n\n}\n\nfunction getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {\n var reducerKeys = Object.keys(reducers);\n var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';\n\n if (reducerKeys.length === 0) {\n return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';\n }\n\n if (!isPlainObject(inputState)) {\n return \"The \" + argumentName + \" has unexpected type of \\\"\" + kindOf(inputState) + \"\\\". Expected argument to be an object with the following \" + (\"keys: \\\"\" + reducerKeys.join('\", \"') + \"\\\"\");\n }\n\n var unexpectedKeys = Object.keys(inputState).filter(function (key) {\n return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];\n });\n unexpectedKeys.forEach(function (key) {\n unexpectedKeyCache[key] = true;\n });\n if (action && action.type === ActionTypes.REPLACE) return;\n\n if (unexpectedKeys.length > 0) {\n return \"Unexpected \" + (unexpectedKeys.length > 1 ? 'keys' : 'key') + \" \" + (\"\\\"\" + unexpectedKeys.join('\", \"') + \"\\\" found in \" + argumentName + \". \") + \"Expected to find one of the known reducer keys instead: \" + (\"\\\"\" + reducerKeys.join('\", \"') + \"\\\". Unexpected keys will be ignored.\");\n }\n}\n\nfunction assertReducerShape(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, {\n type: ActionTypes.INIT\n });\n\n if (typeof initialState === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(12) : \"The slice reducer for key \\\"\" + key + \"\\\" returned undefined during initialization. \" + \"If the state passed to the reducer is undefined, you must \" + \"explicitly return the initial state. The initial state may \" + \"not be undefined. If you don't want to set a value for this reducer, \" + \"you can use null instead of undefined.\");\n }\n\n if (typeof reducer(undefined, {\n type: ActionTypes.PROBE_UNKNOWN_ACTION()\n }) === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(13) : \"The slice reducer for key \\\"\" + key + \"\\\" returned undefined when probed with a random type. \" + (\"Don't try to handle '\" + ActionTypes.INIT + \"' or other actions in \\\"redux/*\\\" \") + \"namespace. They are considered private. Instead, you must return the \" + \"current state for any unknown actions, unless it is undefined, \" + \"in which case you must return the initial state, regardless of the \" + \"action type. The initial state may not be undefined, but can be null.\");\n }\n });\n}\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\n\n\nfunction combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (process.env.NODE_ENV !== 'production') {\n if (typeof reducers[key] === 'undefined') {\n warning(\"No reducer provided for key \\\"\" + key + \"\\\"\");\n }\n }\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n\n var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same\n // keys multiple times.\n\n var unexpectedKeyCache;\n\n if (process.env.NODE_ENV !== 'production') {\n unexpectedKeyCache = {};\n }\n\n var shapeAssertionError;\n\n try {\n assertReducerShape(finalReducers);\n } catch (e) {\n shapeAssertionError = e;\n }\n\n return function combination(state, action) {\n if (state === void 0) {\n state = {};\n }\n\n if (shapeAssertionError) {\n throw shapeAssertionError;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);\n\n if (warningMessage) {\n warning(warningMessage);\n }\n }\n\n var hasChanged = false;\n var nextState = {};\n\n for (var _i = 0; _i < finalReducerKeys.length; _i++) {\n var _key = finalReducerKeys[_i];\n var reducer = finalReducers[_key];\n var previousStateForKey = state[_key];\n var nextStateForKey = reducer(previousStateForKey, action);\n\n if (typeof nextStateForKey === 'undefined') {\n var actionType = action && action.type;\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(14) : \"When called with an action of type \" + (actionType ? \"\\\"\" + String(actionType) + \"\\\"\" : '(unknown type)') + \", the slice reducer for key \\\"\" + _key + \"\\\" returned undefined. \" + \"To ignore an action, you must explicitly return the previous state. \" + \"If you want this reducer to hold no value, you can return null instead of undefined.\");\n }\n\n nextState[_key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n\n hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length;\n return hasChanged ? nextState : state;\n };\n}\n\nfunction bindActionCreator(actionCreator, dispatch) {\n return function () {\n return dispatch(actionCreator.apply(this, arguments));\n };\n}\n/**\n * Turns an object whose values are action creators, into an object with the\n * same keys, but with every function wrapped into a `dispatch` call so they\n * may be invoked directly. This is just a convenience method, as you can call\n * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.\n *\n * For convenience, you can also pass an action creator as the first argument,\n * and get a dispatch wrapped function in return.\n *\n * @param {Function|Object} actionCreators An object whose values are action\n * creator functions. One handy way to obtain it is to use ES6 `import * as`\n * syntax. You may also pass a single function.\n *\n * @param {Function} dispatch The `dispatch` function available on your Redux\n * store.\n *\n * @returns {Function|Object} The object mimicking the original object, but with\n * every action creator wrapped into the `dispatch` call. If you passed a\n * function as `actionCreators`, the return value will also be a single\n * function.\n */\n\n\nfunction bindActionCreators(actionCreators, dispatch) {\n if (typeof actionCreators === 'function') {\n return bindActionCreator(actionCreators, dispatch);\n }\n\n if (typeof actionCreators !== 'object' || actionCreators === null) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(16) : \"bindActionCreators expected an object or a function, but instead received: '\" + kindOf(actionCreators) + \"'. \" + \"Did you write \\\"import ActionCreators from\\\" instead of \\\"import * as ActionCreators from\\\"?\");\n }\n\n var boundActionCreators = {};\n\n for (var key in actionCreators) {\n var actionCreator = actionCreators[key];\n\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);\n }\n }\n\n return boundActionCreators;\n}\n\n/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\nfunction compose() {\n for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n return funcs.reduce(function (a, b) {\n return function () {\n return a(b.apply(void 0, arguments));\n };\n });\n}\n\n/**\n * Creates a store enhancer that applies middleware to the dispatch method\n * of the Redux store. This is handy for a variety of tasks, such as expressing\n * asynchronous actions in a concise manner, or logging every action payload.\n *\n * See `redux-thunk` package as an example of the Redux middleware.\n *\n * Because middleware is potentially asynchronous, this should be the first\n * store enhancer in the composition chain.\n *\n * Note that each middleware will be given the `dispatch` and `getState` functions\n * as named arguments.\n *\n * @param {...Function} middlewares The middleware chain to be applied.\n * @returns {Function} A store enhancer applying the middleware.\n */\n\nfunction applyMiddleware() {\n for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {\n middlewares[_key] = arguments[_key];\n }\n\n return function (createStore) {\n return function () {\n var store = createStore.apply(void 0, arguments);\n\n var _dispatch = function dispatch() {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(15) : 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.');\n };\n\n var middlewareAPI = {\n getState: store.getState,\n dispatch: function dispatch() {\n return _dispatch.apply(void 0, arguments);\n }\n };\n var chain = middlewares.map(function (middleware) {\n return middleware(middlewareAPI);\n });\n _dispatch = compose.apply(void 0, chain)(store.dispatch);\n return _objectSpread(_objectSpread({}, store), {}, {\n dispatch: _dispatch\n });\n };\n };\n}\n\nexport { ActionTypes as __DO_NOT_USE__ActionTypes, applyMiddleware, bindActionCreators, combineReducers, compose, createStore, legacy_createStore };\n","// TODO: This is deprecated and moved into redux-persist. See: https://github.com/wildlifela/redux-persist-migrate\n// It also doesn't seem to be doing much.\n\nimport type { Manifest, Migrator } from \"../typings\"\n\n// NOTE: If changing, also change it in store.ts (avoid circular imports)\nconst VERSION_REDUCER_KEY = \"versioning\"\n\ntype WrapMigrator = (migrator: Migrator) => Migrator\n\n// gets the most recent (largest) version number\nconst latestVersion = () => migrations.length - 1\n\n// if unset, set the app version to the latest\n// this is the case when someone opens the app for the first time\nconst initialVersioning: Migrator = (state) => {\n\tstate[VERSION_REDUCER_KEY] = { version: latestVersion() }\n\treturn state\n}\n\n// migration that signs the user out due to the redux store being changed in a breaking way\nconst signOut: Migrator = () => {\n\t// set the app version to the latest so that this migration is not run again\n\treturn initialVersioning({})\n}\n\n// Added a new state to the outbox slice\nconst createOutboxState: Migrator = (state) => {\n\tif (state.outboxReducer) {\n\t\tstate.outboxReducer.deletedRequests = []\n\t}\n\treturn state\n}\n\n// wraps migrations with the skipAfterInitialVersioning check for convenience\nconst wrapMigration: WrapMigrator = (migrator) => (state) => {\n\t// REASON: This happened to GCS\n\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\tif (state === undefined) {\n\t\tstate = {}\n\t}\n\n\tif (state[VERSION_REDUCER_KEY]?.version === latestVersion()) return state\n\n\treturn migrator(state)\n}\n\n// migrations take in a RootState, modify it, and then return the updated root state\n// add new migrations to the **end** of this array\n// ensure initialVersioning() is always the first migration\nconst migrations: Migrator[] = [initialVersioning, signOut, signOut, createOutboxState]\n\n// used by redux-persist-migrate to run the migrations when rehydrating the app\nexport const manifest: Manifest = Object.fromEntries(migrations.map((migration, i) => [i, wrapMigration(migration)]))\n","import { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore\"\nimport type { BaseState } from \"../typings\"\nimport type { BaseSDK } from \"./base\"\n\n/** The client store is the store passed to the SDKProvider\n * and is used where the SDKProvider is not available.\n */\nlet clientStore: ToolkitStore<BaseState> | undefined\n\nexport function setClientStore<TState extends BaseState>(store: ToolkitStore<TState>) {\n\tclientStore = store\n}\n\nexport function getClientStore(): ToolkitStore<BaseState> | undefined {\n\treturn clientStore\n}\n\nlet clientSDK: BaseSDK<BaseState> | undefined\n\nexport function setClientSDK<TState extends BaseState>(sdkCtor: BaseSDK<TState>) {\n\tclientSDK = sdkCtor\n}\n\nexport function getClientSDK(): BaseSDK<BaseState> | undefined {\n\treturn clientSDK\n}\n","import { AnyAction } from \"@reduxjs/toolkit\"\nimport type { BaseSDK } from \"../base\"\nimport type { BaseState } from \"../../typings\"\nimport type { SDKRequest } from \"../typings\"\n\nexport const CLASS_NAME_TO_SERVICE: Record<string, BaseService<BaseState, BaseSDK<BaseState>>> = {}\n\n/**\n * Abstract base class for building a service that can enqueue API requests\n */\nexport abstract class BaseService<TStore extends BaseState, TSDK extends BaseSDK<TStore>> {\n\tprotected readonly client: TSDK\n\tabstract readonly host: string\n\n\tprotected constructor(sdk: TSDK) {\n\t\tCLASS_NAME_TO_SERVICE[this.constructor.name] = this\n\t\tthis.client = sdk\n\t}\n\n\tprotected async enqueueRequest<TResult>(requestDetails: SDKRequest): Promise<TResult> {\n\t\t// enqueueRequest is a wrapper for _enqueueRequest that ensures the result is not an APIError unless\n\t\t// `.catch()` is triggered.\n\t\treturn this.client.enqueueRequest(requestDetails, this.host, this.constructor.name)\n\t}\n\n\tprotected dispatch(action: AnyAction) {\n\t\tthis.client.store.dispatch(action)\n\t}\n}\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { TokenPair } from \"sdk/typings\"\nimport type { BaseState } from \"../../typings\"\n\nexport interface AuthState {\n\taccessToken: string\n\trefreshToken: string\n\tisLoggedIn: boolean\n}\n\nconst initialState: AuthState = {\n\taccessToken: \"\",\n\trefreshToken: \"\",\n\tisLoggedIn: false,\n}\n\n/**\n * Stores the auth state of the app (tokens, and whether user is logged in or not)\n */\nexport const authSlice = createSlice({\n\tname: \"auth\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetTokens: (state, action: PayloadAction<TokenPair>) => {\n\t\t\tstate.accessToken = action.payload.accessToken\n\t\t\tstate.refreshToken = action.payload.refreshToken\n\t\t},\n\t\tclearTokens: (state) => {\n\t\t\tstate.accessToken = \"\"\n\t\t\tstate.refreshToken = \"\"\n\t\t},\n\t\tsetLoggedIn: (state, action: PayloadAction<boolean>) => {\n\t\t\tif (!action.payload) {\n\t\t\t\tauthSlice.caseReducers.clearTokens(state)\n\t\t\t}\n\t\t\tstate.isLoggedIn = action.payload\n\t\t},\n\t},\n})\n\nexport const { setTokens, clearTokens, setLoggedIn } = authSlice.actions\nexport const selectAccessToken = (state: BaseState) => state.authReducer.accessToken\nexport const selectIsLoggedIn = (state: BaseState) => state.authReducer.isLoggedIn\n\nexport const authReducer: Reducer<AuthState> = authSlice.reducer\n","import { PayloadAction } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"./typings\"\n\nexport interface OvermapModelAdapter<TModel> {\n\taddOne: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => void\n\taddMany: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => void\n\tsetOne: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => void\n\tsetMany: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => void\n\tupdateOne: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => void\n\tupdateMany: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => void\n\tdeleteOne: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<string>) => void\n\tdeleteMany: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<string[]>) => void\n\tinitialize: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => void\n\tgetInitialState: <TState extends object>(state: TState) => TState & ModelState<TModel>\n}\n\nexport function createModelAdapter<TModel>(computeModelId: (model: TModel) => string): OvermapModelAdapter<TModel> {\n\tconst addOne = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => {\n\t\t// TODO: error check here if the model already exists?\n\t\tconst id = computeModelId(action.payload)\n\t\tstate.instances[id] = action.payload\n\t}\n\n\tconst addMany = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => {\n\t\tfor (const model of action.payload) {\n\t\t\t// TODO: error check here if the model already exists?\n\t\t\tconst id = computeModelId(model)\n\t\t\tstate.instances[id] = model\n\t\t}\n\t}\n\n\tconst setOne = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => {\n\t\tconst id = computeModelId(action.payload)\n\t\tstate.instances[id] = action.payload\n\t}\n\n\tconst setMany = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => {\n\t\tfor (const model of action.payload) {\n\t\t\tconst id = computeModelId(model)\n\t\t\tstate.instances[id] = model\n\t\t}\n\t}\n\n\tconst updateOne = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => {\n\t\tconst id = computeModelId(action.payload)\n\t\tstate.instances[id] = action.payload\n\t}\n\n\tconst updateMany = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => {\n\t\tfor (const model of action.payload) {\n\t\t\tconst id = computeModelId(model)\n\t\t\tstate.instances[id] = model\n\t\t}\n\t}\n\n\tconst deleteOne = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<string>) => {\n\t\tdelete state.instances[action.payload]\n\t}\n\n\tconst deleteMany = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<string[]>) => {\n\t\tfor (const id of action.payload) {\n\t\t\tdelete state.instances[id]\n\t\t}\n\t}\n\n\tconst initialize = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => {\n\t\tstate.instances = {}\n\t\tfor (const model of action.payload) {\n\t\t\t// TODO: error check here if the model already exists?\n\t\t\tconst id = computeModelId(model)\n\t\t\tstate.instances[id] = model\n\t\t}\n\t}\n\n\tconst getInitialState = <TState extends object>(state: TState) => {\n\t\treturn {\n\t\t\t...state,\n\t\t\tinstances: {} as Record<string, TModel>,\n\t\t}\n\t}\n\n\treturn {\n\t\taddOne,\n\t\taddMany,\n\t\tsetOne,\n\t\tsetMany,\n\t\tupdateOne,\n\t\tupdateMany,\n\t\tdeleteOne,\n\t\tdeleteMany,\n\t\tinitialize,\n\t\tgetInitialState,\n\t}\n}\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { Category, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type CategoryState = ModelState<Stored<Category>>\n\nconst categoryAdapter = createModelAdapter<Stored<Category>>((category) => category.offline_id)\n\nconst initialState: CategoryState = categoryAdapter.getInitialState({})\n\nexport const categorySlice = createSlice({\n\tname: \"categories\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeCategories: categoryAdapter.initialize,\n\t\taddCategory: categoryAdapter.addOne,\n\t\tupdateCategory: categoryAdapter.updateOne,\n\t\tdeleteCategory: categoryAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeCategories, addCategory, updateCategory, deleteCategory } = categorySlice.actions\n\nexport const selectCategoryMapping = (state: OvermapRootState) => state.categoryReducer.instances\n\nexport const selectCategories = createSelector([selectCategoryMapping], (categoryMapping) => {\n\treturn Object.values(categoryMapping)\n})\n\nexport const selectCategoryById: OvermapSelectorWithArgs<string, Stored<Category> | undefined> =\n\t(id: Category[\"offline_id\"]) => (state) => {\n\t\treturn state.categoryReducer.instances[id]\n\t}\n\nexport const selectCategoriesByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectCategoryMapping, (_state, categoryIds: Category[\"offline_id\"][]) => categoryIds],\n\t\t(categoryMapping, categoryIds) => {\n\t\t\tconst categories: Stored<Category>[] = []\n\n\t\t\tfor (const categoryId of categoryIds) {\n\t\t\t\tconst category = categoryMapping[categoryId]\n\n\t\t\t\tif (category) {\n\t\t\t\t\tcategories.push(category)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\"selectCategoryByIds: No category exists with the id\", categoryId)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn fallbackToEmptyArray(categories)\n\t\t},\n\t),\n)\n\nexport const selectCategoriesOfWorkspace: OvermapSelectorWithArgs<string, Category[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectCategories, (_state, workspaceId: string) => workspaceId], (categories, workspaceId) =>\n\t\t\tcategories.filter((category) => category.workspace === workspaceId),\n\t\t),\n\t)\n\nexport const selectIssueCountOfCategory: OvermapSelectorWithArgs<string | null, number> =\n\t(categoryId) => (state: OvermapRootState) => {\n\t\treturn Object.values(state.issueReducer.instances).filter((issue) => issue.category === categoryId).length\n\t}\n\nexport const categoryReducer: Reducer<CategoryState> = categorySlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { Asset, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetState = ModelState<Stored<Asset>>\n\nconst assetAdapter = createModelAdapter<Stored<Asset>>((asset) => asset.offline_id)\n\nconst initialState: AssetState = assetAdapter.getInitialState({})\n\nexport const assetSlice = createSlice({\n\tname: \"assets\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssets: assetAdapter.initialize,\n\t\taddAsset: assetAdapter.addOne,\n\t\taddAssets: assetAdapter.addMany,\n\t\tsetAsset: assetAdapter.setOne,\n\t\tsetAssets: assetAdapter.setMany,\n\t\tupdateAsset: assetAdapter.updateOne,\n\t\tupdateAssets: assetAdapter.updateMany,\n\t\tdeleteAsset: assetAdapter.deleteOne,\n\t\tdeleteAssets: assetAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssets,\n\taddAsset,\n\taddAssets,\n\tupdateAsset,\n\tupdateAssets,\n\tdeleteAsset,\n\tdeleteAssets,\n\tsetAsset,\n\tsetAssets,\n} = assetSlice.actions\n\nexport const selectAssetsMapping = (state: OvermapRootState) => state.assetReducer.instances\n\nexport const selectAssets = createSelector([selectAssetsMapping], (assetsMapping) => {\n\treturn Object.values(assetsMapping)\n})\n\nexport const selectAssetsOfAssetType: OvermapSelectorWithArgs<string, Asset[]> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssets, (_state, assetTypeId: string) => assetTypeId], (assets, assetTypeId) => {\n\t\treturn fallbackToEmptyArray(assets.filter((asset) => asset.asset_type === assetTypeId))\n\t}),\n)\n\nexport const selectAssetById: OvermapSelectorWithArgs<string, Asset | undefined> =\n\t(assetId) => (state: OvermapRootState) => {\n\t\treturn state.assetReducer.instances[assetId]\n\t}\n\nexport const selectAssetsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssetsMapping, (_, assetIds: string[]) => assetIds], (assetsMapping, assetIds) => {\n\t\tconst assets: Stored<Asset>[] = []\n\n\t\tfor (const assetId of assetIds) {\n\t\t\tconst asset = assetsMapping[assetId]\n\n\t\t\tif (asset) assets.push(asset)\n\t\t}\n\n\t\treturn fallbackToEmptyArray(assets)\n\t}),\n)\n\nexport const selectNumberOfAssetsOfAssetType: OvermapSelectorWithArgs<string, number> = (assetTypeId) => (state) => {\n\treturn selectAssetsOfAssetType(assetTypeId)(state).length\n}\n\nexport const assetReducer: Reducer<AssetState> = assetSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type { AssetAttachment, OvermapRootState, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type AssetAttachmentState = ModelState<Stored<AssetAttachment>>\n\nconst assetAttachmentAdapter = createModelAdapter<Stored<AssetAttachment>>((attachment) => attachment.offline_id)\n\nconst initialState = assetAttachmentAdapter.getInitialState({})\n\nexport const assetAttachmentSlice = createSlice({\n\tname: \"assetAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetAttachments: assetAttachmentAdapter.initialize,\n\t\taddAssetAttachment: assetAttachmentAdapter.addOne,\n\t\taddAssetAttachments: assetAttachmentAdapter.addMany,\n\t\tsetAssetAttachment: assetAttachmentAdapter.setOne,\n\t\tsetAssetAttachments: assetAttachmentAdapter.setMany,\n\t\tupdateAssetAttachment: assetAttachmentAdapter.updateOne,\n\t\tupdateAssetAttachments: assetAttachmentAdapter.updateMany,\n\t\tdeleteAssetAttachment: assetAttachmentAdapter.deleteOne,\n\t\tdeleteAssetAttachments: assetAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetAttachments,\n\taddAssetAttachment,\n\taddAssetAttachments,\n\tsetAssetAttachment,\n\tsetAssetAttachments,\n\tupdateAssetAttachment,\n\tupdateAssetAttachments,\n\tdeleteAssetAttachment,\n\tdeleteAssetAttachments,\n} = assetAttachmentSlice.actions\n\nexport const selectAssetAttachmentMapping = (state: OvermapRootState) => state.assetAttachmentReducer.instances\n\nexport const selectAssetAttachments: OvermapSelector<Stored<AssetAttachment>[]> = createSelector(\n\t[selectAssetAttachmentMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectAssetAttachmentById: OvermapSelectorWithArgs<string, Stored<AssetAttachment> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.assetAttachmentReducer.instances[id]\n\t}\n\nexport const selectAttachmentsOfAsset = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetAttachments, (_state: OvermapRootState, assetId: string) => assetId],\n\t\t(attachments, assetId) => {\n\t\t\treturn fallbackToEmptyArray(attachments.filter(({ asset }) => assetId === asset))\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfAssetByType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetAttachments, (_state: OvermapRootState, assetId: string) => assetId],\n\t\t(attachments, assetId) => {\n\t\t\tconst attachmentsOfAsset = attachments.filter(({ asset }) => assetId === asset)\n\t\t\tconst fileAttachments = attachmentsOfAsset.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => !file_type || !file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\tconst imageAttachments = attachmentsOfAsset.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => file_type && file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\treturn { fileAttachments, imageAttachments }\n\t\t},\n\t),\n)\n\nexport const assetAttachmentReducer: Reducer<AssetAttachmentState> = assetAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport { AssetStageCompletion, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport { ModelState } from \"../typings\"\n\nexport type AssetStageCompletionState = ModelState<AssetStageCompletion>\n\nconst assetStageCompletionAdapter = createModelAdapter<AssetStageCompletion>(\n\t(stageCompletion) => stageCompletion.offline_id,\n)\n\nconst initialState: AssetStageCompletionState = assetStageCompletionAdapter.getInitialState({})\n\nexport const assetStageCompletionSlice = createSlice({\n\tname: \"assetStageCompletions\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetStageCompletions: assetStageCompletionAdapter.initialize,\n\t\taddAssetStageCompletion: assetStageCompletionAdapter.addOne,\n\t\taddAssetStageCompletions: assetStageCompletionAdapter.addMany,\n\t\tupdateAssetStageCompletion: assetStageCompletionAdapter.updateOne,\n\t\tupdateAssetStageCompletions: assetStageCompletionAdapter.updateMany,\n\t\tdeleteAssetStageCompletion: assetStageCompletionAdapter.deleteOne,\n\t\tdeleteAssetStageCompletions: assetStageCompletionAdapter.deleteMany,\n\t},\n})\nexport const {\n\tinitializeAssetStageCompletions,\n\taddAssetStageCompletion,\n\taddAssetStageCompletions,\n\tupdateAssetStageCompletion,\n\tupdateAssetStageCompletions,\n\tdeleteAssetStageCompletion,\n\tdeleteAssetStageCompletions,\n} = assetStageCompletionSlice.actions\n\nexport const assetStageCompletionReducer: Reducer<AssetStageCompletionState> = assetStageCompletionSlice.reducer\n\nexport const selectAssetStageCompletionMapping = (state: OvermapRootState) => {\n\treturn state.assetStageCompletionReducer.instances\n}\n\nexport const selectAssetStageCompletions = createSelector(\n\t[selectAssetStageCompletionMapping],\n\t(stageCompletionMapping) => {\n\t\treturn Object.values(stageCompletionMapping)\n\t},\n)\n\nexport const selectAssetStageCompletionById: OvermapSelectorWithArgs<\n\tstring,\n\tStored<AssetStageCompletion> | undefined\n> = (id) => (state) => {\n\treturn state.assetStageCompletionReducer.instances[id]\n}\n\nexport const selectAssetStageCompletionsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssetStageCompletionMapping, (_, ids: string[]) => ids], (stageCompletionMapping, ids) => {\n\t\tconst stageCompletionIdsSet = new Set(ids)\n\t\treturn fallbackToEmptyArray(\n\t\t\tObject.values(stageCompletionMapping).filter((stageCompletion) =>\n\t\t\t\tstageCompletionIdsSet.has(stageCompletion.offline_id),\n\t\t\t),\n\t\t)\n\t}),\n)\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetStage, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type AssetStageState = ModelState<Stored<AssetStage>>\n\nconst assetStageAdapter = createModelAdapter<Stored<AssetStage>>((assetStage) => assetStage.offline_id)\n\nconst initialState = assetStageAdapter.getInitialState({})\n\nexport const assetStageSlice = createSlice({\n\tname: \"assetStages\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetStages: assetStageAdapter.initialize,\n\t\tsetAssetStage: assetStageAdapter.setOne,\n\t\tsetAssetStages: assetStageAdapter.setMany,\n\t\taddAssetStage: assetStageAdapter.addOne,\n\t\taddAssetStages: assetStageAdapter.addMany,\n\t\tupdateAssetStage: assetStageAdapter.updateOne,\n\t\tupdateAssetStages: assetStageAdapter.updateMany,\n\t\tdeleteAssetStage: assetStageAdapter.deleteOne,\n\t\tdeleteAssetStages: assetStageAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetStages,\n\tsetAssetStage,\n\tsetAssetStages,\n\taddAssetStage,\n\taddAssetStages,\n\tupdateAssetStage,\n\tupdateAssetStages,\n\tdeleteAssetStage,\n\tdeleteAssetStages,\n} = assetStageSlice.actions\n\nexport const assetStageReducer: Reducer<AssetStageState> = assetStageSlice.reducer\n\nexport const selectStageMapping: OvermapSelector<Record<AssetStage[\"offline_id\"], AssetStage>> = (state) =>\n\tstate.assetStageReducer.instances\n\nexport const selectAssetStageById: OvermapSelectorWithArgs<string, AssetStage | undefined> = (id) => (state) => {\n\treturn state.assetStageReducer.instances[id]\n}\n\nexport const selectAssetStages = createSelector([selectStageMapping], (stageMapping) => {\n\treturn Object.values(stageMapping)\n})\n\nexport const selectAssetStagesMappingOfAssetProcedure: OvermapSelectorWithArgs<\n\tstring,\n\tRecord<string, AssetStage>\n> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectStageMapping, (_state, id: string) => id], (stagesMapping, id) => {\n\t\tconst assetStageMapping: Record<string, AssetStage> = {}\n\n\t\tfor (const [stageId, stage] of Object.entries(stagesMapping)) {\n\t\t\tif (stage.asset_procedure === id) {\n\t\t\t\tassetStageMapping[stageId] = stage\n\t\t\t}\n\t\t}\n\n\t\treturn assetStageMapping\n\t}),\n)\n\nexport const selectAssetStagesOfAssetProcedure: OvermapSelectorWithArgs<string, AssetStage[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectAssetStages, (_state, id: string) => id], (stages, id) => {\n\t\t\treturn fallbackToEmptyArray(stages.filter((stage) => stage.asset_procedure === id))\n\t\t}),\n\t)\n\nexport const selectAssetStagesByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectStageMapping, (_state, stageIds: string[]) => stageIds], (stageMapping, stageIds) => {\n\t\tconst assetStages: Stored<AssetStage>[] = []\n\n\t\tfor (const stageId of stageIds) {\n\t\t\tconst stage = stageMapping[stageId]\n\n\t\t\tif (stage) {\n\t\t\t\tassetStages.push(stage)\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"selectStagesFromStageIds: No stage exists with the id\", stageId)\n\t\t\t}\n\t\t}\n\n\t\treturn fallbackToEmptyArray(assetStages)\n\t}),\n)\n","import type { Reducer } from \"@reduxjs/toolkit\"\nimport { createSelector, createSlice } from \"@reduxjs/toolkit\"\nimport type { AssetType, OvermapRootState, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type AssetTypeState = ModelState<Stored<AssetType>>\n\nconst assetTypeAdapter = createModelAdapter<Stored<AssetType>>((assetType) => assetType.offline_id)\n\nconst initialState: AssetTypeState = assetTypeAdapter.getInitialState({})\n\nexport const assetTypeSlice = createSlice({\n\tname: \"assetTypes\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetTypes: assetTypeAdapter.initialize,\n\t\tsetAssetType: assetTypeAdapter.setOne,\n\t\tsetAssetTypes: assetTypeAdapter.setMany,\n\t\taddAssetType: assetTypeAdapter.addOne,\n\t\taddAssetTypes: assetTypeAdapter.addMany,\n\t\tupdateAssetType: assetTypeAdapter.updateOne,\n\t\tupdateAssetTypes: assetTypeAdapter.updateMany,\n\t\tdeleteAssetType: assetTypeAdapter.deleteOne,\n\t\tdeleteAssetTypes: assetTypeAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetTypes,\n\tsetAssetType,\n\tsetAssetTypes,\n\taddAssetType,\n\taddAssetTypes,\n\tupdateAssetType,\n\tupdateAssetTypes,\n\tdeleteAssetType,\n\tdeleteAssetTypes,\n} = assetTypeSlice.actions\n\nexport const selectAssetTypesMapping: OvermapSelector<Record<string, AssetType>> = (state: OvermapRootState) =>\n\tstate.assetTypeReducer.instances\n\nexport const selectAssetTypes: OvermapSelector<AssetType[]> = createSelector([selectAssetTypesMapping], (mapping) =>\n\tObject.values(mapping),\n)\n\nexport const selectAssetTypeById: OvermapSelectorWithArgs<AssetType[\"offline_id\"], Stored<AssetType> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.assetTypeReducer.instances[id]\n\t}\n\nexport const selectAssetTypesByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetTypesMapping, (_state, assetTypeIds: AssetType[\"offline_id\"][]) => assetTypeIds],\n\t\t(assetTypeMapping, assetTypeIds) => {\n\t\t\tconst assetTypes: Stored<AssetType>[] = []\n\n\t\t\tfor (const assetTypeId of assetTypeIds) {\n\t\t\t\tconst assetType = assetTypeMapping[assetTypeId]\n\n\t\t\t\tif (assetType) {\n\t\t\t\t\tassetTypes.push(assetType)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\"selectAssetTypesByIds: No assetType exists with the id\", assetTypeId)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn fallbackToEmptyArray(assetTypes)\n\t\t},\n\t),\n)\n\nexport const assetTypeReducer: Reducer<AssetTypeState> = assetTypeSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tAssetTypeAttachment,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type AssetTypeAttachmentState = ModelState<Stored<AssetTypeAttachment>>\n\nconst assetTypeAttachmentAdapter = createModelAdapter<Stored<AssetTypeAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState = assetTypeAttachmentAdapter.getInitialState({})\n\nexport const assetTypeAttachmentSlice = createSlice({\n\tname: \"assetTypeAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetTypeAttachments: assetTypeAttachmentAdapter.initialize,\n\t\taddAssetTypeAttachment: assetTypeAttachmentAdapter.addOne,\n\t\taddAssetTypeAttachments: assetTypeAttachmentAdapter.addMany,\n\t\tsetAssetTypeAttachment: assetTypeAttachmentAdapter.setOne,\n\t\tsetAssetTypeAttachments: assetTypeAttachmentAdapter.setMany,\n\t\tupdateAssetTypeAttachment: assetTypeAttachmentAdapter.updateOne,\n\t\tupdateAssetTypeAttachments: assetTypeAttachmentAdapter.updateMany,\n\t\tdeleteAssetTypeAttachment: assetTypeAttachmentAdapter.deleteOne,\n\t\tdeleteAssetTypeAttachments: assetTypeAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetTypeAttachments,\n\taddAssetTypeAttachment,\n\taddAssetTypeAttachments,\n\tsetAssetTypeAttachment,\n\tsetAssetTypeAttachments,\n\tupdateAssetTypeAttachment,\n\tupdateAssetTypeAttachments,\n\tdeleteAssetTypeAttachment,\n\tdeleteAssetTypeAttachments,\n} = assetTypeAttachmentSlice.actions\n\nexport const selectAssetTypeAttachmentMapping = (state: OvermapRootState) => state.assetTypeAttachmentReducer.instances\n\nexport const selectAssetTypeAttachments: OvermapSelector<Stored<AssetTypeAttachment>[]> = createSelector(\n\t[selectAssetTypeAttachmentMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectAssetTypeAttachmentById: OvermapSelectorWithArgs<string, Stored<AssetTypeAttachment> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.assetTypeAttachmentReducer.instances[id]\n\t}\n\nexport const selectAttachmentsOfAssetType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetTypeAttachments, (_state: OvermapRootState, assetTypeId: string) => assetTypeId],\n\t\t(attachments, assetTypeId) => {\n\t\t\treturn fallbackToEmptyArray(attachments.filter(({ asset_type }) => assetTypeId === asset_type))\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfAssetTypeByType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetTypeAttachments, (_state: OvermapRootState, assetTypeId: string) => assetTypeId],\n\t\t(attachments, assetTypeId) => {\n\t\t\tconst attachmentsOfAssetType = attachments.filter(({ asset_type }) => asset_type === assetTypeId)\n\t\t\tconst fileAttachments = attachmentsOfAssetType.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => !file_type || !file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\tconst imageAttachments = attachmentsOfAssetType.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => file_type && file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\treturn { fileAttachments, imageAttachments }\n\t\t},\n\t),\n)\n\nexport const assetTypeAttachmentReducer: Reducer<AssetTypeAttachmentState> = assetTypeAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { Issue, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type IssueState = ModelState<Stored<Issue>>\n\nconst issueAdapter = createModelAdapter<Stored<Issue>>((issue) => issue.offline_id)\n\nconst initialState: IssueState = issueAdapter.getInitialState({})\n\nexport const issueSlice = createSlice({\n\tname: \"issues\",\n\tinitialState,\n\textraReducers: (builder) =>\n\t\tbuilder.addCase(\"RESET\", (state) => {\n\t\t\tObject.assign(state, initialState)\n\t\t}),\n\treducers: {\n\t\tinitializeIssues: issueAdapter.initialize,\n\t\taddIssue: issueAdapter.addOne,\n\t\taddIssues: issueAdapter.addMany,\n\t\tupdateIssue: issueAdapter.updateOne,\n\t\tdeleteIssue: issueAdapter.deleteOne,\n\t\tdeleteIssues: issueAdapter.deleteMany,\n\t},\n})\n\nexport const { initializeIssues, addIssue, addIssues, updateIssue, deleteIssue, deleteIssues } = issueSlice.actions\n\nexport interface IssueFilterArgs {\n\tfilterByAssignedTo: boolean\n\tfilterByStatus: boolean\n\tfilterByCategory: boolean\n\tfilterByWorkspace: boolean\n}\n\nexport const selectIssueMapping = (state: OvermapRootState) => state.issueReducer.instances\n\nexport const selectIssueById: OvermapSelectorWithArgs<string, Stored<Issue> | undefined> = (id) => (state) => {\n\treturn state.issueReducer.instances[id]\n}\n\nexport const selectIssuesByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectIssueMapping, (_, issueIds: string[]) => issueIds], (issuesMapping, issueIds) => {\n\t\tconst issues: Stored<Issue>[] = []\n\n\t\tfor (const issueId of issueIds) {\n\t\t\tconst issue = issuesMapping[issueId]\n\t\t\tif (issue) {\n\t\t\t\tissues.push(issue)\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"selectIssuesByIds: No issue exists with the id\", issueId)\n\t\t\t}\n\t\t}\n\n\t\treturn fallbackToEmptyArray(issues)\n\t}),\n)\n\nexport const issueReducer: Reducer<IssueState> = issueSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tIssue,\n\tIssueType,\n\tOrganization,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\n// TODO: add attachment support for issue type descriptions\n\nexport type IssueTypeState = ModelState<Stored<IssueType>>\n\nconst issueTypeAdapter = createModelAdapter<Stored<IssueType>>((issueType) => issueType.offline_id)\n\nconst initialState: IssueTypeState = issueTypeAdapter.getInitialState({})\n\nexport const issueTypeSlice = createSlice({\n\tname: \"issueTypes\",\n\tinitialState,\n\textraReducers: (builder) =>\n\t\tbuilder.addCase(\"RESET\", (state) => {\n\t\t\tObject.assign(state, initialState)\n\t\t}),\n\treducers: {\n\t\tinitializeIssueTypes: issueTypeAdapter.initialize,\n\t\tsetIssueType: issueTypeAdapter.setOne,\n\t\taddIssueType: issueTypeAdapter.addOne,\n\t\tupdateIssueType: issueTypeAdapter.updateOne,\n\t\tremoveIssueType: issueTypeAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeIssueTypes, setIssueType, addIssueType, updateIssueType, removeIssueType } =\n\tissueTypeSlice.actions\n\nexport const selectIssueTypeMapping: OvermapSelector<IssueTypeState[\"instances\"]> = (state) => {\n\treturn state.issueTypeReducer.instances\n}\n\nexport const selectIssueTypes: OvermapSelector<Stored<IssueType>[]> = createSelector(\n\tselectIssueTypeMapping,\n\t(issueTypes) => {\n\t\treturn Object.values(issueTypes)\n\t},\n)\n\nexport const selectIssueTypeById: OvermapSelectorWithArgs<string, Stored<IssueType> | undefined> = (id) => (state) => {\n\treturn state.issueTypeReducer.instances[id]\n}\n\nexport const selectIssueTypesByIds: OvermapSelectorWithArgs<string[], Stored<IssueType>[]> =\n\t(issueTypeIds: string[]) => (state: OvermapRootState) => {\n\t\tconst issueTypes: Stored<IssueType>[] = []\n\n\t\tfor (const issueTypeId of issueTypeIds) {\n\t\t\tconst issueType = state.issueTypeReducer.instances[issueTypeId]\n\t\t\tif (issueType) {\n\t\t\t\tissueTypes.push(issueType)\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"selectIssueTypesByIds: No issue type exists with the id\", issueTypeId)\n\t\t\t}\n\t\t}\n\n\t\treturn issueTypes\n\t}\n\nexport const selectIssueTypesOfOrganization: OvermapSelectorWithArgs<Organization[\"id\"], Stored<IssueType>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectIssueTypes, (_, organizationId: number) => organizationId],\n\t\t\t(issueTypes, organizationId) => {\n\t\t\t\treturn fallbackToEmptyArray(issueTypes.filter((issueType) => issueType.organization === organizationId))\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectIssuesOfIssueType: OvermapSelectorWithArgs<IssueType[\"offline_id\"], Stored<Issue>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[(state: OvermapRootState) => state.issueReducer.instances, (_, issueTypeId: string) => issueTypeId],\n\t\t\t(issuesMapping, issueTypeId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tObject.values(issuesMapping).filter((issue) => issue.issue_type === issueTypeId),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectIssuesOfIssueTypeCount: OvermapSelectorWithArgs<IssueType[\"offline_id\"], number> =\n\t(issueTypeId: string) => (state) => {\n\t\treturn selectIssuesOfIssueType(issueTypeId)(state).length\n\t}\n\nexport const issueTypeReducer: Reducer<IssueTypeState> = issueTypeSlice.reducer\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { BaseState, SelectorWithArgs } from \"typings\"\n\ninterface S3UploadUrl {\n\turl: string\n\tfields: Record<string, string>\n\t/** the time the upload url expires */\n\texp?: number\n}\n\nexport interface FileState {\n\t// maps sha1 hash to upload URL\n\ts3Urls: Record<string, S3UploadUrl>\n}\n\ninterface S3UrlPayload {\n\tsha1: string\n\turl: string\n\tfields: Record<string, string>\n}\n\nconst initialState: FileState = {\n\ts3Urls: {},\n}\n\nconst msPerHour = 1000 * 60 * 60\nconst msPerWeek = msPerHour * 24 * 7\n\n/**\n * Stores the auth state of the app (tokens, and whether user is logged in or not)\n */\nexport const fileSlice = createSlice({\n\tname: \"file\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetUploadUrl: (state, action: PayloadAction<S3UrlPayload>) => {\n\t\t\tconst { url, fields, sha1 } = action.payload\n\t\t\tconst today = new Date()\n\t\t\tconst weekFromToday = new Date(today.getTime() + msPerWeek)\n\n\t\t\tstate.s3Urls[sha1] = {\n\t\t\t\turl,\n\t\t\t\tfields,\n\t\t\t\texp: weekFromToday.getTime(),\n\t\t\t}\n\t\t},\n\t},\n})\n\nexport const { setUploadUrl } = fileSlice.actions\n\nexport const selectUploadUrl: SelectorWithArgs<BaseState, string, S3UploadUrl | undefined> =\n\t(sha1: string) => (state) => {\n\t\tconst url = state.fileReducer.s3Urls[sha1]\n\t\tif (!url) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst today = new Date().getTime()\n\t\tconst expiringWithinAnHour = (url.exp ?? today) - today < msPerHour\n\t\tif (expiringWithinAnHour) return undefined\n\n\t\treturn url\n\t}\n\nexport const fileReducer: Reducer<FileState> = fileSlice.reducer\n","import { createSelector, createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapRootState, OvermapSelectorWithArgs, User } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport interface UserState {\n\tcurrentUser: User | null\n\tusers: Record<number, User>\n}\n\nconst initialState: UserState = {\n\tusers: {},\n\tcurrentUser: null,\n}\n\nexport const userSlice = createSlice({\n\tname: \"users\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetUsers: (state, action: PayloadAction<User[]>) => {\n\t\t\tconst usersMapping: Record<string, User> = {}\n\t\t\taction.payload.forEach((user) => {\n\t\t\t\tusersMapping[user.id] = user\n\t\t\t})\n\t\t\tstate.users = usersMapping\n\t\t},\n\t\taddUsers: (state, action: PayloadAction<User[]>) => {\n\t\t\tfor (const user of action.payload) {\n\t\t\t\tstate.users[user.id] = user\n\t\t\t}\n\t\t},\n\t\tsetCurrentUser: (state, action: PayloadAction<User | null>) => {\n\t\t\tstate.currentUser = action.payload\n\t\t},\n\t\tsetProfilePicture: (state, action: PayloadAction<{ file?: string; file_sha1?: string }>) => {\n\t\t\tif (!state.currentUser) return\n\n\t\t\tstate.currentUser.profile.file = action.payload.file ?? null\n\t\t\tstate.currentUser.profile.file_sha1 = action.payload.file_sha1 ?? null\n\n\t\t\tconst currentUser = state.users[state.currentUser.id]\n\n\t\t\tif (!currentUser) {\n\t\t\t\tthrow new Error(\"Unable to find current user in users slice\")\n\t\t\t}\n\n\t\t\tcurrentUser.profile.file = action.payload.file ?? null\n\t\t\tcurrentUser.profile.file_sha1 = action.payload.file_sha1 ?? null\n\t\t},\n\n\t\tremoveUser: (state, action: PayloadAction<number>) => {\n\t\t\tdelete state.users[action.payload]\n\t\t},\n\t},\n})\n\nexport const { setCurrentUser, setProfilePicture, setUsers, addUsers, removeUser } = userSlice.actions\n\nexport const userReducer: Reducer<UserState> = userSlice.reducer\n\nexport const selectCurrentUser = (state: OvermapRootState) => state.userReducer.currentUser\n\nexport const selectUsersMapping = (state: OvermapRootState) => state.userReducer.users\n\nexport const selectUserById: OvermapSelectorWithArgs<number, User | undefined> = (id) => (state) => {\n\treturn state.userReducer.users[id]\n}\n\nexport const selectUsersByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectUsersMapping, (_state, userIds: number[]) => userIds], (usersMapping, userIds) => {\n\t\tconst users: User[] = []\n\n\t\tfor (const userId of userIds) {\n\t\t\tconst user = usersMapping[userId]\n\t\t\tif (user) {\n\t\t\t\tusers.push(user)\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"selectUsersByIds: No user exists with the id\", userId)\n\t\t\t}\n\t\t}\n\n\t\treturn fallbackToEmptyArray(users)\n\t}),\n)\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapRootState, OvermapSelector, OvermapSelectorWithArgs } from \"typings\"\nimport type { OrganizationAccess, User } from \"typings/models\"\nimport { selectCurrentUser } from \"./userSlice\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type OrganizationAccessState = ModelState<OrganizationAccess>\n\nconst organizationAccessAdapter = createModelAdapter<OrganizationAccess>(\n\t(organizationAccess) => organizationAccess.offline_id,\n)\n\nconst initialState: OrganizationAccessState = organizationAccessAdapter.getInitialState({})\n\nexport const organizationAccessSlice = createSlice({\n\tname: \"organizationAccess\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeOrganizationAccesses: organizationAccessAdapter.initialize,\n\t\tupdateOrganizationAccess: organizationAccessAdapter.updateOne,\n\t\tdeleteOrganizationAccess: organizationAccessAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeOrganizationAccesses, updateOrganizationAccess, deleteOrganizationAccess } =\n\torganizationAccessSlice.actions\n\nexport const selectOrganizationAccesses = (state: OvermapRootState) => {\n\treturn state.organizationAccessReducer.instances\n}\n\nexport const selectOrganizationAccessById: OvermapSelectorWithArgs<string, OrganizationAccess | undefined> =\n\t(id) => (state) => {\n\t\treturn state.organizationAccessReducer.instances[id]\n\t}\n\nexport const selectActiveOrganizationAccess: OvermapSelector<OrganizationAccess | null> = createSelector(\n\t[selectCurrentUser, selectOrganizationAccesses],\n\t(currentUser, organizationAccesses) => {\n\t\tconst activeOrganizationAccess = Object.values(organizationAccesses).find(\n\t\t\t(organizationAccess: OrganizationAccess) => organizationAccess.user === currentUser?.id,\n\t\t)\n\t\treturn activeOrganizationAccess ?? null\n\t},\n)\n\nexport const selectOrganizationAccessForUser: OvermapSelectorWithArgs<User, OrganizationAccess | undefined> =\n\t(user) => (state) => {\n\t\treturn Object.values(state.organizationAccessReducer.instances).find(\n\t\t\t(organizationAccess: OrganizationAccess) => organizationAccess.user === user.id,\n\t\t)\n\t}\n\nexport const selectOrganizationAccessUserMapping = (state: OvermapRootState): Record<number, OrganizationAccess> => {\n\tconst organizationAccesses: Record<number, OrganizationAccess> = {}\n\tfor (const organizationAccess of Object.values(state.organizationAccessReducer.instances)) {\n\t\torganizationAccesses[organizationAccess.user] = organizationAccess\n\t}\n\treturn organizationAccesses\n}\n\nexport const organizationAccessReducer: Reducer<OrganizationAccessState> = organizationAccessSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { License, OvermapRootState, OvermapSelector, OvermapSelectorWithArgs } from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray } from \"../../utils\"\n\nexport type LicenseState = ModelState<License>\n\nconst licenseAdapter = createModelAdapter<License>((license) => license.offline_id)\n\nconst initialState: LicenseState = licenseAdapter.getInitialState({})\n\nexport const licenseSlice = createSlice({\n\tname: \"license\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeLicences: licenseAdapter.initialize,\n\t\taddLicenses: licenseAdapter.addMany,\n\t\tupdateLicense: licenseAdapter.updateOne,\n\t},\n})\n\nexport const { initializeLicences, addLicenses, updateLicense } = licenseSlice.actions\n\nexport const selectLicenses: OvermapSelector<Record<string, License>> = (state: OvermapRootState) => {\n\treturn state.licenseReducer.instances\n}\n\nexport const selectLicense: OvermapSelectorWithArgs<string, License | undefined> = (id) => (state) =>\n\tstate.licenseReducer.instances[id]\n\nexport const selectLicenseForProject: OvermapSelectorWithArgs<number, License | undefined> =\n\t(projectId: number) => (state: OvermapRootState) =>\n\t\tObject.values(state.licenseReducer.instances).find((license) => license.project === projectId)\n\nexport const selectActiveStatusLicenses: OvermapSelector<License[]> = createSelector(\n\t[selectLicenses],\n\t(licenses: Record<string, License>) => {\n\t\treturn fallbackToEmptyArray(Object.values(licenses).filter((license) => license.is_active))\n\t},\n)\n\nexport const selectLicensesForProjectsMapping: OvermapSelector<Record<number, License>> = createSelector(\n\t[selectLicenses],\n\t(licenses: Record<string, License>) =>\n\t\tObject.values(licenses)\n\t\t\t.filter((license) => license.project)\n\t\t\t.reduce((accum, license) => ({ ...accum, [license.project!]: license }), {}),\n)\n\nexport const licenseReducer: Reducer<LicenseState> = licenseSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tProjectAccess,\n\tStored,\n\tUser,\n} from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type ProjectAccessState = ModelState<ProjectAccess>\n\nconst projectAccessAdapter = createModelAdapter<ProjectAccess>((projectAccess) => projectAccess.offline_id)\n\nconst initialState: ProjectAccessState = projectAccessAdapter.getInitialState({})\n\nexport const projectAccessSlice = createSlice({\n\tname: \"projectAccess\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeProjectAccesses: projectAccessAdapter.initialize,\n\t\tupdateProjectAccess: projectAccessAdapter.updateOne,\n\t\tdeleteProjectAccess: projectAccessAdapter.deleteOne,\n\t\tdeleteProjectAccesses: projectAccessAdapter.deleteMany,\n\t},\n})\n\nexport const { initializeProjectAccesses, updateProjectAccess, deleteProjectAccess, deleteProjectAccesses } =\n\tprojectAccessSlice.actions\n\nexport const selectProjectAccessMapping = (state: OvermapRootState) => {\n\treturn state.projectAccessReducer.instances\n}\n\nexport const selectProjectAccesses: OvermapSelector<Stored<ProjectAccess>[]> = createSelector(\n\tselectProjectAccessMapping,\n\t(projectAccesses) => {\n\t\treturn Object.values(projectAccesses)\n\t},\n)\n\nexport const selectProjectAccessById: OvermapSelectorWithArgs<string, ProjectAccess | undefined> = (id) => (state) => {\n\treturn state.projectAccessReducer.instances[id]\n}\n\n// TODO: move to web\nexport const selectActiveProjectAccess: OvermapSelector<ProjectAccess | null> = (state: OvermapRootState) => {\n\tconst currentUser = state.userReducer.currentUser\n\tconst activeProjectId = state.projectReducer.activeProjectId\n\treturn (\n\t\tObject.values(state.projectAccessReducer.instances).find((projectAccess: ProjectAccess) => {\n\t\t\treturn projectAccess.user === currentUser?.id && projectAccess.project === activeProjectId\n\t\t}) ?? null\n\t)\n}\n\nexport const selectProjectAccessForUser: OvermapSelectorWithArgs<User, ProjectAccess | undefined> =\n\t(user: User) => (state: OvermapRootState) => {\n\t\treturn Object.values(state.projectAccessReducer.instances).find(\n\t\t\t(projectAccess: ProjectAccess) => projectAccess.user === user.id,\n\t\t)\n\t}\n\nexport const selectProjectAccessUserMapping: OvermapSelector<Record<string, ProjectAccess>> = (\n\tstate: OvermapRootState,\n) => {\n\tconst projectAccesses: Record<string, ProjectAccess> = {}\n\tfor (const projectAccess of Object.values(state.projectAccessReducer.instances)) {\n\t\tprojectAccesses[projectAccess.user] = projectAccess\n\t}\n\treturn projectAccesses\n}\n\nexport const projectAccessReducer: Reducer<ProjectAccessState> = projectAccessSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tOfflineIdMapping,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tProject,\n\tProjectAccess,\n\tUser,\n} from \"../../typings\"\nimport { selectProjectAccessMapping, selectProjectAccessUserMapping } from \"./projectAccessSlice\"\nimport { selectCurrentUser, selectUsersMapping } from \"./userSlice\"\nimport { ProjectAccessLevel } from \"../../enums\"\n\nexport interface ProjectState {\n\tprojects: Record<number, Project>\n\tactiveProjectId: number | null\n}\n\nconst initialState: ProjectState = {\n\tprojects: {},\n\tactiveProjectId: null,\n}\n\nexport const projectSlice = createSlice({\n\tname: \"projects\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetProjects: (state, action: { payload: Project[] }) => {\n\t\t\tconst projectsMap: Record<number, Project> = {}\n\t\t\taction.payload.forEach((project) => {\n\t\t\t\tprojectsMap[project.id] = project\n\t\t\t})\n\t\t\tstate.projects = projectsMap\n\t\t},\n\t\tsetActiveProjectId: (state, action: { payload: number | null }) => {\n\t\t\tstate.activeProjectId = action.payload\n\t\t},\n\t\tupdateOrCreateProject: (state, action: { payload: Project }) => {\n\t\t\tstate.projects[action.payload.id] = action.payload\n\t\t},\n\t\t// Takes a list of Projects and updates existing ones to match the payload, or adds them\n\t\t// to the store if they are not already present\n\t\tupdateOrCreateProjects: (state, action: { payload: Project[] }) => {\n\t\t\taction.payload.forEach((project) => {\n\t\t\t\tstate.projects[project.id] = project\n\t\t\t})\n\t\t},\n\t\tdeleteProject: (state, action: { payload: Project }) => {\n\t\t\tdelete state.projects[action.payload.id]\n\t\t},\n\t\tacceptProjectInvite: (state, action: { payload: number }) => {\n\t\t\tif (action.payload in state.projects) {\n\t\t\t\tstate.projects[action.payload]!.invited = false\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Accept project invite: user is not in this project\")\n\t\t\t}\n\t\t},\n\t\taddActiveProjectIssuesCount: (state, action: { payload: number }) => {\n\t\t\tif (!state.activeProjectId || !(state.activeProjectId in state.projects)) {\n\t\t\t\tthrow new Error(\"Update issues count: no active project\")\n\t\t\t}\n\n\t\t\tif (!state.projects[state.activeProjectId]!.issues_count) {\n\t\t\t\tstate.projects[state.activeProjectId]!.issues_count = action.payload\n\t\t\t} else {\n\t\t\t\tstate.projects[state.activeProjectId]!.issues_count! += action.payload\n\t\t\t}\n\t\t},\n\t\taddActiveProjectFormSubmissionsCount: (state, action: { payload: number }) => {\n\t\t\tif (state.activeProjectId && state.activeProjectId in state.projects) {\n\t\t\t\tif (!state.projects[state.activeProjectId]!.form_submissions_count) {\n\t\t\t\t\tstate.projects[state.activeProjectId]!.form_submissions_count = action.payload\n\t\t\t\t} else {\n\t\t\t\t\tstate.projects[state.activeProjectId]!.form_submissions_count! += action.payload\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Update form submissions count: no active project\")\n\t\t\t}\n\t\t},\n\t},\n})\n\nexport const {\n\tsetProjects,\n\tupdateOrCreateProject,\n\tupdateOrCreateProjects: addOrReplaceProjects,\n\tsetActiveProjectId,\n\tdeleteProject,\n\tacceptProjectInvite,\n\taddActiveProjectIssuesCount,\n\taddActiveProjectFormSubmissionsCount,\n} = projectSlice.actions\n\nexport const projectReducer: Reducer<ProjectState> = projectSlice.reducer\n\nexport const selectProjectMapping: OvermapSelector<Record<number, Project>> = (state: OvermapRootState) =>\n\tstate.projectReducer.projects\n\nexport const selectActiveProjectId = (state: OvermapRootState): number | null => state.projectReducer.activeProjectId\n\nexport const selectActiveProject = (state: OvermapRootState): Project | null => {\n\tconst activeProjectId = selectActiveProjectId(state)\n\tif (!activeProjectId) {\n\t\treturn null\n\t}\n\treturn state.projectReducer.projects[activeProjectId] ?? null\n}\n\nexport const selectProjectById: OvermapSelectorWithArgs<number, Project | undefined> = (id) => (state) => {\n\treturn state.projectReducer.projects[id]\n}\n\nexport const selectProjectUsersIds: OvermapSelector<number[]> = createSelector(\n\t[selectProjectAccessMapping],\n\t(projectAccesses: OfflineIdMapping<ProjectAccess>) =>\n\t\tObject.values(projectAccesses).map((projectAccess: ProjectAccess) => projectAccess.user),\n)\n\nexport const selectProjectUsersAsMapping: OvermapSelector<Record<number, User>> = createSelector(\n\t[selectProjectUsersIds, selectUsersMapping],\n\t(projectUserIds, users) => projectUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {}),\n)\n\nexport const selectSortedProjectUsers: OvermapSelector<User[]> = createSelector(\n\t[selectCurrentUser, selectProjectUsersAsMapping, selectProjectAccessUserMapping],\n\t(currentUser, userMapping, projectAccessMapping) => {\n\t\treturn Object.values(userMapping).sort((userA, userB) => {\n\t\t\tif (userA.id === currentUser?.id) {\n\t\t\t\treturn -1\n\t\t\t} else if (userB.id === currentUser?.id) {\n\t\t\t\treturn 1\n\t\t\t}\n\t\t\tconst projectAccessesA = projectAccessMapping[userA.id]\n\t\t\tconst projectAccessesB = projectAccessMapping[userB.id]\n\t\t\tif (projectAccessesA?.access_level === projectAccessesB?.access_level) {\n\t\t\t\treturn userA.username.localeCompare(userB.username)\n\t\t\t}\n\t\t\tif (projectAccessesA?.access_level === ProjectAccessLevel.ADMIN) {\n\t\t\t\treturn -1\n\t\t\t}\n\t\t\treturn 1\n\t\t})\n\t},\n)\n","import { createSelector, createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapSelector, OvermapSelectorWithArgs } from \"typings/store\"\nimport type {\n\tLicense,\n\tOfflineIdMapping,\n\tOrganization,\n\tOrganizationAccess,\n\tOvermapRootState,\n\tProject,\n\tUser,\n} from \"../../typings\"\nimport { selectCurrentUser, selectUsersMapping } from \"./userSlice\"\nimport { selectOrganizationAccesses, selectOrganizationAccessUserMapping } from \"./organizationAccessSlice\"\nimport { selectLicenses } from \"./licenseSlice\"\nimport { selectProjectMapping } from \"./projectSlice\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { OrganizationAccessLevel } from \"../../enums\"\n\nexport interface OrganizationState {\n\torganizations: Record<number, Organization>\n}\n\nconst initialState: OrganizationState = {\n\torganizations: {},\n}\n\nexport const organizationSlice = createSlice({\n\tname: \"organizations\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetOrganizations: (state, action: PayloadAction<Organization[]>) => {\n\t\t\tfor (const org of action.payload) {\n\t\t\t\tstate.organizations[org.id] = org\n\t\t\t}\n\t\t},\n\t},\n})\n\nexport const { setOrganizations } = organizationSlice.actions\n\nexport const selectOrganizationsMapping: OvermapSelector<Record<number, Organization>> = (state: OvermapRootState) => {\n\treturn state.organizationReducer.organizations\n}\n\nexport const selectOrganizations = createSelector([selectOrganizationsMapping], (organizationsMapping) => {\n\treturn Object.values(organizationsMapping)\n})\n\nexport const selectOrganizationById: OvermapSelectorWithArgs<number, Organization | undefined> = (id) => (state) => {\n\treturn state.organizationReducer.organizations[id]\n}\n\nexport const selectOrganizationsWithAccess: OvermapSelector<Organization[]> = createSelector(\n\t[selectOrganizations],\n\t(organizations: Record<number, Organization>) => {\n\t\treturn fallbackToEmptyArray(\n\t\t\tObject.values(organizations).filter((organization: Organization) => organization.has_access),\n\t\t)\n\t},\n)\n\nexport const selectOrganizationUsersIds: OvermapSelector<number[]> = createSelector(\n\t[selectOrganizationAccesses],\n\t(organizationAccesses: OfflineIdMapping<OrganizationAccess>) =>\n\t\tObject.values(organizationAccesses).map((organizationAccess: OrganizationAccess) => organizationAccess.user),\n)\n\nexport const selectProjectsOfOrganization: OvermapSelectorWithArgs<number, Project[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectProjectMapping, (_, organizationId: number) => organizationId],\n\t\t\t(projects, organizationId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tObject.values(projects).filter((project) => project.organization_owner === organizationId),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectLicensesOfOrganization: OvermapSelectorWithArgs<number, License[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectLicenses, (_, organizationId: number) => organizationId], (licenses, organizationId) => {\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\tObject.values(licenses).filter((license) => license.organization_owner === organizationId),\n\t\t\t)\n\t\t}),\n\t)\n\nexport const selectOrganizationUsersAsMapping: OvermapSelector<Record<number, User>> = createSelector(\n\t[selectOrganizationUsersIds, selectUsersMapping],\n\t(organizationUserIds: number[], users: Record<number, User>) =>\n\t\torganizationUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {}),\n)\n\nexport const selectSortedOrganizationUsers: OvermapSelector<User[]> = createSelector(\n\t[selectCurrentUser, selectOrganizationUsersAsMapping, selectOrganizationAccessUserMapping],\n\t(currentUser, userMapping, organizationAccessMapping) => {\n\t\treturn Object.values(userMapping).sort((userA: User, userB: User) => {\n\t\t\tif (userA.id === currentUser?.id) {\n\t\t\t\treturn -1\n\t\t\t} else if (userB.id === currentUser?.id) {\n\t\t\t\treturn 1\n\t\t\t}\n\t\t\tconst organizationAccessesA: OrganizationAccess | undefined = organizationAccessMapping[userA.id]\n\t\t\tconst organizationAccessesB: OrganizationAccess | undefined = organizationAccessMapping[userB.id]\n\t\t\tif (organizationAccessesA?.access_level === organizationAccessesB?.access_level) {\n\t\t\t\treturn userA.username.localeCompare(userB.username)\n\t\t\t}\n\t\t\tif (organizationAccessesA?.access_level === OrganizationAccessLevel.ADMIN) {\n\t\t\t\treturn -1\n\t\t\t}\n\t\t\treturn 1\n\t\t})\n\t},\n)\n\nexport const organizationReducer: Reducer<OrganizationState> = organizationSlice.reducer\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { FullOfflineAction } from \"../store\"\nimport type { RequestDetails } from \"../../sdk\"\nimport { v4 as uuidv4 } from \"uuid\"\nimport { SDKRequest } from \"../../sdk\"\nimport type { OvermapRootState } from \"../../typings\"\n\nexport const createOfflineAction = (request: SDKRequest, baseUrl: string, serviceName: string): FullOfflineAction => {\n\tconst requestWithUuid = request.uuid ? (request as RequestDetails) : { ...request, uuid: uuidv4() }\n\treturn {\n\t\tpayload: requestWithUuid,\n\t\ttype: \"\",\n\t\tmeta: {\n\t\t\toffline: {\n\t\t\t\teffect: {\n\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\trequest: requestWithUuid,\n\t\t\t\t\tBASE_URL: baseUrl,\n\t\t\t\t\tserviceName: serviceName,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n}\n\nexport interface OutboxState {\n\t/** A list of requests marked for deletion. Once the offline slice encounters one of these, */\n\tdeletedRequests: string[]\n\t/** The timestamp of the last retry of an outgoing request. (Number of milliseconds since the epoch.) */\n\tlatestRetryTime: number\n}\n\nconst initialState: OutboxState = {\n\tdeletedRequests: [],\n\tlatestRetryTime: 0,\n}\n\n/**\n * This slice primarily exists as an interface to enqueue API requests to the redux-offline slice. Any dispatched action\n * with an `offline` field in its metadata will be handled by redux-offline. This slice is just a sensible place to\n * \"dump\" no-op actions for enqueueing requests to the outbox. At the same time, we can use this slice to keep track of\n * requests that have been marked for deletion, so that we can skip them instead of sending the request.\n */\nexport const outboxSlice = createSlice({\n\tname: \"outbox\",\n\tinitialState: initialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\t// enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox\n\t\t// Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store\n\t\t// Then this reducer enqueueRequest() is responsible for adding the actual request data to the outbox\n\t\tenqueueRequest: {\n\t\t\treducer: (state, _action: PayloadAction<RequestDetails>) => {\n\t\t\t\treturn state\n\t\t\t},\n\t\t\tprepare: (payload: SDKRequest & { BASE_URL: string; serviceName: string }): FullOfflineAction => {\n\t\t\t\tconsole.debug(\"Preparing to enqueue request\", payload)\n\t\t\t\tconst { BASE_URL, serviceName, ...rest } = payload\n\t\t\t\treturn createOfflineAction(rest, BASE_URL, serviceName)\n\t\t\t},\n\t\t},\n\t\tmarkForDeletion(state, action: PayloadAction<string>) {\n\t\t\tstate.deletedRequests.push(action.payload)\n\t\t},\n\t\tmarkAsDeleted(state, action: PayloadAction<string>) {\n\t\t\tconst index = state.deletedRequests.indexOf(action.payload)\n\t\t\tif (index !== -1) state.deletedRequests.splice(index, 1)\n\t\t},\n\t\t_setLatestRetryTime: (state, action: PayloadAction<number>) => {\n\t\t\tstate.latestRetryTime = action.payload\n\t\t},\n\t},\n})\n\nexport const selectDeletedRequests = (state: OvermapRootState) => state.outboxReducer.deletedRequests\nexport const selectLatestRetryTime = (state: OvermapRootState) => state.outboxReducer.latestRetryTime\n\nexport const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions\nexport const outboxReducer: Reducer<OutboxState> = outboxSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tMultiPointGeometry,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tProjectFile,\n} from \"../../typings\"\nimport { selectActiveProjectId } from \"./projectSlice\"\nimport { fallbackToEmptyArray } from \"../../utils\"\n\nexport interface ProjectFileState {\n\tprojectFiles: Record<string, ProjectFile>\n\tactiveProjectFileId: string | null\n\t/**\n\t * State variable which is set true by web client to mark that the activeProjectFile is a new one that was just\n\t * imported and not a pre-existing one which is being edited\n\t */\n\tisImportingProjectFile: boolean\n}\n\nconst initialState: ProjectFileState = {\n\tprojectFiles: {},\n\tactiveProjectFileId: null,\n\tisImportingProjectFile: false,\n}\n\nexport const projectFileSlice = createSlice({\n\tname: \"projectFiles\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\taddOrReplaceProjectFiles: (state, action: { payload: ProjectFile[] }) => {\n\t\t\tfor (let fileObj of action.payload) {\n\t\t\t\tlet file = fileObj.file\n\t\t\t\tif (file.includes(\"+\")) {\n\t\t\t\t\tconsole.warn(\"Attempting to apply fix for image URL with '+' character:\", file)\n\t\t\t\t\t// We have a src such as this:\n\t\t\t\t\t// https://example.com/my-svg.svg+xml\n\t\t\t\t\t// Or:\n\t\t\t\t\t// blob://.../my-svg.svg+xml\n\t\t\t\t\t// We want just the `my-svg.svg+xml` part.\n\t\t\t\t\tconst parts = file.split(\"/\")\n\t\t\t\t\tif (parts.length < 2) {\n\t\t\t\t\t\tthrow new Error(\"Invalid URL: \" + file)\n\t\t\t\t\t}\n\t\t\t\t\tconst lastPart = encodeURIComponent(parts[parts.length - 1]!)\n\t\t\t\t\t// Reconstruct the URL with the fixed last part.\n\t\t\t\t\tfile = parts.slice(0, -1).join(\"/\") + \"/\" + lastPart\n\t\t\t\t\tconsole.warn(\"Fixed URL:\", file)\n\t\t\t\t\tfileObj = { ...fileObj, file }\n\t\t\t\t}\n\t\t\t\tstate.projectFiles[fileObj.offline_id] = fileObj\n\t\t\t}\n\t\t},\n\t\taddOrReplaceProjectFile: (state, action: { payload: ProjectFile }) => {\n\t\t\tif (!action.payload.project) {\n\t\t\t\tthrow new Error(\"ProjectFile has no project. A project must be set before storing.\")\n\t\t\t}\n\t\t\tstate.projectFiles[action.payload.offline_id] = action.payload\n\t\t},\n\t\tsetIsImportingProjectFile: (state, action: { payload: boolean }) => {\n\t\t\tstate.isImportingProjectFile = action.payload\n\t\t},\n\t\tsaveActiveProjectFileBounds: (state, action: { payload: MultiPointGeometry }) => {\n\t\t\tconst activeProjectFileId = state.activeProjectFileId\n\t\t\tif (!activeProjectFileId) {\n\t\t\t\tthrow new Error(\"Tried to save bounds for active project file, but no active project file was set.\")\n\t\t\t}\n\t\t\tif (!state.projectFiles[activeProjectFileId]) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Tried to save bounds for active project file, but project file with ID ${activeProjectFileId} \n\t\t\t\t\tdoesn't exist.`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tstate.projectFiles[activeProjectFileId]!.bounds = action.payload\n\t\t},\n\t\t// TODO: Move to MapContext. Should not be persisted.\n\t\tsetActiveProjectFileId: (state, action: { payload: string | null }) => {\n\t\t\tstate.activeProjectFileId = action.payload\n\t\t},\n\t\tremoveProjectFile: (state, action: { payload: string }) => {\n\t\t\tdelete state.projectFiles[action.payload]\n\t\t},\n\t\tremoveProjectFilesOfProject: (state, action: { payload: number }) => {\n\t\t\tconst filesToDelete = Object.values(state.projectFiles).filter((file) => file.project === action.payload)\n\t\t\tfor (const file of filesToDelete) {\n\t\t\t\tdelete state.projectFiles[file.offline_id]\n\t\t\t}\n\t\t},\n\t\tresetProjectFileObjectUrls: (state, ..._args: []) => {\n\t\t\tfor (const key in state.projectFiles) {\n\t\t\t\tdelete state.projectFiles[key]!.objectURL\n\t\t\t}\n\t\t},\n\t},\n})\n\nexport const {\n\taddOrReplaceProjectFiles,\n\taddOrReplaceProjectFile,\n\tsetIsImportingProjectFile,\n\tsetActiveProjectFileId,\n\tsaveActiveProjectFileBounds,\n\tremoveProjectFile,\n\tremoveProjectFilesOfProject,\n\tresetProjectFileObjectUrls,\n} = projectFileSlice.actions\n\nexport const selectProjectFileMapping = (state: OvermapRootState) => state.projectFileReducer.projectFiles\n\nexport const selectProjectFiles = createSelector(\n\t[selectProjectFileMapping, selectActiveProjectId],\n\t(mapping, activeProjectId) => {\n\t\treturn fallbackToEmptyArray(\n\t\t\tObject.values(mapping)\n\t\t\t\t.filter((file) => file.project === activeProjectId)\n\t\t\t\t.sort((a, b) => a.z_index - b.z_index),\n\t\t)\n\t},\n)\n\nexport const selectActiveProjectFileId: OvermapSelector<string | null> = (state: OvermapRootState) =>\n\tstate.projectFileReducer.activeProjectFileId\n\nexport const selectIsImportingProjectFile: OvermapSelector<boolean> = (state: OvermapRootState) =>\n\tstate.projectFileReducer.isImportingProjectFile\n\nexport const selectProjectFileById: OvermapSelectorWithArgs<string, ProjectFile | undefined> = (id) => (state) => {\n\treturn state.projectFileReducer.projectFiles[id]\n}\n\nexport const projectFileReducer: Reducer<ProjectFileState> = projectFileSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type {\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tProjectAttachment,\n\tStored,\n} from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type ProjectAttachmentState = ModelState<Stored<ProjectAttachment>>\n\nconst projectAttachmentAdapter = createModelAdapter<Stored<ProjectAttachment>>((attachment) => attachment.offline_id)\n\nconst initialState: ProjectAttachmentState = projectAttachmentAdapter.getInitialState({})\n\nexport const projectAttachmentSlice = createSlice({\n\tname: \"projectAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeProjectAttachments: projectAttachmentAdapter.initialize,\n\t\taddProjectAttachment: projectAttachmentAdapter.addOne,\n\t\taddProjectAttachments: projectAttachmentAdapter.addMany,\n\t\tsetProjectAttachment: projectAttachmentAdapter.setOne,\n\t\tsetProjectAttachments: projectAttachmentAdapter.setMany,\n\t\tupdateProjectAttachment: projectAttachmentAdapter.updateOne,\n\t\tupdateProjectAttachments: projectAttachmentAdapter.updateMany,\n\t\tdeleteProjectAttachment: projectAttachmentAdapter.deleteOne,\n\t\tdeleteProjectAttachments: projectAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeProjectAttachments,\n\taddProjectAttachment,\n\taddProjectAttachments,\n\tsetProjectAttachment,\n\tsetProjectAttachments,\n\tupdateProjectAttachment,\n\tupdateProjectAttachments,\n\tdeleteProjectAttachment,\n\tdeleteProjectAttachments,\n} = projectAttachmentSlice.actions\n\nexport const selectProjectAttachmentMapping = (state: OvermapRootState) => state.projectAttachmentReducer.instances\n\nexport const selectAllProjectAttachments: OvermapSelector<Stored<ProjectAttachment>[]> = createSelector(\n\t[selectProjectAttachmentMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectProjectAttachmentById: OvermapSelectorWithArgs<string, ProjectAttachment | undefined> =\n\t(id) => (state) => {\n\t\treturn state.projectAttachmentReducer.instances[id]\n\t}\n\nexport const selectAttachmentsOfProject = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAllProjectAttachments, (_, projectId: number) => projectId], (attachments, projectId) => {\n\t\treturn fallbackToEmptyArray(attachments.filter(({ project }) => projectId === project))\n\t}),\n)\nexport const selectAttachmentsOfProjectByType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAllProjectAttachments, (_state: OvermapRootState, projectId: number) => projectId],\n\t\t(attachments, projectId) => {\n\t\t\tconst attachmentsOfProject = attachments.filter(({ project }) => projectId === project)\n\t\t\tconst fileAttachments = attachmentsOfProject.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => !file_type || !file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\tconst imageAttachments = attachmentsOfProject.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => file_type && file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\treturn { fileAttachments, imageAttachments }\n\t\t},\n\t),\n)\n\nexport const projectAttachmentReducer: Reducer<ProjectAttachmentState> = projectAttachmentSlice.reducer\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapRootState } from \"../../typings\"\n\n// TODO: this slice can be moved to /web ?\n\nexport interface RehydratedState {\n\tisRehydrated: boolean\n}\n\nconst initialState: RehydratedState = {\n\tisRehydrated: false,\n}\n\n// rehydratedSlice is used to indicate when the Redux store has finished rehydrating its state from localForage\n// Once finished, the app renders, which prevents the annoying login screen flickering issue\nexport const rehydratedSlice = createSlice({\n\tname: \"rehydrated\",\n\tinitialState,\n\t// The `reducers` field lets us define reducers and generate associated actions\n\treducers: {\n\t\tsetRehydrated: (state, action: PayloadAction<boolean>) => {\n\t\t\tstate.isRehydrated = action.payload\n\t\t},\n\t},\n})\n\nexport const { setRehydrated } = rehydratedSlice.actions\n\n// The function below is called a selector and allows us to select a value from\n// the state. Selectors can also be defined inline where they're used instead of\n// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`\nexport const selectRehydrated = (state: OvermapRootState) => state.rehydratedReducer.isRehydrated\n\nexport const rehydratedReducer: Reducer<RehydratedState> = rehydratedSlice.reducer\n","import { Stored, FormRevision } from \"../typings\"\n\nexport const formRevisionSortFn = (formRevisionA: Stored<FormRevision>, formRevisionB: Stored<FormRevision>) => {\n\tconst revisionA = formRevisionA.revision\n\tconst revisionB = formRevisionB.revision\n\n\tif (revisionA === \"Pending\" && revisionB === \"Pending\") {\n\t\treturn formRevisionA.submitted_at < formRevisionB.submitted_at ? -1 : 1\n\t} else if (revisionA === \"Pending\") {\n\t\treturn 1\n\t} else if (revisionB === \"Pending\") {\n\t\treturn -1\n\t} else {\n\t\treturn revisionA < revisionB ? -1 : 1\n\t}\n}\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { FormRevision, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { formRevisionSortFn } from \"../../utils/forms\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type FormRevisionState = ModelState<Stored<FormRevision>>\n\nconst formRevisionAdapter = createModelAdapter<Stored<FormRevision>>((revision) => revision.offline_id)\n\nconst initialState: FormRevisionState = formRevisionAdapter.getInitialState({})\n\nexport const formRevisionsSlice = createSlice({\n\tname: \"formRevisions\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeFormRevisions: formRevisionAdapter.initialize,\n\t\tsetFormRevision: formRevisionAdapter.setOne,\n\t\taddFormRevision: formRevisionAdapter.addOne,\n\t\taddFormRevisions: formRevisionAdapter.addMany,\n\t\tdeleteFormRevision: formRevisionAdapter.deleteOne,\n\t\tdeleteFormRevisions: formRevisionAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tsetFormRevision,\n\tinitializeFormRevisions,\n\taddFormRevision,\n\taddFormRevisions,\n\tdeleteFormRevision,\n\tdeleteFormRevisions,\n} = formRevisionsSlice.actions\n\nexport const selectFormRevisionMapping = (state: OvermapRootState) => state.formRevisionReducer.instances\n\nexport const selectFormRevisions = createSelector([selectFormRevisionMapping], (formRevisions) =>\n\tObject.values(formRevisions),\n)\n\nexport const selectFormRevisionById: OvermapSelectorWithArgs<string, Stored<FormRevision> | undefined> =\n\t(formRevisionId: string) => (state: OvermapRootState) => {\n\t\treturn state.formRevisionReducer.instances[formRevisionId]\n\t}\n\n// takes user form state revisions instead of the whole state as an argument\nexport const _selectLatestFormRevision = (\n\tformRevisions: FormRevisionState[\"instances\"],\n\tformId: string,\n): Stored<FormRevision> => {\n\tlet ret: Stored<FormRevision> | null = null\n\n\tfor (const candidate of Object.values(formRevisions)) {\n\t\tif (candidate.form === formId && (!ret || ret.revision < candidate.revision)) {\n\t\t\tret = candidate\n\t\t}\n\t}\n\n\tif (!ret) {\n\t\tthrow new Error(\"No form revision found for form \" + formId)\n\t}\n\n\treturn ret\n}\n\nexport const selectLatestFormRevisionOfForm: OvermapSelectorWithArgs<string, Stored<FormRevision> | undefined> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectFormRevisionMapping, (_state: OvermapRootState, formId: string) => formId],\n\t\t\t(revisions, formId) => {\n\t\t\t\tconst revisionsOfForm = Object.values(revisions).filter((revision) => revision.form === formId)\n\n\t\t\t\tif (revisionsOfForm.length === 0) return undefined\n\n\t\t\t\tconst sortedRevisions = revisionsOfForm.sort(formRevisionSortFn)\n\n\t\t\t\tconst latestRevision = sortedRevisions[revisionsOfForm.length - 1]!\n\n\t\t\t\treturn revisions[latestRevision.offline_id]\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectFormRevisionsOfForm: OvermapSelectorWithArgs<string, Stored<FormRevision>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectFormRevisions, (_state: OvermapRootState, formId: string) => formId],\n\t\t\t(revisions, formId) => {\n\t\t\t\treturn fallbackToEmptyArray(revisions.filter((revision) => revision.form === formId))\n\t\t\t},\n\t\t),\n\t)\n\nexport const formRevisionReducer: Reducer<FormRevisionState> = formRevisionsSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { Form } from \"typings/models/forms\"\nimport type { SearchArgs } from \"typings/search\"\nimport type { OvermapSelector, OvermapSelectorWithArgs } from \"typings/store\"\nimport { restructureCreateSelectorWithArgs } from \"utils/utils\"\nimport type { OvermapRootState, Stored } from \"../../typings\"\nimport { _selectLatestFormRevision } from \"./formRevisionSlice\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { shallowEqual } from \"../../utils\"\n\nexport type FormState = ModelState<Stored<Form>>\n\nconst formAdapter = createModelAdapter<Stored<Form>>((form) => form.offline_id)\n\nconst initialState: FormState = formAdapter.getInitialState({})\n\nexport const formSlice = createSlice({\n\tname: \"forms\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeForms: formAdapter.initialize,\n\t\tsetForm: formAdapter.setOne,\n\t\taddForm: formAdapter.addOne,\n\t\taddForms: formAdapter.addMany,\n\t\tupdateForm: formAdapter.updateOne,\n\t\tdeleteForm: formAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeForms, setForm, addForm, addForms, updateForm, deleteForm } = formSlice.actions\n\nexport const formReducer: Reducer<FormState> = formSlice.reducer\n\nexport type FormSearchArgs = SearchArgs<{\n\t/** organization owner */\n\torganization?: number\n}>\n\nexport const selectFormMapping: OvermapSelector<Record<Stored<Form>[\"offline_id\"], Stored<Form>>> = (\n\tstate: OvermapRootState,\n) => {\n\treturn state.formReducer.instances\n}\n\nexport const selectForms = createSelector([selectFormMapping], (formsMapping) => {\n\treturn Object.values(formsMapping)\n})\n\nexport const selectFormById: OvermapSelectorWithArgs<string, Stored<Form> | undefined> =\n\t(formId: string) => (state: OvermapRootState) => {\n\t\treturn state.formReducer.instances[formId]\n\t}\n\nexport const selectFilteredForms: OvermapSelectorWithArgs<FormSearchArgs, Stored<Form>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[\n\t\t\t\t(state: OvermapRootState) => state.formReducer.instances,\n\t\t\t\t(state: OvermapRootState) => state.formRevisionReducer.instances,\n\t\t\t\t(_state: OvermapRootState, search: FormSearchArgs) => search,\n\t\t\t],\n\t\t\t(formsMapping, revisions, search) => {\n\t\t\t\tconst { searchTerm, maxResults, organization } = search\n\n\t\t\t\tconst regularMatches: Stored<Form>[] = []\n\n\t\t\t\tfor (const [formId, form] of Object.entries(formsMapping)) {\n\t\t\t\t\t// if filtering by organizations, skip forms with the wrong organization\n\t\t\t\t\tif (Number.isInteger(organization) && organization !== form.organization) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// find the latest revision for this form (note: expensive)\n\t\t\t\t\tconst latestRevision = _selectLatestFormRevision(revisions, formId)\n\n\t\t\t\t\tif (latestRevision.title.toLowerCase().includes(searchTerm.toLowerCase())) {\n\t\t\t\t\t\tregularMatches.push(form)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [...regularMatches.slice(0, maxResults)]\n\t\t\t},\n\t\t\t// as the argument is an object, we check the first level of properties for equality\n\t\t\t{ memoizeOptions: { equalityCheck: shallowEqual } },\n\t\t),\n\t)\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { FormSubmission, OvermapRootState, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\nimport { selectFormRevisionMapping } from \"./formRevisionSlice\"\n\nexport type FormSubmissionState = ModelState<Stored<FormSubmission>>\n\nconst submissionAdapter = createModelAdapter<Stored<FormSubmission>>((submission) => submission.offline_id)\n\nconst initialState: FormSubmissionState = submissionAdapter.getInitialState({})\n\nexport const formSubmissionSlice = createSlice({\n\tname: \"formSubmissions\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeFormSubmissions: submissionAdapter.initialize,\n\t\tsetFormSubmission: submissionAdapter.setOne,\n\t\tsetFormSubmissions: submissionAdapter.setMany,\n\t\taddFormSubmission: submissionAdapter.addOne,\n\t\taddFormSubmissions: submissionAdapter.addMany,\n\t\tupdateFormSubmission: submissionAdapter.updateOne,\n\t\tupdateFormSubmissions: submissionAdapter.updateMany,\n\t\tdeleteFormSubmission: submissionAdapter.deleteOne,\n\t\tdeleteFormSubmissions: submissionAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeFormSubmissions,\n\tsetFormSubmission,\n\tsetFormSubmissions,\n\taddFormSubmission,\n\taddFormSubmissions,\n\tupdateFormSubmission,\n\tupdateFormSubmissions,\n\tdeleteFormSubmission,\n\tdeleteFormSubmissions,\n} = formSubmissionSlice.actions\n\nexport const selectFormSubmissionsMapping: OvermapSelector<FormSubmissionState[\"instances\"]> = (state) => {\n\treturn state.formSubmissionReducer.instances\n}\n\nexport const selectFormSubmissions: OvermapSelector<Stored<FormSubmission>[]> = createSelector(\n\t[selectFormSubmissionsMapping],\n\t(submissions) => {\n\t\treturn Object.values(submissions)\n\t},\n)\n\nexport const selectFormSubmissionById: OvermapSelectorWithArgs<string, Stored<FormSubmission> | undefined> =\n\t(submissionId) => (state: OvermapRootState) => {\n\t\treturn state.formSubmissionReducer.instances[submissionId]\n\t}\n\nexport const selectFormSubmissionsOfForm: OvermapSelectorWithArgs<string, Stored<FormSubmission>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[\n\t\t\t\tselectFormSubmissionsMapping,\n\t\t\t\tselectFormRevisionMapping,\n\t\t\t\t(_state: OvermapRootState, formId: string) => formId,\n\t\t\t],\n\t\t\t(submissionsMapping, revisionMapping, formId) => {\n\t\t\t\tconst revisionIds: Set<string> = new Set<string>()\n\n\t\t\t\tfor (const revision of Object.values(revisionMapping)) {\n\t\t\t\t\tif (revision.form !== formId) continue\n\t\t\t\t\trevisionIds.add(revision.offline_id)\n\t\t\t\t}\n\n\t\t\t\treturn Object.values(submissionsMapping).filter((submission) =>\n\t\t\t\t\trevisionIds.has(submission.form_revision),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectFormSubmissionsOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectFormSubmissions, (_state: OvermapRootState, issueId: string) => issueId],\n\t\t(submissions, issueId) => {\n\t\t\treturn Object.values(submissions).filter((submission) => {\n\t\t\t\treturn submission.issue === issueId\n\t\t\t})\n\t\t},\n\t),\n)\n\nexport const selectFormSubmissionsOfAsset = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectFormSubmissions, (_state: OvermapRootState, assetId: string) => assetId],\n\t\t(submissions, assetId) => {\n\t\t\treturn submissions.filter((submission) => {\n\t\t\t\treturn submission.asset === assetId\n\t\t\t})\n\t\t},\n\t),\n)\n\nexport const formSubmissionReducer: Reducer<FormSubmissionState> = formSubmissionSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type {\n\tFormSubmissionAttachment,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type FormSubmissionAttachmentState = ModelState<Stored<FormSubmissionAttachment>>\n\nconst formSubmissionAttachmentAdapter = createModelAdapter<Stored<FormSubmissionAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState: FormSubmissionAttachmentState = formSubmissionAttachmentAdapter.getInitialState({})\n\nexport const formSubmissionAttachmentSlice = createSlice({\n\tname: \"formSubmissionAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeFormSubmissionAttachments: formSubmissionAttachmentAdapter.initialize,\n\t\taddFormSubmissionAttachment: formSubmissionAttachmentAdapter.addOne,\n\t\taddFormSubmissionAttachments: formSubmissionAttachmentAdapter.addMany,\n\t\tsetFormSubmissionAttachment: formSubmissionAttachmentAdapter.setOne,\n\t\tsetFormSubmissionAttachments: formSubmissionAttachmentAdapter.setMany,\n\t\tupdateFormSubmissionAttachment: formSubmissionAttachmentAdapter.updateOne,\n\t\tupdateFormSubmissionAttachments: formSubmissionAttachmentAdapter.updateMany,\n\t\tdeleteFormSubmissionAttachment: formSubmissionAttachmentAdapter.deleteOne,\n\t\tdeleteFormSubmissionAttachments: formSubmissionAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeFormSubmissionAttachments,\n\taddFormSubmissionAttachment,\n\taddFormSubmissionAttachments,\n\tsetFormSubmissionAttachment,\n\tsetFormSubmissionAttachments,\n\tupdateFormSubmissionAttachment,\n\tupdateFormSubmissionAttachments,\n\tdeleteFormSubmissionAttachment,\n\tdeleteFormSubmissionAttachments,\n} = formSubmissionAttachmentSlice.actions\n\nexport const selectFormSubmissionAttachmentsMapping: OvermapSelector<FormSubmissionAttachmentState[\"instances\"]> = (\n\tstate,\n) => {\n\treturn state.formSubmissionAttachmentReducer.instances\n}\n\nexport const selectFormSubmissionAttachemntsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectFormSubmissionAttachmentsMapping, (_, attachmentIds: string[]) => attachmentIds],\n\t\t(mapping, attachmentIds) => {\n\t\t\tconst attachmentIdsSet = new Set(attachmentIds)\n\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\tObject.values(mapping).filter((attachment) => attachmentIdsSet.has(attachment.offline_id)),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfFormSubmission: OvermapSelectorWithArgs<string, Stored<FormSubmissionAttachment>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectFormSubmissionAttachmentsMapping, (_state: OvermapRootState, submissionId: string) => submissionId],\n\t\t\t(attachmentsMapping, submissionId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tObject.values(attachmentsMapping).filter(\n\t\t\t\t\t\t(attachment) => attachment.form_submission === submissionId,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const formSubmissionAttachmentReducer: Reducer<FormSubmissionAttachmentState> =\n\tformSubmissionAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type { FormRevisionAttachment, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type FormRevisionAttachmentState = ModelState<Stored<FormRevisionAttachment>>\n\nconst formRevisionAttachmentAdapter = createModelAdapter<Stored<FormRevisionAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState: FormRevisionAttachmentState = formRevisionAttachmentAdapter.getInitialState({})\n\nexport const formRevisionAttachmentSlice = createSlice({\n\tname: \"formRevisionAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeFormRevisionAttachments: formRevisionAttachmentAdapter.initialize,\n\t\taddFormRevisionAttachment: formRevisionAttachmentAdapter.addOne,\n\t\taddFormRevisionAttachments: formRevisionAttachmentAdapter.addMany,\n\t\tsetFormRevisionAttachment: formRevisionAttachmentAdapter.setOne,\n\t\tsetFormRevisionAttachments: formRevisionAttachmentAdapter.setMany,\n\t\tupdateFormRevisionAttachment: formRevisionAttachmentAdapter.updateOne,\n\t\tupdateFormRevisionAttachments: formRevisionAttachmentAdapter.updateMany,\n\t\tdeleteFormRevisionAttachment: formRevisionAttachmentAdapter.deleteOne,\n\t\tdeleteFormRevisionAttachments: formRevisionAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeFormRevisionAttachments,\n\taddFormRevisionAttachment,\n\taddFormRevisionAttachments,\n\tsetFormRevisionAttachment,\n\tsetFormRevisionAttachments,\n\tupdateFormRevisionAttachment,\n\tupdateFormRevisionAttachments,\n\tdeleteFormRevisionAttachment,\n\tdeleteFormRevisionAttachments,\n} = formRevisionAttachmentSlice.actions\n\nexport const selectFormRevisionAttachmentsMapping: OvermapSelector<FormRevisionAttachmentState[\"instances\"]> = (\n\tstate,\n) => {\n\treturn state.formRevisionAttachmentReducer.instances\n}\n\nexport const selectAttachmentsOfFormRevision: OvermapSelectorWithArgs<string, Stored<FormRevisionAttachment>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectFormRevisionAttachmentsMapping, (_state, revisionId: string) => revisionId],\n\t\t\t(attachments, revisionId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tObject.values(attachments).filter((attachment) => attachment.form_revision === revisionId),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const formRevisionAttachmentReducer: Reducer<FormRevisionAttachmentState> = formRevisionAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapRootState, OvermapSelector, OvermapSelectorWithArgs, Stored, Workspace } from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type WorkspaceState = ModelState<Stored<Workspace>>\n\nconst workspaceAdapter = createModelAdapter<Stored<Workspace>>((workspace) => workspace.offline_id)\n\nconst initialState: WorkspaceState = workspaceAdapter.getInitialState({})\n\nexport const workspaceSlice = createSlice({\n\tname: \"workspace\",\n\tinitialState,\n\treducers: {\n\t\tinitializeWorkspaces: workspaceAdapter.initialize,\n\t\tsetWorkspaces: workspaceAdapter.setMany,\n\t\taddWorkspace: workspaceAdapter.addOne,\n\t\tupdateWorkspace: workspaceAdapter.updateOne,\n\t\tdeleteWorkspace: workspaceAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeWorkspaces, setWorkspaces, addWorkspace, updateWorkspace, deleteWorkspace } =\n\tworkspaceSlice.actions\n\nexport const selectWorkspaceMapping: OvermapSelector<Record<string, Workspace>> = (state: OvermapRootState) =>\n\tstate.workspaceReducer.instances\n\nexport const selectWorkspaces = createSelector([selectWorkspaceMapping], (mapping) => Object.values(mapping))\n\nexport const selectMainWorkspace: OvermapSelector<Workspace | undefined> = createSelector(\n\t[selectWorkspaces],\n\t(workspaces) => {\n\t\treturn workspaces.find((workspace) => workspace.name.toLowerCase() === \"main\")\n\t},\n)\n\nexport const selectWorkspaceById: OvermapSelectorWithArgs<string, Stored<Workspace> | undefined> = (id) => (state) => {\n\treturn state.workspaceReducer.instances[id]\n}\n\nexport const selectPermittedWorkspaceIds: OvermapSelector<Set<string>> = createSelector(\n\t[selectWorkspaceMapping],\n\t(mapping) => {\n\t\treturn new Set(\n\t\t\tObject.values(mapping)\n\t\t\t\t.filter((workspace: Workspace) => workspace.permitted)\n\t\t\t\t.map((workspace: Workspace) => workspace.offline_id),\n\t\t)\n\t},\n)\n\nexport const workspaceReducer: Reducer<WorkspaceState> = workspaceSlice.reducer\n","import type { EmailDomain, OvermapRootState, OvermapSelector } from \"../../typings\"\nimport { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type EmailDomainState = ModelState<EmailDomain>\n\nconst emailDomainAdapter = createModelAdapter<EmailDomain>((emailDomain) => emailDomain.offline_id)\n\nconst initialState = emailDomainAdapter.getInitialState({})\n\nexport const emailDomainsSlice = createSlice({\n\tname: \"emailDomains\",\n\tinitialState,\n\treducers: {\n\t\tinitializeEmailDomains: emailDomainAdapter.initialize,\n\t\taddEmailDomain: emailDomainAdapter.addOne,\n\t\tdeleteEmailDomain: emailDomainAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeEmailDomains, addEmailDomain, deleteEmailDomain } = emailDomainsSlice.actions\n\nexport const selectEmailDomainsAsMapping: OvermapSelector<Record<number, EmailDomain>> = (state: OvermapRootState) =>\n\tstate.emailDomainsReducer.instances\n\nexport const selectEmailDomains = createSelector([selectEmailDomainsAsMapping], (mapping) => Object.values(mapping))\n\nexport const selectEmailDomainsOfOrganization = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectEmailDomains, (_, organizationId: number) => organizationId],\n\t\t(emailDomains, organizationId) => {\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\temailDomains.filter((emailDomain) => emailDomain.organization === organizationId),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const emailDomainsReducer: Reducer<EmailDomainState> = emailDomainsSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tDocument,\n\tMovePosition,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport {\n\tfallbackToEmptyArray,\n\tonlyUniqueOfflineIds,\n\trestructureCreateSelectorWithArgs,\n\ttoOfflineIdRecord,\n} from \"../../utils\"\n\nexport interface DocumentState {\n\tdocuments: Record<string, Stored<Document>>\n}\n\nexport interface MoveDocumentPayload {\n\tdocumentId: Document[\"offline_id\"]\n\ttargetDocumentId: Document[\"offline_id\"] | null\n\tposition: MovePosition\n}\n\nconst initialState: DocumentState = {\n\tdocuments: {},\n}\n\nexport const documentSlice = createSlice({\n\tname: \"documents\",\n\tinitialState: initialState,\n\textraReducers: (builder) =>\n\t\tbuilder.addCase(\"RESET\", (state) => {\n\t\t\tObject.assign(state, initialState)\n\t\t}),\n\treducers: {\n\t\tsetDocuments: (state, action: { payload: Stored<Document>[] }) => {\n\t\t\tif (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {\n\t\t\t\tthrow new Error(\"Tried to use setIssues reducer with duplicate ID's\")\n\t\t\t}\n\t\t\tstate.documents = toOfflineIdRecord(action.payload)\n\t\t},\n\t\taddDocuments: (state, action: { payload: Stored<Document>[] }) => {\n\t\t\tfor (const document of action.payload) {\n\t\t\t\tif (document.offline_id in state.documents) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`attempting to add a document with offline_id ${document.offline_id} which already exists in state.documents.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const document of action.payload) {\n\t\t\t\tif (document.parent_document && !!state.documents[document.parent_document]) {\n\t\t\t\t\tconst parentDocument = state.documents[document.parent_document]!\n\t\t\t\t\tstate.documents[document.parent_document] = {\n\t\t\t\t\t\t...parentDocument,\n\t\t\t\t\t\tchildren_documents: [...parentDocument.children_documents, document.offline_id],\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstate.documents[document.offline_id] = document\n\t\t\t}\n\t\t},\n\t\tupdateDocuments: (state, action: { payload: Stored<Document>[] }) => {\n\t\t\tfor (const document of action.payload) {\n\t\t\t\tif (!(document.offline_id in state.documents)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`attempting to update a document with offline_id ${document.offline_id} which doesn't exists in state.documents.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const document of action.payload) {\n\t\t\t\tconst existingDocument = state.documents[document.offline_id]!\n\t\t\t\tif (document.organization !== undefined && document.organization !== existingDocument.organization) {\n\t\t\t\t\tthrow new Error(\"organization cannot be updated\")\n\t\t\t\t}\n\t\t\t\tif (document.project !== undefined && document.project !== existingDocument.project) {\n\t\t\t\t\tthrow new Error(\"project cannot be updated\")\n\t\t\t\t}\n\t\t\t\tstate.documents[document.offline_id] = {\n\t\t\t\t\t...existingDocument,\n\t\t\t\t\t...document,\n\t\t\t\t\t// Without the cast, TypeScript doesn't realize that we have guaranteed that the document doesn't\n\t\t\t\t\t// have both a project and an organization.\n\t\t\t\t} as Stored<Document>\n\t\t\t}\n\t\t},\n\t\tmoveDocument: (state, action: { payload: MoveDocumentPayload }) => {\n\t\t\tconst { documentId, targetDocumentId, position } = action.payload\n\t\t\tif (!(documentId in state.documents)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`attempting to move a document with offline_id ${documentId} which doesn't exist in state.documents`,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// even if a document is being moved to the same parent, it needs to be removed since its position in its parent would be changing\n\t\t\tconst document = state.documents[documentId]!\n\t\t\tif (document.parent_document && state.documents[document.parent_document]) {\n\t\t\t\tconst { children_documents } = state.documents[document.parent_document]!\n\t\t\t\tstate.documents[document.parent_document]!.children_documents.splice(\n\t\t\t\t\tchildren_documents.indexOf(document.offline_id),\n\t\t\t\t\t1,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (targetDocumentId) {\n\t\t\t\tconst targetDocument = state.documents[targetDocumentId]\n\t\t\t\tconst newParentDocument = targetDocument?.parent_document\n\t\t\t\t\t? state.documents[targetDocument.parent_document]\n\t\t\t\t\t: null\n\n\t\t\t\tswitch (position) {\n\t\t\t\t\tcase \"left\":\n\t\t\t\t\t\tif (!newParentDocument) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\"attempting to move a document to the left of a document with no parent_document\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// if newParentDocument exists, then targetDocument must exist\n\t\t\t\t\t\tstate.documents[targetDocument!.parent_document!]!.children_documents.splice(\n\t\t\t\t\t\t\tnewParentDocument.children_documents.indexOf(targetDocument!.offline_id),\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tdocument.offline_id,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tstate.documents[documentId]!.parent_document = newParentDocument.offline_id\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"right\":\n\t\t\t\t\t\tif (!newParentDocument) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\"attempting to move a document to the left of a document with no parent_document\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// if newParentDocument exists, then targetDocument must exist\n\t\t\t\t\t\tstate.documents[targetDocument!.parent_document!]!.children_documents.splice(\n\t\t\t\t\t\t\tnewParentDocument.children_documents.indexOf(targetDocument!.offline_id) + 1,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tdocument.offline_id,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tstate.documents[documentId]!.parent_document = newParentDocument.offline_id\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"left-child\":\n\t\t\t\t\t\tif (!targetDocument) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\"attempting to move a document to the left-child of a document that doesn't exist\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate.documents[targetDocumentId]!.children_documents.unshift(document.offline_id)\n\t\t\t\t\t\tstate.documents[documentId]!.parent_document = targetDocument.offline_id\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"right-child\":\n\t\t\t\t\t\tif (!targetDocument) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\"attempting to move a document to the left-child of a document that doesn't exist\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate.documents[targetDocumentId]!.children_documents.push(document.offline_id)\n\t\t\t\t\t\tstate.documents[documentId]!.parent_document = targetDocument.offline_id\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstate.documents[documentId]!.parent_document = null\n\t\t\t}\n\t\t},\n\t\tremoveDocuments: (state, action: { payload: string[] }) => {\n\t\t\tfor (const documentId of action.payload) {\n\t\t\t\tif (!(documentId in state.documents)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`attempting to delete a document with offline_id ${documentId} which doesn't exists in state.documents.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const documentId of action.payload) {\n\t\t\t\tconst document = state.documents[documentId]!\n\t\t\t\tif (document.parent_document && !!state.documents[document.parent_document]) {\n\t\t\t\t\tconst parentDocument = state.documents[document.parent_document]!\n\t\t\t\t\tstate.documents[document.parent_document] = {\n\t\t\t\t\t\t...parentDocument,\n\t\t\t\t\t\tchildren_documents: parentDocument.children_documents.filter(\n\t\t\t\t\t\t\t(offline_id) => offline_id !== document.offline_id,\n\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdelete state.documents[documentId]\n\t\t\t}\n\t\t},\n\t},\n})\n\nexport const { setDocuments, addDocuments, updateDocuments, moveDocument, removeDocuments } = documentSlice.actions\n\nexport const selectDocumentsMapping: OvermapSelector<Record<string, Stored<Document>>> = (state: OvermapRootState) =>\n\tstate.documentsReducer.documents\n\nexport const selectDocuments: OvermapSelector<Stored<Document>[]> = createSelector(\n\t[selectDocumentsMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectDocumentById: OvermapSelectorWithArgs<string, Stored<Document> | undefined> =\n\t(documentId: Document[\"offline_id\"]) => (state) => {\n\t\treturn state.documentsReducer.documents[documentId]\n\t}\n\nexport const selectDocumentsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectDocumentsMapping, (_state, documentIds: Document[\"offline_id\"][]) => documentIds],\n\t\t(mapping, documentIds) => {\n\t\t\tconst documents: Stored<Document>[] = []\n\n\t\t\tfor (const documentId of documentIds) {\n\t\t\t\tconst document = mapping[documentId]\n\t\t\t\tif (document) {\n\t\t\t\t\tdocuments.push(document)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\"selectDocumentByIds: No document exists with the id\", documentId)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn fallbackToEmptyArray(documents)\n\t\t},\n\t),\n)\n\nexport const selectAncestorIdsOfDocument = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectDocumentsMapping, (_state, documentId: string) => documentId], (mapping, documentId) => {\n\t\tconst listOfAncestors: string[] = []\n\t\tconst document = mapping[documentId]\n\t\tif (!document || !document.parent_document) return listOfAncestors\n\n\t\tlet currentAncestor = mapping[document.parent_document]\n\n\t\twhile (currentAncestor) {\n\t\t\tlistOfAncestors.push(currentAncestor.offline_id)\n\t\t\tcurrentAncestor = mapping[currentAncestor.parent_document ?? \"\"]\n\t\t}\n\t\treturn fallbackToEmptyArray(listOfAncestors)\n\t}),\n)\n\nexport const selectRootDocuments = createSelector([selectDocuments], (documents) =>\n\tfallbackToEmptyArray(documents.filter((document) => !document.parent_document)),\n)\n\nexport const documentsReducer: Reducer<DocumentState> = documentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type {\n\tDocumentAttachment,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type DocumentAttachmentState = ModelState<Stored<DocumentAttachment>>\n\nconst documentAttachmentAdapter = createModelAdapter<Stored<DocumentAttachment>>((attachment) => attachment.offline_id)\n\nconst initialState = documentAttachmentAdapter.getInitialState({})\n\nexport const documentAttachmentSlice = createSlice({\n\tname: \"documentAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeDocumentAttachments: documentAttachmentAdapter.initialize,\n\t\taddDocumentAttachment: documentAttachmentAdapter.addOne,\n\t\taddDocumentAttachments: documentAttachmentAdapter.addMany,\n\t\tsetDocumentAttachment: documentAttachmentAdapter.setOne,\n\t\tsetDocumentAttachments: documentAttachmentAdapter.setMany,\n\t\tupdateDocumentAttachment: documentAttachmentAdapter.updateOne,\n\t\tupdateDocumentAttachments: documentAttachmentAdapter.updateMany,\n\t\tdeleteDocumentAttachment: documentAttachmentAdapter.deleteOne,\n\t\tdeleteDocumentAttachments: documentAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeDocumentAttachments,\n\taddDocumentAttachment,\n\taddDocumentAttachments,\n\tsetDocumentAttachment,\n\tsetDocumentAttachments,\n\tupdateDocumentAttachment,\n\tupdateDocumentAttachments,\n\tdeleteDocumentAttachment,\n\tdeleteDocumentAttachments,\n} = documentAttachmentSlice.actions\n\nexport const selectDocumentAttachmentMapping = (state: OvermapRootState) => state.documentAttachmentReducer.instances\n\nexport const selectAllDocumentAttachments: OvermapSelector<Stored<DocumentAttachment>[]> = createSelector(\n\t[selectDocumentAttachmentMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectDocumentAttachmentById: OvermapSelectorWithArgs<string, Stored<DocumentAttachment> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.documentAttachmentReducer.instances[id]\n\t}\n\nexport const selectAttachmentsOfDocument = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAllDocumentAttachments, (_state: OvermapRootState, documentId: string) => documentId],\n\t\t(attachments, documentId) => {\n\t\t\treturn fallbackToEmptyArray(attachments.filter(({ document }) => documentId === document))\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfDocumentByType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAllDocumentAttachments, (_state: OvermapRootState, documentId: string) => documentId],\n\t\t(attachments, documentId) => {\n\t\t\tconst attachmentsOfProject = attachments.filter(({ document }) => documentId === document)\n\t\t\tconst fileAttachments = attachmentsOfProject.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => !file_type || !file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\tconst imageAttachments = attachmentsOfProject.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => file_type && file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\treturn { fileAttachments, imageAttachments }\n\t\t},\n\t),\n)\n\nexport const documentAttachmentReducer: Reducer<DocumentAttachmentState> = documentAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tOrganization,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n\tTeam,\n\tUser,\n} from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type TeamState = ModelState<Stored<Team>>\n\nconst teamAdapter = createModelAdapter<Stored<Team>>((team) => team.offline_id)\n\nconst initialState: TeamState = teamAdapter.getInitialState({})\n\nexport const teamSlice = createSlice({\n\tname: \"teams\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetTeam: teamAdapter.setOne,\n\t\tinitializeTeams: teamAdapter.initialize,\n\t\taddTeam: teamAdapter.addOne,\n\t\tupdateTeam: teamAdapter.updateOne,\n\t\tdeleteTeam: teamAdapter.deleteOne,\n\t},\n})\n\nexport const { setTeam, initializeTeams, addTeam, updateTeam, deleteTeam } = teamSlice.actions\n\nexport const selectTeamsMapping: OvermapSelector<TeamState[\"instances\"]> = (state: OvermapRootState) =>\n\tstate.teamReducer.instances\n\nexport const selectTeams: OvermapSelector<Stored<Team>[]> = createSelector([selectTeamsMapping], (teams) => {\n\treturn Object.values(teams)\n})\n\nexport const selectTeamById: OvermapSelectorWithArgs<string, Stored<Team> | undefined> = (id) => (state) => {\n\treturn state.teamReducer.instances[id]\n}\n\nexport const selectTeamsByIds: OvermapSelectorWithArgs<string[], Stored<Team>[]> = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectTeamsMapping, (_state: OvermapRootState, teamIds: string[]) => teamIds],\n\t\t(mapping, teamIds) => {\n\t\t\tconst teams: Stored<Team>[] = []\n\n\t\t\tfor (const teamId of teamIds) {\n\t\t\t\tconst team = mapping[teamId]\n\n\t\t\t\tif (team) {\n\t\t\t\t\tteams.push(team)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\"selectTeamsByIds: No team exists with the id\", teamId)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn fallbackToEmptyArray(teams)\n\t\t},\n\t),\n)\n\nexport const selectTeamsOfOrganization: OvermapSelectorWithArgs<Organization[\"id\"], Stored<Team>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectTeams, (_state: OvermapRootState, organizationId: Organization[\"id\"]) => organizationId],\n\t\t\t(teams, organizationId) => {\n\t\t\t\treturn fallbackToEmptyArray(teams.filter((team) => team.organization === organizationId))\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectTeamsOfUser: OvermapSelectorWithArgs<User[\"id\"], Stored<Team>[]> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectTeams, (_state: OvermapRootState, userId: User[\"id\"]) => userId], (teams, userId) => {\n\t\treturn fallbackToEmptyArray(teams.filter((team) => team.members.includes(userId)))\n\t}),\n)\n\nexport const teamReducer: Reducer<TeamState> = teamSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AgentUserConversation, OvermapRootState, OvermapSelector } from \"../../typings\"\nimport { restructureCreateSelectorWithArgs } from \"../../utils\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type AgentsState = ModelState<AgentUserConversation>\n\nconst agentUserConversationAdapter = createModelAdapter<AgentUserConversation>(\n\t(conversation) => conversation.offline_id,\n)\n\nconst initialState = agentUserConversationAdapter.getInitialState({})\n\nexport const agentsSlice = createSlice({\n\tname: \"agents\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeConversations: agentUserConversationAdapter.initialize,\n\t\taddConversation: agentUserConversationAdapter.addOne,\n\t\tsetConversation: agentUserConversationAdapter.setOne,\n\t\tupdateConversation: agentUserConversationAdapter.updateOne,\n\t},\n})\n\nexport const { initializeConversations, addConversation, setConversation, updateConversation } = agentsSlice.actions\nexport const selectConversationMapping = (state: OvermapRootState) => state.agentsReducer.instances\n\nexport const selectConversations: OvermapSelector<AgentUserConversation[]> = createSelector(\n\t[selectConversationMapping],\n\t(conversationMapping) => Object.values(conversationMapping),\n)\n\nexport const selectConversation = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectConversationMapping, (_state, conversationId: string) => conversationId],\n\t\t(conversationMapping, conversationId) => conversationMapping[conversationId],\n\t),\n)\n\nexport const agentsReducer: Reducer<AgentsState> = agentsSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type { IssueComment, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type IssueCommentState = ModelState<Stored<IssueComment>>\n\nconst issueCommentAdapter = createModelAdapter<Stored<IssueComment>>((comment) => comment.offline_id)\n\nconst initialState: IssueCommentState = issueCommentAdapter.getInitialState({})\n\nexport const issueCommentSlice = createSlice({\n\tname: \"issueComments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\taddIssueComment: issueCommentAdapter.addOne,\n\t\taddIssueComments: issueCommentAdapter.addMany,\n\t\tsetIssueComment: issueCommentAdapter.setOne,\n\t\tsetIssueComments: issueCommentAdapter.setMany,\n\t\tdeleteIssueComment: issueCommentAdapter.deleteOne,\n\t\tdeleteIssueComments: issueCommentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tsetIssueComments,\n\tsetIssueComment,\n\taddIssueComment,\n\taddIssueComments,\n\tdeleteIssueComment,\n\tdeleteIssueComments,\n} = issueCommentSlice.actions\n\nexport const selectIssueCommentMapping = (state: OvermapRootState) => state.issueCommentReducer.instances\n\nexport const selectIssueCommentById: OvermapSelectorWithArgs<string, Stored<IssueComment> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.issueCommentReducer.instances[id]\n\t}\n\nexport const selectCommentsOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectIssueCommentMapping, (_state, issueId: string) => issueId], (commentMapping, issueId) => {\n\t\treturn fallbackToEmptyArray(Object.values(commentMapping).filter((comment) => comment.issue === issueId))\n\t}),\n)\n\nexport const issueCommentReducer: Reducer<IssueCommentState> = issueCommentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { IssueUpdate, OvermapRootState, Stored } from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type IssueUpdateState = ModelState<Stored<IssueUpdate>>\n\nconst issueUpdateAdapter = createModelAdapter<Stored<IssueUpdate>>((issueUpdate) => issueUpdate.offline_id)\n\nconst initialState: IssueUpdateState = issueUpdateAdapter.getInitialState({})\n\nexport const issueUpdateSlice = createSlice({\n\tname: \"issueUpdates\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeIssueUpdates: issueUpdateAdapter.setMany,\n\t\tsetIssueUpdate: issueUpdateAdapter.setOne,\n\t\taddIssueUpdate: issueUpdateAdapter.addOne,\n\t\taddIssueUpdates: issueUpdateAdapter.addMany,\n\t\tdeleteIssueUpdate: issueUpdateAdapter.deleteOne,\n\t\tdeleteIssueUpdates: issueUpdateAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeIssueUpdates,\n\tsetIssueUpdate,\n\taddIssueUpdate,\n\taddIssueUpdates,\n\tdeleteIssueUpdate,\n\tdeleteIssueUpdates,\n} = issueUpdateSlice.actions\n\nexport const selectIssueUpdateMapping = (state: OvermapRootState) => state.issueUpdateReducer.instances\n\nexport const selectIssueUpdatesOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueUpdateMapping, (_state: OvermapRootState, issueId: string) => issueId],\n\t\t(updates, issueId) => {\n\t\t\treturn fallbackToEmptyArray(Object.values(updates).filter((update) => update.issue === issueId))\n\t\t},\n\t),\n)\n\nexport const issueUpdateReducer: Reducer<IssueUpdateState> = issueUpdateSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { IssueAttachment, OvermapRootState, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type IssueAttachmentState = ModelState<Stored<IssueAttachment>>\n\nconst issueAttachmentAdapter = createModelAdapter<Stored<IssueAttachment>>((attachment) => attachment.offline_id)\n\nconst initialState: IssueAttachmentState = issueAttachmentAdapter.getInitialState({})\n\nexport const issueAttachmentSlice = createSlice({\n\tname: \"issueAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeIssueAttachments: issueAttachmentAdapter.initialize,\n\t\taddIssueAttachment: issueAttachmentAdapter.addOne,\n\t\taddIssueAttachments: issueAttachmentAdapter.addMany,\n\t\tsetIssueAttachment: issueAttachmentAdapter.setOne,\n\t\tsetIssueAttachments: issueAttachmentAdapter.setMany,\n\t\tupdateIssueAttachment: issueAttachmentAdapter.updateOne,\n\t\tupdateIssueAttachments: issueAttachmentAdapter.updateMany,\n\t\tdeleteIssueAttachment: issueAttachmentAdapter.deleteOne,\n\t\tdeleteIssueAttachments: issueAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeIssueAttachments,\n\taddIssueAttachment,\n\taddIssueAttachments,\n\tsetIssueAttachment,\n\tsetIssueAttachments,\n\tupdateIssueAttachment,\n\tupdateIssueAttachments,\n\tdeleteIssueAttachment,\n\tdeleteIssueAttachments,\n} = issueAttachmentSlice.actions\n\nexport const selectIssueAttachmentMapping = (state: OvermapRootState) => state.issueAttachmentReducer.instances\nexport const selectIssueAttachments: OvermapSelector<Stored<IssueAttachment>[]> = createSelector(\n\t[selectIssueAttachmentMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectAttachmentsOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueAttachments, (_state: OvermapRootState, issueId: string) => issueId],\n\t\t(attachments, issueId) => {\n\t\t\treturn fallbackToEmptyArray(attachments.filter(({ issue }) => issueId === issue))\n\t\t},\n\t),\n)\n\nexport const selectIssueAttachmentById: OvermapSelectorWithArgs<string, Stored<IssueAttachment> | undefined> =\n\t(id) => (root) => {\n\t\treturn root.issueAttachmentReducer.instances[id]\n\t}\n\nexport const selectAttachmentsOfIssueByType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueAttachments, (_state: OvermapRootState, issueId: string) => issueId],\n\t\t(attachments, issueId) => {\n\t\t\tconst attachmentsOfIssue = attachments.filter(({ issue }) => issue === issueId)\n\t\t\tconst fileAttachments = attachmentsOfIssue.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => !file_type || !file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\tconst imageAttachments = attachmentsOfIssue.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => file_type && file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\treturn { fileAttachments, imageAttachments }\n\t\t},\n\t),\n)\n\nexport const issueAttachmentReducer: Reducer<IssueAttachmentState> = issueAttachmentSlice.reducer\n","import { createSlice, Reducer } from \"@reduxjs/toolkit\"\n\nexport interface VersioningState {\n\tversion: number\n}\n\nconst initialState: VersioningState = {\n\tversion: 0,\n}\n\n/**\n * Version of the offline redux store\n */\nexport const versioningSlice = createSlice({\n\tname: \"versioning\",\n\tinitialState,\n\treducers: {},\n})\n\nexport const versioningReducer: Reducer<VersioningState> = versioningSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { GeoImage, OvermapRootState, Stored } from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type GeoImageSliceState = ModelState<Stored<GeoImage>>\n\nconst geoImageAdapter = createModelAdapter<GeoImage>((model) => model.offline_id)\n\nconst initialState: GeoImageSliceState = geoImageAdapter.getInitialState({})\n\nexport const geoImageSlice = createSlice({\n\tname: \"geoImages\",\n\tinitialState,\n\textraReducers: (builder) => {\n\t\tbuilder.addCase(\"RESET\", (state) => {\n\t\t\tObject.assign(state, initialState)\n\t\t})\n\t},\n\treducers: {\n\t\tinitializeGeoImages: geoImageAdapter.initialize,\n\t\tsetGeoImage: geoImageAdapter.setOne,\n\t\tsetGeoImages: geoImageAdapter.setMany,\n\t\taddGeoImage: geoImageAdapter.addOne,\n\t\taddGeoImages: geoImageAdapter.addMany,\n\t\tupdateGeoImage: geoImageAdapter.updateOne,\n\t\tupdateGeoImages: geoImageAdapter.updateMany,\n\t\tdeleteGeoImage: geoImageAdapter.deleteOne,\n\t\tdeleteGeoImages: geoImageAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeGeoImages,\n\tsetGeoImage,\n\tsetGeoImages,\n\taddGeoImage,\n\taddGeoImages,\n\tupdateGeoImage,\n\tupdateGeoImages,\n\tdeleteGeoImage,\n\tdeleteGeoImages,\n} = geoImageSlice.actions\n\nexport const selectGeoImageMapping = (state: OvermapRootState) => state.geoImageReducer.instances\n\nexport const selectGeoImages = (state: OvermapRootState) => Object.values(state.geoImageReducer.instances)\n\nexport const selectGeoImageById = (id: string) => (state: OvermapRootState) => {\n\treturn state.geoImageReducer.instances[id]\n}\n\nexport const selectGeoImagesOfProject = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectGeoImages, (_, projectId: number) => projectId], (mapImages, projectId) => {\n\t\treturn fallbackToEmptyArray(mapImages.filter((mapImage) => mapImage.project === projectId))\n\t}),\n)\n\nexport const geoImageReducer: Reducer<GeoImageSliceState> = geoImageSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { IssueAssociation, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type IssueAssociationSliceState = ModelState<Stored<IssueAssociation>>\n\nconst issueAssociationAdapter = createModelAdapter<Stored<IssueAssociation>>((assoc) => assoc.offline_id)\n\nconst initialState: IssueAssociationSliceState = issueAssociationAdapter.getInitialState({})\n\nexport const issueAssociationSlice = createSlice({\n\tname: \"issueAssociations\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeIssueAssociations: issueAssociationAdapter.initialize,\n\t\taddIssueAssociation: issueAssociationAdapter.addOne,\n\t\taddIssueAssociations: issueAssociationAdapter.addMany,\n\t\tsetIssueAssociation: issueAssociationAdapter.setOne,\n\t\tsetIssueAssociations: issueAssociationAdapter.setMany,\n\t\tupdateIssueAssociation: issueAssociationAdapter.updateOne,\n\t\tupdateIssueAssociations: issueAssociationAdapter.updateMany,\n\t\tdeleteIssueAssociation: issueAssociationAdapter.deleteOne,\n\t\tdeleteIssueAssociations: issueAssociationAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeIssueAssociations,\n\tsetIssueAssociations,\n\tsetIssueAssociation,\n\tupdateIssueAssociation,\n\tupdateIssueAssociations,\n\taddIssueAssociation,\n\taddIssueAssociations,\n\tdeleteIssueAssociation,\n\tdeleteIssueAssociations,\n} = issueAssociationSlice.actions\n\nexport const selectIssueAssociationMapping = (state: OvermapRootState): Record<string, Stored<IssueAssociation>> =>\n\tstate.issueAssociationReducer.instances\n\nexport const selectIssueAssociations = createSelector([selectIssueAssociationMapping], (associations) => {\n\treturn Object.values(associations)\n})\n\nexport const selectIssueAssociationById: OvermapSelectorWithArgs<string, Stored<IssueAssociation> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.issueAssociationReducer.instances[id]\n\t}\n\nexport const selectIssueAssociationsToIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueAssociationMapping, (_state, issueId: string) => issueId],\n\t\t(associationMapping, issueId) => {\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\tObject.values(associationMapping).filter((assoc) => assoc.associated_issue === issueId),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const selectIssueAssociationsOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueAssociationMapping, (_state, issueId: string) => issueId],\n\t\t(associationMapping, issueId) => {\n\t\t\treturn fallbackToEmptyArray(Object.values(associationMapping).filter((assoc) => assoc.issue === issueId))\n\t\t},\n\t),\n)\n\nexport const selectIssueAssociationsOfAsset = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueAssociationMapping, (_state, assetId: string) => assetId],\n\t\t(associationMapping, assetId) => {\n\t\t\treturn fallbackToEmptyArray(Object.values(associationMapping).filter((assoc) => assoc.asset === assetId))\n\t\t},\n\t),\n)\n\nexport const issueAssociationReducer: Reducer<IssueAssociationSliceState> = issueAssociationSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { IssueTypeFieldValues, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type IssueTypeFieldValuesState = ModelState<Stored<IssueTypeFieldValues>>\n\nconst issueTypeFieldValuesAdapter = createModelAdapter<Stored<IssueTypeFieldValues>>(\n\t(fieldValues) => fieldValues.offline_id,\n)\n\nconst initialState: IssueTypeFieldValuesState = issueTypeFieldValuesAdapter.getInitialState({})\n\nexport const issueTypeFieldValuesSlice = createSlice({\n\tname: \"issueTypeFieldValues\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeIssueTypeFieldValues: issueTypeFieldValuesAdapter.initialize,\n\t\taddIssueTypeFieldValues: issueTypeFieldValuesAdapter.addOne,\n\t\taddIssueTypeFieldValuesMany: issueTypeFieldValuesAdapter.addMany,\n\t\tsetIssueTypeFieldValues: issueTypeFieldValuesAdapter.setOne,\n\t\tsetIssueTypeFieldValuesMany: issueTypeFieldValuesAdapter.setMany,\n\t\tupdateIssueTypeFieldValues: issueTypeFieldValuesAdapter.updateOne,\n\t\tupdateIssueTypeFieldValuesMany: issueTypeFieldValuesAdapter.updateMany,\n\t\tdeleteIssueTypeFieldValues: issueTypeFieldValuesAdapter.deleteOne,\n\t\tdeleteIssueTypeFieldValuesMany: issueTypeFieldValuesAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeIssueTypeFieldValues,\n\taddIssueTypeFieldValues,\n\taddIssueTypeFieldValuesMany,\n\tsetIssueTypeFieldValues,\n\tsetIssueTypeFieldValuesMany,\n\tupdateIssueTypeFieldValues,\n\tupdateIssueTypeFieldValuesMany,\n\tdeleteIssueTypeFieldValues,\n\tdeleteIssueTypeFieldValuesMany,\n} = issueTypeFieldValuesSlice.actions\n\nexport const selectIssueTypeFieldValuesMapping = (state: OvermapRootState) =>\n\tstate.issueTypeFieldValuesReducer.instances\n\nexport const selectIssueTypeFieldValues = createSelector([selectIssueTypeFieldValuesMapping], (fieldValuesMapping) => {\n\treturn Object.values(fieldValuesMapping)\n})\n\nexport const selectIssueTypeFieldValuesOfIssue: OvermapSelectorWithArgs<string, Stored<IssueTypeFieldValues>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectIssueTypeFieldValues, (_state, issueId: string) => issueId], (fieldValues, issueId) => {\n\t\t\treturn fallbackToEmptyArray(fieldValues.filter((fieldValue) => fieldValue.issue === issueId))\n\t\t}),\n\t)\n\nexport const selectIssueTypeFieldValuesById: OvermapSelectorWithArgs<\n\tstring,\n\tStored<IssueTypeFieldValues> | undefined\n> = (fieldValuesId) => (state: OvermapRootState) => {\n\treturn state.issueTypeFieldValuesReducer.instances[fieldValuesId]\n}\n\nexport const issueTypeFieldValuesReducer: Reducer<IssueTypeFieldValuesState> = issueTypeFieldValuesSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tIssueTypeFields,\n\tIssueTypeFieldValues,\n\tOvermapRootState,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\nimport { selectIssueTypeFieldValues } from \"./issueTypeFieldValuesSlice\"\n\nexport type IssueTypeFieldsState = ModelState<Stored<IssueTypeFields>>\n\nconst issueTypeFieldsAdapter = createModelAdapter<Stored<IssueTypeFields>>((fields) => fields.offline_id)\n\nconst initialState: IssueTypeFieldsState = issueTypeFieldsAdapter.getInitialState({})\n\nexport const issueTypeFieldsSlice = createSlice({\n\tname: \"issueTypeFields\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeIssueTypeFields: issueTypeFieldsAdapter.initialize,\n\t\taddIssueTypeFields: issueTypeFieldsAdapter.addOne,\n\t\taddIssueTypeFieldsMany: issueTypeFieldsAdapter.addMany,\n\t\tsetIssueTypeFields: issueTypeFieldsAdapter.setOne,\n\t\tsetIssueTypeFieldsMany: issueTypeFieldsAdapter.setMany,\n\t\tupdateIssueTypeFields: issueTypeFieldsAdapter.updateOne,\n\t\tupdateIssueTypeFieldsMany: issueTypeFieldsAdapter.updateMany,\n\t\tdeleteIssueTypeFields: issueTypeFieldsAdapter.deleteOne,\n\t\tdeleteIssueTypeFieldsMany: issueTypeFieldsAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeIssueTypeFields,\n\taddIssueTypeFields,\n\taddIssueTypeFieldsMany,\n\tsetIssueTypeFields,\n\tsetIssueTypeFieldsMany,\n\tupdateIssueTypeFields,\n\tupdateIssueTypeFieldsMany,\n\tdeleteIssueTypeFields,\n\tdeleteIssueTypeFieldsMany,\n} = issueTypeFieldsSlice.actions\n\nexport const selectIssueTypeFieldsMapping = (state: OvermapRootState) => state.issueTypeFieldsReducer.instances\n\nexport const selectIssueTypeFields = createSelector([selectIssueTypeFieldsMapping], (fieldsMapping) => {\n\treturn Object.values(fieldsMapping)\n})\n\nexport const selectIssueTypeFieldsOfIssueType: OvermapSelectorWithArgs<string, Stored<IssueTypeFields>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectIssueTypeFields, (_state, issueTypeId: string) => issueTypeId], (fields, issueTypeId) => {\n\t\t\treturn fallbackToEmptyArray(fields.filter((field) => field.issue_type === issueTypeId))\n\t\t}),\n\t)\n\nexport const selectLatestIssueTypeFieldsOfIssueType: OvermapSelectorWithArgs<string, IssueTypeFields | undefined> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectIssueTypeFields, (_state, id: string) => id], (fields, id) => {\n\t\t\treturn fields\n\t\t\t\t.filter((field) => field.issue_type === id)\n\t\t\t\t.sort((a, b) => (a.submitted_at > b.submitted_at ? -1 : 1))[0]\n\t\t}),\n\t)\n\nexport const selectIssueTypeValuesOfIssueType: OvermapSelectorWithArgs<string, Stored<IssueTypeFieldValues>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectIssueTypeFields, selectIssueTypeFieldValues, (_state, id: string) => id],\n\t\t\t(fields, fieldValues, id) => {\n\t\t\t\tconst fieldsIds: Set<string> = new Set<string>(\n\t\t\t\t\tfields.filter((field) => field.issue_type === id).map((field) => field.offline_id),\n\t\t\t\t)\n\n\t\t\t\treturn fallbackToEmptyArray(fieldValues.filter((values) => fieldsIds.has(values.fields_revision)))\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectIssueTypeFieldsById: OvermapSelectorWithArgs<string, Stored<IssueTypeFields> | undefined> =\n\t(fieldsId) => (state: OvermapRootState) => {\n\t\treturn state.issueTypeFieldsReducer.instances[fieldsId]\n\t}\n\nexport const issueTypeFieldsReducer: Reducer<IssueTypeFieldsState> = issueTypeFieldsSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { IssueTypeFieldsAttachment, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type IssueTypeFieldsAttachmentState = ModelState<Stored<IssueTypeFieldsAttachment>>\n\nconst issueTypeFieldsAttachmentAdapter = createModelAdapter<Stored<IssueTypeFieldsAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState: IssueTypeFieldsAttachmentState = issueTypeFieldsAttachmentAdapter.getInitialState({})\n\nexport const issueTypeFieldsAttachmentSlice = createSlice({\n\tname: \"issueTypeFieldsAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeIssueTypeFieldsAttachments: issueTypeFieldsAttachmentAdapter.initialize,\n\t\taddIssueTypeFieldsAttachment: issueTypeFieldsAttachmentAdapter.addOne,\n\t\taddIssueTypeFieldsAttachments: issueTypeFieldsAttachmentAdapter.addMany,\n\t\tsetIssueTypeFieldsAttachment: issueTypeFieldsAttachmentAdapter.setOne,\n\t\tsetIssueTypeFieldsAttachments: issueTypeFieldsAttachmentAdapter.setMany,\n\t\tupdateIssueTypeFieldsAttachment: issueTypeFieldsAttachmentAdapter.updateOne,\n\t\tupdateIssueTypeFieldsAttachments: issueTypeFieldsAttachmentAdapter.updateMany,\n\t\tdeleteIssueTypeFieldsAttachment: issueTypeFieldsAttachmentAdapter.deleteOne,\n\t\tdeleteIssueTypeFieldsAttachments: issueTypeFieldsAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeIssueTypeFieldsAttachments,\n\taddIssueTypeFieldsAttachment,\n\taddIssueTypeFieldsAttachments,\n\tsetIssueTypeFieldsAttachment,\n\tsetIssueTypeFieldsAttachments,\n\tupdateIssueTypeFieldsAttachment,\n\tupdateIssueTypeFieldsAttachments,\n\tdeleteIssueTypeFieldsAttachment,\n\tdeleteIssueTypeFieldsAttachments,\n} = issueTypeFieldsAttachmentSlice.actions\n\nexport const selectIssueTypeFieldsAttachmentsMapping = (state: OvermapRootState) =>\n\tstate.issueTypeFieldsAttachmentReducer.instances\n\nexport const selectIssueTypeFieldsAttachments = createSelector(\n\t[selectIssueTypeFieldsAttachmentsMapping],\n\t(attachmentsMapping) => {\n\t\treturn Object.values(attachmentsMapping)\n\t},\n)\n\nexport const selectAttachmentsOfIssueTypeFields: OvermapSelectorWithArgs<string, IssueTypeFieldsAttachment[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectIssueTypeFieldsAttachments, (_state, fieldsRevision: string) => fieldsRevision],\n\t\t\t(attachments, fieldsRevision) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tattachments.filter((attachment) => attachment.fields_revision === fieldsRevision),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectIssueTypeFieldsAttachmentById: OvermapSelectorWithArgs<\n\tstring,\n\tIssueTypeFieldsAttachment | undefined\n> = (attachmentId) => (state: OvermapRootState) => {\n\treturn state.issueTypeFieldsAttachmentReducer.instances[attachmentId]\n}\n\nexport const issueTypeFieldsAttachmentReducer: Reducer<IssueTypeFieldsAttachmentState> =\n\tissueTypeFieldsAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { IssueTypeFieldValuesAttachment, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type IssueTypeFieldValuesAttachmentState = ModelState<Stored<IssueTypeFieldValuesAttachment>>\n\nconst issueTypeFieldValuesAttachmentAdapter = createModelAdapter<Stored<IssueTypeFieldValuesAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState: IssueTypeFieldValuesAttachmentState = issueTypeFieldValuesAttachmentAdapter.getInitialState({})\n\nexport const issueTypeFieldValuesAttachmentSlice = createSlice({\n\tname: \"issueTypeFieldValuesAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeIssueTypeFieldValuesAttachments: issueTypeFieldValuesAttachmentAdapter.initialize,\n\t\taddIssueTypeFieldValuesAttachment: issueTypeFieldValuesAttachmentAdapter.addOne,\n\t\taddIssueTypeFieldValuesAttachments: issueTypeFieldValuesAttachmentAdapter.addMany,\n\t\tsetIssueTypeFieldValuesAttachment: issueTypeFieldValuesAttachmentAdapter.setOne,\n\t\tsetIssueTypeFieldValuesAttachments: issueTypeFieldValuesAttachmentAdapter.setMany,\n\t\tupdateIssueTypeFieldValuesAttachment: issueTypeFieldValuesAttachmentAdapter.updateOne,\n\t\tupdateIssueTypeFieldValuesAttachments: issueTypeFieldValuesAttachmentAdapter.updateMany,\n\t\tdeleteIssueTypeFieldValuesAttachment: issueTypeFieldValuesAttachmentAdapter.deleteOne,\n\t\tdeleteIssueTypeFieldValuesAttachments: issueTypeFieldValuesAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeIssueTypeFieldValuesAttachments,\n\taddIssueTypeFieldValuesAttachment,\n\taddIssueTypeFieldValuesAttachments,\n\tsetIssueTypeFieldValuesAttachment,\n\tsetIssueTypeFieldValuesAttachments,\n\tupdateIssueTypeFieldValuesAttachment,\n\tupdateIssueTypeFieldValuesAttachments,\n\tdeleteIssueTypeFieldValuesAttachment,\n\tdeleteIssueTypeFieldValuesAttachments,\n} = issueTypeFieldValuesAttachmentSlice.actions\n\nexport const selectIssueTypeFieldValuesAttachmentsMapping = (state: OvermapRootState) =>\n\tstate.issueTypeFieldValuesAttachmentReducer.instances\n\nexport const selectIssueTypeFieldValuesAttachments = createSelector(\n\t[selectIssueTypeFieldValuesAttachmentsMapping],\n\t(attachmentsMapping) => {\n\t\treturn Object.values(attachmentsMapping)\n\t},\n)\n\nexport const selectIssueTypeFieldValuesAttachmentById: OvermapSelectorWithArgs<\n\tstring,\n\tStored<IssueTypeFieldValuesAttachment> | undefined\n> = (attachmentId) => (state: OvermapRootState) => {\n\treturn state.issueTypeFieldValuesAttachmentReducer.instances[attachmentId]\n}\n\nexport const selectIssueTypeFieldValuesAttachmentsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueTypeFieldValuesAttachmentsMapping, (_, attachmentIds: string[]) => attachmentIds],\n\t\t(mapping, attachmentIds) => {\n\t\t\tconst attachmentIdsSet = new Set(attachmentIds)\n\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\tObject.values(mapping).filter((attachment) => attachmentIdsSet.has(attachment.offline_id)),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfIssueTypeFieldValues: OvermapSelectorWithArgs<\n\tstring,\n\tStored<IssueTypeFieldValuesAttachment>[]\n> = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueTypeFieldValuesAttachments, (_state, fieldValuesId: string) => fieldValuesId],\n\t\t(attachments, fieldValuesId) => {\n\t\t\treturn fallbackToEmptyArray(attachments.filter((attachment) => attachment.field_values === fieldValuesId))\n\t\t},\n\t),\n)\n\nexport const issueTypeFieldValuesAttachmentReducer: Reducer<IssueTypeFieldValuesAttachmentState> =\n\tissueTypeFieldValuesAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetTypeFields, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetTypeFieldsState = ModelState<Stored<AssetTypeFields>>\n\nconst assetTypeFieldsAdapter = createModelAdapter<Stored<AssetTypeFields>>((fields) => fields.offline_id)\n\nconst initialState: AssetTypeFieldsState = assetTypeFieldsAdapter.getInitialState({})\n\nexport const assetTypeFieldsSlice = createSlice({\n\tname: \"assetTypeFields\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetTypeFields: assetTypeFieldsAdapter.initialize,\n\t\taddAssetTypeFields: assetTypeFieldsAdapter.addOne,\n\t\taddAssetTypeFieldsMany: assetTypeFieldsAdapter.addMany,\n\t\tsetAssetTypeFields: assetTypeFieldsAdapter.setOne,\n\t\tsetAssetTypeFieldsMany: assetTypeFieldsAdapter.setMany,\n\t\tupdateAssetTypeFields: assetTypeFieldsAdapter.updateOne,\n\t\tupdateAssetTypeFieldsMany: assetTypeFieldsAdapter.updateMany,\n\t\tdeleteAssetTypeFields: assetTypeFieldsAdapter.deleteOne,\n\t\tdeleteAssetTypeFieldsMany: assetTypeFieldsAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetTypeFields,\n\taddAssetTypeFields,\n\taddAssetTypeFieldsMany,\n\tsetAssetTypeFields,\n\tsetAssetTypeFieldsMany,\n\tupdateAssetTypeFields,\n\tupdateAssetTypeFieldsMany,\n\tdeleteAssetTypeFields,\n\tdeleteAssetTypeFieldsMany,\n} = assetTypeFieldsSlice.actions\n\nexport const selectAssetTypeFieldsMapping = (state: OvermapRootState) => state.assetTypeFieldsReducer.instances\n\nexport const selectAssetTypeFields = createSelector([selectAssetTypeFieldsMapping], (fieldsMapping) => {\n\treturn Object.values(fieldsMapping)\n})\n\nexport const selectAssetTypeFieldsOfAssetType: OvermapSelectorWithArgs<string, AssetTypeFields[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectAssetTypeFields, (_state, assetTypeId: string) => assetTypeId], (fields, assetTypeId) => {\n\t\t\treturn fallbackToEmptyArray(fields.filter((field) => field.asset_type === assetTypeId))\n\t\t}),\n\t)\n\nexport const selectLatestAssetTypeFieldsOfAssetType: OvermapSelectorWithArgs<string, AssetTypeFields | undefined> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectAssetTypeFields, (_state, id: string) => id], (fields, id) => {\n\t\t\treturn fields\n\t\t\t\t.filter((field) => field.asset_type === id)\n\t\t\t\t.sort((a, b) => (a.submitted_at > b.submitted_at ? -1 : 1))[0]\n\t\t}),\n\t)\n\nexport const selectAssetTypeFieldsById: OvermapSelectorWithArgs<string, AssetTypeFields | undefined> =\n\t(fieldsId) => (state: OvermapRootState) => {\n\t\treturn state.assetTypeFieldsReducer.instances[fieldsId]\n\t}\n\nexport const assetTypeFieldsReducer: Reducer<AssetTypeFieldsState> = assetTypeFieldsSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetTypeFieldValues, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\nimport { selectAssetTypeFields } from \"./assetTypeFieldsSlice\"\n\nexport type AssetTypeFieldValuesState = ModelState<Stored<AssetTypeFieldValues>>\n\nconst assetTypeFieldValuesAdapter = createModelAdapter<Stored<AssetTypeFieldValues>>(\n\t(fieldValues) => fieldValues.offline_id,\n)\n\nconst initialState: AssetTypeFieldValuesState = assetTypeFieldValuesAdapter.getInitialState({})\n\nexport const assetTypeFieldValuesSlice = createSlice({\n\tname: \"assetTypeFieldValues\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetTypeFieldValues: assetTypeFieldValuesAdapter.initialize,\n\t\taddAssetTypeFieldValues: assetTypeFieldValuesAdapter.addOne,\n\t\taddAssetTypeFieldValuesMany: assetTypeFieldValuesAdapter.addMany,\n\t\tsetAssetTypeFieldValues: assetTypeFieldValuesAdapter.setOne,\n\t\tsetAssetTypeFieldValuesMany: assetTypeFieldValuesAdapter.setMany,\n\t\tupdateAssetTypeFieldValues: assetTypeFieldValuesAdapter.updateOne,\n\t\tupdateAssetTypeFieldValuesMany: assetTypeFieldValuesAdapter.updateMany,\n\t\tdeleteAssetTypeFieldValues: assetTypeFieldValuesAdapter.deleteOne,\n\t\tdeleteAssetTypeFieldValuesMany: assetTypeFieldValuesAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetTypeFieldValues,\n\taddAssetTypeFieldValues,\n\taddAssetTypeFieldValuesMany,\n\tsetAssetTypeFieldValues,\n\tsetAssetTypeFieldValuesMany,\n\tupdateAssetTypeFieldValues,\n\tupdateAssetTypeFieldValuesMany,\n\tdeleteAssetTypeFieldValues,\n\tdeleteAssetTypeFieldValuesMany,\n} = assetTypeFieldValuesSlice.actions\n\nexport const selectAssetTypeFieldValuesMapping = (state: OvermapRootState) =>\n\tstate.assetTypeFieldValuesReducer.instances\n\nexport const selectAssetTypeFieldValues = createSelector([selectAssetTypeFieldValuesMapping], (fieldValuesMapping) => {\n\treturn Object.values(fieldValuesMapping)\n})\n\nexport const selectAssetTypeFieldValuesOfAsset: OvermapSelectorWithArgs<string, AssetTypeFieldValues[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectAssetTypeFieldValues, (_state, assetId: string) => assetId], (fieldValues, assetId) => {\n\t\t\treturn fallbackToEmptyArray(fieldValues.filter((fieldValue) => fieldValue.asset === assetId))\n\t\t}),\n\t)\n\nexport const selectAssetTypeValuesOfAssetType: OvermapSelectorWithArgs<string, Stored<AssetTypeFieldValues>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectAssetTypeFields, selectAssetTypeFieldValues, (_state, id: string) => id],\n\t\t\t(fields, fieldValues, id) => {\n\t\t\t\tconst fieldsIds: Set<string> = new Set<string>(\n\t\t\t\t\tfields.filter((field) => field.asset_type === id).map((field) => field.offline_id),\n\t\t\t\t)\n\n\t\t\t\treturn fallbackToEmptyArray(fieldValues.filter((values) => fieldsIds.has(values.fields_revision)))\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectAssetTypeFieldValuesById: OvermapSelectorWithArgs<string, AssetTypeFieldValues | undefined> =\n\t(fieldValuesId) => (state: OvermapRootState) => {\n\t\treturn state.assetTypeFieldValuesReducer.instances[fieldValuesId]\n\t}\n\nexport const assetTypeFieldValuesReducer: Reducer<AssetTypeFieldValuesState> = assetTypeFieldValuesSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetTypeFieldsAttachment, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetTypeFieldsAttachmentState = ModelState<Stored<AssetTypeFieldsAttachment>>\n\nconst assetTypeFieldsAttachmentAdapter = createModelAdapter<Stored<AssetTypeFieldsAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState: AssetTypeFieldsAttachmentState = assetTypeFieldsAttachmentAdapter.getInitialState({})\n\nexport const assetTypeFieldsAttachmentSlice = createSlice({\n\tname: \"assetTypeFieldsAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetTypeFieldsAttachments: assetTypeFieldsAttachmentAdapter.initialize,\n\t\taddAssetTypeFieldsAttachment: assetTypeFieldsAttachmentAdapter.addOne,\n\t\taddAssetTypeFieldsAttachments: assetTypeFieldsAttachmentAdapter.addMany,\n\t\tsetAssetTypeFieldsAttachment: assetTypeFieldsAttachmentAdapter.setOne,\n\t\tsetAssetTypeFieldsAttachments: assetTypeFieldsAttachmentAdapter.setMany,\n\t\tupdateAssetTypeFieldsAttachment: assetTypeFieldsAttachmentAdapter.updateOne,\n\t\tupdateAssetTypeFieldsAttachments: assetTypeFieldsAttachmentAdapter.updateMany,\n\t\tdeleteAssetTypeFieldsAttachment: assetTypeFieldsAttachmentAdapter.deleteOne,\n\t\tdeleteAssetTypeFieldsAttachments: assetTypeFieldsAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetTypeFieldsAttachments,\n\taddAssetTypeFieldsAttachment,\n\taddAssetTypeFieldsAttachments,\n\tsetAssetTypeFieldsAttachment,\n\tsetAssetTypeFieldsAttachments,\n\tupdateAssetTypeFieldsAttachment,\n\tupdateAssetTypeFieldsAttachments,\n\tdeleteAssetTypeFieldsAttachment,\n\tdeleteAssetTypeFieldsAttachments,\n} = assetTypeFieldsAttachmentSlice.actions\n\nexport const selectAssetTypeFieldsAttachmentsMapping = (state: OvermapRootState) =>\n\tstate.assetTypeFieldsAttachmentReducer.instances\n\nexport const selectAssetTypeFieldsAttachments = createSelector(\n\t[selectAssetTypeFieldsAttachmentsMapping],\n\t(attachmentsMapping) => {\n\t\treturn Object.values(attachmentsMapping)\n\t},\n)\n\nexport const selectAttachmentsOfAssetTypeFields: OvermapSelectorWithArgs<string, AssetTypeFieldsAttachment[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectAssetTypeFieldsAttachments, (_state, id: string) => id], (attachments, id) => {\n\t\t\treturn fallbackToEmptyArray(attachments.filter((attachment) => attachment.fields_revision === id))\n\t\t}),\n\t)\n\nexport const selectAssetTypeFieldsAttachmentById: OvermapSelectorWithArgs<\n\tstring,\n\tAssetTypeFieldsAttachment | undefined\n> = (attachmentId) => (state: OvermapRootState) => {\n\treturn state.assetTypeFieldsAttachmentReducer.instances[attachmentId]\n}\n\nexport const assetTypeFieldsAttachmentReducer: Reducer<AssetTypeFieldsAttachmentState> =\n\tassetTypeFieldsAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetTypeFieldValuesAttachment, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetTypeFieldValuesAttachmentState = ModelState<Stored<AssetTypeFieldValuesAttachment>>\n\nconst assetTypeFieldValuesAttachmentAdapter = createModelAdapter<Stored<AssetTypeFieldValuesAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState: AssetTypeFieldValuesAttachmentState = assetTypeFieldValuesAttachmentAdapter.getInitialState({})\n\nexport const assetTypeFieldValuesAttachmentSlice = createSlice({\n\tname: \"assetTypeFieldValuesAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetTypeFieldValuesAttachments: assetTypeFieldValuesAttachmentAdapter.initialize,\n\t\taddAssetTypeFieldValuesAttachment: assetTypeFieldValuesAttachmentAdapter.addOne,\n\t\taddAssetTypeFieldValuesAttachments: assetTypeFieldValuesAttachmentAdapter.addMany,\n\t\tsetAssetTypeFieldValuesAttachment: assetTypeFieldValuesAttachmentAdapter.setOne,\n\t\tsetAssetTypeFieldValuesAttachments: assetTypeFieldValuesAttachmentAdapter.setMany,\n\t\tupdateAssetTypeFieldValuesAttachment: assetTypeFieldValuesAttachmentAdapter.updateOne,\n\t\tupdateAssetTypeFieldValuesAttachments: assetTypeFieldValuesAttachmentAdapter.updateMany,\n\t\tdeleteAssetTypeFieldValuesAttachment: assetTypeFieldValuesAttachmentAdapter.deleteOne,\n\t\tdeleteAssetTypeFieldValuesAttachments: assetTypeFieldValuesAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetTypeFieldValuesAttachments,\n\taddAssetTypeFieldValuesAttachment,\n\taddAssetTypeFieldValuesAttachments,\n\tsetAssetTypeFieldValuesAttachment,\n\tsetAssetTypeFieldValuesAttachments,\n\tupdateAssetTypeFieldValuesAttachment,\n\tupdateAssetTypeFieldValuesAttachments,\n\tdeleteAssetTypeFieldValuesAttachment,\n\tdeleteAssetTypeFieldValuesAttachments,\n} = assetTypeFieldValuesAttachmentSlice.actions\n\nexport const selectAssetTypeFieldValuesAttachmentsMapping = (state: OvermapRootState) =>\n\tstate.assetTypeFieldValuesAttachmentReducer.instances\n\nexport const selectAssetTypeFieldValuesAttachments = createSelector(\n\t[selectAssetTypeFieldValuesAttachmentsMapping],\n\t(attachmentsMapping) => {\n\t\treturn Object.values(attachmentsMapping)\n\t},\n)\n\nexport const selectAssetTypeFieldValuesAttachmentById: OvermapSelectorWithArgs<\n\tstring,\n\tAssetTypeFieldValuesAttachment | undefined\n> = (attachmentId) => (state: OvermapRootState) => {\n\treturn state.assetTypeFieldValuesAttachmentReducer.instances[attachmentId]\n}\n\nexport const selectAssetTypeFieldValuesAttachmentsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetTypeFieldValuesAttachmentsMapping, (_, attachmentIds: string[]) => attachmentIds],\n\t\t(mapping, attachmentIds) => {\n\t\t\tconst attachmentIdsSet = new Set(attachmentIds)\n\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\tObject.values(mapping).filter((attachment) => attachmentIdsSet.has(attachment.offline_id)),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfAssetTypeFieldValues: OvermapSelectorWithArgs<\n\tstring,\n\tStored<AssetTypeFieldValuesAttachment>[]\n> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssetTypeFieldValuesAttachments, (_state, id: string) => id], (attachments, id) => {\n\t\treturn fallbackToEmptyArray(attachments.filter((attachment) => attachment.field_values === id))\n\t}),\n)\n\nexport const assetTypeFieldValuesAttachmentReducer: Reducer<AssetTypeFieldValuesAttachmentState> =\n\tassetTypeFieldValuesAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetProcedure, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetProcedureState = ModelState<Stored<AssetProcedure>>\n\nconst assetProcedureAdapter = createModelAdapter<Stored<AssetProcedure>>((assetProcedure) => assetProcedure.offline_id)\n\nconst initialState: AssetProcedureState = assetProcedureAdapter.getInitialState({})\n\nexport const assetProcedureSlice = createSlice({\n\tname: \"assetProcedures\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetProcedures: assetProcedureAdapter.initialize,\n\t\taddAssetProcedure: assetProcedureAdapter.addOne,\n\t\taddAssetProcedures: assetProcedureAdapter.addMany,\n\t\tsetAssetProcedure: assetProcedureAdapter.setOne,\n\t\tsetAssetProcedures: assetProcedureAdapter.setMany,\n\t\tupdateAssetProcedure: assetProcedureAdapter.updateOne,\n\t\tupdateAssetProcedures: assetProcedureAdapter.updateMany,\n\t\tdeleteAssetProcedure: assetProcedureAdapter.deleteOne,\n\t\tdeleteAssetProcedures: assetProcedureAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetProcedures,\n\taddAssetProcedure,\n\taddAssetProcedures,\n\tupdateAssetProcedure,\n\tupdateAssetProcedures,\n\tdeleteAssetProcedure,\n\tdeleteAssetProcedures,\n\tsetAssetProcedure,\n\tsetAssetProcedures,\n} = assetProcedureSlice.actions\n\nexport const selectAssetProceduresMapping = (state: OvermapRootState) => state.assetProcedureReducer.instances\n\nexport const selectAssetProcedures = createSelector([selectAssetProceduresMapping], (assetProceduresMapping) => {\n\treturn Object.values(assetProceduresMapping)\n})\n\nexport const selectAssetProceduresOfOrganization: OvermapSelectorWithArgs<number, AssetProcedure[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectAssetProcedures, (_state, organizationId: number) => organizationId],\n\t\t\t(assetProcedures, organizationId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tassetProcedures.filter((assetProcedure) => assetProcedure.organization === organizationId),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectAssetProcedureById: OvermapSelectorWithArgs<string, AssetProcedure | undefined> =\n\t(assetProcedureId) => (state: OvermapRootState) => {\n\t\treturn state.assetProcedureReducer.instances[assetProcedureId]\n\t}\n\nexport const selectAssetProceduresByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetProceduresMapping, (_, assetProcedureIds: string[]) => assetProcedureIds],\n\t\t(assetProceduresMapping, assetProcedureIds) => {\n\t\t\tconst assetProcedures: Stored<AssetProcedure>[] = []\n\n\t\t\tfor (const assetProcedureId of assetProcedureIds) {\n\t\t\t\tconst assetProcedure = assetProceduresMapping[assetProcedureId]\n\n\t\t\t\tif (assetProcedure) assetProcedures.push(assetProcedure)\n\t\t\t}\n\n\t\t\treturn fallbackToEmptyArray(assetProcedures)\n\t\t},\n\t),\n)\n\nexport const assetProcedureReducer: Reducer<AssetProcedureState> = assetProcedureSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetProcedureInstance, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetProcedureInstanceState = ModelState<Stored<AssetProcedureInstance>>\n\nconst assetProcedureInstanceAdapter = createModelAdapter<Stored<AssetProcedureInstance>>(\n\t(assetProcedureInstance) => assetProcedureInstance.offline_id,\n)\n\nconst initialState: AssetProcedureInstanceState = assetProcedureInstanceAdapter.getInitialState({})\n\nexport const assetProcedureInstanceSlice = createSlice({\n\tname: \"assetProcedureInstances\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetProcedureInstances: assetProcedureInstanceAdapter.initialize,\n\t\taddAssetProcedureInstance: assetProcedureInstanceAdapter.addOne,\n\t\taddAssetProcedureInstances: assetProcedureInstanceAdapter.addMany,\n\t\tsetAssetProcedureInstance: assetProcedureInstanceAdapter.setOne,\n\t\tsetAssetProcedureInstances: assetProcedureInstanceAdapter.setMany,\n\t\tupdateAssetProcedureInstance: assetProcedureInstanceAdapter.updateOne,\n\t\tupdateAssetProcedureInstances: assetProcedureInstanceAdapter.updateMany,\n\t\tdeleteAssetProcedureInstance: assetProcedureInstanceAdapter.deleteOne,\n\t\tdeleteAssetProcedureInstances: assetProcedureInstanceAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetProcedureInstances,\n\taddAssetProcedureInstance,\n\taddAssetProcedureInstances,\n\tupdateAssetProcedureInstance,\n\tupdateAssetProcedureInstances,\n\tdeleteAssetProcedureInstance,\n\tdeleteAssetProcedureInstances,\n\tsetAssetProcedureInstance,\n\tsetAssetProcedureInstances,\n} = assetProcedureInstanceSlice.actions\n\nexport const selectAssetProcedureInstancesMapping = (state: OvermapRootState) =>\n\tstate.assetProcedureInstanceReducer.instances\n\nexport const selectAssetProcedureInstances = createSelector(\n\t[selectAssetProcedureInstancesMapping],\n\t(assetProcedureInstancesMapping) => {\n\t\treturn Object.values(assetProcedureInstancesMapping)\n\t},\n)\n\nexport const selectAssetProcedureInstancesOfAssetProcedure: OvermapSelectorWithArgs<string, AssetProcedureInstance[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectAssetProcedureInstances, (_state, assetProcedureId: string) => assetProcedureId],\n\t\t\t(assetProcedureInstances, assetProcedureId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tassetProcedureInstances.filter(\n\t\t\t\t\t\t(assetProcedureInstance) => assetProcedureInstance.asset_procedure === assetProcedureId,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectAssetProcedureInstancesOfAssetType: OvermapSelectorWithArgs<string, AssetProcedureInstance[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectAssetProcedureInstances, (_state, assetTypeId: string) => assetTypeId],\n\t\t\t(assetProcedureInstances, assetTypeId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tassetProcedureInstances.filter(\n\t\t\t\t\t\t(assetProcedureInstance) => assetProcedureInstance.asset_type === assetTypeId,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectAssetProcedureInstanceById: OvermapSelectorWithArgs<string, AssetProcedureInstance | undefined> =\n\t(assetProcedureInstanceId) => (state: OvermapRootState) => {\n\t\treturn state.assetProcedureInstanceReducer.instances[assetProcedureInstanceId]\n\t}\n\nexport const selectAssetProcedureInstancesByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetProcedureInstancesMapping, (_, assetProcedureInstanceIds: string[]) => assetProcedureInstanceIds],\n\t\t(assetProcedureInstancesMapping, assetProcedureInstanceIds) => {\n\t\t\tconst assetProcedureInstances: Stored<AssetProcedureInstance>[] = []\n\n\t\t\tfor (const assetProcedureInstanceId of assetProcedureInstanceIds) {\n\t\t\t\tconst assetProcedureInstance = assetProcedureInstancesMapping[assetProcedureInstanceId]\n\n\t\t\t\tif (assetProcedureInstance) assetProcedureInstances.push(assetProcedureInstance)\n\t\t\t}\n\n\t\t\treturn fallbackToEmptyArray(assetProcedureInstances)\n\t\t},\n\t),\n)\n\nexport const assetProcedureInstanceReducer: Reducer<AssetProcedureInstanceState> = assetProcedureInstanceSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetProcedureFields, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetProcedureFieldsState = ModelState<Stored<AssetProcedureFields>>\n\nconst assetProcedureFieldsAdapter = createModelAdapter<Stored<AssetProcedureFields>>((fields) => fields.offline_id)\n\nconst initialState: AssetProcedureFieldsState = assetProcedureFieldsAdapter.getInitialState({})\n\nexport const assetProcedureFieldsSlice = createSlice({\n\tname: \"assetProcedureFields\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetProcedureFields: assetProcedureFieldsAdapter.initialize,\n\t\taddAssetProcedureFields: assetProcedureFieldsAdapter.addOne,\n\t\taddAssetProcedureFieldsMany: assetProcedureFieldsAdapter.addMany,\n\t\tsetAssetProcedureFields: assetProcedureFieldsAdapter.setOne,\n\t\tsetAssetProcedureFieldsMany: assetProcedureFieldsAdapter.setMany,\n\t\tupdateAssetProcedureFields: assetProcedureFieldsAdapter.updateOne,\n\t\tupdateAssetProcedureFieldsMany: assetProcedureFieldsAdapter.updateMany,\n\t\tdeleteAssetProcedureFields: assetProcedureFieldsAdapter.deleteOne,\n\t\tdeleteAssetProcedureFieldsMany: assetProcedureFieldsAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetProcedureFields,\n\taddAssetProcedureFields,\n\taddAssetProcedureFieldsMany,\n\tsetAssetProcedureFields,\n\tsetAssetProcedureFieldsMany,\n\tupdateAssetProcedureFields,\n\tupdateAssetProcedureFieldsMany,\n\tdeleteAssetProcedureFields,\n\tdeleteAssetProcedureFieldsMany,\n} = assetProcedureFieldsSlice.actions\n\nexport const selectAssetProcedureFieldsMapping = (state: OvermapRootState) =>\n\tstate.assetProcedureFieldsReducer.instances\n\nexport const selectAssetProcedureFields = createSelector([selectAssetProcedureFieldsMapping], (fieldsMapping) => {\n\treturn Object.values(fieldsMapping)\n})\n\nexport const selectAssetProcedureFieldsOfAssetProcedure: OvermapSelectorWithArgs<string, AssetProcedureFields[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectAssetProcedureFields, (_state, assetProcedureId: string) => assetProcedureId],\n\t\t\t(fields, assetProcedureId) => {\n\t\t\t\treturn fallbackToEmptyArray(fields.filter((field) => field.asset_procedure === assetProcedureId))\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectLatestAssetProcedureFieldsOfAssetProcedure: OvermapSelectorWithArgs<\n\tstring,\n\tAssetProcedureFields | undefined\n> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssetProcedureFields, (_state, id: string) => id], (fields, id) => {\n\t\treturn fields\n\t\t\t.filter((field) => field.asset_procedure === id)\n\t\t\t.sort((a, b) => (a.submitted_at > b.submitted_at ? -1 : 1))[0]\n\t}),\n)\n\nexport const selectAssetProcedureFieldsById: OvermapSelectorWithArgs<string, AssetProcedureFields | undefined> =\n\t(fieldsId) => (state: OvermapRootState) => {\n\t\treturn state.assetProcedureFieldsReducer.instances[fieldsId]\n\t}\n\nexport const assetProcedureFieldsReducer: Reducer<AssetProcedureFieldsState> = assetProcedureFieldsSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetProcedureFieldValues, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetProcedureFieldValuesState = ModelState<Stored<AssetProcedureFieldValues>>\n\nconst assetProcedureFieldValuesAdapter = createModelAdapter<Stored<AssetProcedureFieldValues>>(\n\t(fieldValues) => fieldValues.offline_id,\n)\n\nconst initialState: AssetProcedureFieldValuesState = assetProcedureFieldValuesAdapter.getInitialState({})\n\nexport const assetProcedureFieldValuesSlice = createSlice({\n\tname: \"assetProcedureFieldValues\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetProcedureFieldValues: assetProcedureFieldValuesAdapter.initialize,\n\t\taddAssetProcedureFieldValues: assetProcedureFieldValuesAdapter.addOne,\n\t\taddAssetProcedureFieldValuesMany: assetProcedureFieldValuesAdapter.addMany,\n\t\tsetAssetProcedureFieldValues: assetProcedureFieldValuesAdapter.setOne,\n\t\tsetAssetProcedureFieldValuesMany: assetProcedureFieldValuesAdapter.setMany,\n\t\tupdateAssetProcedureFieldValues: assetProcedureFieldValuesAdapter.updateOne,\n\t\tupdateAssetProcedureFieldValuesMany: assetProcedureFieldValuesAdapter.updateMany,\n\t\tdeleteAssetProcedureFieldValues: assetProcedureFieldValuesAdapter.deleteOne,\n\t\tdeleteAssetProcedureFieldValuesMany: assetProcedureFieldValuesAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetProcedureFieldValues,\n\taddAssetProcedureFieldValues,\n\taddAssetProcedureFieldValuesMany,\n\tsetAssetProcedureFieldValues,\n\tsetAssetProcedureFieldValuesMany,\n\tupdateAssetProcedureFieldValues,\n\tupdateAssetProcedureFieldValuesMany,\n\tdeleteAssetProcedureFieldValues,\n\tdeleteAssetProcedureFieldValuesMany,\n} = assetProcedureFieldValuesSlice.actions\n\nexport const selectAssetProcedureFieldValuesMapping = (state: OvermapRootState) =>\n\tstate.assetProcedureFieldValuesReducer.instances\n\nexport const selectAssetProcedureFieldValues = createSelector(\n\t[selectAssetProcedureFieldValuesMapping],\n\t(fieldValuesMapping) => {\n\t\treturn Object.values(fieldValuesMapping)\n\t},\n)\n\nexport const selectAssetProcedureFieldValuesOfAsset: OvermapSelectorWithArgs<string, AssetProcedureFieldValues[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectAssetProcedureFieldValues, (_state, assetId: string) => assetId],\n\t\t\t(fieldValues, assetId) => {\n\t\t\t\treturn fallbackToEmptyArray(fieldValues.filter((fieldValue) => fieldValue.asset === assetId))\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectFieldValuesOfAssetProcedureInstance: OvermapSelectorWithArgs<\n\tstring,\n\tStored<AssetProcedureFieldValues>[]\n> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssetProcedureFieldValues, (_state, id: string) => id], (fieldValues, id) => {\n\t\treturn fallbackToEmptyArray(fieldValues.filter((values) => values.asset_procedure_instance === id))\n\t}),\n)\n\nexport const selectAssetProcedureFieldValuesById: OvermapSelectorWithArgs<\n\tstring,\n\tAssetProcedureFieldValues | undefined\n> = (fieldValuesId) => (state: OvermapRootState) => {\n\treturn state.assetProcedureFieldValuesReducer.instances[fieldValuesId]\n}\n\nexport const assetProcedureFieldValuesReducer: Reducer<AssetProcedureFieldValuesState> =\n\tassetProcedureFieldValuesSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetProcedureFieldsAttachment, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetProcedureFieldsAttachmentState = ModelState<Stored<AssetProcedureFieldsAttachment>>\n\nconst assetProcedureFieldsAttachmentAdapter = createModelAdapter<Stored<AssetProcedureFieldsAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState: AssetProcedureFieldsAttachmentState = assetProcedureFieldsAttachmentAdapter.getInitialState({})\n\nexport const assetProcedureFieldsAttachmentSlice = createSlice({\n\tname: \"assetProcedureFieldsAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetProcedureFieldsAttachments: assetProcedureFieldsAttachmentAdapter.initialize,\n\t\taddAssetProcedureFieldsAttachment: assetProcedureFieldsAttachmentAdapter.addOne,\n\t\taddAssetProcedureFieldsAttachments: assetProcedureFieldsAttachmentAdapter.addMany,\n\t\tsetAssetProcedureFieldsAttachment: assetProcedureFieldsAttachmentAdapter.setOne,\n\t\tsetAssetProcedureFieldsAttachments: assetProcedureFieldsAttachmentAdapter.setMany,\n\t\tupdateAssetProcedureFieldsAttachment: assetProcedureFieldsAttachmentAdapter.updateOne,\n\t\tupdateAssetProcedureFieldsAttachments: assetProcedureFieldsAttachmentAdapter.updateMany,\n\t\tdeleteAssetProcedureFieldsAttachment: assetProcedureFieldsAttachmentAdapter.deleteOne,\n\t\tdeleteAssetProcedureFieldsAttachments: assetProcedureFieldsAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetProcedureFieldsAttachments,\n\taddAssetProcedureFieldsAttachment,\n\taddAssetProcedureFieldsAttachments,\n\tsetAssetProcedureFieldsAttachment,\n\tsetAssetProcedureFieldsAttachments,\n\tupdateAssetProcedureFieldsAttachment,\n\tupdateAssetProcedureFieldsAttachments,\n\tdeleteAssetProcedureFieldsAttachment,\n\tdeleteAssetProcedureFieldsAttachments,\n} = assetProcedureFieldsAttachmentSlice.actions\n\nexport const selectAssetProcedureFieldsAttachmentsMapping = (state: OvermapRootState) =>\n\tstate.assetProcedureFieldsAttachmentReducer.instances\n\nexport const selectAssetProcedureFieldsAttachments = createSelector(\n\t[selectAssetProcedureFieldsAttachmentsMapping],\n\t(attachmentsMapping) => {\n\t\treturn Object.values(attachmentsMapping)\n\t},\n)\n\nexport const selectAttachmentsOfAssetProcedureFields: OvermapSelectorWithArgs<\n\tstring,\n\tAssetProcedureFieldsAttachment[]\n> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssetProcedureFieldsAttachments, (_state, id: string) => id], (attachments, id) => {\n\t\treturn fallbackToEmptyArray(attachments.filter((attachment) => attachment.fields_revision === id))\n\t}),\n)\n\nexport const selectAssetProcedureFieldsAttachmentById: OvermapSelectorWithArgs<\n\tstring,\n\tAssetProcedureFieldsAttachment | undefined\n> = (attachmentId) => (state: OvermapRootState) => {\n\treturn state.assetProcedureFieldsAttachmentReducer.instances[attachmentId]\n}\n\nexport const assetProcedureFieldsAttachmentReducer: Reducer<AssetProcedureFieldsAttachmentState> =\n\tassetProcedureFieldsAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tAssetProcedureFieldValuesAttachment,\n\tOvermapRootState,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetProcedureFieldValuesAttachmentState = ModelState<Stored<AssetProcedureFieldValuesAttachment>>\n\nconst assetProcedureFieldValuesAttachmentAdapter = createModelAdapter<Stored<AssetProcedureFieldValuesAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState: AssetProcedureFieldValuesAttachmentState =\n\tassetProcedureFieldValuesAttachmentAdapter.getInitialState({})\n\nexport const assetProcedureFieldValuesAttachmentSlice = createSlice({\n\tname: \"assetProcedureFieldValuesAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetProcedureFieldValuesAttachments: assetProcedureFieldValuesAttachmentAdapter.initialize,\n\t\taddAssetProcedureFieldValuesAttachment: assetProcedureFieldValuesAttachmentAdapter.addOne,\n\t\taddAssetProcedureFieldValuesAttachments: assetProcedureFieldValuesAttachmentAdapter.addMany,\n\t\tsetAssetProcedureFieldValuesAttachment: assetProcedureFieldValuesAttachmentAdapter.setOne,\n\t\tsetAssetProcedureFieldValuesAttachments: assetProcedureFieldValuesAttachmentAdapter.setMany,\n\t\tupdateAssetProcedureFieldValuesAttachment: assetProcedureFieldValuesAttachmentAdapter.updateOne,\n\t\tupdateAssetProcedureFieldValuesAttachments: assetProcedureFieldValuesAttachmentAdapter.updateMany,\n\t\tdeleteAssetProcedureFieldValuesAttachment: assetProcedureFieldValuesAttachmentAdapter.deleteOne,\n\t\tdeleteAssetProcedureFieldValuesAttachments: assetProcedureFieldValuesAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetProcedureFieldValuesAttachments,\n\taddAssetProcedureFieldValuesAttachment,\n\taddAssetProcedureFieldValuesAttachments,\n\tsetAssetProcedureFieldValuesAttachment,\n\tsetAssetProcedureFieldValuesAttachments,\n\tupdateAssetProcedureFieldValuesAttachment,\n\tupdateAssetProcedureFieldValuesAttachments,\n\tdeleteAssetProcedureFieldValuesAttachment,\n\tdeleteAssetProcedureFieldValuesAttachments,\n} = assetProcedureFieldValuesAttachmentSlice.actions\n\nexport const selectAssetProcedureFieldValuesAttachmentsMapping = (state: OvermapRootState) =>\n\tstate.assetProcedureFieldValuesAttachmentReducer.instances\n\nexport const selectAssetProcedureFieldValuesAttachments = createSelector(\n\t[selectAssetProcedureFieldValuesAttachmentsMapping],\n\t(attachmentsMapping) => {\n\t\treturn Object.values(attachmentsMapping)\n\t},\n)\n\nexport const selectAssetProcedureFieldValuesAttachmentById: OvermapSelectorWithArgs<\n\tstring,\n\tAssetProcedureFieldValuesAttachment | undefined\n> = (attachmentId) => (state: OvermapRootState) => {\n\treturn state.assetProcedureFieldValuesAttachmentReducer.instances[attachmentId]\n}\n\nexport const selectAssetProcedureFieldValuesAttachmentsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetProcedureFieldValuesAttachmentsMapping, (_, attachmentIds: string[]) => attachmentIds],\n\t\t(mapping, attachmentIds) => {\n\t\t\tconst attachmentIdsSet = new Set(attachmentIds)\n\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\tObject.values(mapping).filter((attachment) => attachmentIdsSet.has(attachment.offline_id)),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfAssetProcedureFieldValues: OvermapSelectorWithArgs<\n\tstring,\n\tStored<AssetProcedureFieldValuesAttachment>[]\n> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssetProcedureFieldValuesAttachments, (_state, id: string) => id], (attachments, id) => {\n\t\treturn fallbackToEmptyArray(attachments.filter((attachment) => attachment.field_values === id))\n\t}),\n)\n\nexport const assetProcedureFieldValuesAttachmentReducer: Reducer<AssetProcedureFieldValuesAttachmentState> =\n\tassetProcedureFieldValuesAttachmentSlice.reducer\n","import { offline } from \"@redux-offline/redux-offline\"\nimport { compose, Reducer } from \"redux\"\nimport offlineConfig from \"@redux-offline/redux-offline/lib/defaults\"\nimport localforage from \"localforage\"\n\n// TODO: Fix\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nimport createMigration from \"redux-persist-migrate\"\n\nimport { combineReducers } from \"@reduxjs/toolkit\"\nimport {\n\tConfig,\n\tOfflineAction,\n\tOfflineMetadata,\n\tOfflineState,\n\tResultAction,\n} from \"@redux-offline/redux-offline/lib/types\"\nimport request from \"superagent\"\nimport { HttpMethod } from \"../enums\"\nimport { manifest } from \"./migrations\"\n\n// There are two \"blobs\": The Blob type from the \"buffer\" package (part of node),\n// and the Blob type from the browser. For some reason, superagent uses the \"buffer\"\n// version after moving code from hemora-web to overmap-core. This overwrites the name\n// \"Blob\". There are minor differences between the two interfaces (remove the type casting\n// of the `file` argument to `req.field()` in performRequest() to see the error), but it's\n// unlikely that we'll run into any problems.\nimport { ToastProps, unsafeShowToast } from \"@overmap-ai/blocks\"\nimport { Blob } from \"buffer\"\nimport { OUTBOX_RETRY_DELAY } from \"../constants\"\nimport {\n\tAPIError,\n\tBaseApiService,\n\ttype BaseSDK,\n\ttype OfflineMetaEffect,\n\tOutboxCoordinator,\n\tRequestDetails,\n} from \"../sdk\"\nimport { getClientSDK, getClientStore } from \"../sdk/globals\"\nimport { CLASS_NAME_TO_SERVICE } from \"../sdk/services/BaseService\"\nimport type { BaseState, OvermapRootState } from \"../typings\"\nimport {\n\t_setLatestRetryTime,\n\tagentsReducer,\n\tAgentsState,\n\tassetAttachmentReducer,\n\tAssetAttachmentState,\n\tassetProcedureInstanceReducer,\n\tAssetProcedureInstanceState,\n\tassetProcedureReducer,\n\tAssetProcedureState,\n\tassetProcedureFieldsReducer,\n\tAssetProcedureFieldsState,\n\tassetProcedureFieldValuesReducer,\n\tAssetProcedureFieldValuesState,\n\tassetProcedureFieldsAttachmentReducer,\n\tAssetProcedureFieldsAttachmentState,\n\tassetProcedureFieldValuesAttachmentReducer,\n\tAssetProcedureFieldValuesAttachmentState,\n\tassetReducer,\n\tassetStageCompletionReducer,\n\tAssetStageCompletionState,\n\tassetStageReducer,\n\tAssetStageState,\n\tAssetState,\n\tassetTypeAttachmentReducer,\n\tAssetTypeAttachmentState,\n\tassetTypeFieldsAttachmentReducer,\n\tAssetTypeFieldsAttachmentState,\n\tassetTypeFieldsReducer,\n\tAssetTypeFieldsState,\n\tassetTypeFieldValuesAttachmentReducer,\n\tAssetTypeFieldValuesAttachmentState,\n\tassetTypeFieldValuesReducer,\n\tAssetTypeFieldValuesState,\n\tassetTypeReducer,\n\tAssetTypeState,\n\tauthReducer,\n\tAuthState,\n\tcategoryReducer,\n\tCategoryState,\n\tdocumentAttachmentReducer,\n\tDocumentAttachmentState,\n\tdocumentsReducer,\n\tDocumentState,\n\temailDomainsReducer,\n\tEmailDomainState,\n\tfileReducer,\n\tFileState,\n\tformReducer,\n\tformRevisionAttachmentReducer,\n\tFormRevisionAttachmentState,\n\tformRevisionReducer,\n\tFormRevisionState,\n\tFormState,\n\tformSubmissionAttachmentReducer,\n\tFormSubmissionAttachmentState,\n\tformSubmissionReducer,\n\tFormSubmissionState,\n\tgeoImageReducer,\n\tGeoImageSliceState,\n\tissueAssociationReducer,\n\tIssueAssociationSliceState,\n\tissueAttachmentReducer,\n\tIssueAttachmentState,\n\tissueCommentReducer,\n\tIssueCommentState,\n\tissueReducer,\n\tIssueState,\n\tissueTypeFieldsAttachmentReducer,\n\tIssueTypeFieldsAttachmentState,\n\tissueTypeFieldsReducer,\n\tIssueTypeFieldsState,\n\tissueTypeFieldValuesAttachmentReducer,\n\tIssueTypeFieldValuesAttachmentState,\n\tissueTypeFieldValuesReducer,\n\tIssueTypeFieldValuesState,\n\tissueTypeReducer,\n\tIssueTypeState,\n\tissueUpdateReducer,\n\tIssueUpdateState,\n\tlicenseReducer,\n\tLicenseState,\n\tmarkAsDeleted,\n\torganizationAccessReducer,\n\tOrganizationAccessState,\n\torganizationReducer,\n\tOrganizationState,\n\toutboxReducer,\n\tOutboxState,\n\tprojectAccessReducer,\n\tProjectAccessState,\n\tprojectAttachmentReducer,\n\tProjectAttachmentState,\n\tprojectFileReducer,\n\tProjectFileState,\n\tprojectReducer,\n\tProjectState,\n\trehydratedReducer,\n\tRehydratedState,\n\tteamReducer,\n\tTeamState,\n\tuserReducer,\n\tUserState,\n\tversioningReducer,\n\tVersioningState,\n\tworkspaceReducer,\n\tWorkspaceState,\n} from \"./slices\"\n\n// NOTE: If changing, also change it in migrations.ts (avoid circular imports)\nexport const VERSION_REDUCER_KEY = \"versioning\"\n\nexport const overmapReducers = {\n\t// TODO: attachmentReducer,\n\t[VERSION_REDUCER_KEY]: versioningReducer,\n\tfileReducer,\n\tauthReducer,\n\tcategoryReducer,\n\tassetReducer,\n\tassetAttachmentReducer,\n\tassetStageCompletionReducer,\n\tassetStageReducer,\n\tassetTypeReducer,\n\tassetTypeAttachmentReducer,\n\tissueReducer,\n\tissueAttachmentReducer,\n\tissueTypeReducer,\n\torganizationReducer,\n\toutboxReducer,\n\tprojectReducer,\n\tprojectAttachmentReducer,\n\tprojectAccessReducer,\n\torganizationAccessReducer,\n\tprojectFileReducer,\n\trehydratedReducer,\n\tformReducer,\n\tformRevisionReducer,\n\tformRevisionAttachmentReducer,\n\tformSubmissionAttachmentReducer,\n\tformSubmissionReducer,\n\tuserReducer,\n\tworkspaceReducer,\n\temailDomainsReducer,\n\tlicenseReducer,\n\tdocumentsReducer,\n\tdocumentAttachmentReducer,\n\tteamReducer,\n\tagentsReducer,\n\tissueCommentReducer,\n\tissueUpdateReducer,\n\tgeoImageReducer,\n\tissueAssociationReducer,\n\tissueTypeFieldsReducer,\n\tissueTypeFieldValuesReducer,\n\tissueTypeFieldsAttachmentReducer,\n\tissueTypeFieldValuesAttachmentReducer,\n\tassetTypeFieldsReducer,\n\tassetTypeFieldValuesReducer,\n\tassetTypeFieldsAttachmentReducer,\n\tassetTypeFieldValuesAttachmentReducer,\n\tassetProcedureReducer,\n\tassetProcedureInstanceReducer,\n\tassetProcedureFieldsReducer,\n\tassetProcedureFieldValuesReducer,\n\tassetProcedureFieldsAttachmentReducer,\n\tassetProcedureFieldValuesAttachmentReducer,\n} satisfies {\n\tversioning: Reducer<VersioningState>\n\tfileReducer: Reducer<FileState>\n\tauthReducer: Reducer<AuthState>\n\tcategoryReducer: Reducer<CategoryState>\n\tassetReducer: Reducer<AssetState>\n\tassetAttachmentReducer: Reducer<AssetAttachmentState>\n\tassetStageCompletionReducer: Reducer<AssetStageCompletionState>\n\tassetStageReducer: Reducer<AssetStageState>\n\tassetTypeReducer: Reducer<AssetTypeState>\n\tassetTypeAttachmentReducer: Reducer<AssetTypeAttachmentState>\n\tissueReducer: Reducer<IssueState>\n\tissueTypeReducer: Reducer<IssueTypeState>\n\torganizationReducer: Reducer<OrganizationState>\n\toutboxReducer: Reducer<OutboxState>\n\tprojectReducer: Reducer<ProjectState>\n\tprojectAttachmentReducer: Reducer<ProjectAttachmentState>\n\tprojectAccessReducer: Reducer<ProjectAccessState>\n\torganizationAccessReducer: Reducer<OrganizationAccessState>\n\tprojectFileReducer: Reducer<ProjectFileState>\n\trehydratedReducer: Reducer<RehydratedState>\n\tformReducer: Reducer<FormState>\n\tuserReducer: Reducer<UserState>\n\tformRevisionReducer: Reducer<FormRevisionState>\n\tformRevisionAttachmentReducer: Reducer<FormRevisionAttachmentState>\n\tformSubmissionAttachmentReducer: Reducer<FormSubmissionAttachmentState>\n\tformSubmissionReducer: Reducer<FormSubmissionState>\n\tworkspaceReducer: Reducer<WorkspaceState>\n\temailDomainsReducer: Reducer<EmailDomainState>\n\tlicenseReducer: Reducer<LicenseState>\n\tdocumentsReducer: Reducer<DocumentState>\n\tdocumentAttachmentReducer: Reducer<DocumentAttachmentState>\n\tteamReducer: Reducer<TeamState>\n\tagentsReducer: Reducer<AgentsState>\n\tissueCommentReducer: Reducer<IssueCommentState>\n\tissueUpdateReducer: Reducer<IssueUpdateState>\n\tissueAttachmentReducer: Reducer<IssueAttachmentState>\n\tgeoImageReducer: Reducer<GeoImageSliceState>\n\tissueAssociationReducer: Reducer<IssueAssociationSliceState>\n\tissueTypeFieldsReducer: Reducer<IssueTypeFieldsState>\n\tissueTypeFieldValuesReducer: Reducer<IssueTypeFieldValuesState>\n\tissueTypeFieldsAttachmentReducer: Reducer<IssueTypeFieldsAttachmentState>\n\tissueTypeFieldValuesAttachmentReducer: Reducer<IssueTypeFieldValuesAttachmentState>\n\tassetTypeFieldsReducer: Reducer<AssetTypeFieldsState>\n\tassetTypeFieldValuesReducer: Reducer<AssetTypeFieldValuesState>\n\tassetTypeFieldsAttachmentReducer: Reducer<AssetTypeFieldsAttachmentState>\n\tassetTypeFieldValuesAttachmentReducer: Reducer<AssetTypeFieldValuesAttachmentState>\n\tassetProcedureReducer: Reducer<AssetProcedureState>\n\tassetProcedureInstanceReducer: Reducer<AssetProcedureInstanceState>\n\tassetProcedureFieldsReducer: Reducer<AssetProcedureFieldsState>\n\tassetProcedureFieldValuesReducer: Reducer<AssetProcedureFieldValuesState>\n\tassetProcedureFieldsAttachmentReducer: Reducer<AssetProcedureFieldsAttachmentState>\n\tassetProcedureFieldValuesAttachmentReducer: Reducer<AssetProcedureFieldValuesAttachmentState>\n}\n\nconst overmapReducer = combineReducers(overmapReducers)\n\n// Special action to revert all slices to their initial state. A reducer for this is added to each slice using\n// `extraReducers` in the slice definition.\nexport const resetStore = \"RESET\"\n\n// NOTE: Leaving this here for now until stories are removed from /core which requires a store to be set up.\n// not being used in /web\nexport const overmapRootReducer: Reducer<OvermapRootState> = (state, action): OvermapRootState => {\n\t// TODO: dont know if this is needed?\n\tif (action.type === \"auth/setLoggedIn\" && !action.payload) {\n\t\treturn overmapReducer(undefined, action) as OvermapRootState\n\t}\n\n\treturn overmapReducer(state, action) as OvermapRootState\n}\n\nexport interface FullOfflineMetadata extends OfflineMetadata {\n\teffect: OfflineMetaEffect\n}\n\nexport interface FullOfflineAction extends OfflineAction {\n\tmeta: { offline: FullOfflineMetadata }\n\t// Redundantly store request details in the unused `payload` property to make TypeScript happy\n\tpayload: RequestDetails\n}\n\nlet __OUTBOX_COORDINATOR: OutboxCoordinator | null = null\n\nexport function getOutboxCoordinator(): OutboxCoordinator | null {\n\tconst clientStore = getClientStore()\n\tif (!clientStore) {\n\t\tconsole.warn(\"Client store not set; cannot get outbox coordinator yet.\")\n\t\treturn null\n\t}\n\tif (__OUTBOX_COORDINATOR) {\n\t\treturn __OUTBOX_COORDINATOR\n\t}\n\tconst outbox = clientStore.getState().offline.outbox\n\tconst coordinator = OutboxCoordinator._fromOutbox(outbox)\n\t__OUTBOX_COORDINATOR = coordinator\n\treturn coordinator\n}\n\n// This callback is run when the Redux store has finished rehydrating itself from localForage\n// We signal to the rest of the app that hydration has finished\nconst persistCallback = (err: null | Error) => {\n\tif (err) throw err\n\tconst clientStore = getClientStore()\n\tif (clientStore) {\n\t\tclientStore.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\n\t} else {\n\t\tconsole.error(\"Client store not set\")\n\t}\n}\n\nexport const enqueue: Config[\"queue\"][\"enqueue\"] = (_array, item, _context) => {\n\tconst coordinator = getOutboxCoordinator()\n\tif (!coordinator) {\n\t\tconsole.warn(\"Outbox coordinator not set; cannot enqueue request yet.\")\n\t\treturn []\n\t}\n\tcoordinator.addRequest(item as FullOfflineAction)\n\treturn coordinator.getQueue()\n}\n\nexport const dequeue: Config[\"queue\"][\"dequeue\"] = (_array, item, _context) => {\n\tconst coordinator = getOutboxCoordinator()\n\tif (!coordinator) {\n\t\tconsole.warn(\"Outbox coordinator not set; cannot dequeue request yet.\")\n\t\treturn []\n\t}\n\t// The redux-offline type leaves out the \"offlineAction\" property\n\ttype BadMetaType = ResultAction[\"meta\"]\n\ttype CorrectedMetaType = BadMetaType & { offlineAction: FullOfflineAction }\n\tconst meta = item.meta as CorrectedMetaType\n\tconst uuid = meta.offlineAction.payload.uuid\n\tcoordinator.remove(uuid)\n\treturn coordinator.getQueue()\n}\n\n// This is called an \"effect reconciler\", and it turns an offline action into a real API request\nasync function effect(_effect: OfflineMetaEffect, action: FullOfflineAction) {\n\t// REASON: Handling of unexpected case\n\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\tif (!action.payload) {\n\t\tthrow new Error(\"Received empty payload\")\n\t}\n\n\t// We pass the action through a chain of middleware, which can do some useful things and then perform the action.\n\t// `runMiddleware` returns a Promise<Response> if everything goes well.\n\treturn runMiddleware(action)\n}\n\nconst customConfig: Partial<Config> = {\n\t...offlineConfig,\n\teffect: effect as Config[\"effect\"],\n\t// Casting needed because we are saving FullOfflineAction objects, not just OfflineAction objects,\n\t// but redux-offline does not know this.\n\tdiscard: discard as Config[\"discard\"],\n\treturnPromises: true,\n\tpersistCallback,\n\tretry: retry as Config[\"retry\"],\n\t// Modify the configuration of the offline store to use localforage\n\t// which uses IndexedDB by default (persists even on mobile when installed as a PWA, unlike localStorage)\n\tpersistOptions: { storage: localforage },\n\t// TODO: custom enqueue implementation to take care of intelligently cancelling \"create/delete same issue\",\n\t// and custom dequeue for e.g. if user insists on removing a failed a \"create issue\", then remove the \"edit\n\t// that same issue\"\n\tqueue: {\n\t\t...offlineConfig.queue,\n\t\tenqueue,\n\t\tdequeue,\n\t\t// Bad typing, undefined is actually fine, and the action is a FullOfflineAction, not just an OfflineAction.\n\t\tpeek: (...args) => peek(...(args as Parameters<typeof peek>))!,\n\t} satisfies Config[\"queue\"],\n}\n\n// migration to compose into store\nconst migration = createMigration(manifest, VERSION_REDUCER_KEY) as (_: unknown) => unknown\n\n/**\n * Enhancer for the Redux store that adds offline support and needed middleware for overmap.\n * Add to your store's `enhancers` array.\n */\nexport const overmapEnhancer = compose(offline(customConfig), migration)\n\n/**\n * Makes a best-effort attempt to extract a request.Response from an error object.\n * @param error The error object\n */\nfunction extractResponseFromError(error: unknown): request.Response | undefined {\n\tfunction isResponse(response: unknown): response is request.Response {\n\t\t// Just some keys we know are on a request.Response\n\t\tconst knownKeys = [\"ok\", \"redirect\", \"clientError\", \"serverError\", \"error\"]\n\t\treturn typeof response === \"object\" && response !== null && knownKeys.every((key) => key in response)\n\t}\n\n\tif (isResponse(error)) return error\n\tif (typeof error === \"object\" && error !== null) {\n\t\tconst typedError = error as { response?: { response?: request.Response } }\n\t\tif (isResponse(typedError.response)) return typedError.response\n\t\tif (typedError.response && isResponse(typedError.response.response)) return typedError.response.response\n\t}\n\treturn undefined\n}\n\n// Executes an offline action by making the API request specified in the action's offline metadata\nexport async function performRequest(action: FullOfflineAction, client: BaseSDK<BaseState>): Promise<request.Response> {\n\tconst serviceOfRequest = CLASS_NAME_TO_SERVICE[action.meta.offline.effect.serviceName]\n\n\tif (!serviceOfRequest) {\n\t\tthrow new Error(`Service ${action.meta.offline.effect.serviceName} not found`)\n\t}\n\n\tconst isApiService = serviceOfRequest instanceof BaseApiService\n\n\tconst state = client.store.getState()\n\tif (state.outboxReducer.deletedRequests.includes(action.payload.uuid)) {\n\t\t// The request has been marked for deletion, so we don't want to perform it.\n\t\t// Instead, throw an error, so it will be retried and discarded in the `discard` function.\n\t\tthrow new Error(\"Request was marked for deletion\")\n\t}\n\n\tif (isApiService && action.payload.checkAuth !== false) {\n\t\tawait serviceOfRequest.auth.prepareAuth()\n\t}\n\n\tconst defaultSettings = {\n\t\tqueryParams: \"\",\n\t\tisAuthNeeded: true,\n\t}\n\n\tconst offlineEffect = action.meta.offline.effect\n\tconst { payload, headers, method, queryParams, attachmentHash, isExternalUrl, isAuthNeeded, isResponseBlob } = {\n\t\t...defaultSettings,\n\t\t...offlineEffect.request,\n\t}\n\tconst requestDetails = offlineEffect.request\n\tlet url = requestDetails.url\n\tconst file = attachmentHash ? await client.files.fetchCache(attachmentHash) : undefined\n\n\tif (attachmentHash && !file) {\n\t\tthrow new Error(`Cannot upload file ${attachmentHash} because it's not cached.`)\n\t}\n\n\tif ((!isExternalUrl || import.meta.env.DEV) && !url.startsWith(\"http\")) {\n\t\tif (!url.startsWith(\"/\") && !url.startsWith(\"blob:\")) {\n\t\t\turl = \"/\" + url\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.trace(`You have passed a host-relative URL: ${url}`)\n\t\t\t}\n\t\t}\n\t\turl = action.meta.offline.effect.BASE_URL + url\n\t}\n\n\tconst addPayload = (req: request.SuperAgentRequest) => {\n\t\tif (attachmentHash) {\n\t\t\tconst s3url = requestDetails.s3url\n\t\t\tif (!s3url) throw new Error(`No S3 URL for file ${attachmentHash}`)\n\t\t\tif (\"warning\" in s3url) throw new Error(`S3 URL warning for file ${attachmentHash}`)\n\t\t\tif (!file) throw new Error(`No file for file ${attachmentHash}`)\n\t\t\tconst s3Sha1Checksum = s3url.fields[\"x-amz-checksum-sha1\"]\n\t\t\tif (!s3Sha1Checksum) throw new Error(`No checksum for file ${attachmentHash}`)\n\t\t\treturn req\n\t\t\t\t.set(\"x-amz-checksum-sha1\", s3Sha1Checksum)\n\t\t\t\t.field({ ...payload, ...s3url.fields })\n\t\t\t\t.attach(\"file\", file as unknown as Blob)\n\t\t}\n\t\treturn req.send(payload)\n\t}\n\n\tconst methodRequestMapping: Record<HttpMethod, () => request.SuperAgentRequest> = {\n\t\t[HttpMethod.GET]: () => {\n\t\t\tif (isResponseBlob) {\n\t\t\t\treturn request.get(url.toString()).responseType(\"blob\")\n\t\t\t}\n\t\t\treturn request.get(url.toString())\n\t\t},\n\t\t[HttpMethod.POST]: () => {\n\t\t\tconst ret = request.post(url.toString())\n\t\t\treturn addPayload(ret)\n\t\t},\n\t\t[HttpMethod.PATCH]: () => {\n\t\t\tconst ret = request.patch(url.toString())\n\t\t\treturn addPayload(ret)\n\t\t},\n\t\t[HttpMethod.PUT]: () => {\n\t\t\tconst ret = request.put(url.toString())\n\t\t\treturn addPayload(ret)\n\t\t},\n\t\t[HttpMethod.DELETE]: () => {\n\t\t\tconst ret = request.delete(url.toString())\n\t\t\treturn addPayload(ret)\n\t\t},\n\t}\n\n\tconst selectedRequest = methodRequestMapping[method]\n\n\tlet requestToSend = selectedRequest()\n\tif (isAuthNeeded && isApiService) {\n\t\tconst authHeader = serviceOfRequest.auth.getAuthHeader()\n\t\trequestToSend = requestToSend.set(\"Authorization\", authHeader)\n\t}\n\tif (headers) {\n\t\trequestToSend = requestToSend.set(headers)\n\t}\n\n\ttry {\n\t\treturn await requestToSend.query(queryParams)\n\t} catch (error) {\n\t\t// Observed error types: Error, request.Response\n\t\t// If it's an Error, it has a `response.response` property that is a request.Response.\n\t\tconst errorResponse = extractResponseFromError(error)\n\t\tconst status: number | undefined = errorResponse?.status\n\n\t\tif (isApiService && status === 401) {\n\t\t\tawait serviceOfRequest.auth.handleUnauthorized(requestToSend, errorResponse!)\n\t\t\treturn requestToSend.query(queryParams)\n\t\t}\n\n\t\t// TODO: Error codes for all APIErrors.\n\t\t// TODO: Constant for all messages.\n\t\tthrow new APIError({ response: errorResponse, innerError: error, discard: discardStatuses.includes(status!) })\n\t}\n}\n\ninterface MiddlewareChainer {\n\tthen: (next: OfflineMiddleware) => MiddlewareChainer\n\tcompile: () => OfflineMiddleware[]\n}\n\nclass MiddlewareChainerPrivate {\n\t_all: OfflineMiddleware[]\n\t_previous?: OfflineMiddleware\n\n\tconstructor(current: OfflineMiddleware) {\n\t\tthis._all = [current]\n\t\tthis._previous = current\n\t\tthis.then = this.then.bind(this)\n\t\tthis.compile = this.compile.bind(this)\n\t}\n\n\tthen(next: OfflineMiddleware): MiddlewareChainer {\n\t\tif (this._previous) this._previous.next = next // \"next\" is now \"current\"\n\t\tthis._all.push(next)\n\t\tthis._previous = next // \"next\" is now \"previous\"\n\n\t\treturn {\n\t\t\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\t\t\tthen: this.then,\n\t\t\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\t\t\tcompile: this.compile,\n\t\t}\n\t}\n\n\tcompile() {\n\t\treturn this._all\n\t}\n}\n\nabstract class OfflineMiddleware {\n\tnext: OfflineMiddleware | null\n\n\tconstructor() {\n\t\tthis.next = null\n\t}\n\n\tthen(next: OfflineMiddleware): MiddlewareChainer {\n\t\treturn new MiddlewareChainerPrivate(this).then(next)\n\t}\n\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\n\t\tif (this.next) {\n\t\t\treturn this.next.run(action)\n\t\t} else {\n\t\t\tconsole.debug(\"Middleware finished. Performing request:\", action)\n\n\t\t\tconst clientStore = getClientStore()\n\t\t\tif (!clientStore) throw new Error(\"Client store not set\")\n\n\t\t\tconst clientSDK = getClientSDK()\n\t\t\tif (!clientSDK) throw new Error(\"Client SDK not set\")\n\n\t\t\t// At the end of the middleware chain, we want to perform the action\n\t\t\treturn performRequest(action, clientSDK)\n\t\t}\n\t}\n}\n\nclass OfflineAnalyticsMiddleware extends OfflineMiddleware {\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\n\t\t// TODO: Store some statistics on which actions are called and enqueue reports periodically\n\t\treturn super.run(action)\n\t}\n}\n\nclass RateLimitingMiddleware extends OfflineMiddleware {\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\n\t\t// TODO: Consider rate limits (enable offline mode programmatically to reduce rate)\n\t\treturn super.run(action)\n\t}\n}\n\nconst allMiddleware = new OfflineAnalyticsMiddleware().then(new RateLimitingMiddleware()).compile()\n\nfunction runMiddleware(action: FullOfflineAction) {\n\treturn allMiddleware[0]?.run(action)\n}\n\n// These status codes are due to a fundamental problem that can never be corrected except by manual intervention.\n// TODO: 400 (Bad Request) should result in the user being given a chance to amend their request to be valid.\nconst discardStatuses = [400, 409, 403, 404, 405, 500]\nconst statusMessages: Record<number, ToastProps | undefined> = {\n\t403: { title: \"Forbidden\", description: \"You are not authorized to perform this action.\", accentColor: \"red\" },\n\t404: { title: \"Not found\", description: \"The requested resource was not found.\", accentColor: \"red\" },\n\t405: {\n\t\ttitle: \"Not supported\",\n\t\tdescription: \"It's not you. It's us. Sorry for the inconvenience.\",\n\t\taccentColor: \"red\",\n\t},\n\t500: {\n\t\ttitle: \"Server error\",\n\t\tdescription:\n\t\t\t\"Our server seems to be experiencing problems at the moment. We have been alerted and will fix the \" +\n\t\t\t\"problem as soon as possible.\",\n\t\taccentColor: \"red\",\n\t},\n}\n\n// Discard function is used by Redux Offline to decide whether to discard an action or not, based on the error\n// that the effect reconciler threw and/or the action\nexport function discard(reason: unknown, action: FullOfflineAction, retries = 0): boolean {\n\t// TODO: If 401, renew auth and return false\n\t// TODO: If 400, set state to rescue mode, allowing the user to fix the request and retry (or discard)\n\n\tconsole.debug(\n\t\t\"Considering discarding request due to error:\",\n\t\treason,\n\t\t`(${typeof reason})`,\n\t\t\"\\nAction:\",\n\t\taction,\n\t\t\"\\nRetries:\",\n\t\tretries,\n\t)\n\n\tif (!(reason instanceof Error)) {\n\t\tconsole.error(\n\t\t\t\"ENCOUNTERED NON-ERROR ERROR:\",\n\t\t\treason,\n\t\t\t\"(throwing immediately, which may lead to unexpected behavior)\",\n\t\t)\n\t\tthrow reason\n\t}\n\n\tconst clientStore = getClientStore()\n\tconst state = clientStore!.getState()\n\tconst deletedRequests = state.outboxReducer.deletedRequests\n\tconst uuid = action.payload.uuid\n\n\t// NOTE: Doesn't really return true, but TypeScript doesn't need to know that.\n\t// Adding a `return true` would be meaningless since we are throwing the passed error.\n\tfunction rollbackAndThrow(): true {\n\t\tclientStore!.dispatch(markAsDeleted(uuid))\n\t\tconst coordinator = getOutboxCoordinator()\n\t\tif (!coordinator) {\n\t\t\tthrow new Error(\"Outbox coordinator not set\")\n\t\t}\n\t\tcoordinator.remove(action.payload.uuid)\n\t\tconst rollbackAction = action.meta.offline.rollback\n\t\tif (rollbackAction) {\n\t\t\tconsole.warn(\"Rolling back request due to SDK error:\", action)\n\t\t\tclientStore!.dispatch(rollbackAction)\n\t\t}\n\t\tthrow reason\n\t}\n\n\tif (reason instanceof APIError && reason.options.discard) {\n\t\tconsole.debug(\"Discarding request due to explicit discard:\", action)\n\t\treturn rollbackAndThrow()\n\t}\n\n\tif (deletedRequests.includes(uuid)) {\n\t\tconsole.debug(\"Discarding request due to deletion:\", action)\n\t\treturn rollbackAndThrow()\n\t}\n\n\tif (reason instanceof APIError) {\n\t\tconst status: number | undefined = reason.status || reason.response?.status\n\t\tif (!status) {\n\t\t\tconsole.warn(\"Error has no status code:\", reason)\n\t\t}\n\t\tif (status !== undefined && discardStatuses.includes(status)) {\n\t\t\tconsole.warn(\"Discarding request due to error:\", reason, \"\\nAction:\", action)\n\t\t\tconst message = statusMessages[status]\n\t\t\tif (message) {\n\t\t\t\tif (unsafeShowToast) {\n\t\t\t\t\tunsafeShowToast(message)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(`Could not display toast for status ${status} because there is no toast handle.`)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst coordinator = getOutboxCoordinator()\n\t\t\tif (!coordinator) {\n\t\t\t\tthrow new Error(\"Outbox coordinator not set\")\n\t\t\t}\n\t\t\tcoordinator.remove(action.payload.uuid)\n\t\t\treason.options.discard = true\n\t\t\trollbackAndThrow()\n\t\t}\n\t}\n\n\tconsole.debug(\"Registering a retry for request:\", action.payload.uuid)\n\t// All failures due to any other reason should be retried indefinitely. It will not block the outbox thanks to\n\t// OutboxCoordinator.\n\tconst coordinator = getOutboxCoordinator()\n\tif (!coordinator) {\n\t\tthrow new Error(\"Outbox coordinator not set\")\n\t}\n\tcoordinator.registerRetry(action.payload.uuid)\n\treturn false\n}\n\n// Peek function is used by Redux Offline to determine the next action of the outbox to execute.\n// We are overriding the default implementation (return array[0]) with our own to support our graph-based outbox.\nfunction peek(\n\t_array: FullOfflineAction[],\n\t_item: unknown,\n\t_context: { offline: OfflineState },\n): OfflineAction | undefined {\n\treturn getOutboxCoordinator()?.peek()\n}\n\n// Retry function is used by Redux Offline to determine how long to retry an action, given number of retries\nfunction retry(_action: FullOfflineAction, _retries: number): number | undefined {\n\t// Always retry, but wait a few seconds after a failed request. We have our own custom discard/retry logic.\n\tgetClientStore()!.dispatch(_setLatestRetryTime(new Date().getTime()))\n\treturn OUTBOX_RETRY_DELAY\n}\n\n// export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, RootState, unknown, Action<string>>\n","// The shape of an object that describes the details of an API request\nimport { FileService } from \"./services\"\nimport { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore\"\nimport request from \"superagent\"\nimport { v4 as uuidv4 } from \"uuid\"\nimport { OfflineMetaEffect, SDKRequest } from \"./typings\"\nimport { APIError } from \"./errors\"\nimport { DeferredPromise } from \"../utils\"\nimport { discard, enqueueRequest, FullOfflineAction, performRequest } from \"../store\"\nimport type { BaseState } from \"../typings\"\n\n// This is a bundle of the services that our app uses. These can be used in tandem with the types\n// declared above in order to execute requests to the backend (queued or otherwise). To use it,\n// you can declare a \"PlaceholderName-Service.ts\" and have CRUD methods to send to the backend,\n// and call it by using `sdk.PlaceHolderName.CRUD_METHOD`\nexport abstract class BaseSDK<TState extends BaseState> {\n\treadonly store: ToolkitStore<TState>\n\tabstract readonly files: FileService<TState, BaseSDK<TState>>\n\n\tprotected constructor(store: ToolkitStore<TState>) {\n\t\tthis.store = store\n\t}\n\n\tpublic async enqueueRequest<TResult>(\n\t\trequestDetails: SDKRequest,\n\t\thost: string,\n\t\tserviceName: string,\n\t): Promise<TResult> {\n\t\t// enqueueRequest is a wrapper for _enqueueRequest that ensures the result is not an APIError unless\n\t\t// `.catch()` is triggered.\n\t\treturn this._enqueueRequest<TResult>(requestDetails, host, serviceName).then((result) => {\n\t\t\tif (result instanceof APIError) {\n\t\t\t\tthrow result\n\t\t\t}\n\t\t\treturn result\n\t\t})\n\t}\n\n\tprivate _enqueueRequest<TResult>(\n\t\trequestDetails: SDKRequest,\n\t\thost: string,\n\t\tserviceName: string,\n\t): DeferredPromise<TResult | APIError> {\n\t\t// We'll receive a Response object, but we want to return just the body of the response. This means\n\t\t// that we must inject a callback in the middle. We will use two promises:\n\t\tconst promise = new DeferredPromise<TResult | APIError>()\n\n\t\t// We dispatch an action that will eventually result in a request.\n\t\tconst requestDetailsWithBaseUrl = { ...requestDetails, BASE_URL: host, serviceName: serviceName }\n\n\t\tif (requestDetails.immediate) {\n\t\t\tconst requestWithUuid = {\n\t\t\t\t...requestDetailsWithBaseUrl,\n\t\t\t\tuuid: requestDetails.uuid ?? uuidv4(),\n\t\t\t}\n\t\t\t// TODO: Does this result in sending the request multiple times?\n\t\t\t// Should performRequest accept pure requestDetails?\n\t\t\t// (It shouldn't result in dupes because we're not dispatching an action.)\n\t\t\tconst fullOfflineAction: FullOfflineAction = {\n\t\t\t\tpayload: requestWithUuid,\n\t\t\t\ttype: \"\",\n\t\t\t\tmeta: {\n\t\t\t\t\toffline: {\n\t\t\t\t\t\teffect: {\n\t\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t\t\trequest: requestWithUuid,\n\t\t\t\t\t\t\tBASE_URL: host,\n\t\t\t\t\t\t\tserviceName: serviceName,\n\t\t\t\t\t\t} satisfies OfflineMetaEffect,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t\tperformRequest(fullOfflineAction, this)\n\t\t\t\t.then((result) => {\n\t\t\t\t\tpromise.resolve(result.body as TResult)\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tdiscard(error, fullOfflineAction)\n\t\t\t\t\tpromise.reject(error)\n\t\t\t\t})\n\t\t} else {\n\t\t\tconst innerPromise: Promise<request.Response> = this.store.dispatch(\n\t\t\t\tenqueueRequest(requestDetailsWithBaseUrl),\n\t\t\t) as unknown as Promise<request.Response>\n\n\t\t\tconst successOrUndefinedHandler = (response: request.Response | undefined) => {\n\t\t\t\tif (response) {\n\t\t\t\t\tpromise.resolve(response.body as TResult)\n\t\t\t\t} else {\n\t\t\t\t\tconst error = new APIError({\n\t\t\t\t\t\tmessage: \"Could not get a response from the server.\",\n\t\t\t\t\t\tresponse: response satisfies undefined,\n\t\t\t\t\t\tdiscard: true,\n\t\t\t\t\t})\n\t\t\t\t\tpromise.reject(error)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Handles errors from the inner promise (which performs the request) and rejects the outer promise, which has\n\t\t\t * been returned to the caller by the time this is triggered. This handler is only expected to be triggered if\n\t\t\t * the request has been discarded from the outbox.\n\t\t\t * @param error The error that caused the request to be discarded. Expected to be an APIError instance.\n\t\t\t */\n\t\t\tconst errorHandler = (error: unknown) => {\n\t\t\t\tif (error instanceof APIError) {\n\t\t\t\t\terror.options.discard = true\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"Received an unexpected error while processing a request:\",\n\t\t\t\t\t\terror,\n\t\t\t\t\t\t\"\\nConverting error to APIError and discarding.\",\n\t\t\t\t\t)\n\t\t\t\t\terror = new APIError({\n\t\t\t\t\t\tmessage: \"An error occurred while processing the request.\",\n\t\t\t\t\t\tinnerError: error,\n\t\t\t\t\t\tdiscard: true,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tpromise.reject(error)\n\t\t\t}\n\n\t\t\tinnerPromise.then(successOrUndefinedHandler, errorHandler)\n\t\t}\n\n\t\treturn promise\n\t}\n\n\t// NOTE: these are currently expected to be present in the base SDK, not sure if that is desired\n}\n","import type { BaseSDK } from \"./base\"\nimport { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore\"\nimport type { BaseState } from \"../typings\"\nimport { setClientSDK, setClientStore } from \"./globals\"\nimport type { OvermapSDKConstructor } from \"./typings\"\n\nexport const initSDK = <TState extends BaseState, TSDK extends BaseSDK<TState>>(\n\tstore: ToolkitStore<TState>,\n\tsdk: OvermapSDKConstructor<TState, TSDK>,\n) => {\n\tconst sdkInstance = new sdk(store)\n\tsetClientSDK(sdkInstance)\n\tsetClientStore(store)\n\n\treturn sdkInstance\n}\n","import { Response, SuperAgentRequest } from \"superagent\"\nimport type { BaseState } from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseService } from \"./BaseService\"\n\nexport abstract class BaseAuthService<TStore extends BaseState, TSDK extends BaseSDK<TStore>> extends BaseService<\n\tTStore,\n\tTSDK\n> {\n\tprotected constructor(sdk: TSDK) {\n\t\tsuper(sdk)\n\t}\n\n\tabstract initAuth(payload: object): Promise<void>\n\n\tabstract clearAuth(): void\n\n\tabstract prepareAuth(): Promise<void>\n\n\tabstract getAuthHeader(): string\n\n\tabstract handleUnauthorized(request: SuperAgentRequest, response: Response): Promise<void>\n}\n","import { markForDeletion, resetStore, setLoggedIn } from \"../../store\"\nimport { RESET_STATE } from \"@redux-offline/redux-offline/lib/constants\"\nimport request from \"superagent\"\nimport jwtDecode, { JwtPayload } from \"jwt-decode\"\nimport type { BaseState } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport { v4 as uuidv4 } from \"uuid\"\nimport { APIError } from \"../errors\"\nimport type { BaseSDK } from \"../base\"\nimport type { TokenPair } from \"../typings\"\nimport { BaseAuthService } from \"./BaseAuthService\"\n\n// Number of seconds until expiry that we consider as \"expiring soon\"\nconst EXPIRING_SOON_THRESHOLD = 1800\n\n// TODO: Rename `accessToken` and `refreshToken` to `access` and `refresh` respectively, then remove this function and\n// just return the response directly.\nfunction parseTokens(response: { access: string; refresh: string }): TokenPair {\n\tif (!response.access) throw new Error(\"Missing access token\")\n\tif (!response.refresh) throw new Error(\"Missing refresh token\")\n\treturn { accessToken: response.access, refreshToken: response.refresh }\n}\n\n/**\n * Handles login, logout and renewing tokens\n */\nexport abstract class JWTService<TState extends BaseState, TSDK extends BaseSDK<TState>> extends BaseAuthService<\n\tTState,\n\tTSDK\n> {\n\t// AUTH below\n\tprotected abstract initTokensUrl: string\n\tprotected abstract refreshTokensUrl: string\n\tprotected abstract setTokens: (tokens: TokenPair) => void\n\tprotected abstract clearTokens: () => void\n\tprotected abstract getAccessToken: () => string\n\tprotected abstract getRefreshToken: () => string\n\n\t// _getTokenPair and _getRenewedTokens don't need to use enqueueRequest from the BaseApiService because\n\t// they are very simple. However, if we need robust error handling or want these operations to queue in the Outbox,\n\t// we will use enqueueRequest.\n\n\t/**\n\t * Takes refresh token and gets a new token pair\n\t * @async\n\t * @param {string} refreshToken The refresh token used to get new tokens\n\t * @returns {Promise<TokenPair>} The new access and refresh tokens\n\t */\n\tprivate _getRenewedTokens = async (refreshToken: string): Promise<TokenPair | undefined> => {\n\t\tinterface MaybeTokenPair {\n\t\t\taccess?: string\n\t\t\trefresh?: string\n\t\t}\n\n\t\tconst promise = this.enqueueRequest<MaybeTokenPair>({\n\t\t\tdescription: \"Get renewed tokens\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: this.refreshTokensUrl,\n\t\t\tpayload: { refresh: refreshToken },\n\t\t\tisAuthNeeded: false,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t\t// Don't wait for an auth check since this is a refresh token request.\n\t\t\tcheckAuth: false,\n\t\t\t// Don't wait for other requests to finish, or we might end up in a deadlock.\n\t\t\timmediate: true,\n\t\t})\n\n\t\tlet response: MaybeTokenPair | undefined = undefined\n\t\ttry {\n\t\t\tresponse = await promise\n\t\t} catch (e) {\n\t\t\t// TODO: See TODOs in `renewTokens`\n\t\t\t// Log out if the request fails\n\t\t\tconsole.error(\"Could not renew tokens; clearing auth\", e)\n\t\t\tthis.clearAuth()\n\t\t\treturn undefined\n\t\t}\n\n\t\tif (!response.access) throw new Error(\"Missing access token\")\n\n\t\treturn { accessToken: response.access, refreshToken: response.refresh ?? this.getRefreshToken() }\n\t}\n\n\t/**\n\t * Logs the user out\n\t */\n\tclearAuth() {\n\t\t// This also sends an action to the store.ts rootReducer function, allowing\n\t\t// the store to be reset upon sending an undefined state to the other\n\t\t// reducers.\n\t\tconsole.debug(this.constructor.name, \"clearing auth;\")\n\n\t\tthis.dispatch(setLoggedIn(false))\n\t\tthis.clearTokens()\n\t\t// Clear the outbox\n\t\tthis.dispatch({ type: RESET_STATE })\n\t\t// TODO: Consider using only one of the two approaches\n\t\t// For good measure:\n\t\tthis.dispatch({ type: resetStore })\n\t}\n\n\t/**\n\t * Attempts to renew tokens\n\t */\n\tasync renewTokens() {\n\t\tconst dyingRefreshToken = this.getRefreshToken()\n\t\tif (!dyingRefreshToken) {\n\t\t\tthrow new Error(\"No refresh token found\")\n\t\t}\n\n\t\tconsole.debug(this.constructor.name, \"renewing tokens\")\n\n\t\ttry {\n\t\t\tconst tokens = await this._getRenewedTokens(dyingRefreshToken)\n\t\t\tif (!tokens) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tconsole.log(\"Got renewed tokens\")\n\t\t\tthis.setTokens(tokens)\n\t\t} catch (e) {\n\t\t\t// TODO: Why is this not being triggered when the request fails inside _getRenewedTokens?\n\t\t\t// TODO: This is temporary behaviour, replace it with login button on outbox failed requests\n\t\t\t// that failed because of a 401 Unauthorized\n\t\t\tconsole.error(\"Could not renew tokens; clearing auth\", e)\n\t\t\tthis.clearAuth()\n\t\t\tthrow e\n\t\t}\n\t}\n\n\ttokenIsExpiringSoon(): boolean {\n\t\tconst accessToken = this.getAccessToken()\n\t\tif (!accessToken) {\n\t\t\t// If the access token doesn't exist, it's not expiring.\n\t\t\treturn false\n\t\t}\n\t\t// Convert the current date from milliseconds to seconds (divide by 1000)\n\t\tconst currentDate = Date.now() / 1000\n\t\t// Find the expiration date of access token (in seconds)\n\t\tlet expiryDate: number\n\t\t// jwtDecode may throw an error if the access token is an empty string (logged out)\n\t\ttry {\n\t\t\t// REASON: Bad types\n\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error,@typescript-eslint/ban-ts-comment\n\t\t\t// @ts-ignore\n\n\t\t\texpiryDate = jwtDecode<JwtPayload>(accessToken).exp ?? currentDate\n\t\t} catch {\n\t\t\t// Enforce expiration if unable to decode token\n\t\t\texpiryDate = currentDate\n\t\t}\n\t\tconst secondsUntilExpiry = expiryDate - currentDate\n\t\treturn secondsUntilExpiry < EXPIRING_SOON_THRESHOLD\n\t}\n\n\tpublic getAuthHeader() {\n\t\tconst accessToken = this.getAccessToken()\n\t\treturn `Bearer ${accessToken}`\n\t}\n\n\tpublic async prepareAuth() {\n\t\tif (!this.tokenIsExpiringSoon()) return\n\n\t\tconsole.debug(this.constructor.name, \"preparing auth\")\n\t\ttry {\n\t\t\tawait this.renewTokens()\n\t\t} catch (e) {\n\t\t\tif (e instanceof APIError) {\n\t\t\t\t// Renewing tokens has failed; we should sign out the user.\n\t\t\t\tthis.clearAuth()\n\t\t\t}\n\t\t\treturn Promise.reject(e)\n\t\t}\n\t}\n\n\t/* if not successfull in gracefully handling an unauthorized response, throw and APIError */\n\tpublic async handleUnauthorized(request: request.SuperAgentRequest, response: request.Response) {\n\t\tconst state = this.client.store.getState()\n\t\t// Without this check, we end up in a loop:\n\t\t// client.auth.renewTokens() -> enqueue -> performRequest -> status === 401 -> client.auth.renewTokens()\n\t\t// See [1] below\n\t\tif (request.url.endsWith(\"/token/refresh/\")) {\n\t\t\t// If the refresh token has expired, we can't do anything.\n\t\t\tif (state.authReducer.isLoggedIn) {\n\t\t\t\t// This is only expected when signing in for the first time with invalid credentials.\n\t\t\t\tconsole.warn(\"No signed-in user to sign out.\")\n\t\t\t}\n\t\t\tthis.clearAuth()\n\t\t\tthrow new APIError({\n\t\t\t\tmessage: \"You have been signed out due to inactivity.\",\n\t\t\t\tresponse: response,\n\t\t\t\tdiscard: true,\n\t\t\t})\n\t\t}\n\t\tif (state.authReducer.isLoggedIn) {\n\t\t\tawait this.renewTokens()\n\t\t} else {\n\t\t\t// If the user is not logged in, we can't renew tokens.\n\t\t\t// Assume this is a login attempt with invalid credentials.\n\t\t\tconsole.debug(\"Forbidden; user is not logged in.\")\n\t\t\tthrow new APIError({\n\t\t\t\tmessage: \"Incorrect username or password.\",\n\t\t\t\tresponse: response,\n\t\t\t\tdiscard: true,\n\t\t\t})\n\t\t}\n\t}\n\n\tasync initAuth(payload: object): Promise<undefined> {\n\t\t// false: Don't log out on failure because we're not currently logged in. Instead, throw and show an error.\n\t\tconst uuid = uuidv4()\n\n\t\tconsole.debug(this.constructor.name, \"Initiating auth\")\n\t\tconst promise = this.enqueueRequest<{ access: string; refresh: string }>({\n\t\t\tuuid,\n\t\t\tdescription: \"Get token pair\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: this.initTokensUrl,\n\t\t\tpayload: payload,\n\t\t\tisAuthNeeded: false,\n\t\t\tcheckAuth: false,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t}).then(parseTokens)\n\n\t\t// The goal: Cancel the request if it takes too long\n\t\tconst timeout = 5 // seconds\n\t\tlet timedOut = false\n\n\t\tconst timeoutPromise = new Promise<undefined>((_, reject) => {\n\t\t\tsetTimeout(() => {\n\t\t\t\ttimedOut = true\n\t\t\t\tthis.dispatch(markForDeletion(uuid))\n\t\t\t\treject(new APIError({ message: `Request timed out after ${timeout} seconds` }))\n\t\t\t}, timeout * 1000)\n\t\t})\n\n\t\tconst successPromise: Promise<undefined> = promise.then((tokens) => {\n\t\t\tif (timedOut) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tthis.setTokens(tokens)\n\t\t})\n\n\t\treturn Promise.race([timeoutPromise, successPromise])\n\t}\n}\n","import type { BaseSDK } from \"../base\"\nimport type { BaseState } from \"../../typings\"\nimport { BaseAuthService } from \"./BaseAuthService\"\nimport { BaseService } from \"./BaseService\"\n\n/**\n * Abstract base class for building a service that can enqueue API requests\n */\nexport abstract class BaseApiService<TStore extends BaseState, TSDK extends BaseSDK<TStore>> extends BaseService<\n\tTStore,\n\tTSDK\n> {\n\treadonly auth: BaseAuthService<TStore, TSDK>\n\n\tconstructor(sdk: TSDK, auth: BaseAuthService<TStore, TSDK>) {\n\t\tsuper(sdk)\n\t\tthis.auth = auth\n\t}\n}\n","import type { Category, Created, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport { addCategory, deleteCategory, initializeCategories, selectCategoryById, updateCategory } from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class CategoryService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<Category>): OptimisticModelResult<Category> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineCategory: Stored<Category> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addCategory(offlineCategory))\n\n\t\tconst promise = this.enqueueRequest<Created<Category>>({\n\t\t\tdescription: \"Create Category\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/categories/\",\n\t\t\tpayload: offlineCategory,\n\t\t\tblockers: [payload.workspace],\n\t\t\tblocks: [offlineCategory.offline_id],\n\t\t})\n\t\treturn [offlineCategory, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Category>>>): OptimisticModelResult<Category> {\n\t\tconst state = this.client.store.getState()\n\t\tconst existingCategory = selectCategoryById(payload.offline_id)(state)\n\n\t\tif (!existingCategory) {\n\t\t\tthrow new Error(`Expected an existing category with offline_id ${payload.offline_id}`)\n\t\t}\n\n\t\tconst optimisticCategory: Stored<Category> = { ...existingCategory, ...payload }\n\n\t\tthis.dispatch(updateCategory(optimisticCategory))\n\n\t\tconst promise = this.enqueueRequest<Created<Category>>({\n\t\t\tdescription: \"Edit Category\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/categories/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\treturn [optimisticCategory, promise]\n\t}\n\n\tremove(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst category = selectCategoryById(id)(store.getState())\n\n\t\tif (!category) {\n\t\t\tthrow new Error(`No category with id ${id} found in the store`)\n\t\t}\n\n\t\tthis.dispatch(deleteCategory(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete Category\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/categories/${category.offline_id}/`,\n\t\t\tblockers: [category.offline_id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addCategory(category))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<Created<Category>[]>({\n\t\t\tdescription: \"Get categories\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/categories/`,\n\t\t\tblocks: [],\n\t\t\tblockers: [],\n\t\t})\n\t\tthis.dispatch(initializeCategories(result))\n\t}\n}\n","export function chunkArray<T>(arr: T[], chunkSize: number) {\n\tconst chunks: T[][] = []\n\tlet index = 0\n\tconst arrLength = arr.length\n\n\twhile (index < arrLength) {\n\t\tchunks.push(arr.slice(index, (index += chunkSize)))\n\t}\n\n\treturn chunks\n}\n","import { v4 as uuidv4 } from \"uuid\"\nimport type { Asset, Created, Offline, OvermapRootState, Payload, PointGeometry, Stored } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddAsset,\n\taddAssetAttachments,\n\taddAssets,\n\taddFormSubmissions,\n\taddIssueAssociations,\n\tdeleteAsset,\n\tdeleteAssetAttachments,\n\tdeleteFormSubmissions,\n\tdeleteIssueAssociations,\n\tinitializeAssets,\n\tselectAssetById,\n\tselectAttachmentsOfAsset,\n\tselectFormSubmissionsOfAsset,\n\tselectIssueAssociationsOfAsset,\n\tupdateAsset,\n} from \"../../store\"\nimport { chunkArray } from \"../../utils/array\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class AssetService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\t// Basic CRUD functions\n\tadd(payload: Payload<Asset>): OptimisticModelResult<Asset> {\n\t\tconst { store } = this.client\n\n\t\tif (!payload.canvas_marker && !payload.geo_marker) {\n\t\t\tthrow new Error(\"Asset must have either a canvas_marker or geo_marker\")\n\t\t}\n\n\t\tconst createdBy = store.getState().userReducer.currentUser!.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAsset: Stored<Asset> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addAsset(offlineAsset))\n\n\t\tconst promise = this.enqueueRequest<Created<Asset>>({\n\t\t\tdescription: \"Create asset\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/assets/\",\n\t\t\tpayload: offlineAsset,\n\t\t\tblockers: [offlineAsset.asset_type],\n\t\t\tblocks: [offlineAsset.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((createdAsset) => {\n\t\t\t\tthis.dispatch(updateAsset(createdAsset))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAsset(offlineAsset.offline_id))\n\t\t\t})\n\n\t\treturn [offlineAsset, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Asset>>>): OptimisticModelResult<Asset> {\n\t\tconst { store } = this.client\n\n\t\tconst asset = selectAssetById(payload.offline_id)(store.getState())\n\n\t\tif (!asset) {\n\t\t\tthrow new Error(`No asset with id ${payload.offline_id} found in the store`)\n\t\t}\n\n\t\tconst updatedAsset: Stored<Asset> = {\n\t\t\t...asset,\n\t\t\t...payload,\n\t\t}\n\n\t\tif (!updatedAsset.canvas_marker && !updatedAsset.geo_marker) {\n\t\t\tthrow new Error(\"Asset must have either a canvas_marker or geo_marker\")\n\t\t}\n\n\t\tthis.dispatch(updateAsset(updatedAsset))\n\n\t\tconst promise = this.enqueueRequest<Asset>({\n\t\t\tdescription: \"Edit asset\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/assets/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAsset(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateAsset(asset))\n\t\t\t})\n\n\t\treturn [updatedAsset, promise]\n\t}\n\n\tasync remove(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\t\tconst assetToBeDeleted = selectAssetById(id)(state)\n\n\t\tif (!assetToBeDeleted) throw new Error(`No asset with id ${id} found in the store`)\n\n\t\tconst attachmentsOfAssets = selectAttachmentsOfAsset(id)(state)\n\t\tconst formSubmissionsOfAssets = selectFormSubmissionsOfAsset(id)(state)\n\t\tconst issueAssociations = selectIssueAssociationsOfAsset(id)(state)\n\n\t\tthis.dispatch(deleteAsset(id))\n\n\t\t// remove any attachments of asset from the store\n\t\tif (attachmentsOfAssets.length > 0) {\n\t\t\tconst attachmentsOfAssetIds = attachmentsOfAssets.map(({ offline_id }) => offline_id)\n\t\t\tthis.dispatch(deleteAssetAttachments(attachmentsOfAssetIds))\n\t\t}\n\n\t\t// remove any form submissions of asset from the store\n\t\tif (formSubmissionsOfAssets.length > 0) {\n\t\t\tconst formSubmissionsOfAssetIds = formSubmissionsOfAssets.map(({ offline_id }) => offline_id)\n\t\t\tthis.dispatch(deleteFormSubmissions(formSubmissionsOfAssetIds))\n\t\t}\n\n\t\tif (issueAssociations.length > 0) {\n\t\t\tconst issueAssociationsIds = issueAssociations.map(({ offline_id }) => offline_id)\n\t\t\tthis.dispatch(deleteIssueAssociations(issueAssociationsIds))\n\t\t}\n\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete asset\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/assets/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t}).catch((err) => {\n\t\t\tthis.dispatch(addAsset(assetToBeDeleted))\n\t\t\tthis.dispatch(addAssetAttachments(attachmentsOfAssets))\n\t\t\tthis.dispatch(addFormSubmissions(formSubmissionsOfAssets))\n\t\t\tthis.dispatch(addIssueAssociations(issueAssociations))\n\t\t\tthrow err\n\t\t})\n\t}\n\n\tbulkAdd(\n\t\tpayloads: Omit<Payload<Asset>, \"asset_type\" | \"project\">[],\n\t\tassetTypeId: string,\n\t\tprojectId: number,\n\t\t// TODO: should we validate this?\n\t\tbatchSize: number,\n\t): Promise<Created<Asset>[]>[] {\n\t\tinterface BulkAddAssetPayload {\n\t\t\toffline_id: string\n\t\t\tlabel?: string | null\n\t\t\tdescription?: string | null\n\t\t\tgeo_marker?: PointGeometry | null\n\t\t\tcanvas_marker?: PointGeometry | null\n\t\t}\n\n\t\tinterface BulkAddAssetsPayload {\n\t\t\ttransaction_id: string\n\t\t\tassets: BulkAddAssetPayload[]\n\t\t\tasset_type: string\n\t\t\tproject: number\n\t\t\tsubmitted_at: string\n\t\t}\n\n\t\tinterface BulkAddAssetBatch {\n\t\t\tbatchId: string\n\t\t\tpayload: BulkAddAssetsPayload\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst transactionId = uuidv4()\n\n\t\tconst assetBatches: BulkAddAssetBatch[] = chunkArray(payloads, batchSize).map((assetBatch) => {\n\t\t\tconst assetPayloads: BulkAddAssetPayload[] = assetBatch.map((assetPayload) => offline(assetPayload))\n\n\t\t\treturn {\n\t\t\t\tbatchId: uuidv4(),\n\t\t\t\tpayload: {\n\t\t\t\t\ttransaction_id: transactionId,\n\t\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\t\tasset_type: assetTypeId,\n\t\t\t\t\tproject: projectId,\n\t\t\t\t\tassets: assetPayloads,\n\t\t\t\t},\n\t\t\t}\n\t\t})\n\n\t\tconst batchPromises: Promise<Created<Asset>[]>[] = []\n\t\tlet prevBatchId: string | null = null\n\n\t\tfor (const assetBatch of assetBatches) {\n\t\t\tconst { batchId, payload } = assetBatch\n\n\t\t\tconst batchAssetOfflineIds = payload.assets.map((c) => c.offline_id)\n\n\t\t\tconst blockers = [assetTypeId]\n\t\t\tif (prevBatchId) blockers.push(prevBatchId)\n\n\t\t\tconst blocks = batchAssetOfflineIds\n\t\t\tblocks.push(batchId)\n\n\t\t\tconst promise = this.enqueueRequest<Created<Asset>[]>({\n\t\t\t\tdescription: \"Batch create assets\",\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\turl: \"/assets/bulk/\",\n\t\t\t\tpayload: payload,\n\t\t\t\tblockers: blockers,\n\t\t\t\tblocks: blocks,\n\t\t\t})\n\n\t\t\tprevBatchId = assetBatch.batchId\n\n\t\t\tbatchPromises.push(promise)\n\t\t}\n\n\t\tvoid Promise.all(batchPromises).then((result) => {\n\t\t\tconst allCreatedAssets = result.flat()\n\t\t\tthis.dispatch(addAssets(allCreatedAssets))\n\t\t})\n\n\t\treturn batchPromises\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Asset[]>({\n\t\t\tdescription: \"Get assets\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/assets/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssets(result))\n\t}\n}\n","import {\n\taddAssetStageCompletion,\n\taddAssetStageCompletions,\n\tdeleteAssetStageCompletion,\n\tdeleteAssetStageCompletions,\n\tinitializeAssetStageCompletions,\n\tselectAssetStageCompletionById,\n\tselectAssetStageCompletionsByIds,\n\tupdateAssetStageCompletion,\n\tupdateAssetStageCompletions,\n} from \"../../store\"\nimport type { OptimisticModelResult, OptimisticMultipleModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport type { AssetStageCompletion, Created, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class AssetStageCompletionService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<AssetStageCompletion>): OptimisticModelResult<AssetStageCompletion> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser!.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineStageCompletion: Stored<AssetStageCompletion> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addAssetStageCompletion(offlineStageCompletion))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetStageCompletion>>({\n\t\t\tdescription: \"Add asset stage completion\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-stage-completions/\",\n\t\t\tpayload: {\n\t\t\t\toffline_id: offlineStageCompletion.offline_id,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tasset_procedure_instance: payload.asset_procedure_instance,\n\t\t\t\tasset: payload.asset,\n\t\t\t\tstage: payload.stage,\n\t\t\t},\n\t\t\tblockers: [payload.asset_procedure_instance, payload.stage],\n\t\t\tblocks: [offlineStageCompletion.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetStageCompletion(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetStageCompletion(offlineStageCompletion.offline_id))\n\t\t\t})\n\n\t\treturn [offlineStageCompletion, promise]\n\t}\n\n\tdelete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst assetStageCompletion = selectAssetStageCompletionById(id)(store.getState())\n\n\t\tif (!assetStageCompletion) {\n\t\t\tthrow new Error(`Expected asset stage completion with id ${id} to exist`)\n\t\t}\n\n\t\tthis.dispatch(deleteAssetStageCompletion(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete asset stage completion\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/asset-stage-completions/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addAssetStageCompletion(assetStageCompletion))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tbulkAdd(payloads: Payload<AssetStageCompletion>[]): OptimisticMultipleModelResult<AssetStageCompletion> {\n\t\tconst { store } = this.client\n\n\t\tinterface BulkAddAssetStageCompletionPayload {\n\t\t\toffline_id: string\n\t\t\tasset_procedure_instance: string\n\t\t\tstage: string\n\t\t\tasset: string\n\t\t}\n\n\t\tinterface BulkAddAssetStageCompletionsPayload {\n\t\t\tsubmitted_at: string\n\t\t\tcompletions: Payload<AssetStageCompletion>[]\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = store.getState().userReducer.currentUser!.id\n\n\t\tconst payload: BulkAddAssetStageCompletionPayload[] = payloads.map((payload) => offline(payload))\n\n\t\tconst offlineStageCompletions = payload.map((completion) => {\n\t\t\treturn {\n\t\t\t\t...completion,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t}\n\t\t})\n\n\t\tconst offlineIds = offlineStageCompletions.map(({ offline_id }) => offline_id)\n\n\t\tthis.dispatch(addAssetStageCompletions(offlineStageCompletions))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetStageCompletion>[]>({\n\t\t\tdescription: \"Bulk create asset stage completions\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-stage-completions/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tcompletions: payload,\n\t\t\t} satisfies BulkAddAssetStageCompletionsPayload,\n\t\t\tblockers: [...payloads.map((c) => c.asset_procedure_instance), ...payloads.map((c) => c.stage)],\n\t\t\tblocks: offlineIds,\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetStageCompletions(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetStageCompletions(offlineIds))\n\t\t\t})\n\n\t\treturn [offlineStageCompletions, promise]\n\t}\n\n\tbulkDelete(ids: string[]): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst assetStageCompletions = selectAssetStageCompletionsByIds(ids)(store.getState())\n\n\t\tthis.dispatch(deleteAssetStageCompletions(ids))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Deleting asset stage completions\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: \"/asset-stage-completions/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tcompletion_ids: ids,\n\t\t\t},\n\t\t\tblockers: ids,\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addAssetStageCompletions(assetStageCompletions))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<AssetStageCompletion>[]>({\n\t\t\tdescription: \"Get asset stage completions\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-stage-completions/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetStageCompletions(result))\n\t}\n}\n","import type { AssetStage, Created, CSSColor, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddAssetStages,\n\tdeleteAssetStages,\n\tinitializeAssetStages,\n\tselectAssetStageById,\n\tselectAssetStagesByIds,\n\tsetAssetStage,\n\tupdateAssetStage,\n\tupdateAssetStages,\n} from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\nimport type { OptimisticModelResult, OptimisticMultipleModelResult } from \"../typings\"\n\nexport abstract class AssetStageService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tbulkAdd(\n\t\tstagesToSubmit: Omit<Payload<AssetStage>, \"asset_procedure\">[],\n\t\tassetProcedureId: string,\n\t): OptimisticMultipleModelResult<AssetStage> {\n\t\tinterface BulkAddAssetStagePayload {\n\t\t\toffline_id: string\n\t\t\tname?: string | null\n\t\t\tdescription?: string | null\n\t\t\tpriority: number\n\t\t\tcolor: CSSColor\n\t\t}\n\n\t\tinterface BulkAddAssetStagesPayload {\n\t\t\tstages: BulkAddAssetStagePayload[]\n\t\t\tasset_procedure: string\n\t\t\tsubmitted_at: string\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser!.id\n\n\t\tconst payload: BulkAddAssetStagePayload[] = stagesToSubmit.map((stage) => {\n\t\t\treturn offline(stage)\n\t\t})\n\n\t\tconst offlineStages: AssetStage[] = payload.map((stage) => {\n\t\t\treturn { ...stage, asset_procedure: assetProcedureId, created_by: createdBy, submitted_at: submittedAt }\n\t\t})\n\n\t\tthis.dispatch(addAssetStages(offlineStages))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetStage>[]>({\n\t\t\tdescription: \"Add asset stages\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-stages/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tasset_procedure: assetProcedureId,\n\t\t\t\tstages: payload,\n\t\t\t} satisfies BulkAddAssetStagesPayload,\n\t\t\tblockers: [assetProcedureId],\n\t\t\tblocks: payload.map(({ offline_id }) => offline_id),\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetStages(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetStages(offlineStages.map(({ offline_id }) => offline_id)))\n\t\t\t})\n\n\t\treturn [offlineStages, promise]\n\t}\n\n\tasync bulkUpdate(stagesToUpdate: AssetStage[], assetProcedureId: string): Promise<AssetStage[]> {\n\t\tconst store = this.client.store\n\t\tconst state = store.getState()\n\t\tconst prevStages = selectAssetStagesByIds(stagesToUpdate.map(({ offline_id }) => offline_id))(state)\n\n\t\tthis.dispatch(updateAssetStages(stagesToUpdate))\n\n\t\treturn this.enqueueRequest<AssetStage[]>({\n\t\t\tdescription: \"Edit asset stages\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/asset-procedures/${assetProcedureId}/bulk-update-stages/`,\n\t\t\tpayload: {\n\t\t\t\tstages: stagesToUpdate,\n\t\t\t},\n\t\t\tblockers: [assetProcedureId],\n\t\t\tblocks: stagesToUpdate.map(({ offline_id }) => offline_id),\n\t\t}).catch((e) => {\n\t\t\t// restore stages in store if request fails\n\t\t\tthis.dispatch(updateAssetStages(prevStages))\n\t\t\tthrow e\n\t\t})\n\t}\n\n\tasync bulkDelete(idsToDelete: string[]): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst assetStages = selectAssetStagesByIds(idsToDelete)(store.getState())\n\n\t\tthis.dispatch(deleteAssetStages(idsToDelete))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete asset stages\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: \"/asset-stages/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tstage_ids: idsToDelete,\n\t\t\t},\n\t\t\tblockers: idsToDelete,\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addAssetStages(assetStages))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<AssetStage>>>): OptimisticModelResult<AssetStage> {\n\t\tconst { store } = this.client\n\n\t\tconst assetStage = selectAssetStageById(payload.offline_id)(store.getState())\n\n\t\tif (!assetStage) throw new Error(`No asset stage with id ${payload.offline_id} found in the store`)\n\n\t\tconst updatedAssetStage: Stored<AssetStage> = {\n\t\t\t...assetStage,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateAssetStage(updatedAssetStage))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetStage>>({\n\t\t\tdescription: \"Update asset stage\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/asset-stages/${assetStage.offline_id}/`,\n\t\t\tpayload: {\n\t\t\t\tname: payload.name,\n\t\t\t\tdescription: payload.description,\n\t\t\t\tpriority: payload.priority,\n\t\t\t\tcolor: payload.color,\n\t\t\t},\n\t\t\tblockers: [assetStage.offline_id],\n\t\t\tblocks: [assetStage.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetStage(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(setAssetStage(assetStage))\n\t\t\t})\n\n\t\treturn [updatedAssetStage, promise]\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<AssetStage[]>({\n\t\t\tdescription: \"Get asset stages\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-stages/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetStages(result))\n\t}\n}\n","import { BaseApiService } from \"./BaseApiService\"\nimport { HttpMethod } from \"../../enums\"\nimport type { PresignedUrlsResponse, SDKRequest } from \"../typings\"\nimport type { FilePayload, OvermapRootState } from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { hashFile } from \"../../utils\"\n\nexport abstract class BaseUploadService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tprotected getNumberOfAttachmentsWithSha1(sha1: string) {\n\t\tconst {\n\t\t\tissueAttachmentReducer,\n\t\t\tassetAttachmentReducer,\n\t\t\tassetTypeAttachmentReducer,\n\t\t\tdocumentAttachmentReducer,\n\t\t\tprojectAttachmentReducer,\n\t\t\tformRevisionAttachmentReducer,\n\t\t\tformSubmissionAttachmentReducer,\n\t\t\tgeoImageReducer,\n\t\t\t// fields\n\t\t\tassetTypeFieldsAttachmentReducer,\n\t\t\tassetTypeFieldValuesAttachmentReducer,\n\t\t\tissueTypeFieldsAttachmentReducer,\n\t\t\tissueTypeFieldValuesAttachmentReducer,\n\t\t} = this.client.store.getState()\n\n\t\t// creating an array of objects with the file_sha1 property\n\t\t// TODO: @Audiopolis, probably makes sense to also include projectFiles in here?\n\t\tconst objectsWithSha1: { file_sha1: string }[] = ([] as { file_sha1: string }[]).concat(\n\t\t\tObject.values(issueAttachmentReducer.instances),\n\t\t\tObject.values(assetAttachmentReducer.instances),\n\t\t\tObject.values(assetTypeAttachmentReducer.instances),\n\t\t\tObject.values(documentAttachmentReducer.instances),\n\t\t\tObject.values(projectAttachmentReducer.instances),\n\t\t\tObject.values(formRevisionAttachmentReducer.instances),\n\t\t\tObject.values(formSubmissionAttachmentReducer.instances),\n\t\t\tObject.values(geoImageReducer.instances),\n\t\t\tObject.values(assetTypeFieldsAttachmentReducer.instances),\n\t\t\tObject.values(assetTypeFieldValuesAttachmentReducer.instances),\n\t\t\tObject.values(issueTypeFieldsAttachmentReducer.instances),\n\t\t\tObject.values(issueTypeFieldValuesAttachmentReducer.instances),\n\t\t)\n\n\t\treturn objectsWithSha1.filter((object) => object.file_sha1 === sha1).length\n\t}\n\n\tprotected processPresignedUrls(presignedUrls: PresignedUrlsResponse): Record<string, Promise<undefined>> {\n\t\tconst promisesBySha1: Record<string, Promise<undefined>> = {}\n\n\t\tfor (const [sha1, presignedUrl] of Object.entries(presignedUrls)) {\n\t\t\tpromisesBySha1[sha1] = this.enqueueRequest<undefined>({\n\t\t\t\turl: presignedUrl.url,\n\t\t\t\tdescription: \"Upload file to S3\",\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\tisExternalUrl: true,\n\t\t\t\tisAuthNeeded: false,\n\t\t\t\tattachmentHash: sha1,\n\t\t\t\t// TODO: can we use the sha1 as the blocker?\n\t\t\t\tblockers: [`s3-${presignedUrl.fields.key}`],\n\t\t\t\tblocks: [sha1],\n\t\t\t\ts3url: presignedUrl,\n\t\t\t} satisfies SDKRequest)\n\t\t}\n\n\t\treturn promisesBySha1\n\t}\n\n\tprotected async getFilePayload(file: File): Promise<FilePayload> {\n\t\tconst sha1 = await hashFile(file)\n\n\t\tconst filePayload: FilePayload = {\n\t\t\tsha1,\n\t\t\tfile_type: file.type,\n\t\t\textension: file.name.split(\".\").pop()!,\n\t\t\tsize: file.size,\n\t\t}\n\n\t\tawait this.client.files.addCache(file, sha1)\n\n\t\treturn filePayload\n\t}\n}\n","import { ActionCreatorWithPayload } from \"@reduxjs/toolkit\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport type {\n\tAttachment,\n\tCreated,\n\tFileModelPayload,\n\tFilePayload,\n\tOfflineModel,\n\tOvermapRootState,\n\tOvermapSelectorWithArgs,\n\tStored,\n\tSubmitted,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\n\nexport interface AttachmentPayload extends FileModelPayload {\n\toffline_id: OfflineModel[\"offline_id\"]\n\tdescription: Attachment[\"description\"]\n}\n\nexport interface BuildOfflineAttachmentData<TModelId> {\n\tfile: File\n\t// passing sha1 here so dont have to hash multiple times\n\tfile_sha1: string\n\tsubmitted_at: string\n\tcreated_by?: number\n\tdescription?: string\n\t// this the offline_id passed in from the bulkAdd method\n\tmodelId: TModelId\n}\n\nexport interface BuildAttachmentPayloadData<TModelId> extends AttachmentPayload {\n\tmodelId: TModelId\n}\n\nexport abstract class BaseAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n\tTModelId extends string | number,\n\tTAttachment extends Attachment,\n\tTAttachmentPayload extends AttachmentPayload,\n> extends BaseUploadService<TState, TSDK> {\n\tabstract readonly name: string\n\tabstract readonly url: string\n\n\t// redux actions\n\tabstract readonly addAttachments: ActionCreatorWithPayload<Submitted<TAttachment>[]>\n\tabstract readonly updateAttachments: ActionCreatorWithPayload<Submitted<TAttachment>[]>\n\tabstract readonly removeAttachments: ActionCreatorWithPayload<string[]>\n\tabstract readonly setAttachment: ActionCreatorWithPayload<Stored<TAttachment>>\n\tabstract readonly removeAttachment: ActionCreatorWithPayload<string>\n\n\t// redux selectors\n\tabstract readonly selectAttachment: OvermapSelectorWithArgs<string, Stored<TAttachment> | undefined>\n\n\tprotected abstract buildOfflineAttachment(data: BuildOfflineAttachmentData<TModelId>): Stored<TAttachment>\n\n\tprotected abstract buildAttachmentPayload(data: BuildAttachmentPayloadData<TModelId>): TAttachmentPayload\n\n\tasync _bulkAdd(payloads: { modelId: TModelId; file: File }[]): Promise<OptimisticMultipleModelResult<TAttachment>> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAttachments: Stored<TAttachment>[] = []\n\t\tconst attachmentPayloads: TAttachmentPayload[] = []\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\n\t\tfor (const payload of payloads) {\n\t\t\tconst { modelId, file } = payload\n\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\tif (!(filePayload.sha1 in filePayloads)) filePayloads[filePayload.sha1] = filePayload\n\n\t\t\tconst offlineAttachment = this.buildOfflineAttachment({\n\t\t\t\tfile,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tdescription: \"\",\n\t\t\t\tmodelId: modelId,\n\t\t\t})\n\t\t\tofflineAttachments.push(offlineAttachment)\n\n\t\t\tattachmentPayloads.push(\n\t\t\t\tthis.buildAttachmentPayload({\n\t\t\t\t\toffline_id: offlineAttachment.offline_id,\n\t\t\t\t\tfile_name: offlineAttachment.file_name,\n\t\t\t\t\tfile_sha1: offlineAttachment.file_sha1,\n\t\t\t\t\tfile_extension: filePayload.extension,\n\t\t\t\t\tdescription: offlineAttachment.description,\n\t\t\t\t\tmodelId: modelId,\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\n\t\tthis.dispatch(this.addAttachments(offlineAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<TAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: `Add ${this.name}`,\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `${this.url}/bulk/`,\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblocks: offlineAttachments.map((attachment) => attachment.offline_id),\n\t\t\tblockers: offlineAttachments.map((attachment) => attachment.file_sha1),\n\t\t})\n\n\t\tpromise\n\t\t\t.then(({ attachments, presigned_urls }) => {\n\t\t\t\tthis.dispatch(this.updateAttachments(attachments))\n\t\t\t\tthis.processPresignedUrls(presigned_urls)\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(this.removeAttachments(offlineAttachments.map((attachment) => attachment.offline_id)))\n\t\t\t})\n\n\t\treturn [offlineAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tasync _delete(attachmendId: string): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst attachment = this.selectAttachment(attachmendId)(store.getState())\n\n\t\tif (!attachment) {\n\t\t\tthrow new Error(\n\t\t\t\t`Attempting to delete attachment with offline_id ${attachmendId} that does not exist in the store`,\n\t\t\t)\n\t\t}\n\n\t\tthis.dispatch(this.removeAttachment(attachment.offline_id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: `Delete ${this.name}`,\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `${this.url}/${attachmendId}/`,\n\t\t\tblockers: [attachmendId],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise\n\t\t\t.then(() => {\n\t\t\t\tif (this.getNumberOfAttachmentsWithSha1(attachment.file_sha1) === 0) {\n\t\t\t\t\tvoid this.client.files.removeCache(attachment.file_sha1)\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(this.setAttachment(attachment))\n\t\t\t})\n\n\t\treturn promise\n\t}\n}\n","import {\n\tAttachmentPayload,\n\tBaseAttachmentService,\n\tBuildAttachmentPayloadData,\n\tBuildOfflineAttachmentData,\n} from \"./BaseAttachmentService\"\nimport type { AssetAttachment, Created, OvermapRootState, Stored } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport type { OptimisticMultipleModelResult } from \"../typings\"\nimport {\n\taddAssetAttachments,\n\tdeleteAssetAttachment,\n\tdeleteAssetAttachments,\n\tinitializeAssetAttachments,\n\tselectAssetAttachmentById,\n\tsetAssetAttachment,\n\tupdateAssetAttachments,\n} from \"../../store\"\nimport type { BaseSDK } from \"../base\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class AssetAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseAttachmentService<TState, TSDK, string, AssetAttachment, AttachmentPayload & { asset: string }> {\n\tname = \"Asset Attachment\"\n\turl = \"/asset-attachments\"\n\n\tinitializeAttachments = initializeAssetAttachments\n\taddAttachments = addAssetAttachments\n\tupdateAttachments = updateAssetAttachments\n\tremoveAttachments = deleteAssetAttachments\n\tremoveAttachment = deleteAssetAttachment\n\tsetAttachment = setAssetAttachment\n\n\tselectAttachment = selectAssetAttachmentById\n\n\tprotected buildOfflineAttachment(data: BuildOfflineAttachmentData<string>) {\n\t\treturn offline({\n\t\t\tfile: URL.createObjectURL(data.file),\n\t\t\tfile_sha1: data.file_sha1,\n\t\t\tcreated_by: data.created_by,\n\t\t\tfile_name: data.file.name,\n\t\t\tfile_type: data.file.type,\n\t\t\tsubmitted_at: data.submitted_at,\n\t\t\tdescription: data.description,\n\t\t\tasset: data.modelId,\n\t\t}) satisfies Stored<AssetAttachment>\n\t}\n\n\tprotected buildAttachmentPayload(data: BuildAttachmentPayloadData<string>) {\n\t\treturn {\n\t\t\t...data,\n\t\t\tasset: data.modelId,\n\t\t} satisfies AttachmentPayload & { asset: string }\n\t}\n\n\tasync bulkAdd(\n\t\tpayloads: { assetId: string; file: File }[],\n\t): Promise<OptimisticMultipleModelResult<AssetAttachment>> {\n\t\treturn this._bulkAdd(payloads.map((p) => ({ modelId: p.assetId, file: p.file })))\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\treturn this._delete(id)\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<AssetAttachment>[]>({\n\t\t\tdescription: \"Get asset attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `${this.url}/`,\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblocks: [],\n\t\t\tblockers: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetAttachments(result))\n\t}\n}\n","import { offline } from \"../../utils\"\nimport {\n\taddAssets,\n\taddAssetStages,\n\taddAssetType,\n\taddAssetTypeAttachments,\n\tdeleteAssets,\n\tdeleteAssetStages,\n\tdeleteAssetType,\n\tdeleteAssetTypeAttachments,\n\tinitializeAssetTypes,\n\tselectAssetsOfAssetType,\n\tselectAssetTypeById,\n\tselectAttachmentsOfAssetType,\n\tselectAssetStagesOfAssetProcedure,\n\tupdateAssetType,\n} from \"../../store\"\nimport type { AssetStage, AssetType, Created, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class AssetTypeService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<AssetType>): OptimisticModelResult<AssetType> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser!.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAssetType: Stored<AssetType> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addAssetType(offlineAssetType))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetType>>({\n\t\t\tdescription: \"Create asset type\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-types/\",\n\t\t\tpayload: offlineAssetType,\n\t\t\tblockers: [],\n\t\t\tblocks: [offlineAssetType.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetType(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetType(offlineAssetType.offline_id))\n\t\t\t})\n\n\t\treturn [offlineAssetType, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<AssetType>>>): OptimisticModelResult<AssetType> {\n\t\tconst { store } = this.client\n\n\t\tconst assetType = selectAssetTypeById(payload.offline_id)(store.getState())\n\n\t\tif (!assetType) {\n\t\t\tthrow new Error(`Expected asset type with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst updatedAssetType: Stored<AssetType> = {\n\t\t\t...assetType,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateAssetType(updatedAssetType))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetType>>({\n\t\t\tdescription: \"Update asset type\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/asset-types/${payload.offline_id}/`,\n\t\t\tpayload: {\n\t\t\t\ticon: payload.icon,\n\t\t\t\tcolor: payload.color,\n\t\t\t\tname: payload.name,\n\t\t\t\tdescription: payload.description,\n\t\t\t},\n\t\t\tblockers: [assetType.offline_id],\n\t\t\tblocks: [assetType.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetType(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateAssetType(assetType))\n\t\t\t})\n\n\t\treturn [updatedAssetType, promise]\n\t}\n\n\tasync delete(assetTypeId: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst assetType = selectAssetTypeById(assetTypeId)(state)\n\n\t\tif (!assetType) {\n\t\t\tthrow new Error(`Expected asset type with offline_id ${assetTypeId} to exist`)\n\t\t}\n\n\t\tconst assetsOfAssetType = selectAssetsOfAssetType(assetTypeId)(state)\n\t\tconst stagesOfAssetType = selectAssetStagesOfAssetProcedure(assetTypeId)(state)\n\t\tconst attachmentsOfAssetType = selectAttachmentsOfAssetType(assetTypeId)(state)\n\n\t\tthis.dispatch(deleteAssetType(assetTypeId))\n\t\tthis.dispatch(deleteAssets(assetsOfAssetType.map((asset) => asset.offline_id)))\n\t\tthis.dispatch(deleteAssetStages(stagesOfAssetType.map((assetStage: AssetStage) => assetStage.offline_id)))\n\t\tthis.dispatch(deleteAssetTypeAttachments(attachmentsOfAssetType.map(({ offline_id }) => offline_id)))\n\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete asset type\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/asset-types/${assetTypeId}/`,\n\t\t\tblockers: [assetTypeId],\n\t\t\tblocks: [],\n\t\t}).catch((e) => {\n\t\t\tthis.dispatch(addAssetType(assetType))\n\t\t\tthis.dispatch(addAssets(assetsOfAssetType))\n\t\t\tthis.dispatch(addAssetStages(stagesOfAssetType))\n\t\t\tthis.dispatch(addAssetTypeAttachments(attachmentsOfAssetType))\n\t\t\tthrow e\n\t\t})\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<AssetType[]>({\n\t\t\tdescription: \"Get asset types\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-types/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(initializeAssetTypes(result))\n\t}\n}\n","import {\n\tAttachmentPayload,\n\tBaseAttachmentService,\n\tBuildAttachmentPayloadData,\n\tBuildOfflineAttachmentData,\n} from \"./BaseAttachmentService\"\nimport {\n\taddAssetTypeAttachments,\n\tdeleteAssetTypeAttachment,\n\tdeleteAssetTypeAttachments,\n\tinitializeAssetTypeAttachments,\n\tselectAssetTypeAttachmentById,\n\tsetAssetTypeAttachment,\n\tupdateAssetTypeAttachments,\n} from \"../../store\"\nimport type { AssetTypeAttachment, Created, OvermapRootState, Stored } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport type { OptimisticMultipleModelResult } from \"../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class AssetTypeAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseAttachmentService<TState, TSDK, string, AssetTypeAttachment, AttachmentPayload & { asset_type: string }> {\n\tname = \"Asset Type Attachment\"\n\turl = \"/asset-type-attachments\"\n\n\taddAttachments = addAssetTypeAttachments\n\tupdateAttachments = updateAssetTypeAttachments\n\tremoveAttachments = deleteAssetTypeAttachments\n\tremoveAttachment = deleteAssetTypeAttachment\n\tsetAttachment = setAssetTypeAttachment\n\n\tselectAttachment = selectAssetTypeAttachmentById\n\n\tprotected buildOfflineAttachment(data: BuildOfflineAttachmentData<string>) {\n\t\treturn offline({\n\t\t\tfile: URL.createObjectURL(data.file),\n\t\t\tfile_sha1: data.file_sha1,\n\t\t\tcreated_by: data.created_by,\n\t\t\tfile_name: data.file.name,\n\t\t\tfile_type: data.file.type,\n\t\t\tsubmitted_at: data.submitted_at,\n\t\t\tdescription: data.description,\n\t\t\tasset_type: data.modelId,\n\t\t}) satisfies Stored<AssetTypeAttachment>\n\t}\n\n\tprotected buildAttachmentPayload(data: BuildAttachmentPayloadData<string>) {\n\t\treturn {\n\t\t\t...data,\n\t\t\tasset_type: data.modelId,\n\t\t} satisfies AttachmentPayload & { asset_type: string }\n\t}\n\n\tasync bulkAdd(\n\t\tpayloads: {\n\t\t\tassetTypeId: string\n\t\t\tfile: File\n\t\t}[],\n\t): Promise<OptimisticMultipleModelResult<AssetTypeAttachment>> {\n\t\treturn this._bulkAdd(payloads.map((p) => ({ modelId: p.assetTypeId, file: p.file })))\n\t}\n\n\tasync delete(attachmentId: string): Promise<void> {\n\t\treturn this._delete(attachmentId)\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<AssetTypeAttachment>[]>({\n\t\t\tdescription: \"Get asset type attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `${this.url}/`,\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblocks: [],\n\t\t\tblockers: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetTypeAttachments(result))\n\t}\n}\n","import type { Created, IssueComment, Offline, OvermapRootState, Payload, Stored, Submitted } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddIssueComment,\n\tdeleteIssueComment,\n\tselectIssueCommentById,\n\tsetIssueComment,\n\tsetIssueComments,\n} from \"../../store\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class IssueCommentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Omit<Payload<IssueComment>, \"author\">): OptimisticModelResult<IssueComment> {\n\t\tconst { store } = this.client\n\n\t\tconst offlineComment: Submitted<IssueComment> = offline({\n\t\t\t...payload,\n\t\t\tauthor: store.getState().userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t})\n\n\t\tthis.dispatch(addIssueComment(offlineComment))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueComment>>({\n\t\t\tdescription: \"Add issue comment\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/issue-comments/\",\n\t\t\tpayload: offlineComment,\n\t\t\tblockers: [payload.issue],\n\t\t\tblocks: [offlineComment.offline_id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(deleteIssueComment(offlineComment.offline_id))\n\t\t})\n\n\t\treturn [offlineComment, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<IssueComment>>>): OptimisticModelResult<IssueComment> {\n\t\tconst { store } = this.client\n\n\t\tconst commentToUpdate = selectIssueCommentById(payload.offline_id)(store.getState())\n\n\t\tif (!commentToUpdate) {\n\t\t\tthrow new Error(`Comment with offline_id ${payload.offline_id} not found in store`)\n\t\t}\n\n\t\tconst updatedComment: Stored<IssueComment> = {\n\t\t\t...commentToUpdate,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(setIssueComment(updatedComment))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueComment>>({\n\t\t\tdescription: \"Edit issue comment\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/issue-comments/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(setIssueComment(commentToUpdate))\n\t\t})\n\n\t\treturn [updatedComment, promise]\n\t}\n\n\tremove(id: string): Promise<undefined> {\n\t\tconst commentToRemove = this.client.store.getState().issueCommentReducer.instances[id]\n\n\t\tif (!commentToRemove) {\n\t\t\tthrow new Error(`Comment with offline_id ${id} not found in store`)\n\t\t}\n\n\t\tthis.dispatch(deleteIssueComment(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete comment\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/issue-comments/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addIssueComment(commentToRemove))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<IssueComment>[]>({\n\t\t\tdescription: \"Get comments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/issue-comments/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(setIssueComments(result))\n\t}\n}\n","import type { Created, IssueUpdate, OvermapRootState } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport { initializeIssueUpdates } from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class IssueUpdateService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<IssueUpdate>[]>({\n\t\t\tdescription: \"Get issue updates\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/issue-updates/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssueUpdates(result))\n\t}\n}\n","import {\n\tAttachmentPayload,\n\tBaseAttachmentService,\n\tBuildAttachmentPayloadData,\n\tBuildOfflineAttachmentData,\n} from \"./BaseAttachmentService\"\nimport type { OptimisticMultipleModelResult } from \"../typings\"\nimport type { Created, IssueAttachment, OvermapRootState, Stored } from \"../../typings\"\nimport {\n\taddIssueAttachments,\n\tdeleteIssueAttachment,\n\tdeleteIssueAttachments,\n\tinitializeIssueAttachments,\n\tselectIssueAttachmentById,\n\tsetIssueAttachment,\n\tupdateIssueAttachments,\n} from \"../../store\"\nimport { offline } from \"../../utils\"\nimport type { BaseSDK } from \"../base\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class IssueAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseAttachmentService<TState, TSDK, string, IssueAttachment, AttachmentPayload & { issue: string }> {\n\tname = \"Issue Attachment\"\n\turl = \"/issue-attachments\"\n\n\taddAttachments = addIssueAttachments\n\tupdateAttachments = updateIssueAttachments\n\tremoveAttachments = deleteIssueAttachments\n\tremoveAttachment = deleteIssueAttachment\n\tsetAttachment = setIssueAttachment\n\n\tselectAttachment = selectIssueAttachmentById\n\n\tprotected buildOfflineAttachment(data: BuildOfflineAttachmentData<string>) {\n\t\treturn offline({\n\t\t\tfile: URL.createObjectURL(data.file),\n\t\t\tfile_sha1: data.file_sha1,\n\t\t\tcreated_by: data.created_by,\n\t\t\tfile_name: data.file.name,\n\t\t\tfile_type: data.file.type,\n\t\t\tsubmitted_at: data.submitted_at,\n\t\t\tdescription: data.description,\n\t\t\tissue: data.modelId,\n\t\t}) satisfies Stored<IssueAttachment>\n\t}\n\n\tprotected buildAttachmentPayload(data: BuildAttachmentPayloadData<string>) {\n\t\treturn {\n\t\t\t...data,\n\t\t\tissue: data.modelId,\n\t\t} satisfies AttachmentPayload & { issue: string }\n\t}\n\n\tasync bulkAdd(\n\t\tpayloads: { issueId: string; file: File }[],\n\t): Promise<OptimisticMultipleModelResult<IssueAttachment>> {\n\t\treturn this._bulkAdd(payloads.map((p) => ({ modelId: p.issueId, file: p.file })))\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\treturn this._delete(id)\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<IssueAttachment>[]>({\n\t\t\tdescription: \"Get issue attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `${this.url}/`,\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblocks: [],\n\t\t\tblockers: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssueAttachments(result))\n\t}\n}\n","import type { OptimisticModelResult } from \"../typings\"\nimport type {\n\tCategory,\n\tCreated,\n\tIssue,\n\tIssueAssociation,\n\tIssueUpdate,\n\tOffline,\n\tOvermapRootState,\n\tPayload,\n\tStored,\n\tSubmitted,\n\tUser,\n} from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddActiveProjectIssuesCount,\n\taddFormSubmissions,\n\taddIssue,\n\taddIssueAssociations,\n\taddIssueAttachments,\n\taddIssueUpdate,\n\taddIssueUpdates,\n\tdeleteFormSubmissions,\n\tdeleteIssue,\n\tdeleteIssueAssociations,\n\tdeleteIssueAttachments,\n\tdeleteIssueUpdate,\n\tdeleteIssueUpdates,\n\tinitializeIssues,\n\tselectAttachmentsOfIssue,\n\tselectFormSubmissionsOfIssue,\n\tselectIssueAssociationsOfIssue,\n\tselectIssueAssociationsToIssue,\n\tselectIssueById,\n\tselectIssueUpdatesOfIssue,\n\tupdateIssue,\n} from \"../../store\"\nimport { HttpMethod, IssueUpdateChange } from \"../../enums\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class IssueService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<Issue>): OptimisticModelResult<Issue> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = state.userReducer.currentUser?.id\n\n\t\tconst offlineIssue: Submitted<Issue> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: submittedAt,\n\t\t\tcreated_by: createdBy,\n\t\t})\n\n\t\tthis.dispatch(addIssue(offlineIssue))\n\t\tthis.dispatch(addActiveProjectIssuesCount(1))\n\n\t\tconst promise = this.enqueueRequest<Created<Issue>>({\n\t\t\tdescription: \"Create issue\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/issues/\",\n\t\t\tpayload: offlineIssue,\n\t\t\tblockers: [\"add-issue\", ...(offlineIssue.index_workspace ? [offlineIssue.index_workspace] : [])],\n\t\t\tblocks: [offlineIssue.offline_id],\n\t\t})\n\t\tvoid promise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateIssue(result)) // Updates the index in the store\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.dispatch(deleteIssue(offlineIssue.offline_id))\n\t\t\t\tthis.dispatch(addActiveProjectIssuesCount(-1))\n\t\t\t\tthrow error\n\t\t\t})\n\t\treturn [offlineIssue, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Issue>>>): OptimisticModelResult<Issue> {\n\t\tconst state = this.client.store.getState()\n\t\tconst issueToBeUpdated = selectIssueById(payload.offline_id)(state)\n\n\t\tif (!issueToBeUpdated) {\n\t\t\tthrow new Error(\n\t\t\t\t`Attempting to update an issue with offline_id ${payload.offline_id} that doesn't exist in the store`,\n\t\t\t)\n\t\t}\n\n\t\tconst updatedIssue: Stored<Issue> = { ...issueToBeUpdated, ...payload }\n\n\t\tthis.dispatch(updateIssue(updatedIssue))\n\n\t\tconst changes: IssueUpdate[\"changes\"] = {}\n\t\t// NOTE: order here mirrors the backend order\n\t\tfor (const issueUpdateChange of [\n\t\t\tIssueUpdateChange.TITLE,\n\t\t\tIssueUpdateChange.DESCRIPTION,\n\t\t\tIssueUpdateChange.STATUS,\n\t\t\tIssueUpdateChange.CATEGORY,\n\t\t\tIssueUpdateChange.PRIORITY,\n\t\t\tIssueUpdateChange.ASSIGNED_TO,\n\t\t\tIssueUpdateChange.DUE_DATE,\n\t\t]) {\n\t\t\tif (issueUpdateChange in payload && payload[issueUpdateChange] !== issueToBeUpdated[issueUpdateChange]) {\n\t\t\t\tswitch (issueUpdateChange) {\n\t\t\t\t\tcase \"category\": {\n\t\t\t\t\t\tlet categoryOrNull: Category | null = null\n\t\t\t\t\t\tconst categoryIdOrNull = payload[issueUpdateChange]\n\t\t\t\t\t\tif (categoryIdOrNull) {\n\t\t\t\t\t\t\tcategoryOrNull = state.categoryReducer.instances[categoryIdOrNull] ?? null\n\n\t\t\t\t\t\t\tif (!categoryOrNull)\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t`Trying to update issue category to ${categoryIdOrNull} which does not exist in store`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchanges[issueUpdateChange] = categoryOrNull\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tname: categoryOrNull.name,\n\t\t\t\t\t\t\t\t\tcolor: categoryOrNull.color,\n\t\t\t\t\t\t\t\t\toffline_id: categoryOrNull.offline_id,\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: null\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase \"assigned_to\": {\n\t\t\t\t\t\tlet userOrNull: User | null = null\n\t\t\t\t\t\tconst userIdOrNull = payload[issueUpdateChange]\n\t\t\t\t\t\tif (userIdOrNull) {\n\t\t\t\t\t\t\tuserOrNull = state.userReducer.users[userIdOrNull] ?? null\n\n\t\t\t\t\t\t\tif (!userOrNull)\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t`Trying to update issue assigned_to to ${userIdOrNull} which does not exist in store`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchanges[issueUpdateChange] = userOrNull\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tfull_name: userOrNull.username,\n\t\t\t\t\t\t\t\t\tid: userOrNull.id,\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: null\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase \"description\":\n\t\t\t\t\t\tchanges[issueUpdateChange] = payload[issueUpdateChange] ?? null\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\tchanges[issueUpdateChange] = payload[issueUpdateChange] ?? null\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"priority\":\n\t\t\t\t\t\tchanges[issueUpdateChange] = payload[issueUpdateChange]!\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"status\":\n\t\t\t\t\t\tchanges[issueUpdateChange] = payload[issueUpdateChange]!\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"due_date\":\n\t\t\t\t\t\tchanges[issueUpdateChange] = payload[issueUpdateChange]\n\t\t\t\t\t\t\t? (payload[issueUpdateChange] as string)\n\t\t\t\t\t\t\t: null\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst offlineIssueUpdate: Stored<IssueUpdate> = offline({\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\tissue: issueToBeUpdated.offline_id,\n\t\t\tchanges: changes,\n\t\t})\n\n\t\tthis.dispatch(addIssueUpdate(offlineIssueUpdate))\n\n\t\tconst promise = this.enqueueRequest<Created<Issue>>({\n\t\t\tdescription: \"Edit issue\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/issues/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\t// the patch failed, revert issue back, remove offline issue update\n\t\t\tthis.dispatch(updateIssue(issueToBeUpdated))\n\t\t\tthis.dispatch(deleteIssueUpdate(offlineIssueUpdate.offline_id))\n\t\t})\n\n\t\treturn [updatedIssue, promise]\n\t}\n\n\tasync remove(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst backup = selectIssueById(id)(state)\n\n\t\tif (!backup) {\n\t\t\tthrow new Error(`No issue with id ${id} found in the store`)\n\t\t}\n\n\t\tconst attachmentsOfIssue = selectAttachmentsOfIssue(id)(state)\n\t\tconst updatesOfIssue = selectIssueUpdatesOfIssue(id)(state)\n\t\tconst formSubmissionsOfIssue = selectFormSubmissionsOfIssue(id)(state)\n\n\t\tconst issueAssociationsRecord: Record<string, Stored<IssueAssociation>> = {}\n\n\t\tfor (const issueAssociation of selectIssueAssociationsToIssue(id)(state))\n\t\t\tissueAssociationsRecord[issueAssociation.offline_id] = issueAssociation\n\t\tfor (const issueAssociation of selectIssueAssociationsOfIssue(id)(state))\n\t\t\tissueAssociationsRecord[issueAssociation.offline_id] = issueAssociation\n\n\t\tconst issueAssociations = Object.values(issueAssociationsRecord)\n\n\t\tthis.dispatch(deleteIssue(id))\n\t\tthis.dispatch(addActiveProjectIssuesCount(-1))\n\t\tif (attachmentsOfIssue.length > 0)\n\t\t\tthis.dispatch(deleteIssueAttachments(attachmentsOfIssue.map(({ offline_id }) => offline_id)))\n\t\tif (updatesOfIssue.length > 0)\n\t\t\tthis.dispatch(deleteIssueUpdates(updatesOfIssue.map(({ offline_id }) => offline_id)))\n\t\tif (formSubmissionsOfIssue.length > 0)\n\t\t\tthis.dispatch(deleteFormSubmissions(formSubmissionsOfIssue.map(({ offline_id }) => offline_id)))\n\t\tif (issueAssociations.length > 0)\n\t\t\tthis.dispatch(deleteIssueAssociations(issueAssociations.map(({ offline_id }) => offline_id)))\n\n\t\t// TODO: remove Issue comments in similar pattern above\n\n\t\ttry {\n\t\t\t// REASON: Need to await to trigger the catch block.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n\t\t\treturn await this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete issue\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/issues/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addIssue(backup))\n\t\t\tthis.dispatch(addIssueAttachments(attachmentsOfIssue))\n\t\t\tthis.dispatch(addIssueUpdates(updatesOfIssue))\n\t\t\tthis.dispatch(addActiveProjectIssuesCount(1))\n\t\t\tthis.dispatch(addFormSubmissions(formSubmissionsOfIssue))\n\t\t\tthis.dispatch(addIssueAssociations(issueAssociations))\n\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<Created<Issue>[]>({\n\t\t\tdescription: \"Get issues\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/issues/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssues(result))\n\t}\n}\n","import type { OptimisticModelResult } from \"../typings\"\nimport type { Created, IssueType, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddIssues,\n\taddIssueType,\n\tdeleteIssues,\n\tinitializeIssueTypes,\n\tremoveIssueType,\n\tselectIssuesOfIssueType,\n\tselectIssueTypeById,\n\tsetIssueType,\n\tupdateIssueType,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class IssueTypeService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<IssueType>): OptimisticModelResult<IssueType> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst offlineIssueType: Stored<IssueType> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t})\n\n\t\tthis.dispatch(addIssueType(offlineIssueType))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueType>>({\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/issue-types/\",\n\t\t\tpayload: offlineIssueType,\n\t\t\tblockers: [],\n\t\t\tblocks: [offlineIssueType.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((createdIssueType) => {\n\t\t\t\tthis.dispatch(setIssueType(createdIssueType))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(removeIssueType(offlineIssueType.offline_id))\n\t\t\t})\n\n\t\treturn [offlineIssueType, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<IssueType>>>): OptimisticModelResult<IssueType> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst issueTypeToBeUpdated = selectIssueTypeById(payload.offline_id)(state)\n\n\t\tif (!issueTypeToBeUpdated) {\n\t\t\tthrow new Error(`IssueType with offline_id ${payload.offline_id} does not exist in the store.`)\n\t\t}\n\n\t\tconst offlineUpdatedIssueType: Stored<IssueType> = {\n\t\t\t...issueTypeToBeUpdated,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateIssueType(offlineUpdatedIssueType))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueType>>({\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/issue-types/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((updatedIssueType) => {\n\t\t\t\tthis.dispatch(setIssueType(updatedIssueType))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(setIssueType(issueTypeToBeUpdated))\n\t\t\t})\n\n\t\treturn [offlineUpdatedIssueType, promise]\n\t}\n\n\tdelete(id: string): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst issueTypeToDelete = selectIssueTypeById(id)(state)\n\n\t\tif (!issueTypeToDelete) {\n\t\t\tthrow new Error(`IssueType with offline_id ${id} does not exist in the store.`)\n\t\t}\n\n\t\tconst issuesOfIssueType = selectIssuesOfIssueType(id)(state)\n\n\t\tthis.dispatch(removeIssueType(id))\n\n\t\tthis.dispatch(deleteIssues(issuesOfIssueType.map((issue) => issue.offline_id)))\n\n\t\t// TODO: probably want to remove any forms, revisions and submissions associated with the issue type\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/issue-types/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(setIssueType(issueTypeToDelete))\n\t\t\tthis.dispatch(addIssues(issuesOfIssueType))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\t// TODO: fetch for projects too\n\n\t\tconst result = await this.enqueueRequest<Created<IssueType>[]>({\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/issue-types/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssueTypes(result))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport { deleteProjectAccess, initializeProjectAccesses, updateProjectAccess } from \"../../store\"\nimport type { OvermapRootState, ProjectAccess } from \"../../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\n/**\n * Handles the creation of ProjectAccess Service\n */\nexport abstract class ProjectAccessService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync update(projectAccess: ProjectAccess): Promise<ProjectAccess> {\n\t\tthis.dispatch(updateProjectAccess(projectAccess))\n\n\t\treturn this.enqueueRequest<ProjectAccess>({\n\t\t\tdescription: \"Edit project access\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/access/${projectAccess.offline_id}/`,\n\t\t\tpayload: projectAccess,\n\t\t\tblockers: [projectAccess.offline_id, \"change-access-level\"],\n\t\t\tblocks: [projectAccess.offline_id],\n\t\t})\n\t}\n\n\t// TODO: Re-add user to project if removal fails\n\tasync remove(id: string): Promise<undefined> {\n\t\tthis.dispatch(deleteProjectAccess(id))\n\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete project access\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/access/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<ProjectAccess[]>({\n\t\t\tdescription: \"Get project accesses\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/access/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeProjectAccesses(result))\n\t}\n}\n","import { HttpMethod } from \"enums/api\"\nimport type { Created, OvermapRootState, ProjectFile } from \"../../typings\"\nimport type { OptimisticGenericResult, SDKRequest } from \"../typings\"\nimport {\n\taddOrReplaceProjectFile,\n\taddOrReplaceProjectFiles,\n\tremoveProjectFile,\n\tsaveActiveProjectFileBounds,\n\tsetActiveProjectFileId,\n\tsetIsImportingProjectFile,\n} from \"store/slices/projectFileSlice\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\n/**\n * Handles creation and caching of ProjectFiles\n */\nexport abstract class ProjectFileService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync saveExisting(file: ProjectFile): Promise<ProjectFile> {\n\t\tif (!file.offline_id) {\n\t\t\tthrow new Error(\n\t\t\t\t\"You can only use this method to save existing project files. The one provided has no offline_id.\",\n\t\t\t)\n\t\t}\n\t\tconst editableData: { file?: unknown } = { ...file }\n\t\tdelete editableData.file\n\t\tconst promise = this.enqueueRequest<ProjectFile>({\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/projects/files/${file.offline_id}/`,\n\t\t\tpayload: editableData,\n\t\t\tblockers: [file.offline_id],\n\t\t\tblocks: [file.offline_id],\n\t\t})\n\t\tvoid promise.then((result) => {\n\t\t\tthis.dispatch(addOrReplaceProjectFile(result))\n\t\t})\n\t\treturn promise\n\t}\n\n\t// TODO: This needs to be seperated into a update and create method\n\tsaveActive(): OptimisticGenericResult<ProjectFile> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\t\tconst activeProjectFileId = state.projectFileReducer.activeProjectFileId\n\t\tconst activeProjectId = state.projectReducer.activeProjectId\n\t\tif (!activeProjectFileId) {\n\t\t\tthrow new Error(\"No active project file\")\n\t\t}\n\t\tif (!activeProjectId) {\n\t\t\tthrow new Error(\"No active project\")\n\t\t}\n\t\tconst activeProjectFile = state.projectFileReducer.projectFiles[activeProjectFileId]\n\t\tif (!activeProjectFile) {\n\t\t\tthrow new Error(\"No active project file\")\n\t\t}\n\n\t\tif (!activeProjectFile.bounds && !activeProjectFile.canvas_bounds) {\n\t\t\tthrow new Error(\"Project file must either have bounds or canvas_bounds set\")\n\t\t}\n\n\t\tlet requestDetails: SDKRequest | Promise<SDKRequest>\n\t\tconst existing = typeof activeProjectFile.file === \"string\" && !activeProjectFile.file.startsWith(\"blob:\")\n\t\tif (existing) {\n\t\t\tconst editableData: { file?: unknown } = { ...activeProjectFile }\n\t\t\tdelete editableData.file\n\t\t\trequestDetails = {\n\t\t\t\tmethod: HttpMethod.PATCH,\n\t\t\t\turl: `/projects/files/${activeProjectFileId}/`,\n\t\t\t\tpayload: editableData,\n\t\t\t\tblockers: [activeProjectFileId],\n\t\t\t\tblocks: [activeProjectFileId],\n\t\t\t}\n\t\t} else {\n\t\t\trequestDetails = new Promise<SDKRequest>((resolve, reject) => {\n\t\t\t\tthis.client.files\n\t\t\t\t\t.uploadFileToS3(activeProjectFile.file_sha1)\n\t\t\t\t\t.then(([fileProps]) => {\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\t\t\t\turl: `/projects/${activeProjectId}/files/`,\n\t\t\t\t\t\t\tpayload: {\n\t\t\t\t\t\t\t\t...activeProjectFile,\n\t\t\t\t\t\t\t\t...fileProps,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tblockers: [activeProjectFileId],\n\t\t\t\t\t\t\tblocks: [activeProjectFileId],\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t\t.catch(reject)\n\t\t\t})\n\t\t}\n\t\tconst promise = Promise.resolve(requestDetails).then((requestDetails) => {\n\t\t\treturn this.enqueueRequest<ProjectFile>(requestDetails)\n\t\t})\n\t\tvoid promise.then((result) => {\n\t\t\tthis.dispatch(addOrReplaceProjectFile(result))\n\t\t})\n\t\tthis.dispatch(saveActiveProjectFileBounds)\n\t\tthis.dispatch(setActiveProjectFileId(null))\n\t\tthis.dispatch(setIsImportingProjectFile(false))\n\t\treturn [activeProjectFile, promise]\n\t}\n\n\tdelete(projectFileId: string): Promise<undefined> {\n\t\tthis.dispatch(removeProjectFile(projectFileId))\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/projects/files/${projectFileId}`,\n\t\t\tblockers: [projectFileId],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<ProjectFile>[]>({\n\t\t\tdescription: \"Get project files\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/files/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(addOrReplaceProjectFiles([]))\n\t\tthis.dispatch(addOrReplaceProjectFiles(result))\n\t}\n}\n","import {\n\tAttachmentPayload,\n\tBaseAttachmentService,\n\tBuildAttachmentPayloadData,\n\tBuildOfflineAttachmentData,\n} from \"./BaseAttachmentService\"\nimport { offline } from \"../../utils\"\nimport type { Created, OvermapRootState, ProjectAttachment, Stored } from \"../../typings\"\nimport type { OptimisticMultipleModelResult } from \"../typings\"\nimport {\n\taddProjectAttachments,\n\tdeleteProjectAttachment,\n\tdeleteProjectAttachments,\n\tinitializeProjectAttachments,\n\tselectProjectAttachmentById,\n\tsetProjectAttachment,\n\tupdateProjectAttachments,\n} from \"../../store\"\nimport type { BaseSDK } from \"../base\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class ProjectAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseAttachmentService<TState, TSDK, number, ProjectAttachment, AttachmentPayload & { project: number }> {\n\tname = \"Project Attachment\"\n\turl = \"/project-attachments\"\n\n\taddAttachments = addProjectAttachments\n\tupdateAttachments = updateProjectAttachments\n\tremoveAttachments = deleteProjectAttachments\n\tremoveAttachment = deleteProjectAttachment\n\tsetAttachment = setProjectAttachment\n\n\tselectAttachment = selectProjectAttachmentById\n\n\tprotected buildOfflineAttachment(data: BuildOfflineAttachmentData<number>) {\n\t\treturn offline({\n\t\t\tfile: URL.createObjectURL(data.file),\n\t\t\tfile_sha1: data.file_sha1,\n\t\t\tcreated_by: data.created_by,\n\t\t\tfile_name: data.file.name,\n\t\t\tfile_type: data.file.type,\n\t\t\tsubmitted_at: data.submitted_at,\n\t\t\tdescription: data.description,\n\t\t\tproject: data.modelId,\n\t\t}) satisfies Stored<ProjectAttachment>\n\t}\n\n\tprotected buildAttachmentPayload(data: BuildAttachmentPayloadData<number>) {\n\t\treturn {\n\t\t\t...data,\n\t\t\tproject: data.modelId,\n\t\t} satisfies AttachmentPayload & { project: number }\n\t}\n\n\tasync bulkAdd(\n\t\tpayloads: {\n\t\t\tprojectId: number\n\t\t\tfile: File\n\t\t}[],\n\t): Promise<OptimisticMultipleModelResult<ProjectAttachment>> {\n\t\treturn this._bulkAdd(payloads.map((p) => ({ modelId: p.projectId, file: p.file })))\n\t}\n\n\tasync delete(attachmentId: string): Promise<void> {\n\t\treturn this._delete(attachmentId)\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<ProjectAttachment>[]>({\n\t\t\tdescription: \"Get project attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `${this.url}/`,\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeProjectAttachments(result))\n\t}\n}\n","import { HttpMethod } from \"enums/api\"\nimport type { Created, License, OvermapRootState, Payload, Project } from \"../../typings\"\nimport { v4 as uuidv4 } from \"uuid\"\nimport {\n\tacceptProjectInvite,\n\taddOrReplaceProjectFiles,\n\tdeleteProject,\n\tdeleteProjectAccesses,\n\tdeleteProjectAttachments,\n\tinitializeProjectAccesses,\n\tremoveProjectFilesOfProject,\n\tselectAttachmentsOfProject,\n\tselectLicenseForProject,\n\tselectProjectAccesses,\n\tselectProjectFiles,\n\tselectProjectMapping,\n\tsetProjectAttachments,\n\tsetProjects,\n\tupdateLicense,\n\tupdateOrCreateProject,\n} from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\ninterface JoinProjectResponse {\n\tusername: string\n}\n\nexport abstract class ProjectService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync add(payload: Payload<Project>): Promise<Project> {\n\t\tif (!payload.bounds && !payload.canvas_bounds) {\n\t\t\tthrow new Error(\"Project must either have bounds or canvas_bounds set\")\n\t\t}\n\n\t\treturn await this.enqueueRequest<Created<Project>>({\n\t\t\tdescription: \"Create project\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/projects/\",\n\t\t\tpayload: {\n\t\t\t\tname: payload.name,\n\t\t\t\tbounds: payload.bounds,\n\t\t\t\torganization_owner: payload.organization_owner,\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync update(project: Project): Promise<Project> {\n\t\tif (!project.bounds && !project.canvas_bounds) {\n\t\t\tthrow new Error(\"Project must either have bounds or canvas_bounds set\")\n\t\t}\n\n\t\tthis.dispatch(updateOrCreateProject(project))\n\t\treturn await this.enqueueRequest<Project>({\n\t\t\tdescription: \"Update project\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/projects/${project.id}/`,\n\t\t\tpayload: {\n\t\t\t\tname: project.name,\n\t\t\t\tbounds: project.bounds,\n\t\t\t},\n\t\t\tblockers: [project.id.toString()],\n\t\t\tblocks: [project.id.toString()],\n\t\t})\n\t}\n\n\tasync delete(projectId: number): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\t\tconst projects = selectProjectMapping(state)\n\t\tconst project = projects[projectId]\n\t\tif (!project) {\n\t\t\tthrow new Error(\"Expected project to exist\")\n\t\t}\n\n\t\t// TODO: this shouldnt be an optimistic result\n\t\t// Selector needed to restore if the request fails\n\t\tconst filesToDelete = selectProjectFiles(state).filter((file) => file.project === projectId)\n\t\tthis.dispatch(removeProjectFilesOfProject(project.id))\n\n\t\t// Selector needed to restore if the request fails\n\t\tconst attachmentsOfProject = selectAttachmentsOfProject(project.id)(state)\n\t\tthis.dispatch(deleteProjectAttachments(attachmentsOfProject.map(({ offline_id }) => offline_id)))\n\n\t\t// Selector needed to restore if the request fails\n\t\tconst projectAccesses = selectProjectAccesses(state)\n\t\tthis.dispatch(deleteProjectAccesses(projectAccesses.map(({ offline_id }) => offline_id)))\n\n\t\t// Necessary to prevent no projects view from showing when project is deleted\n\t\tthis.dispatch({ type: \"rehydrated/setRehydrated\", payload: false })\n\t\tthis.dispatch(deleteProject(project))\n\n\t\tconst license = selectLicenseForProject(project.id)(state)\n\t\t// Detach license from project\n\t\tif (license) {\n\t\t\tthis.dispatch(updateLicense({ ...license, project: null } as License))\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete project\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/projects/${projectId}/`,\n\t\t\t\tblockers: [projectId.toString()],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t\tthis.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\n\t\t} catch (e) {\n\t\t\tthis.dispatch(setProjects(Object.values(projects)))\n\t\t\tthis.dispatch(initializeProjectAccesses(Object.values(projectAccesses)))\n\t\t\tthis.dispatch(addOrReplaceProjectFiles(filesToDelete))\n\t\t\tthis.dispatch(setProjectAttachments(attachmentsOfProject))\n\t\t\tthis.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\n\t\t\tif (license) {\n\t\t\t\tthis.dispatch(updateLicense({ ...license, project: project.id } as License))\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tinvite(projectId: number, email: string): Promise<undefined> {\n\t\tconst offline_id: string = uuidv4()\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Invite user to project\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/projects/${projectId}/invite/${email}/`,\n\t\t\tpayload: {\n\t\t\t\toffline_id,\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [offline_id],\n\t\t})\n\t}\n\n\tjoinProject(projectId: number, userId: number, inviteCode: string): Promise<JoinProjectResponse> {\n\t\treturn this.enqueueRequest<JoinProjectResponse>({\n\t\t\tdescription: \"Join project\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/join-project/${userId}/${inviteCode}/`,\n\t\t\tisAuthNeeded: false,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync acceptInvite(projectId: number): Promise<void> {\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Accept project invite\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/projects/${projectId}/accept-invite/`,\n\t\t\tblockers: [projectId.toString()],\n\t\t\tblocks: [projectId.toString()],\n\t\t}).then(() => {\n\t\t\tthis.dispatch(acceptProjectInvite(projectId))\n\t\t})\n\t}\n}\n","import { HttpMethod } from \"enums/api\"\nimport { addForm, deleteForm, initializeForms, selectFormById } from \"store/slices/formSlice\"\nimport type { Created, Form, FormRevision, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { offline } from \"utils/offline\"\nimport {\n\taddFormRevision,\n\taddFormRevisions,\n\taddFormSubmissions,\n\tdeleteFormRevision,\n\tdeleteFormRevisions,\n\tdeleteFormSubmissions,\n\tselectFormRevisionsOfForm,\n\tselectFormSubmissionsOfForm,\n} from \"../../store\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport { ISerializedField, ISerializedOnlyField } from \"@overmap-ai/forms\"\n\n// TODO: move to /forms\n/**\n * Finds and separates image files from form revision fields. The image attribute is deleted from the field objects and\n * is returned separately from the image files as they are stored in a different table.\n */\nexport const separateImageFromFields = async (fields: ISerializedField[]) => {\n\tconst images: Record<string, File> = {} // key: field identifier, value: File\n\tconst newFields: ISerializedField[] = [] // fields without image attribute\n\tfor (const section of fields) {\n\t\tif (section.type !== \"section\") {\n\t\t\tthrow new Error(`Expected ISerializedField type to be a section. Got ${section.type} instead.`)\n\t\t}\n\n\t\tconst { fields: sectionFields } = section\n\t\tconst newSectionFields: ISerializedOnlyField[] = []\n\t\tfor (const field of sectionFields) {\n\t\t\tif (field.image) {\n\t\t\t\tif (field.image instanceof Promise) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\timages[field.identifier] = await field.image\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.error(\"Failed to get image from promise\", e)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\timages[field.identifier] = field.image\n\t\t\t\t}\n\t\t\t\tdelete field.image\n\t\t\t}\n\t\t\tnewSectionFields.push(field)\n\t\t}\n\t\tnewFields.push({ ...section, fields: newSectionFields })\n\t}\n\n\treturn { fields: newFields, images }\n}\n\nexport abstract class FormService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tadd(\n\t\tpayload: Payload<Form>,\n\t\tinitialRevision: Pick<FormRevision, \"title\" | \"description\" | \"fields\">,\n\t): [Stored<Form>, Stored<FormRevision>, Promise<Created<FormRevision>>] {\n\t\tconst { store } = this.client\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\n\t\tconst offlineForm: Stored<Form> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: submittedAt,\n\t\t\tcreated_by: createdBy,\n\t\t})\n\n\t\tconst offlineFormRevision: Stored<FormRevision> = offline({\n\t\t\t...initialRevision,\n\t\t\tform: offlineForm.offline_id,\n\t\t\trevision: \"Pending\",\n\t\t\tsubmitted_at: submittedAt,\n\t\t\tcreated_by: createdBy,\n\t\t})\n\n\t\tthis.dispatch(addForm(offlineForm))\n\t\tthis.dispatch(addFormRevision(offlineFormRevision))\n\n\t\tconst formPromise = this.enqueueRequest<Created<FormRevision>>({\n\t\t\tdescription: \"Create form\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/forms/\",\n\t\t\tpayload: {\n\t\t\t\t...offlineForm,\n\t\t\t\tinitial_revision: {\n\t\t\t\t\toffline_id: offlineFormRevision.offline_id,\n\t\t\t\t\tsubmitted_at: offlineFormRevision.submitted_at,\n\t\t\t\t\ttitle: offlineFormRevision.title,\n\t\t\t\t\tdescription: offlineFormRevision.description,\n\t\t\t\t\tfields: offlineFormRevision.fields,\n\t\t\t\t},\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [offlineForm.offline_id, offlineFormRevision.offline_id],\n\t\t})\n\n\t\tvoid formPromise.catch((e) => {\n\t\t\tthis.dispatch(deleteForm(offlineForm.offline_id))\n\t\t\tthis.dispatch(deleteFormRevision(offlineFormRevision.offline_id))\n\t\t\t// TODO: remove form revision attachments\n\t\t\tthrow e\n\t\t})\n\n\t\treturn [offlineForm, offlineFormRevision, formPromise]\n\t}\n\n\tasync delete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\t\tconst form = selectFormById(id)(state)\n\t\tif (!form) {\n\t\t\tthrow new Error(\"Expected form to exist\")\n\t\t}\n\t\t// Delete all submissions for this form\n\t\tconst formSubmissions = selectFormSubmissionsOfForm(id)(state)\n\t\tif (formSubmissions.length > 0) {\n\t\t\tthis.dispatch(deleteFormSubmissions(formSubmissions.map(({ offline_id }) => offline_id)))\n\t\t}\n\n\t\t// Delete all revisions for this form\n\t\tconst formRevisions = selectFormRevisionsOfForm(id)(state)\n\t\tif (formRevisions.length > 0) {\n\t\t\tthis.dispatch(deleteFormRevisions(formRevisions.map(({ offline_id }) => offline_id)))\n\t\t}\n\n\t\t// Delete the form itself\n\t\tthis.dispatch(deleteForm(id))\n\n\t\ttry {\n\t\t\t// REASON: Need to await to trigger the catch block.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n\t\t\treturn await this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete form\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/forms/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addForm(form))\n\t\t\tif (formRevisions.length > 0) {\n\t\t\t\tthis.dispatch(addFormRevisions(formRevisions))\n\t\t\t}\n\t\t\tif (formSubmissions.length > 0) {\n\t\t\t\tthis.dispatch(addFormSubmissions(formSubmissions))\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst forms = await this.enqueueRequest<Created<Form>[]>({\n\t\t\tdescription: \"Fetch organization forms\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/forms/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [organizationId.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeForms(forms))\n\t}\n}\n","import type { Created, FormSubmission, Offline, OvermapRootState, Payload, Stored, Submitted } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { HttpMethod } from \"enums/api\"\nimport { offline } from \"utils\"\nimport {\n\taddActiveProjectFormSubmissionsCount,\n\taddFormSubmission,\n\taddFormSubmissionAttachments,\n\tdeleteFormSubmission,\n\tdeleteFormSubmissionAttachments,\n\tinitializeFormSubmissions,\n\tselectAttachmentsOfFormSubmission,\n\tselectFormSubmissionById,\n\tsetFormSubmission,\n\tupdateFormSubmission,\n} from \"../../store\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport { FieldValue } from \"@overmap-ai/forms\"\n\nconst isArrayOfFiles = (value: unknown): value is File[] => {\n\treturn Array.isArray(value) && value[0] instanceof File\n}\n\n// TODO: move to /forms\n// returns a new object with the files separated from the values, files is a dictionary with the key being the\n// field identifier and the value being the list of files for that field\nexport const separateFilesFromValues = (values: Record<string, FieldValue>) => {\n\tconst files: Record<string, File[]> = {}\n\tconst newValues: Record<string, FieldValue> = {}\n\n\tfor (const key in values) {\n\t\tconst value = values[key]\n\n\t\t// TODO: Not sure if this top condition is possible, but leaving it in for now\n\t\tif (value instanceof File) {\n\t\t\tfiles[key] = [value]\n\t\t} else if (isArrayOfFiles(value)) {\n\t\t\tfiles[key] = value\n\t\t} else if (value !== undefined) {\n\t\t\tnewValues[key] = value\n\t\t}\n\t}\n\n\treturn { values: newValues, files }\n}\n\nexport abstract class FormSubmissionService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tadd(payload: Payload<FormSubmission>): OptimisticModelResult<FormSubmission> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst { values } = separateFilesFromValues(payload.values)\n\n\t\tconst offlineSubmission: Submitted<FormSubmission> = offline({\n\t\t\t...payload,\n\t\t\tvalues: values,\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t})\n\n\t\tconst promise = this.enqueueRequest<Created<FormSubmission>>({\n\t\t\tdescription: \"Add form submission\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/form-submissions/\",\n\t\t\tpayload: offlineSubmission,\n\t\t\tblockers: [\n\t\t\t\t\"add-form-entry\",\n\t\t\t\tpayload.form_revision,\n\t\t\t\t...(payload.issue ? [payload.issue] : []),\n\t\t\t\t...(payload.asset ? [payload.asset] : []),\n\t\t\t],\n\t\t\tblocks: [offlineSubmission.offline_id],\n\t\t})\n\n\t\tthis.dispatch(addFormSubmission(offlineSubmission))\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(addActiveProjectFormSubmissionsCount(1))\n\t\t\t\tthis.dispatch(setFormSubmission(result))\n\t\t\t\treturn result\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteFormSubmission(offlineSubmission.offline_id))\n\t\t\t\tthis.dispatch(addActiveProjectFormSubmissionsCount(-1))\n\t\t\t})\n\n\t\treturn [offlineSubmission, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<FormSubmission>>>): OptimisticModelResult<FormSubmission> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst submissionToBeUpdated = selectFormSubmissionById(payload.offline_id)(state)\n\n\t\tif (!submissionToBeUpdated) {\n\t\t\tthrow new Error(`Expected submission with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst { values } = separateFilesFromValues(payload.values ?? {})\n\n\t\tconst updatedSubmission: Stored<FormSubmission> = {\n\t\t\t...submissionToBeUpdated,\n\t\t\t...payload,\n\t\t\t// values could also have a partial update\n\t\t\tvalues: {\n\t\t\t\t...submissionToBeUpdated.values,\n\t\t\t\t...values,\n\t\t\t},\n\t\t}\n\n\t\tthis.dispatch(updateFormSubmission(updatedSubmission))\n\n\t\tconst promise = this.enqueueRequest<Created<FormSubmission>>({\n\t\t\tdescription: \"Delete user form submissions\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/form-submissions/${updatedSubmission.offline_id}/`,\n\t\t\t// TODO: send just payload when FormSubmissionDeserializer is updated to handle partial updates\n\t\t\tpayload: updatedSubmission,\n\t\t\tblockers: [updatedSubmission.offline_id],\n\t\t\tblocks: [updatedSubmission.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(setFormSubmission(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(setFormSubmission(submissionToBeUpdated))\n\t\t\t})\n\n\t\treturn [updatedSubmission, promise]\n\t}\n\n\tasync delete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst submissionToBeDeleted = selectFormSubmissionById(id)(state)\n\n\t\tif (!submissionToBeDeleted) {\n\t\t\tthrow new Error(`Expected submission with offline_id ${id} to exist`)\n\t\t}\n\n\t\tconst submissionAttachments = selectAttachmentsOfFormSubmission(id)(state)!\n\n\t\tthis.dispatch(deleteFormSubmission(id))\n\t\tthis.dispatch(addActiveProjectFormSubmissionsCount(-1))\n\t\tthis.dispatch(deleteFormSubmissionAttachments(submissionAttachments.map((x) => x.offline_id)))\n\n\t\ttry {\n\t\t\t// REASON: Need to await to trigger the catch block.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n\t\t\treturn await this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete user form submissions\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/form-submissions/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addActiveProjectFormSubmissionsCount(1))\n\t\t\tthis.dispatch(addFormSubmission(submissionToBeDeleted))\n\t\t\tthis.dispatch(addFormSubmissionAttachments(submissionAttachments))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<FormSubmission>[]>({\n\t\t\tdescription: \"Fetch form submissions\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/form-submissions/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeFormSubmissions(result))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport { addWorkspace, deleteWorkspace, initializeWorkspaces, selectWorkspaceById, updateWorkspace } from \"../../store\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport type { Created, Offline, OvermapRootState, Payload, Stored, Workspace } from \"../../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\nimport { offline } from \"../../utils\"\n\nexport abstract class WorkspaceService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<Workspace>): OptimisticModelResult<Workspace> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\n\t\tconst offlineWorkspace: Stored<Workspace> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\tcreated_by: createdBy,\n\t\t})\n\n\t\tthis.dispatch(addWorkspace(offlineWorkspace))\n\n\t\tconst promise = this.enqueueRequest<Created<Workspace>>({\n\t\t\tdescription: \"Create Workspace\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/projects/${payload.project}/workspaces/`,\n\t\t\tpayload: offlineWorkspace,\n\t\t\tblockers: [\"add-workspace\"],\n\t\t\tblocks: [offlineWorkspace.offline_id],\n\t\t})\n\n\t\tvoid promise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateWorkspace(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteWorkspace(offlineWorkspace.offline_id))\n\t\t\t})\n\n\t\treturn [offlineWorkspace, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Workspace>>>): OptimisticModelResult<Workspace> {\n\t\tconst { store } = this.client\n\n\t\tconst workspace = selectWorkspaceById(payload.offline_id)(store.getState())\n\n\t\tif (!workspace) {\n\t\t\tthrow new Error(`Expected an existing workspace with offline_id ${payload.offline_id}`)\n\t\t}\n\n\t\tconst updatedWorkspace: Stored<Workspace> = { ...workspace, ...payload }\n\n\t\tthis.dispatch(updateWorkspace(updatedWorkspace))\n\n\t\tconst promise = this.enqueueRequest<Created<Workspace>>({\n\t\t\tdescription: \"Update Workspace\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/workspaces/${workspace.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [workspace.offline_id],\n\t\t\tblocks: [workspace.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateWorkspace(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateWorkspace(workspace))\n\t\t\t})\n\n\t\treturn [workspace, promise]\n\t}\n\n\tdelete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst originalWorkspace = selectWorkspaceById(id)(store.getState())\n\n\t\tif (!originalWorkspace) {\n\t\t\tthrow new Error(`Expected an existing workspace with id ${id}`)\n\t\t}\n\n\t\tthis.dispatch(deleteWorkspace(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete Workspace\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/workspaces/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tvoid promise.catch((reason) => {\n\t\t\tthis.dispatch(addWorkspace(originalWorkspace))\n\t\t\tthrow reason\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<Created<Workspace>[]>({\n\t\t\tdescription: \"Get workspaces\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/workspaces/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeWorkspaces(result))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport type { OrganizationAccess, Created, OvermapRootState } from \"../../typings\"\nimport {\n\tinitializeOrganizationAccesses,\n\tdeleteOrganizationAccess,\n\tremoveUser,\n\tupdateOrganizationAccess,\n} from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\n/**\n * Handles the creation of OrganizationAccess Service\n */\nexport abstract class OrganizationAccessService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync update(organizationAccess: OrganizationAccess): Promise<OrganizationAccess> {\n\t\tconst promise = this.enqueueRequest<Created<OrganizationAccess>>({\n\t\t\tdescription: \"Edit organization access\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/organizations/${organizationAccess.organization}/access/${organizationAccess.offline_id}/`,\n\t\t\tpayload: organizationAccess,\n\t\t\tblockers: [organizationAccess.offline_id],\n\t\t\tblocks: [organizationAccess.offline_id],\n\t\t})\n\n\t\tvoid promise.then(() => {\n\t\t\tthis.dispatch(updateOrganizationAccess(organizationAccess))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync remove(organizationAccess: OrganizationAccess): Promise<undefined> {\n\t\tthis.dispatch(deleteOrganizationAccess(organizationAccess.offline_id))\n\t\tthis.dispatch(removeUser(organizationAccess.user))\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Remove organization access\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/organizations/${organizationAccess.organization}/access/${organizationAccess.offline_id}/`,\n\t\t\tblockers: [organizationAccess.offline_id],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<OrganizationAccess[]>({\n\t\t\tdescription: \"Get organization accesses\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/access/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeOrganizationAccesses(result))\n\t}\n}\n","import { BaseApiService } from \"./BaseApiService\"\n\n// TODO: add more methods, add error handling, add quota management etc, make it work for any Attachment\n// Goal is to not use more than 80% of quota, as full utilization would stop the Redux offline store from\n// functioning properly as well\nimport { DBSchema, IDBPDatabase, openDB } from \"idb\"\nimport { HttpMethod } from \"enums\"\nimport { fileToBlob, getFileS3Key, getRenamedFile, hashFile } from \"utils\"\nimport { selectUploadUrl, setUploadUrl } from \"store/slices/fileSlice\"\nimport { APIError } from \"../errors\"\nimport type { SDKRequest } from \"../typings\"\nimport type { BaseSDK } from \"../base\"\nimport type { BaseState } from \"../../typings\"\n\nexport interface GetS3UrlSuccessResponse {\n\turl: string\n\tfields: Record<string, string>\n}\n\ninterface GetS3UrlWarningResponse {\n\twarning: string\n}\n\nexport type GetS3UrlResponse = GetS3UrlSuccessResponse | GetS3UrlWarningResponse\n\ninterface DatabaseFileProperties {\n\tfile_name: string\n\tfile_sha1: string\n\t/** When uploading, this is the s3 key of the file.\n\t * When downloading, this is the s3 public url.\n\t */\n\tfile: string\n}\n\ninterface FileCacheDB extends DBSchema {\n\tfiles: {\n\t\tvalue: File\n\t\tkey: string\n\t}\n}\n\nconst cachedRequestPromises: Record<string, Promise<File> | undefined> = {}\n// Used to minimize writing to the cache.\nconst _cachedKeys = new Set<string>()\n\n// <ANALYTICS>\nlet _filePutCacheHits = 0\nlet _filePutCacheMisses = 0\nlet _totalCount = 0\nconst summarizeEvery = 20\n// </ANALYTICS>\n\nexport abstract class FileService<TState extends BaseState, TSDK extends BaseSDK<TState>> extends BaseApiService<\n\tTState,\n\tTSDK\n> {\n\thost = import.meta.env.REACT_APP_API_URL as string\n\t// NOTE: If you alter the schema (of the IndexedDB database) in any way, you must increment the version in order to\n\t// migrate the store. This allows idb to automatically migrate the user's existing data to the new schema.\n\tprivate _dbPromise = openDB<FileCacheDB>(\"fileCache\", 1, {\n\t\tupgrade(db) {\n\t\t\tdb.createObjectStore(\"files\")\n\t\t},\n\t})\n\n\tprivate async renewUploadUrl(sha1: string): Promise<GetS3UrlResponse> {\n\t\tconst file = await this.fetchCache(sha1)\n\t\tif (!file) throw new Error(`File with sha1 ${sha1} not found in cache`)\n\t\tconst key = await getFileS3Key(file, sha1)\n\n\t\tconst s3UploadUrl = await this.enqueueRequest<GetS3UrlResponse>({\n\t\t\tdescription: \"Get S3 URL\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/authentication/files/presigned-upload-url/\",\n\t\t\tqueryParams: {\n\t\t\t\tsha1: await hashFile(file),\n\t\t\t\tfile_type: file.type,\n\t\t\t\textension: file.name.split(\".\").pop(),\n\t\t\t\tsize: file.size.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [`s3-${key}`],\n\t\t})\n\n\t\tif (\"url\" in s3UploadUrl) {\n\t\t\t// TODO: Why save it to the store?\n\t\t\tthis.dispatch(setUploadUrl({ sha1, ...s3UploadUrl }))\n\t\t}\n\t\treturn s3UploadUrl\n\t}\n\n\t/**\n\t * Adds a file to the cache using the sha1 hash as the key and returns the sha1 hash.\n\t * @param file The file to add to the cache\n\t * TODO: This should be removed once the bug described in [1] is fixed.\n\t * @param sha1 The sha1 hash of the file to cache.\n\t */\n\tasync addCache(file: File, sha1: string): Promise<void> {\n\t\tif (_cachedKeys.has(sha1)) {\n\t\t\treturn\n\t\t}\n\t\t// TODO: Check\n\t\tif (!file.type) {\n\t\t\tconst parts = file.name.split(\".\")\n\t\t\tconst extension = parts[parts.length - 1]\n\t\t\tfile = new File([file], file.name, { type: extension })\n\t\t}\n\t\tif (!file.name || !file.size || !file.type) {\n\t\t\tthrow new Error(\"Cannot add files to cache that do not have a name, size and type.\")\n\t\t}\n\t\tconst fileStorage: IDBPDatabase<FileCacheDB> = await this._dbPromise\n\t\t// TODO: Is this an improvement or not?\n\t\tconst alreadyCached = !!(await fileStorage.get(\"files\", sha1))\n\t\tif (!alreadyCached) {\n\t\t\tawait fileStorage.put(\"files\", file, sha1)\n\t\t\t_filePutCacheMisses++\n\t\t} else {\n\t\t\tconsole.error(\"File already cached (this is unexpected at this point):\", file.name, sha1)\n\t\t\t_filePutCacheHits++\n\t\t}\n\t\t_cachedKeys.add(sha1)\n\t\t_totalCount++\n\t\tif (_totalCount % summarizeEvery === 0) {\n\t\t\t// TODO: If this ends up hitting the console more often than not, they `alreadyCached` check might be more\n\t\t\t// performant than overwriting the identical file in the database. Because all file names saved are based\n\t\t\t// on the sha1 hash, we can guarantee that the files are identical, so there is no point in overwriting.\n\t\t\tconsole.debug(\n\t\t\t\t\"File cache summary: \" +\n\t\t\t\t\t`${_filePutCacheHits} hits and ${_filePutCacheMisses} misses, ` +\n\t\t\t\t\t`${(_filePutCacheHits / (_filePutCacheHits + _filePutCacheMisses)) * 100}% hit rate over ` +\n\t\t\t\t\t`${_totalCount} calls to addCache.`,\n\t\t\t)\n\t\t}\n\t}\n\n\tasync removeCache(sha1: string): Promise<void> {\n\t\tawait (await this._dbPromise).delete(\"files\", sha1)\n\t\t_cachedKeys.delete(sha1)\n\t}\n\n\tasync fetchCache(sha1: string): Promise<File | undefined> {\n\t\treturn (await this._dbPromise).get(\"files\", sha1)\n\t}\n\n\tasync getOrRenewUploadUrl(sha1: string): Promise<GetS3UrlResponse> {\n\t\tconst state = this.client.store.getState()\n\t\tconst uploadUrl = selectUploadUrl(sha1)(state)\n\n\t\treturn uploadUrl ?? (await this.renewUploadUrl(sha1))\n\t}\n\n\t/** Ensure the file has been added to the file cache before calling `uploadFileToS3()` */\n\tasync uploadFileToS3(sha1: string): Promise<[DatabaseFileProperties, Promise<undefined>]> {\n\t\tconst file = await this.fetchCache(sha1)\n\n\t\tif (!file) throw new Error(`File with sha1 ${sha1} not found in cache`)\n\n\t\tconst key = await getFileS3Key(file, sha1)\n\t\tconst dbFileProperties: DatabaseFileProperties = {\n\t\t\tfile_name: file.name,\n\t\t\tfile_sha1: sha1,\n\t\t\tfile: key,\n\t\t}\n\t\tconst fileUploadUrlResponse: GetS3UrlResponse = await this.getOrRenewUploadUrl(sha1)\n\n\t\tif (\"warning\" in fileUploadUrlResponse) {\n\t\t\tif (fileUploadUrlResponse.warning === \"already_uploaded\") {\n\t\t\t\treturn [dbFileProperties, Promise.resolve(undefined).then()]\n\t\t\t}\n\t\t\tthrow new Error(fileUploadUrlResponse.warning)\n\t\t}\n\n\t\tconst url = fileUploadUrlResponse.url\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\turl,\n\t\t\tdescription: \"Upload file\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\tisExternalUrl: true,\n\t\t\tisAuthNeeded: false,\n\t\t\tattachmentHash: sha1,\n\t\t\tblockers: [`s3-${key}`],\n\t\t\tblocks: [sha1],\n\t\t\ts3url: fileUploadUrlResponse,\n\t\t} satisfies SDKRequest)\n\n\t\treturn [dbFileProperties, promise]\n\t}\n\n\t/**\n\t * Fetches a file based on its URL and SHA1. SHA1 values should be known ahead of time because the SHA1 and URL of\n\t * any file is stored in a FileModelMixin (see backend). If the expected SHA1 doesn't match the actual SHA1 of the\n\t * file, an error will be thrown.\n\t * @param url The URL from which to get the file.\n\t * @param expectedSha1 The expected SHA1 of the file. If this doesn't match the actual SHA1 of the file, an error\n\t * will be thrown.\n\t * @param downloadedName (Optional) The name to give the file after download. Set to the name of an attachment, for\n\t * example.\n\t */\n\tasync fetchFileFromUrl(url: string, expectedSha1: string, downloadedName?: string | undefined): Promise<File> {\n\t\tconst requestCacheKey: string = url.split(\"?\")[0] ?? url\n\n\t\tconst cachedResult = await this.fetchCache(expectedSha1)\n\n\t\tif (cachedResult) {\n\t\t\tif (!cachedResult.name) {\n\t\t\t\tthrow new Error(\"Cached file unexpectedly has no name.\")\n\t\t\t}\n\t\t\treturn cachedResult\n\t\t}\n\n\t\tif (url.startsWith(\"blob:\")) {\n\t\t\tconst blob = await fileToBlob(url)\n\t\t\tconst file = new File([blob], downloadedName ?? expectedSha1, { type: blob.type })\n\t\t\tawait this.addCache(file, expectedSha1)\n\t\t\treturn file\n\t\t}\n\n\t\tlet promise = cachedRequestPromises[requestCacheKey]\n\t\tlet isFirstRequest = true\n\n\t\tif (!promise) {\n\t\t\tpromise = new Promise((resolve) => {\n\t\t\t\tvoid this.enqueueRequest<Blob>({\n\t\t\t\t\tdescription: \"Download file\",\n\t\t\t\t\tmethod: HttpMethod.GET,\n\t\t\t\t\turl,\n\t\t\t\t\t// If in development, we should assume the files are saved at localhost by the Django development server.\n\t\t\t\t\t// Setting this to true will lead to localhost:8000 being prepended to the URL.\n\t\t\t\t\tisExternalUrl: import.meta.env.PROD || url.startsWith(\"https://\"),\n\t\t\t\t\tisResponseBlob: true,\n\t\t\t\t\tisAuthNeeded: false,\n\t\t\t\t\tblockers: [expectedSha1],\n\t\t\t\t\tblocks: [expectedSha1],\n\t\t\t\t}).then((blob) => {\n\t\t\t\t\tconst blobToFile = new File([blob], downloadedName ?? expectedSha1, { type: blob.type })\n\t\t\t\t\tresolve(blobToFile)\n\t\t\t\t})\n\t\t\t})\n\t\t\tcachedRequestPromises[requestCacheKey] = promise\n\t\t} else {\n\t\t\tisFirstRequest = false\n\t\t}\n\n\t\tlet file: File\n\n\t\ttry {\n\t\t\tfile = await promise\n\t\t} catch (e) {\n\t\t\tif (isFirstRequest && e instanceof APIError) {\n\t\t\t\t// Don't cache failed promises\n\t\t\t\tdelete cachedRequestPromises[requestCacheKey]\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\n\t\tif (isFirstRequest) {\n\t\t\t// The first request for this image (in case there are concurrent ones) has the responsibility to cache the\n\t\t\t// file itself.\n\t\t\tconst actualSha1 = await hashFile(file)\n\t\t\tif (actualSha1 !== expectedSha1) {\n\t\t\t\tconst message = `The hash of the file returned from the server (${actualSha1}) does not match the \n\t\t\t\t\texpected hash (${expectedSha1}). This can happen if you're using a local development server and the \n\t\t\t\t\tisExternalUrl flag in the request details is set to true, because instead of requesting the local\n\t\t\t\t\tREST API, you will be requesting localhost:80 (where this app runs), resulting in a transformed blob\n\t\t\t\t\t(with an offline_id attached) being returned. Alternatively, you may be running with \n\t\t\t\t\timport.meta.env.PROD, which will result in some file requests being treated as\n\t\t\t\t\texternal URLs and therefore not prepended with VITE_API_URL.`\n\n\t\t\t\tthrow new Error(message)\n\t\t\t}\n\t\t\t// All files need a name. Otherwise, they might end up with duplicated keys in the PrimeReact FileUpload\n\t\t\t// asset (it uses the name, size and type as the key).\n\t\t\tconst extension = file.type.split(\"/\")[1]\n\t\t\tif (!extension) {\n\t\t\t\tthrow new Error(\"File has no extension\")\n\t\t\t}\n\t\t\tconst fileName = downloadedName ?? actualSha1 + \".\" + extension\n\n\t\t\tfile = getRenamedFile(file, fileName)\n\n\t\t\tif (!file.name) {\n\t\t\t\tthrow new Error(\"Failed to set file's name\")\n\t\t\t}\n\n\t\t\tawait this.addCache(file, actualSha1)\n\n\t\t\t// Overwrite the cached promise, so it returns the renamed file\n\t\t\tcachedRequestPromises[requestCacheKey] = new Promise((resolve) => {\n\t\t\t\tresolve(file)\n\t\t\t})\n\t\t}\n\n\t\treturn file\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\nimport type {\n\tEmailVerificationPayload,\n\tEmailVerificationReturn,\n\tOvermapRootState,\n\tVerificationCode,\n} from \"../../typings\"\n\nexport abstract class EmailVerificationService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync getVerificationCode(verificationCode: string): Promise<VerificationCode> {\n\t\treturn this.enqueueRequest<VerificationCode>({\n\t\t\tdescription: \"Get verification code\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/verification/email-verification/${verificationCode}/`,\n\t\t\tisAuthNeeded: false,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tvalidateVerificationCode(\n\t\tverificationCode: string,\n\t\tpayload: EmailVerificationPayload | undefined = undefined,\n\t): Promise<EmailVerificationReturn> {\n\t\treturn this.enqueueRequest<EmailVerificationReturn>({\n\t\t\tdescription: \"Validate verification code\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/verification/email-verification/${verificationCode}/`,\n\t\t\tisAuthNeeded: false,\n\t\t\tpayload,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport { initializeEmailDomains, deleteEmailDomain, addEmailDomain } from \"../../store\"\nimport type { Created, EmailDomain, OvermapRootState } from \"../../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class EmailDomainsService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync add(orgId: number, email: string): Promise<undefined> {\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Add email domain to organization\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/organizations/${orgId}/email-domains/`,\n\t\t\tpayload: { email },\n\t\t\tblockers: [orgId.toString(), \"create-org\"],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync remove(emailDomain: EmailDomain): Promise<undefined> {\n\t\tthis.dispatch(deleteEmailDomain(emailDomain.offline_id))\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Remove email domain from organization\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/organizations/${emailDomain.organization}/email-domains/${emailDomain.offline_id}/`,\n\t\t\tblockers: [emailDomain.domain],\n\t\t\tblocks: [],\n\t\t}).catch((e) => {\n\t\t\tthis.dispatch(addEmailDomain(emailDomain))\n\t\t\tthrow e\n\t\t})\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<Created<EmailDomain>[]>({\n\t\t\tdescription: \"Fetch email domains for organization\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/email-domains/`,\n\t\t\tblockers: [organizationId.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeEmailDomains(result))\n\t}\n}\n","import type { Organization, OvermapRootState } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport { setOrganizations } from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class OrganizationService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tcreate(name: string): Promise<Organization> {\n\t\treturn this.enqueueRequest<Organization>({\n\t\t\tdescription: \"Create organization\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/organizations/\",\n\t\t\tpayload: { name },\n\t\t\tblockers: [],\n\t\t\tblocks: [`add-org-${name}`, \"create-org\"],\n\t\t})\n\t}\n\n\tasync update(organization: Organization): Promise<Organization> {\n\t\treturn this.enqueueRequest<Organization>({\n\t\t\tdescription: \"Edit organization\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/organizations/${organization.id}/`,\n\t\t\tpayload: organization,\n\t\t\tblockers: [`add-org-${organization.name}`, organization.id.toString()],\n\t\t\tblocks: [organization.id.toString()],\n\t\t})\n\t}\n\n\tasync invite(organizationId: number, email: string): Promise<undefined> {\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Invite user to organization\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/organizations/${organizationId}/invite/${email}/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number, organizationId: number): Promise<void> {\n\t\tconst organizationsRecord: Record<number, Organization> = {}\n\n\t\tconst projectOrganizations = await this.enqueueRequest<Organization[]>({\n\t\t\tdescription: \"Get organizations\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/organizations/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const organization of projectOrganizations) {\n\t\t\torganizationsRecord[organization.id] = organization\n\t\t}\n\n\t\tconst organization = await this.enqueueRequest<Organization>({\n\t\t\tdescription: \"Get organization\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\torganizationsRecord[organization.id] = organization\n\n\t\tthis.dispatch(setOrganizations(Object.values(organizationsRecord)))\n\t}\n}\n","import type { License, OvermapRootState, Project, Transaction } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport { initializeLicences, updateLicense } from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class LicenseService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync getLicense(license: License): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Get license\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/billing/${license.offline_id}/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.organization_owner ? license.organization_owner.toString() : \"\"],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\n\tasync pauseLicense(license: License): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Pause license\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/billing/${license.offline_id}/suspend/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.organization_owner ? license.organization_owner.toString() : \"\"],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\tasync resumeLicense(license: License): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Resume license\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/billing/${license.offline_id}/suspend/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.organization_owner ? license.organization_owner.toString() : \"\"],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\n\tasync cancelLicense(license: License): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Cancel license\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/billing/${license.offline_id}/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.organization_owner ? license.organization_owner.toString() : \"\"],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\n\tasync attachLicenseToProject(license: License, project: Project): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Attach license\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/billing/${license.offline_id}/project/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tpayload: { project: project.id },\n\t\t\tblockers: [\n\t\t\t\tlicense.organization_owner ? license.organization_owner.toString() : \"\",\n\t\t\t\tproject.id ? project.id.toString() : \"\",\n\t\t\t],\n\t\t\tblocks: [\"add-issue\", \"add-form-entry\", \"change-access-level\", \"add-workspace\"],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\n\tasync detachLicenseFromProject(license: License): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Detach license\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/billing/${license.offline_id}/project/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.organization_owner ? license.organization_owner.toString() : \"\"],\n\t\t\tblocks: [\"add-issue\", \"add-form-entry\", \"change-access-level\", \"add-workspace\"],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\n\tasync getLatestTransaction(license: License): Promise<Transaction> {\n\t\treturn await this.enqueueRequest<Transaction>({\n\t\t\tdescription: \"Get latest transaction\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/billing/${license.offline_id}/transaction/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.offline_id],\n\t\t\tblocks: [license.offline_id],\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number, organizationId: number): Promise<void> {\n\t\tconst licencesRecord: Record<string, License> = {}\n\n\t\tconst organizationLicences = await this.enqueueRequest<License[]>({\n\t\t\tdescription: \"Get licenses\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/licenses/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [organizationId.toString()],\n\t\t\tblocks: [\"add-issue\", \"add-form-entry\", \"change-access-level\", \"add-workspace\"],\n\t\t})\n\n\t\tfor (const license of organizationLicences) {\n\t\t\tlicencesRecord[license.offline_id] = license\n\t\t}\n\n\t\tconst projectLicences = await this.enqueueRequest<License[]>({\n\t\t\tdescription: \"Get licenses\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/licenses/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [projectId.toString()],\n\t\t\tblocks: [\"add-issue\", \"add-form-entry\", \"change-access-level\", \"add-workspace\"],\n\t\t})\n\n\t\tfor (const license of projectLicences) {\n\t\t\tlicencesRecord[license.offline_id] = license\n\t\t}\n\n\t\tthis.dispatch(initializeLicences(Object.values(licencesRecord)))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport {\n\taddDocuments,\n\tmoveDocument,\n\tremoveDocuments,\n\tselectDocumentById,\n\tselectDocumentsMapping,\n\tsetDocuments,\n\tupdateDocuments,\n} from \"../../store\"\nimport type { Created, Document, MovePosition, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class DocumentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<Document>): OptimisticModelResult<Document> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineDocument: Stored<Document> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addDocuments([offlineDocument]))\n\n\t\tconst promise = this.enqueueRequest<Document>({\n\t\t\tdescription: \"Create Document\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/documents/\",\n\t\t\tpayload: offlineDocument,\n\t\t\tqueryParams: {\n\t\t\t\tparent_document: offlineDocument.parent_document ?? undefined,\n\t\t\t},\n\t\t\t// if adding as a child of another document, need that document to exist first\n\t\t\tblockers: offlineDocument.parent_document ? [offlineDocument.parent_document] : [],\n\t\t\tblocks: [offlineDocument.offline_id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(removeDocuments([offlineDocument.offline_id]))\n\t\t})\n\n\t\treturn [offlineDocument, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Document>>>): OptimisticModelResult<Document> {\n\t\tconst { store } = this.client\n\t\tconst documentToBeUpdated = store.getState().documentsReducer.documents[payload.offline_id]\n\n\t\tif (!documentToBeUpdated) {\n\t\t\tthrow new Error(\n\t\t\t\t`attempting to update a document with offline_id ${payload.offline_id} that does not exist in store.documents`,\n\t\t\t)\n\t\t}\n\n\t\tconst updatedDocument: Stored<Document> = {\n\t\t\t...documentToBeUpdated,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateDocuments([updatedDocument]))\n\n\t\tconst promise = this.enqueueRequest<Document>({\n\t\t\tdescription: \"Update Document\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/documents/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tupdateDocuments([documentToBeUpdated])\n\t\t})\n\n\t\treturn [updatedDocument, promise]\n\t}\n\n\tmove(documentId: string, targetDocumentId: string | null, position: MovePosition): Promise<Document[]> {\n\t\tconst { store } = this.client\n\t\tconst documentsMapping = selectDocumentsMapping(store.getState())\n\t\t/** the documents that need to be reverted if the move operation fails are:\n\t\t * 1. the document itself (could have attempted to change parents, changing to parent_document property)\n\t\t * 2. the parent of the document (the document could have been moved to a different parent, changing the old parents children_documents property)\n\t\t * 3. the target document (could have been the desired new parent document, changing the children_documents property)\n\t\t * 4. the parent of the target document (could have been the desired new parent document, changing the children_documents property) */\n\t\tconst documentsToRevertIfMoveFails: Document[] = []\n\n\t\tconst documentBeingMoved = documentsMapping[documentId]\n\t\tif (!documentBeingMoved) {\n\t\t\tthrow new Error(\n\t\t\t\t`attempting to move a document with offline_id ${documentId} that does not exist in store.documents`,\n\t\t\t)\n\t\t}\n\t\tdocumentsToRevertIfMoveFails.push(documentBeingMoved)\n\n\t\tif (documentBeingMoved.parent_document) {\n\t\t\tdocumentsToRevertIfMoveFails.push(documentsMapping[documentBeingMoved.parent_document]!)\n\t\t}\n\n\t\tif (targetDocumentId) {\n\t\t\tconst targetDocument = documentsMapping[targetDocumentId]\n\t\t\tif (!targetDocument) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`attempting to move a document to target with offline_id ${targetDocumentId} that does not exist in store.documents`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tdocumentsToRevertIfMoveFails.push(targetDocument)\n\n\t\t\tif (targetDocument.parent_document) {\n\t\t\t\tdocumentsToRevertIfMoveFails.push(documentsMapping[targetDocument.parent_document]!)\n\t\t\t}\n\t\t}\n\n\t\tthis.dispatch(moveDocument({ documentId, targetDocumentId, position }))\n\n\t\tconst promise = this.enqueueRequest<Document[]>({\n\t\t\tdescription: \"Move Document\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/documents/${documentId}/move/`,\n\t\t\tqueryParams: {\n\t\t\t\ttarget: targetDocumentId ?? undefined,\n\t\t\t\tposition,\n\t\t\t},\n\t\t\tblockers: [documentId],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateDocuments(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateDocuments(documentsToRevertIfMoveFails))\n\t\t\t})\n\n\t\treturn promise\n\t}\n\n\tdelete(id: string): Promise<Document[]> {\n\t\tconst { store } = this.client\n\t\tconst documentsMapping = selectDocumentsMapping(store.getState())\n\t\tconst documentToBeDeleted = selectDocumentById(id)(store.getState())\n\t\tif (!documentToBeDeleted) {\n\t\t\tthrow new Error(\n\t\t\t\t`attempting to delete a document with offline_id ${id} that does not exist in store.documents`,\n\t\t\t)\n\t\t}\n\t\tconst parentDocument = documentToBeDeleted.parent_document\n\t\t\t? documentsMapping[documentToBeDeleted.parent_document]\n\t\t\t: undefined\n\n\t\tthis.dispatch(removeDocuments([id]))\n\t\tconst promise = this.enqueueRequest<Created<Document>[]>({\n\t\t\tdescription: \"Delete Document\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/documents/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((documentsToUpdate) => {\n\t\t\t\tthis.dispatch(updateDocuments(documentsToUpdate))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateDocuments([documentToBeDeleted]))\n\t\t\t\tif (parentDocument) {\n\t\t\t\t\tthis.dispatch(updateDocuments([parentDocument]))\n\t\t\t\t}\n\t\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number, organizationId: number): Promise<void> {\n\t\t// NOTE: below fetches are guaranteed to not have any common documents between them since documents are owned exclusively by either a project or an organization\n\n\t\tconst projectDocumentsPromise = this.enqueueRequest<Created<Document>[]>({\n\t\t\tdescription: \"Get project documents\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/documents/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tconst organizationDocumentsPromise = this.enqueueRequest<Created<Document>[]>({\n\t\t\tdescription: \"Get organization documents\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/documents/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\t// Load project documents first because they are more likely to be seen\n\t\tthis.dispatch(setDocuments(await projectDocumentsPromise))\n\n\t\t// Load organization documents\n\t\tthis.dispatch(addDocuments(await organizationDocumentsPromise))\n\t}\n}\n","import {\n\tAttachmentPayload,\n\tBaseAttachmentService,\n\tBuildAttachmentPayloadData,\n\tBuildOfflineAttachmentData,\n} from \"./BaseAttachmentService\"\nimport {\n\taddDocumentAttachments,\n\tdeleteDocumentAttachment,\n\tdeleteDocumentAttachments,\n\tinitializeDocumentAttachments,\n\tselectDocumentAttachmentById,\n\tsetDocumentAttachment,\n\tupdateDocumentAttachments,\n} from \"../../store\"\nimport type { Created, DocumentAttachment, FilePayload, OvermapRootState, Stored } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class DocumentAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseAttachmentService<TState, TSDK, string, DocumentAttachment, AttachmentPayload & { document: string }> {\n\tname = \"Document Attachment\"\n\turl = \"/document-attachments\"\n\n\taddAttachments = addDocumentAttachments\n\tupdateAttachments = updateDocumentAttachments\n\tremoveAttachments = deleteDocumentAttachments\n\tremoveAttachment = deleteDocumentAttachment\n\tsetAttachment = setDocumentAttachment\n\n\tselectAttachment = selectDocumentAttachmentById\n\n\tprotected buildOfflineAttachment(data: BuildOfflineAttachmentData<string>) {\n\t\treturn offline({\n\t\t\tfile: URL.createObjectURL(data.file),\n\t\t\tfile_sha1: data.file_sha1,\n\t\t\tcreated_by: data.created_by,\n\t\t\tfile_name: data.file.name,\n\t\t\tfile_type: data.file.type,\n\t\t\tsubmitted_at: data.submitted_at,\n\t\t\tdescription: data.description,\n\t\t\tdocument: data.modelId,\n\t\t}) satisfies Stored<DocumentAttachment>\n\t}\n\n\tprotected buildAttachmentPayload(data: BuildAttachmentPayloadData<string>) {\n\t\treturn {\n\t\t\t...data,\n\t\t\tdocument: data.modelId,\n\t\t} satisfies AttachmentPayload & { document: string }\n\t}\n\n\t// NOTE: overriding the method from BaseAttachmentService since document attachments get vectorized\n\tasync bulkAdd(\n\t\tpayloads: {\n\t\t\tdocumentId: string\n\t\t\tfile: File\n\t\t}[],\n\t): Promise<OptimisticMultipleModelResult<DocumentAttachment>> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAttachments: Stored<DocumentAttachment>[] = []\n\t\tconst attachmentPayloads: (AttachmentPayload & { document: string })[] = []\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\n\t\t// track what attachments are associated with which sha1 so we can make them readable after processing presigned S3 urls\n\t\tconst sha1ToAttachmentIds: Record<string, string[]> = {}\n\n\t\tfor (const payload of payloads) {\n\t\t\tconst { documentId: documentId, file } = payload\n\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\tif (!(filePayload.sha1 in filePayloads)) {\n\t\t\t\tfilePayloads[filePayload.sha1] = filePayload\n\t\t\t\tsha1ToAttachmentIds[filePayload.sha1] = []\n\t\t\t}\n\n\t\t\tconst offlineAttachment = this.buildOfflineAttachment({\n\t\t\t\tfile,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tdescription: \"\",\n\t\t\t\tmodelId: documentId,\n\t\t\t})\n\t\t\tofflineAttachments.push(offlineAttachment)\n\n\t\t\tattachmentPayloads.push({\n\t\t\t\toffline_id: offlineAttachment.offline_id,\n\t\t\t\tfile_name: offlineAttachment.file_name,\n\t\t\t\tfile_sha1: offlineAttachment.file_sha1,\n\t\t\t\tfile_extension: filePayload.extension,\n\t\t\t\tdescription: offlineAttachment.description,\n\t\t\t\tdocument: documentId,\n\t\t\t})\n\n\t\t\tsha1ToAttachmentIds[filePayload.sha1]!.push(offlineAttachment.offline_id)\n\t\t}\n\n\t\tthis.dispatch(this.addAttachments(offlineAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<DocumentAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: \"Attach files to document\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/document-attachments/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblocks: offlineAttachments.map((attachment) => attachment.offline_id),\n\t\t\tblockers: offlineAttachments.map((attachment) => attachment.file_sha1),\n\t\t})\n\n\t\tpromise\n\t\t\t.then(({ attachments, presigned_urls }) => {\n\t\t\t\tthis.dispatch(this.updateAttachments(attachments))\n\t\t\t\tconst promisesBySha1 = this.processPresignedUrls(presigned_urls)\n\n\t\t\t\tfor (const [sha1, promise] of Object.entries(promisesBySha1)) {\n\t\t\t\t\t// If successfully uploaded to S3, make each attachment readable\n\t\t\t\t\tvoid promise.then(() => {\n\t\t\t\t\t\tconst attachmentIds = sha1ToAttachmentIds[sha1]!\n\n\t\t\t\t\t\tfor (const attachmentId of attachmentIds) {\n\t\t\t\t\t\t\tthis.makeReadable(attachmentId)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(this.removeAttachments(offlineAttachments.map((attachment) => attachment.offline_id)))\n\t\t\t})\n\n\t\treturn [offlineAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\treturn this._delete(id)\n\t}\n\n\tprivate makeReadable(attachmnentId: string) {\n\t\tvoid this.enqueueRequest({\n\t\t\tdescription: \"Add attachment to AI assistant\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/document-attachments/${attachmnentId}/`,\n\t\t\tpayload: {\n\t\t\t\treadable_to_assistant: true,\n\t\t\t},\n\t\t\t// passing through \"index-document-attachment\" so at most one document attachment being indexed at a time\n\t\t\tblockers: [\"index-document-attachment\", attachmnentId],\n\t\t\tblocks: [\"index-document-attachment\"],\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number, organizationId: number): Promise<void> {\n\t\tconst projectDocumentAttachments = await this.enqueueRequest<Created<DocumentAttachment>[]>({\n\t\t\tdescription: \"Get document attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/document-attachments/`,\n\t\t\tblocks: [],\n\t\t\tblockers: [],\n\t\t})\n\n\t\tthis.dispatch(initializeDocumentAttachments(projectDocumentAttachments))\n\n\t\tconst organizationDocumentAttachments = await this.enqueueRequest<Created<DocumentAttachment>[]>({\n\t\t\tdescription: \"Get document attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/document-attachments/`,\n\t\t\tblocks: [],\n\t\t\tblockers: [],\n\t\t})\n\n\t\tthis.dispatch(this.addAttachments(organizationDocumentAttachments))\n\t}\n}\n","import type { AgentUserConversation, Created, OvermapRootState } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport { addConversation, initializeConversations, setConversation, updateConversation } from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class AgentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync startConversation(prompt: string): Promise<AgentUserConversation> {\n\t\tconst activeProjectId = this.client.store.getState().projectReducer.activeProjectId\n\t\treturn this.enqueueRequest<AgentUserConversation>({\n\t\t\tdescription: \"Start agent conversation\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/agents/prompt/\",\n\t\t\tpayload: {\n\t\t\t\tprompt,\n\t\t\t\tactive_project: activeProjectId,\n\t\t\t},\n\t\t\tblockers: [\"prompt\"],\n\t\t\tblocks: [\"prompt\"],\n\t\t}).then((response) => {\n\t\t\tthis.dispatch(addConversation(response))\n\t\t\treturn response\n\t\t})\n\t}\n\n\t/**\n\t * Prompt the agent with a message.\n\t * @param prompt The message to prompt the agent with.\n\t * @param conversationId If continuing an existing message, the UUID of that conversation.\n\t */\n\tasync continueConversation(prompt: string, conversationId: AgentUserConversation[\"offline_id\"]): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst activeProjectId = store.getState().projectReducer.activeProjectId\n\n\t\treturn this.enqueueRequest<Created<AgentUserConversation>>({\n\t\t\tdescription: \"Prompt agent\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/agents/prompt/\",\n\t\t\tpayload: {\n\t\t\t\tprompt: prompt,\n\t\t\t\tactive_project: activeProjectId,\n\t\t\t},\n\t\t\tblockers: [\"prompt\"],\n\t\t\tblocks: [\"prompt\"],\n\t\t\tqueryParams: { conversation_id: conversationId },\n\t\t}).then((response) => {\n\t\t\tthis.dispatch(updateConversation(response))\n\t\t})\n\t}\n\n\tasync fetchDetails(conversationId: AgentUserConversation[\"offline_id\"]): Promise<void> {\n\t\treturn this.enqueueRequest<AgentUserConversation>({\n\t\t\tdescription: \"Get agent conversation\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/agents/conversations/${conversationId}/`,\n\t\t\tblockers: [\"conversation\"],\n\t\t\tblocks: [\"conversation\"],\n\t\t}).then((response) => {\n\t\t\tthis.dispatch(setConversation(response))\n\t\t})\n\t}\n\n\tasync rate(responseId: string, rating: 1 | 5): Promise<undefined> {\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Rate agent response\",\n\t\t\tmethod: HttpMethod.PUT,\n\t\t\turl: `/agents/responses/${responseId}/rate/`,\n\t\t\tpayload: { rating },\n\t\t\tblockers: [\"rate\"],\n\t\t\tblocks: [\"rate\"],\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<AgentUserConversation[]>({\n\t\t\tdescription: \"Get agent conversation history\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/agent-conversations/`,\n\t\t\tblockers: [\"agent-conversations\"],\n\t\t\tblocks: [\"agent-conversations\"],\n\t\t})\n\t\tthis.dispatch(initializeConversations(result))\n\t}\n}\n","import type { Created, Offline, OvermapRootState, Payload, Submitted, Team, User } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { addTeam, deleteTeam, initializeTeams, selectTeamById, setTeam, updateTeam } from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class TeamService<TState extends OvermapRootState, TSDK extends BaseSDK<TState>> extends BaseApiService<\n\tTState,\n\tTSDK\n> {\n\tadd(payload: Payload<Team>): OptimisticModelResult<Team> {\n\t\tconst offlineTeam: Submitted<Team> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\t// TODO: uncomment once supported\n\t\t\t// created_by: state.userReducer.currentUser.id,\n\t\t})\n\n\t\tthis.dispatch(addTeam(offlineTeam))\n\n\t\tconst promise = this.enqueueRequest<Team>({\n\t\t\tdescription: \"Create team\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/organizations/${payload.organization}/teams/`,\n\t\t\tpayload: offlineTeam,\n\t\t\t// No blocks since users and organizations are not offline\n\t\t\tblockers: [],\n\t\t\tblocks: [offlineTeam.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((createdTeam) => {\n\t\t\t\tthis.dispatch(setTeam(createdTeam))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteTeam(offlineTeam.offline_id))\n\t\t\t})\n\n\t\treturn [offlineTeam, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Team>>>): OptimisticModelResult<Team> {\n\t\tconst { store } = this.client\n\n\t\tconst teamToBeUpdated = selectTeamById(payload.offline_id)(store.getState())\n\n\t\tif (!teamToBeUpdated) {\n\t\t\tthrow new Error(`Expected team with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst offlineUpdatedTeam: Submitted<Team> = {\n\t\t\t...teamToBeUpdated,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateTeam(offlineUpdatedTeam))\n\n\t\tconst promise = this.enqueueRequest<Team>({\n\t\t\tdescription: \"Update team\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/organizations/teams/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((updatedTeam) => {\n\t\t\t\t// sync the updated team with the store\n\t\t\t\tthis.dispatch(setTeam(updatedTeam))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(setTeam(teamToBeUpdated))\n\t\t\t})\n\n\t\treturn [offlineUpdatedTeam, promise]\n\t}\n\n\tasync delete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst team = selectTeamById(id)(state)\n\n\t\tif (!team) {\n\t\t\tthrow new Error(`Expected team with id ${id} to exist`)\n\t\t}\n\n\t\tthis.dispatch(deleteTeam(id))\n\n\t\ttry {\n\t\t\t// REASON: Need to await to trigger the catch block.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n\t\t\treturn await this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete team\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/organizations/teams/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [id],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(setTeam(team))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync setMembers(teamId: string, members: User[\"id\"][]): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst team = selectTeamById(teamId)(store.getState())\n\n\t\tif (!team) {\n\t\t\tthrow new Error(`Expected team with id ${teamId} to exist`)\n\t\t}\n\n\t\tif (members.length !== new Set(members).size) {\n\t\t\tthrow new Error(\"Duplicate members found in the list\")\n\t\t}\n\n\t\tthis.dispatch(updateTeam({ ...team, members }))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Set team members\",\n\t\t\tmethod: HttpMethod.PUT,\n\t\t\turl: `/organizations/teams/${teamId}/set-members/`,\n\t\t\tpayload: {\n\t\t\t\tusers: members,\n\t\t\t},\n\t\t\tblockers: [teamId],\n\t\t\tblocks: [teamId],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(setTeam(team))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync addMembers(teamId: string, members: User[\"id\"][]): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst team = selectTeamById(teamId)(store.getState())\n\n\t\tif (!team) {\n\t\t\tthrow new Error(`Expected team with id ${teamId} to exist`)\n\t\t}\n\n\t\tconst newMembers = [...team.members, ...members]\n\n\t\treturn this.setMembers(teamId, newMembers)\n\t}\n\n\tasync removeMembers(teamId: string, members: User[\"id\"][]): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst team = selectTeamById(teamId)(store.getState())\n\n\t\tif (!team) {\n\t\t\tthrow new Error(`Expected team with id ${teamId} to exist`)\n\t\t}\n\n\t\tconst newMembers = team.members.filter((member) => !members.includes(member))\n\n\t\treturn this.setMembers(teamId, newMembers)\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<Team>[]>({\n\t\t\tdescription: \"Fetch teams\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/teams/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeTeams(result))\n\t}\n}\n","import { BaseApiService } from \"./BaseApiService\"\nimport { setUsers } from \"../../store\"\nimport type { OvermapRootState, User } from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class UserService<TState extends OvermapRootState, TSDK extends BaseSDK<TState>> extends BaseApiService<\n\tTState,\n\tTSDK\n> {\n\tasync refreshStore(projectId: number, organizationId: number): Promise<void> {\n\t\tconst usersRecord: Record<number, User> = {}\n\n\t\tconst organizationUsers = await this.enqueueRequest<User[]>({\n\t\t\tdescription: \"Fetch organization users\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/users/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const user of organizationUsers) {\n\t\t\tusersRecord[user.id] = user\n\t\t}\n\n\t\tconst projectUsers = await this.enqueueRequest<User[]>({\n\t\t\tdescription: \"Fetch project users\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/users/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const user of projectUsers) {\n\t\t\tusersRecord[user.id] = user\n\t\t}\n\n\t\tthis.dispatch(setUsers(Object.values(usersRecord)))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport type {\n\tBulkGeoImagePayload,\n\tCreated,\n\tFilePayload,\n\tGeoImage,\n\tGeoImagePayload,\n\tOffline,\n\tOvermapRootState,\n\tPointGeometry,\n\tStored,\n\tSubmitted,\n} from \"../../typings\"\nimport type { OptimisticModelResult, OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport {\n\taddGeoImage,\n\taddGeoImages,\n\tdeleteGeoImage,\n\tdeleteGeoImages,\n\tinitializeGeoImages,\n\tselectGeoImageById,\n\tsetGeoImage,\n\tsetGeoImages,\n\tupdateGeoImage,\n} from \"../../store\"\n\ninterface BulkCreateGeoImagesPayload {\n\tsubmitted_at: string\n\tproject: number\n\tgeo_images: {\n\t\t// requireds\n\t\toffline_id: string\n\t\tsha1: string\n\t\tfile_name: string\n\t\t// optionals\n\t\ttitle?: string\n\t\tdescription?: string\n\t\tgeo_marker?: PointGeometry\n\t\tcanvas_marker?: PointGeometry\n\n\t\tdirection?: number\n\t\toriginal_date?: string\n\t}[]\n\tfiles: FilePayload[]\n}\n\ninterface CreateGeoImageResult {\n\tgeo_image: Created<GeoImage>\n\tpresigned_urls: PresignedUrlsResponse\n}\n\ninterface BulkCreateMapImagesResult {\n\tgeo_images: Created<GeoImage>[]\n\tpresigned_urls: PresignedUrlsResponse\n}\n\nexport abstract class GeoImageService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync add(payload: GeoImagePayload): Promise<OptimisticModelResult<GeoImage>> {\n\t\tconst { store } = this.client\n\n\t\tconst { file, ...payloadWithoutFile } = payload\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst projectId = payloadWithoutFile.project\n\n\t\tconst filePayload: FilePayload = await this.getFilePayload(file)\n\n\t\tconst offlineMapImage: Stored<GeoImage> = offline({\n\t\t\t...payloadWithoutFile,\n\t\t\tfile_name: file.name,\n\t\t\tfile_sha1: filePayload.sha1,\n\t\t\tfile: URL.createObjectURL(file),\n\t\t\tsubmitted_at: submittedAt,\n\t\t\tcreated_by: createdBy,\n\t\t})\n\n\t\tthis.dispatch(addGeoImage(offlineMapImage))\n\n\t\tconst promise = this.enqueueRequest<CreateGeoImageResult>({\n\t\t\tdescription: \"Add geo image\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/geo-images/\",\n\t\t\tpayload: {\n\t\t\t\toffline_id: offlineMapImage.offline_id,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\ttitle: offlineMapImage.title,\n\t\t\t\tdescription: offlineMapImage.description,\n\t\t\t\tgeo_marker: offlineMapImage.geo_marker,\n\t\t\t\tcanvas_marker: offlineMapImage.canvas_marker,\n\t\t\t\tsha1: offlineMapImage.file_sha1,\n\t\t\t\tproject: offlineMapImage.project,\n\t\t\t\tfile_name: offlineMapImage.file_name,\n\t\t\t\tdirection: offlineMapImage.direction,\n\t\t\t\toriginal_date: offlineMapImage.original_date,\n\t\t\t\tfile: filePayload,\n\t\t\t},\n\t\t\tblocks: [projectId.toString()],\n\t\t\tblockers: [projectId.toString()],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(setGeoImage(result.geo_image))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteGeoImage(offlineMapImage.offline_id))\n\t\t\t})\n\n\t\treturn [offlineMapImage, promise.then((result) => result.geo_image)]\n\t}\n\n\tasync bulkAdd(\n\t\tpayloads: BulkGeoImagePayload[],\n\t\tprojectId: number,\n\t): Promise<OptimisticMultipleModelResult<GeoImage>> {\n\t\tconst { store } = this.client\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\n\t\tconst offlineGeoImages: Submitted<GeoImage>[] = []\n\t\tconst offlineIds: string[] = []\n\t\tconst geoImagePayloads: BulkCreateGeoImagesPayload[\"geo_images\"] = []\n\t\tconst filePayloads: Record<string, FilePayload> = {}\n\n\t\tfor (const payloadAndFile of payloads) {\n\t\t\tconst { file, ...payload } = payloadAndFile\n\n\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\tif (!(filePayload.sha1 in filePayloads)) filePayloads[filePayload.sha1] = filePayload\n\n\t\t\tconst offlineMapImage: Stored<GeoImage> = offline({\n\t\t\t\t...payload,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tproject: projectId,\n\t\t\t})\n\t\t\tofflineGeoImages.push(offlineMapImage)\n\n\t\t\tofflineIds.push(offlineMapImage.offline_id)\n\n\t\t\tgeoImagePayloads.push({\n\t\t\t\toffline_id: offlineMapImage.offline_id,\n\t\t\t\tsha1: offlineMapImage.file_sha1,\n\t\t\t\tfile_name: offlineMapImage.file_name,\n\n\t\t\t\ttitle: offlineMapImage.title,\n\t\t\t\tdescription: offlineMapImage.description,\n\t\t\t\tgeo_marker: offlineMapImage.geo_marker,\n\t\t\t\tcanvas_marker: offlineMapImage.canvas_marker,\n\t\t\t\tdirection: offlineMapImage.direction,\n\t\t\t\toriginal_date: offlineMapImage.original_date,\n\t\t\t})\n\t\t}\n\n\t\tthis.dispatch(addGeoImages(offlineGeoImages))\n\n\t\tconst promise = this.enqueueRequest<BulkCreateMapImagesResult>({\n\t\t\tdescription: \"Bulk add geo images\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/geo-images/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tproject: projectId,\n\t\t\t\tgeo_images: geoImagePayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t} satisfies BulkCreateGeoImagesPayload,\n\t\t\tblocks: [projectId.toString()],\n\t\t\tblockers: offlineIds,\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(setGeoImages(result.geo_images))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteGeoImages(offlineIds))\n\t\t\t})\n\n\t\treturn [offlineGeoImages, promise.then((result) => result.geo_images)]\n\t}\n\n\tupdate(payload: Offline<Partial<Pick<GeoImagePayload, \"title\" | \"description\">>>): OptimisticModelResult<GeoImage> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst geoImageToUpdate = selectGeoImageById(payload.offline_id)(state)\n\n\t\tif (!geoImageToUpdate) {\n\t\t\tthrow new Error(`Map image with offline_id ${payload.offline_id} does not exist in the store`)\n\t\t}\n\n\t\tconst updatedGeoImage: Stored<GeoImage> = { ...geoImageToUpdate, ...payload }\n\n\t\tthis.dispatch(updateGeoImage(updatedGeoImage))\n\n\t\tconst promise = this.enqueueRequest<Created<GeoImage>>({\n\t\t\tdescription: \"Update geo image\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/geo-images/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblocks: [payload.offline_id],\n\t\t\tblockers: [payload.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(setGeoImage(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(setGeoImage(geoImageToUpdate))\n\t\t\t})\n\n\t\treturn [updatedGeoImage, promise]\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst geoImageToDelete = selectGeoImageById(id)(state)\n\n\t\tif (!geoImageToDelete) {\n\t\t\tthrow new Error(`Map image with offline_id ${id} does not exist in the store`)\n\t\t}\n\n\t\tthis.dispatch(deleteGeoImage(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete geo image\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/geo-images/${id}/`,\n\t\t\tblocks: [id],\n\t\t\tblockers: [id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(setGeoImage(geoImageToDelete))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<GeoImage>[]>({\n\t\t\tdescription: \"Get geo images\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/geo-images/`,\n\t\t\tblocks: [projectId.toString()],\n\t\t\tblockers: [],\n\t\t})\n\n\t\tthis.dispatch(initializeGeoImages(result))\n\t}\n}\n","import type { Created, IssueAssociation, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { offline } from \"../../utils\"\nimport {\n\taddIssueAssociation,\n\tdeleteIssueAssociation,\n\tinitializeIssueAssociations,\n\tselectIssueAssociationById,\n\tupdateIssueAssociation,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\nimport { BaseApiService } from \"./BaseApiService\"\n\nexport abstract class IssueAssociationService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<IssueAssociation>): OptimisticModelResult<IssueAssociation> {\n\t\tconst { store } = this.client\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\n\t\tconst offlineIssueAssociation: Stored<IssueAssociation> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: submittedAt,\n\t\t\tcreated_by: createdBy,\n\t\t})\n\n\t\tthis.dispatch(addIssueAssociation(offlineIssueAssociation))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueAssociation>>({\n\t\t\tdescription: \"Add issue association\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/issue-associations/\",\n\t\t\tpayload: {\n\t\t\t\toffline_id: offlineIssueAssociation.offline_id,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\t...payload,\n\t\t\t},\n\t\t\tblockers: [\n\t\t\t\tpayload.associated_issue,\n\t\t\t\t...(payload.issue ? [payload.issue] : []),\n\t\t\t\t...(payload.asset ? [payload.asset] : []),\n\t\t\t],\n\t\t\tblocks: [offlineIssueAssociation.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((issueAssociation) => {\n\t\t\t\tthis.dispatch(updateIssueAssociation(issueAssociation))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteIssueAssociation(offlineIssueAssociation.offline_id))\n\t\t\t})\n\n\t\treturn [offlineIssueAssociation, promise]\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tconst { store } = this.client\n\n\t\tconst issueAssociation = selectIssueAssociationById(id)(store.getState())\n\n\t\tif (!issueAssociation) {\n\t\t\tthrow new Error(`Issue association with id ${id} not found in store.`)\n\t\t}\n\n\t\tthis.dispatch(deleteIssueAssociation(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete issue association\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/issue-associations/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addIssueAssociation(issueAssociation))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst issueAssociations = await this.enqueueRequest<Created<IssueAssociation>[]>({\n\t\t\tdescription: \"Fetch issue associations\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/issue-associations/\",\n\t\t\tqueryParams: { project: projectId.toString() },\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssueAssociations(issueAssociations))\n\t}\n}\n","import type {\n\tCreated,\n\tFileModelPayload,\n\tFilePayload,\n\tFormRevisionAttachment,\n\tOvermapRootState,\n\tStored,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddFormRevisionAttachments,\n\tdeleteFormRevisionAttachments,\n\tinitializeFormRevisionAttachments,\n\tupdateFormRevisionAttachments,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class FormRevisionAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync bulkAdd(\n\t\tpayloads: { revisionId: string; fieldIdentifier: string; file: File }[],\n\t): Promise<OptimisticMultipleModelResult<FormRevisionAttachment>> {\n\t\tinterface AttachmentPayload extends FileModelPayload {\n\t\t\toffline_id: string\n\t\t\tfield_identifier: string\n\t\t\tform_revision: string\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser?.id\n\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\t\tconst offlineFormRevisionAttachments: Stored<FormRevisionAttachment>[] = []\n\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\n\t\tfor (const payload of payloads) {\n\t\t\tconst { revisionId, fieldIdentifier, file } = payload\n\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\tif (!(filePayload.sha1 in filePayloads)) filePayloads[filePayload.sha1] = filePayload\n\n\t\t\tconst offlineFormRevisionAttachment: Stored<FormRevisionAttachment> = offline({\n\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\tfile_type: file.type,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tform_revision: revisionId,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t})\n\t\t\tofflineFormRevisionAttachments.push(offlineFormRevisionAttachment)\n\n\t\t\tconst attachmentPayload: AttachmentPayload = {\n\t\t\t\toffline_id: offlineFormRevisionAttachment.offline_id,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\tfile_extension: filePayload.extension,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tform_revision: revisionId,\n\t\t\t}\n\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t}\n\n\t\tthis.dispatch(addFormRevisionAttachments(offlineFormRevisionAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<FormRevisionAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: \"Attach files to form revision\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/form-revision-attachments/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblockers: offlineFormRevisionAttachments.map((attachment) => attachment.form_revision),\n\t\t\tblocks: offlineFormRevisionAttachments.map((attachment) => attachment.offline_id),\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(updateFormRevisionAttachments(result.attachments))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteFormRevisionAttachments(\n\t\t\t\t\t\tofflineFormRevisionAttachments.map((attachment) => attachment.offline_id),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t})\n\n\t\treturn [offlineFormRevisionAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst formRevisions = await this.enqueueRequest<Created<FormRevisionAttachment>[]>({\n\t\t\tdescription: \"Fetch organization form revision attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/form-revision-attachments/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [organizationId.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeFormRevisionAttachments(formRevisions))\n\t}\n}\n","import type {\n\tCreated,\n\tFileModelPayload,\n\tFilePayload,\n\tFormSubmissionAttachment,\n\tOvermapRootState,\n\tStored,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddFormSubmissionAttachments,\n\tdeleteFormSubmissionAttachments,\n\tinitializeFormSubmissionAttachments,\n\tselectFormSubmissionAttachemntsByIds,\n\tupdateFormSubmissionAttachments,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class FormSubmissionAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync bulkAdd(\n\t\tpayloads: { submissionId: string; fieldIdentifier: string; file: File }[],\n\t): Promise<OptimisticMultipleModelResult<FormSubmissionAttachment>> {\n\t\tinterface AttachmentPayload extends FileModelPayload {\n\t\t\toffline_id: string\n\t\t\tfield_identifier: string\n\t\t\tform_submission: string\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser?.id\n\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\t\tconst offlineFormSubmissionAttachments: Stored<FormSubmissionAttachment>[] = []\n\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\n\t\tfor (const payload of payloads) {\n\t\t\tconst { submissionId, fieldIdentifier, file } = payload\n\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\tif (!(filePayload.sha1 in filePayloads)) filePayloads[filePayload.sha1] = filePayload\n\n\t\t\tconst offlineFormSubmissionAttachment: Stored<FormSubmissionAttachment> = offline({\n\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\tfile_type: file.type,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tform_submission: submissionId,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t})\n\t\t\tofflineFormSubmissionAttachments.push(offlineFormSubmissionAttachment)\n\n\t\t\tconst attachmentPayload: AttachmentPayload = {\n\t\t\t\toffline_id: offlineFormSubmissionAttachment.offline_id,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tfile_extension: filePayload.extension,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\tform_submission: submissionId,\n\t\t\t}\n\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t}\n\n\t\tthis.dispatch(addFormSubmissionAttachments(offlineFormSubmissionAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<FormSubmissionAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: \"Attach files to form submission\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/form-submission-attachments/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblockers: offlineFormSubmissionAttachments.map((attachment) => attachment.form_submission),\n\t\t\tblocks: offlineFormSubmissionAttachments.map((attachment) => attachment.offline_id),\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(updateFormSubmissionAttachments(result.attachments))\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteFormSubmissionAttachments(\n\t\t\t\t\t\tofflineFormSubmissionAttachments.map((attachment) => attachment.offline_id),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\tthrow error\n\t\t\t})\n\n\t\treturn [offlineFormSubmissionAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tasync bulkDelete(attachmentsIds: string[]): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst formSubmissionAttachments = selectFormSubmissionAttachemntsByIds(attachmentsIds)(state)\n\n\t\tthis.dispatch(deleteFormSubmissionAttachments(attachmentsIds))\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete form submission attachments\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: \"/form-submission-attachments/bulk/\",\n\t\t\t\tpayload: { attachment_ids: attachmentsIds },\n\t\t\t\tblockers: attachmentsIds,\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addFormSubmissionAttachments(formSubmissionAttachments))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<FormSubmissionAttachment>[]>({\n\t\t\tdescription: \"Get form submission attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/form-submission-attachments/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeFormSubmissionAttachments(result))\n\t}\n}\n","import { HttpMethod } from \"enums\"\nimport type { Created, FormRevision, FormRevisionPayload, OvermapRootState, Stored } from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport { addFormRevision, deleteFormRevision, initializeFormRevisions, setFormRevision } from \"../../store\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\n\nexport abstract class FormRevisionService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tadd(payload: FormRevisionPayload): OptimisticModelResult<FormRevision> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst createdBy = state.userReducer.currentUser?.id\n\n\t\tconst offlineFormRevision: Stored<FormRevision> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\trevision: \"Pending\",\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t})\n\n\t\tthis.dispatch(addFormRevision(offlineFormRevision))\n\n\t\tconst promise = this.enqueueRequest<Created<FormRevision>>({\n\t\t\tdescription: \"Create form revision\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/form-revisions/\",\n\t\t\tpayload: offlineFormRevision,\n\t\t\tblockers: [payload.form],\n\t\t\tblocks: [offlineFormRevision.offline_id],\n\t\t})\n\n\t\tvoid promise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(setFormRevision(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteFormRevision(offlineFormRevision.offline_id))\n\t\t\t})\n\n\t\treturn [offlineFormRevision, promise]\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst formRevisions = await this.enqueueRequest<Created<FormRevision>[]>({\n\t\t\tdescription: \"Get organization form revisions\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/form-revisions/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [organizationId.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeFormRevisions(formRevisions))\n\t}\n}\n","import type {\n\tAssetTypeFieldsAttachment,\n\tCreated,\n\tFileModelPayload,\n\tFilePayload,\n\tOvermapRootState,\n\tStored,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddAssetTypeFieldsAttachments,\n\tdeleteAssetTypeFieldsAttachments,\n\tinitializeAssetTypeFieldsAttachments,\n\tupdateAssetTypeFieldsAttachments,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class AssetTypeFieldsAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync bulkAdd(\n\t\tpayloads: { fieldsRevisionId: string; fieldIdentifier: string; file: File }[],\n\t): Promise<OptimisticMultipleModelResult<AssetTypeFieldsAttachment>> {\n\t\tinterface AttachmentPayload extends FileModelPayload {\n\t\t\toffline_id: string\n\t\t\tfield_identifier: string\n\t\t\tfields_revision: string\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser?.id\n\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\t\tconst offlineAssetTypeFieldsAttachments: Stored<AssetTypeFieldsAttachment>[] = []\n\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\n\t\tfor (const payload of payloads) {\n\t\t\tconst { fieldsRevisionId, fieldIdentifier, file } = payload\n\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\tif (!(filePayload.sha1 in filePayloads)) filePayloads[filePayload.sha1] = filePayload\n\n\t\t\tconst offlineAssetTypeFieldsAttachment: Stored<AssetTypeFieldsAttachment> = offline({\n\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\tfile_type: file.type,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tfields_revision: fieldsRevisionId,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t})\n\t\t\tofflineAssetTypeFieldsAttachments.push(offlineAssetTypeFieldsAttachment)\n\n\t\t\tconst attachmentPayload: AttachmentPayload = {\n\t\t\t\toffline_id: offlineAssetTypeFieldsAttachment.offline_id,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\tfile_extension: filePayload.extension,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tfields_revision: fieldsRevisionId,\n\t\t\t}\n\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t}\n\n\t\tthis.dispatch(addAssetTypeFieldsAttachments(offlineAssetTypeFieldsAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<AssetTypeFieldsAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: \"Add asset type fields attachments\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-type-fields-attachments/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblockers: offlineAssetTypeFieldsAttachments.map((attachment) => attachment.fields_revision),\n\t\t\tblocks: offlineAssetTypeFieldsAttachments.map((attachment) => attachment.offline_id),\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(updateAssetTypeFieldsAttachments(result.attachments))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteAssetTypeFieldsAttachments(\n\t\t\t\t\t\tofflineAssetTypeFieldsAttachments.map((attachment) => attachment.offline_id),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t})\n\n\t\treturn [offlineAssetTypeFieldsAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tasync refreshStore(organization: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<AssetTypeFieldsAttachment>[]>({\n\t\t\tdescription: \"Get asset type fields attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-type-fields-attachments/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organization.toString(),\n\t\t\t},\n\t\t\tblockers: [organization.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetTypeFieldsAttachments(result))\n\t}\n}\n","import type { AssetTypeFields, Created, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddAssetTypeFields,\n\tdeleteAssetTypeFields,\n\tinitializeAssetTypeFields,\n\tupdateAssetTypeFields,\n} from \"../../store\"\n\nexport abstract class AssetTypeFieldsService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<AssetTypeFields>): OptimisticModelResult<AssetTypeFields> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAssetTypeFields: Stored<AssetTypeFields> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addAssetTypeFields(offlineAssetTypeFields))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetTypeFields>>({\n\t\t\tdescription: \"Add Asset Type Fields\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-type-fields/\",\n\t\t\tpayload: offlineAssetTypeFields,\n\t\t\tblockers: [offlineAssetTypeFields.asset_type],\n\t\t\tblocks: [offlineAssetTypeFields.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((response) => {\n\t\t\t\tthis.dispatch(updateAssetTypeFields(response))\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.dispatch(deleteAssetTypeFields(offlineAssetTypeFields.offline_id))\n\t\t\t\tthrow error\n\t\t\t})\n\n\t\treturn [offlineAssetTypeFields, promise]\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<AssetTypeFields[]>({\n\t\t\tdescription: \"Get Asset Type Fields\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-type-fields/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetTypeFields(result))\n\t}\n}\n","import type {\n\tAssetTypeFieldValues,\n\tCreated,\n\tOffline,\n\tOvermapRootState,\n\tPayload,\n\tStored,\n\tSubmitted,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddAssetTypeFieldValues,\n\taddAssetTypeFieldValuesAttachments,\n\taddAssetTypeFieldValuesMany,\n\tdeleteAssetTypeFieldValues,\n\tdeleteAssetTypeFieldValuesAttachments,\n\tdeleteAssetTypeFieldValuesMany,\n\tinitializeAssetTypeFieldValues,\n\tselectAssetTypeFieldValuesById,\n\tselectAttachmentsOfAssetTypeFieldValues,\n\tupdateAssetTypeFieldValues,\n\tupdateAssetTypeFieldValuesMany,\n} from \"../../store\"\nimport { separateFilesFromValues } from \"./FormSubmissionService\"\nimport { FieldValue } from \"@overmap-ai/forms\"\nimport { chunkArray } from \"../../utils/array\"\n\nexport abstract class AssetTypeFieldValuesService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<AssetTypeFieldValues>): OptimisticModelResult<AssetTypeFieldValues> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst { values } = separateFilesFromValues(payload.values)\n\n\t\tconst offlineAssetTypeFieldValues: Submitted<AssetTypeFieldValues> = offline({\n\t\t\t...payload,\n\t\t\tvalues: values,\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t})\n\n\t\tconst promise = this.enqueueRequest<Created<AssetTypeFieldValues>>({\n\t\t\tdescription: \"Add asset type field values\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-type-field-values/\",\n\t\t\tpayload: offlineAssetTypeFieldValues,\n\t\t\tblockers: [payload.asset, payload.fields_revision],\n\t\t\tblocks: [offlineAssetTypeFieldValues.offline_id],\n\t\t})\n\n\t\tthis.dispatch(addAssetTypeFieldValues(offlineAssetTypeFieldValues))\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetTypeFieldValues(result))\n\t\t\t\treturn result\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetTypeFieldValues(offlineAssetTypeFieldValues.offline_id))\n\t\t\t})\n\n\t\treturn [offlineAssetTypeFieldValues, promise]\n\t}\n\n\tbulkAdd(\n\t\tpayload: {\n\t\t\tvalues: Record<string, FieldValue>\n\t\t\tpayloads: {\n\t\t\t\tvalues: Record<string, FieldValue>\n\t\t\t\tasset: string\n\t\t\t\tfields_revision: string\n\t\t\t\tpublished_at: string\n\t\t\t}[]\n\t\t},\n\t\tbatchSize?: number,\n\t): [Stored<AssetTypeFieldValues>[], Promise<Created<AssetTypeFieldValues>[]>[]] {\n\t\tinterface AssetTypeFieldValuesBulkPayload {\n\t\t\toffline_id: string\n\t\t\tasset: string\n\t\t\tfields_revision: string\n\t\t\tpublished_at: string\n\t\t\tvalues: Record<string, FieldValue>\n\t\t}\n\n\t\tinterface Payload {\n\t\t\tsubmitted_at: string\n\t\t\tvalues: Record<string, FieldValue>\n\t\t\tfield_values: AssetTypeFieldValuesBulkPayload[]\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst { values } = separateFilesFromValues(payload.values)\n\t\tconst offlineAssetTypeFieldValuesMany: Stored<AssetTypeFieldValues>[] = []\n\t\tconst batches = chunkArray(payload.payloads, batchSize ?? payload.payloads.length)\n\t\tconst batchPayloads: Payload[] = []\n\n\t\tfor (const batch of batches) {\n\t\t\tconst assetTypeFieldValuesPayloads: AssetTypeFieldValuesBulkPayload[] = []\n\n\t\t\tfor (const payload of batch) {\n\t\t\t\tconst offlineAssetTypeFieldValues: Stored<AssetTypeFieldValues> = offline({\n\t\t\t\t\t...payload,\n\t\t\t\t\tvalues: separateFilesFromValues(payload.values).values,\n\t\t\t\t\tcreated_by: this.client.store.getState().userReducer.currentUser?.id,\n\t\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\t})\n\n\t\t\t\tofflineAssetTypeFieldValuesMany.push(offlineAssetTypeFieldValues)\n\n\t\t\t\tassetTypeFieldValuesPayloads.push({\n\t\t\t\t\toffline_id: offlineAssetTypeFieldValues.offline_id,\n\t\t\t\t\tasset: payload.asset,\n\t\t\t\t\tfields_revision: payload.fields_revision,\n\t\t\t\t\tpublished_at: payload.published_at,\n\t\t\t\t\tvalues: offlineAssetTypeFieldValues.values,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tbatchPayloads.push({\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tvalues: values,\n\t\t\t\tfield_values: assetTypeFieldValuesPayloads,\n\t\t\t})\n\t\t}\n\n\t\tthis.dispatch(addAssetTypeFieldValuesMany(offlineAssetTypeFieldValuesMany))\n\n\t\tconst promises: Promise<Created<AssetTypeFieldValues>[]>[] = []\n\n\t\tfor (const payload of batchPayloads) {\n\t\t\tconst assetIds = payload.field_values.map((x) => x.asset)\n\t\t\tconst assetTypeFieldsIds = payload.field_values.map((x) => x.fields_revision)\n\t\t\tconst assetTypeFieldValuesIds = payload.field_values.map((x) => x.offline_id)\n\n\t\t\tconst promise = this.enqueueRequest<Created<AssetTypeFieldValues>[]>({\n\t\t\t\tdescription: \"Bulk add asset type field values\",\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\turl: \"/asset-type-field-values/bulk/\",\n\t\t\t\tpayload: payload,\n\t\t\t\tblockers: [...assetIds, ...assetTypeFieldsIds],\n\t\t\t\tblocks: assetTypeFieldValuesIds,\n\t\t\t})\n\n\t\t\tpromises.push(promise)\n\t\t}\n\n\t\tvoid Promise.all(promises)\n\t\t\t.then((results) => {\n\t\t\t\tthis.dispatch(updateAssetTypeFieldValuesMany(results.flat()))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetTypeFieldValuesMany(offlineAssetTypeFieldValuesMany.map((x) => x.offline_id)))\n\t\t\t})\n\n\t\treturn [offlineAssetTypeFieldValuesMany, promises]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<AssetTypeFieldValues>>>): OptimisticModelResult<AssetTypeFieldValues> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst assetTypeFieldValues = selectAssetTypeFieldValuesById(payload.offline_id)(state)\n\n\t\tif (!assetTypeFieldValues) {\n\t\t\tthrow new Error(`Expected AssetTypeFieldValues with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst { values } = separateFilesFromValues(payload.values ?? {})\n\n\t\tconst updatedAssetTypeFieldValues: Stored<AssetTypeFieldValues> = {\n\t\t\t...assetTypeFieldValues,\n\t\t\t...payload,\n\t\t\t// values could also have a partial update\n\t\t\tvalues: {\n\t\t\t\t...assetTypeFieldValues.values,\n\t\t\t\t...values,\n\t\t\t},\n\t\t}\n\n\t\tthis.dispatch(updateAssetTypeFieldValues(updatedAssetTypeFieldValues))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetTypeFieldValues>>({\n\t\t\tdescription: \"Delete asset type field values\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/asset-type-field-values/${payload.offline_id}/`,\n\t\t\tpayload: {\n\t\t\t\t...payload,\n\t\t\t\tvalues: {\n\t\t\t\t\t...assetTypeFieldValues.values,\n\t\t\t\t\t...values,\n\t\t\t\t},\n\t\t\t},\n\t\t\tblockers: [\n\t\t\t\tupdatedAssetTypeFieldValues.offline_id,\n\t\t\t\tupdatedAssetTypeFieldValues.fields_revision,\n\t\t\t\tupdatedAssetTypeFieldValues.asset,\n\t\t\t],\n\t\t\tblocks: [updatedAssetTypeFieldValues.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetTypeFieldValues(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateAssetTypeFieldValues(assetTypeFieldValues))\n\t\t\t})\n\n\t\treturn [updatedAssetTypeFieldValues, promise]\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst assetTypeFieldValues = selectAssetTypeFieldValuesById(id)(state)\n\n\t\tif (!assetTypeFieldValues) {\n\t\t\tthrow new Error(`Expected submission with offline_id ${id} to exist`)\n\t\t}\n\n\t\tconst assetTypeFieldValuesAttachments = selectAttachmentsOfAssetTypeFieldValues(id)(state)!\n\n\t\tthis.dispatch(deleteAssetTypeFieldValues(id))\n\t\tthis.dispatch(deleteAssetTypeFieldValuesAttachments(assetTypeFieldValuesAttachments.map((x) => x.offline_id)))\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete asset type field values\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/asset-type-field-values/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addAssetTypeFieldValues(assetTypeFieldValues))\n\t\t\tthis.dispatch(addAssetTypeFieldValuesAttachments(assetTypeFieldValuesAttachments))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<AssetTypeFieldValues>[]>({\n\t\t\tdescription: \"Get asset type field values\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-type-field-values/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetTypeFieldValues(result))\n\t}\n}\n","import type {\n\tAssetTypeFieldValuesAttachment,\n\tCreated,\n\tFileModelPayload,\n\tFilePayload,\n\tOvermapRootState,\n\tStored,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport { type PresignedUrlsResponse } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddAssetTypeFieldValuesAttachments,\n\tdeleteAssetTypeFieldValuesAttachments,\n\tinitializeAssetTypeFieldValuesAttachments,\n\tselectAssetTypeFieldValuesAttachmentsByIds,\n\tupdateAssetTypeFieldValuesAttachments,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\nimport { chunkArray } from \"../../utils/array\"\n\nexport abstract class AssetTypeFieldValuesAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync bulkAdd(\n\t\tpayloads: { fieldValuesId: string; fieldIdentifier: string; file: File }[],\n\t\tbatchSize?: number,\n\t): Promise<[Stored<AssetTypeFieldValuesAttachment>[], Promise<Created<AssetTypeFieldValuesAttachment>[]>[]]> {\n\t\tinterface AttachmentPayload extends FileModelPayload {\n\t\t\toffline_id: string\n\t\t\tfield_identifier: string\n\t\t\tfield_values: string\n\t\t}\n\n\t\tinterface Payload {\n\t\t\tsubmitted_at: string\n\t\t\tattachments: AttachmentPayload[]\n\t\t\tfiles: FilePayload[]\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser?.id\n\t\tconst batches = chunkArray(payloads, batchSize ?? payloads.length)\n\t\tconst offlineAssetTypeFieldValuesAttachments: Stored<AssetTypeFieldValuesAttachment>[] = []\n\t\tconst batchPayloads: Payload[] = []\n\n\t\tfor (const batch of batches) {\n\t\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\t\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\n\t\t\tfor (const payload of batch) {\n\t\t\t\tconst { fieldValuesId, fieldIdentifier, file } = payload\n\t\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\t\tif (!(filePayload.sha1 in filePayloads)) filePayloads[filePayload.sha1] = filePayload\n\n\t\t\t\tconst offlineAssetTypeFieldValuesAttachment: Stored<AssetTypeFieldValuesAttachment> = offline({\n\t\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\t\tfile_type: file.type,\n\t\t\t\t\tfile_name: file.name,\n\t\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\t\tcreated_by: createdBy,\n\t\t\t\t\tfield_values: fieldValuesId,\n\t\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\t})\n\t\t\t\tofflineAssetTypeFieldValuesAttachments.push(offlineAssetTypeFieldValuesAttachment)\n\n\t\t\t\tconst attachmentPayload: AttachmentPayload = {\n\t\t\t\t\toffline_id: offlineAssetTypeFieldValuesAttachment.offline_id,\n\t\t\t\t\tfile_name: file.name,\n\t\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\t\tfile_extension: filePayload.extension,\n\t\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\t\tfield_values: fieldValuesId,\n\t\t\t\t}\n\t\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t\t}\n\n\t\t\tbatchPayloads.push({\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t})\n\t\t}\n\n\t\tthis.dispatch(addAssetTypeFieldValuesAttachments(offlineAssetTypeFieldValuesAttachments))\n\n\t\tconst promises = batchPayloads.map((payload) => {\n\t\t\treturn this.enqueueRequest<{\n\t\t\t\tattachments: Created<AssetTypeFieldValuesAttachment>[]\n\t\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t\t}>({\n\t\t\t\tdescription: \"Add asset type field values attachments\",\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\turl: \"/asset-type-field-values-attachments/bulk/\",\n\t\t\t\tpayload: payload,\n\t\t\t\tblockers: payload.attachments.map((payload) => payload.field_values),\n\t\t\t\tblocks: payload.attachments.map((payload) => payload.offline_id),\n\t\t\t})\n\t\t})\n\n\t\tPromise.all(promises)\n\t\t\t.then((result) => {\n\t\t\t\tfor (const res of result) this.processPresignedUrls(res.presigned_urls)\n\t\t\t\tconst attachments = result.flatMap((res) => res.attachments)\n\t\t\t\tthis.dispatch(updateAssetTypeFieldValuesAttachments(attachments))\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteAssetTypeFieldValuesAttachments(\n\t\t\t\t\t\tofflineAssetTypeFieldValuesAttachments.map((attachment) => attachment.offline_id),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\tthrow error\n\t\t\t})\n\n\t\treturn [\n\t\t\tofflineAssetTypeFieldValuesAttachments,\n\t\t\tpromises.map((promise) => promise.then(({ attachments }) => attachments)),\n\t\t]\n\t}\n\n\tasync bulkDelete(ids: string[]): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst attachments = selectAssetTypeFieldValuesAttachmentsByIds(ids)(state)\n\t\tthis.dispatch(deleteAssetTypeFieldValuesAttachments(ids))\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete asset type field values attachments\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: \"/asset-type-field-values-attachments/bulk/\",\n\t\t\t\tpayload: { attachment_ids: ids },\n\t\t\t\tblockers: ids,\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addAssetTypeFieldValuesAttachments(attachments))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<AssetTypeFieldValuesAttachment>[]>({\n\t\t\tdescription: \"Get asset type field values attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-type-field-values-attachments/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetTypeFieldValuesAttachments(result))\n\t}\n}\n","import type {\n\tIssueTypeFieldsAttachment,\n\tCreated,\n\tFilePayload,\n\tOvermapRootState,\n\tStored,\n\tFileModelPayload,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddIssueTypeFieldsAttachments,\n\tdeleteIssueTypeFieldsAttachments,\n\tinitializeIssueTypeFieldsAttachments,\n\tupdateIssueTypeFieldsAttachments,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class IssueTypeFieldsAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync bulkAdd(\n\t\tpayloads: { fieldsRevisionId: string; fieldIdentifier: string; file: File }[],\n\t): Promise<OptimisticMultipleModelResult<IssueTypeFieldsAttachment>> {\n\t\tinterface AttachmentPayload extends FileModelPayload {\n\t\t\toffline_id: string\n\t\t\tfield_identifier: string\n\t\t\tfields_revision: string\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser?.id\n\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\t\tconst offlineIssueTypeFieldsAttachments: Stored<IssueTypeFieldsAttachment>[] = []\n\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\n\t\tfor (const payload of payloads) {\n\t\t\tconst { fieldsRevisionId, fieldIdentifier, file } = payload\n\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\tif (!(filePayload.sha1 in filePayloads)) filePayloads[filePayload.sha1] = filePayload\n\n\t\t\tconst offlineIssueTypeFieldsAttachment: Stored<IssueTypeFieldsAttachment> = offline({\n\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\tfile_type: file.type,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tfields_revision: fieldsRevisionId,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t})\n\t\t\tofflineIssueTypeFieldsAttachments.push(offlineIssueTypeFieldsAttachment)\n\n\t\t\tconst attachmentPayload: AttachmentPayload = {\n\t\t\t\toffline_id: offlineIssueTypeFieldsAttachment.offline_id,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_extension: filePayload.extension,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tfields_revision: fieldsRevisionId,\n\t\t\t}\n\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t}\n\n\t\tthis.dispatch(addIssueTypeFieldsAttachments(offlineIssueTypeFieldsAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<IssueTypeFieldsAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: \"Add issue type fields attachments\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/issue-type-fields-attachments/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblockers: offlineIssueTypeFieldsAttachments.map((attachment) => attachment.fields_revision),\n\t\t\tblocks: offlineIssueTypeFieldsAttachments.map((attachment) => attachment.offline_id),\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(updateIssueTypeFieldsAttachments(result.attachments))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteIssueTypeFieldsAttachments(\n\t\t\t\t\t\tofflineIssueTypeFieldsAttachments.map((attachment) => attachment.offline_id),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t})\n\n\t\treturn [offlineIssueTypeFieldsAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<IssueTypeFieldsAttachment>[]>({\n\t\t\tdescription: \"get issue type fields attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/issue-type-fields-attachments/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [organizationId.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssueTypeFieldsAttachments(result))\n\t}\n}\n","import type { IssueTypeFields, Created, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddIssueTypeFields,\n\tdeleteIssueTypeFields,\n\tinitializeIssueTypeFields,\n\tupdateIssueTypeFields,\n} from \"../../store\"\n\nexport abstract class IssueTypeFieldsService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<IssueTypeFields>): OptimisticModelResult<IssueTypeFields> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineIssueTypeFields: Stored<IssueTypeFields> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addIssueTypeFields(offlineIssueTypeFields))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueTypeFields>>({\n\t\t\tdescription: \"Add Issue Type Fields\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/issue-type-fields/\",\n\t\t\tpayload: offlineIssueTypeFields,\n\t\t\tblockers: [offlineIssueTypeFields.issue_type],\n\t\t\tblocks: [offlineIssueTypeFields.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((response) => {\n\t\t\t\tthis.dispatch(updateIssueTypeFields(response))\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.dispatch(deleteIssueTypeFields(offlineIssueTypeFields.offline_id))\n\t\t\t\tthrow error\n\t\t\t})\n\n\t\treturn [offlineIssueTypeFields, promise]\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<IssueTypeFields[]>({\n\t\t\tdescription: \"Get Issue Type Fields\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/issue-type-fields/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssueTypeFields(result))\n\t}\n}\n","import type {\n\tCreated,\n\tFileModelPayload,\n\tFilePayload,\n\tIssueTypeFieldValuesAttachment,\n\tOvermapRootState,\n\tStored,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddIssueTypeFieldValuesAttachments,\n\tdeleteIssueTypeFieldValuesAttachments,\n\tinitializeIssueTypeFieldValuesAttachments,\n\tselectIssueTypeFieldValuesAttachmentsByIds,\n\tupdateIssueTypeFieldValuesAttachments,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class IssueTypeFieldValuesAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync bulkAdd(\n\t\tpayloads: {\n\t\t\tfieldValuesId: string\n\t\t\tfieldIdentifier: string\n\t\t\tfile: File\n\t\t}[],\n\t): Promise<OptimisticMultipleModelResult<IssueTypeFieldValuesAttachment>> {\n\t\tinterface AttachmentPayload extends FileModelPayload {\n\t\t\toffline_id: string\n\t\t\tfield_values: string\n\t\t\tfield_identifier: string\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser?.id\n\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\t\tconst offlineIssueTypeFieldValuesAttachments: Stored<IssueTypeFieldValuesAttachment>[] = []\n\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\n\t\tfor (const payload of payloads) {\n\t\t\tconst { fieldValuesId, fieldIdentifier, file } = payload\n\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\tif (!(filePayload.sha1 in filePayloads)) filePayloads[filePayload.sha1] = filePayload\n\n\t\t\tconst offlineIssueTypeFieldValuesAttachment: Stored<IssueTypeFieldValuesAttachment> = offline({\n\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\tfile_type: file.type,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tfield_values: fieldValuesId,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t})\n\t\t\tofflineIssueTypeFieldValuesAttachments.push(offlineIssueTypeFieldValuesAttachment)\n\n\t\t\tconst attachmentPayload: AttachmentPayload = {\n\t\t\t\toffline_id: offlineIssueTypeFieldValuesAttachment.offline_id,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tfile_extension: filePayload.extension,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\tfield_values: fieldValuesId,\n\t\t\t}\n\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t}\n\n\t\tthis.dispatch(addIssueTypeFieldValuesAttachments(offlineIssueTypeFieldValuesAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<IssueTypeFieldValuesAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: \"Add issue type field values attachments\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/issue-type-field-values-attachments/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblockers: offlineIssueTypeFieldValuesAttachments.map((attachment) => attachment.field_values),\n\t\t\tblocks: offlineIssueTypeFieldValuesAttachments.map((attachment) => attachment.offline_id),\n\t\t})\n\n\t\tpromise\n\t\t\t.then(({ presigned_urls, attachments }) => {\n\t\t\t\tthis.processPresignedUrls(presigned_urls)\n\t\t\t\tthis.dispatch(updateIssueTypeFieldValuesAttachments(attachments))\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteIssueTypeFieldValuesAttachments(\n\t\t\t\t\t\tofflineIssueTypeFieldValuesAttachments.map((attachment) => attachment.offline_id),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\tthrow error\n\t\t\t})\n\n\t\treturn [offlineIssueTypeFieldValuesAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tasync bulkDelete(attachmentsIds: string[]): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst attachments = selectIssueTypeFieldValuesAttachmentsByIds(attachmentsIds)(state)\n\t\tthis.dispatch(deleteIssueTypeFieldValuesAttachments(attachmentsIds))\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete issue type field values attachments\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: \"/issue-type-field-values-attachments/bulk/\",\n\t\t\t\tpayload: { attachment_ids: attachmentsIds },\n\t\t\t\tblockers: attachmentsIds,\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addIssueTypeFieldValuesAttachments(attachments))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<IssueTypeFieldValuesAttachment>[]>({\n\t\t\tdescription: \"Get issue type field values attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/issue-type-field-values-attachments/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssueTypeFieldValuesAttachments(result))\n\t}\n}\n","import type {\n\tIssueTypeFieldValues,\n\tCreated,\n\tOffline,\n\tOvermapRootState,\n\tPayload,\n\tStored,\n\tSubmitted,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddIssueTypeFieldValues,\n\taddIssueTypeFieldValuesAttachments,\n\tdeleteIssueTypeFieldValues,\n\tdeleteIssueTypeFieldValuesAttachments,\n\tinitializeIssueTypeFieldValues,\n\tselectIssueTypeFieldValuesById,\n\tselectAttachmentsOfIssueTypeFieldValues,\n\tupdateIssueTypeFieldValues,\n} from \"../../store\"\nimport { separateFilesFromValues } from \"./FormSubmissionService\"\n\nexport abstract class IssueTypeFieldValuesService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<IssueTypeFieldValues>): OptimisticModelResult<IssueTypeFieldValues> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst { values } = separateFilesFromValues(payload.values)\n\n\t\tconst offlineIssueTypeFieldValues: Submitted<IssueTypeFieldValues> = offline({\n\t\t\t...payload,\n\t\t\tvalues: values,\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t})\n\n\t\tconst promise = this.enqueueRequest<Created<IssueTypeFieldValues>>({\n\t\t\tdescription: \"Add issue type field values\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/issue-type-field-values/\",\n\t\t\tpayload: offlineIssueTypeFieldValues,\n\t\t\tblockers: [payload.issue, payload.fields_revision],\n\t\t\tblocks: [offlineIssueTypeFieldValues.offline_id],\n\t\t})\n\n\t\tthis.dispatch(addIssueTypeFieldValues(offlineIssueTypeFieldValues))\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateIssueTypeFieldValues(result))\n\t\t\t\treturn result\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteIssueTypeFieldValues(offlineIssueTypeFieldValues.offline_id))\n\t\t\t})\n\n\t\treturn [offlineIssueTypeFieldValues, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<IssueTypeFieldValues>>>): OptimisticModelResult<IssueTypeFieldValues> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst issueTypeFieldValues = selectIssueTypeFieldValuesById(payload.offline_id)(state)\n\n\t\tif (!issueTypeFieldValues) {\n\t\t\tthrow new Error(`Expected IssueTypeFieldValues with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst { values } = separateFilesFromValues(payload.values ?? {})\n\n\t\tconst updatedIssueTypeFieldValues: Stored<IssueTypeFieldValues> = {\n\t\t\t...issueTypeFieldValues,\n\t\t\t...payload,\n\t\t\t// values could also have a partial update\n\t\t\tvalues: {\n\t\t\t\t...issueTypeFieldValues.values,\n\t\t\t\t...values,\n\t\t\t},\n\t\t}\n\n\t\tthis.dispatch(updateIssueTypeFieldValues(updatedIssueTypeFieldValues))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueTypeFieldValues>>({\n\t\t\tdescription: \"Update issue type field values\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/issue-type-field-values/${payload.offline_id}/`,\n\t\t\tpayload: {\n\t\t\t\t...payload,\n\t\t\t\tvalues: {\n\t\t\t\t\t...issueTypeFieldValues.values,\n\t\t\t\t\t...values,\n\t\t\t\t},\n\t\t\t},\n\t\t\tblockers: [\n\t\t\t\tupdatedIssueTypeFieldValues.offline_id,\n\t\t\t\tupdatedIssueTypeFieldValues.fields_revision,\n\t\t\t\tupdatedIssueTypeFieldValues.issue,\n\t\t\t],\n\t\t\tblocks: [updatedIssueTypeFieldValues.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateIssueTypeFieldValues(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateIssueTypeFieldValues(issueTypeFieldValues))\n\t\t\t})\n\n\t\treturn [updatedIssueTypeFieldValues, promise]\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst issueTypeFieldValues = selectIssueTypeFieldValuesById(id)(state)\n\n\t\tif (!issueTypeFieldValues) {\n\t\t\tthrow new Error(`Expected submission with offline_id ${id} to exist`)\n\t\t}\n\n\t\tconst issueTypeFieldValuesAttachments = selectAttachmentsOfIssueTypeFieldValues(id)(state)!\n\n\t\tthis.dispatch(deleteIssueTypeFieldValues(id))\n\t\tthis.dispatch(deleteIssueTypeFieldValuesAttachments(issueTypeFieldValuesAttachments.map((x) => x.offline_id)))\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete issue type field values\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/issue-type-field-values/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addIssueTypeFieldValues(issueTypeFieldValues))\n\t\t\tthis.dispatch(addIssueTypeFieldValuesAttachments(issueTypeFieldValuesAttachments))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<IssueTypeFieldValues>[]>({\n\t\t\tdescription: \"Get issue type field values\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/issue-type-field-values/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssueTypeFieldValues(result))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport {\n\taddAssetProcedureInstance,\n\tdeleteAssetProcedureInstance,\n\tinitializeAssetProcedureInstances,\n\tselectAssetProcedureInstanceById,\n\tupdateAssetProcedureInstance,\n} from \"../../store\"\nimport type { AssetProcedureInstance, Created, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport type { BaseSDK } from \"../base\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\n\nexport abstract class AssetProcedureInstanceService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<AssetProcedureInstance>): OptimisticModelResult<AssetProcedureInstance> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser!.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAssetProcedureInstance: Stored<AssetProcedureInstance> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addAssetProcedureInstance(offlineAssetProcedureInstance))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetProcedureInstance>>({\n\t\t\tdescription: \"Create asset procedure instance\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-procedure-instances/\",\n\t\t\tpayload: { ...offlineAssetProcedureInstance },\n\t\t\tblockers: [payload.asset_procedure, payload.asset_type],\n\t\t\tblocks: [offlineAssetProcedureInstance.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetProcedureInstance(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetProcedureInstance(offlineAssetProcedureInstance.offline_id))\n\t\t\t})\n\n\t\treturn [offlineAssetProcedureInstance, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<AssetProcedureInstance>>>): OptimisticModelResult<AssetProcedureInstance> {\n\t\tconst { store } = this.client\n\n\t\tconst assetProcedureInstance = selectAssetProcedureInstanceById(payload.offline_id)(store.getState())\n\n\t\tif (!assetProcedureInstance) {\n\t\t\tthrow new Error(`Expected asset procedure instance with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst updatedAssetProcedureInstance: Stored<AssetProcedureInstance> = {\n\t\t\t...assetProcedureInstance,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateAssetProcedureInstance(updatedAssetProcedureInstance))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetProcedureInstance>>({\n\t\t\tdescription: \"Update asset procedure instance\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/asset-procedure-instances/${payload.offline_id}/`,\n\t\t\tpayload: {\n\t\t\t\tasset_procedure: payload.asset_procedure,\n\t\t\t\tasset_type: payload.asset_type,\n\t\t\t},\n\t\t\tblockers: [assetProcedureInstance.offline_id],\n\t\t\tblocks: [assetProcedureInstance.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetProcedureInstance(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateAssetProcedureInstance(assetProcedureInstance))\n\t\t\t})\n\n\t\treturn [updatedAssetProcedureInstance, promise]\n\t}\n\n\tasync remove(assetProcedureInstanceId: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst assetProcedureInstance = selectAssetProcedureInstanceById(assetProcedureInstanceId)(state)\n\n\t\tif (!assetProcedureInstance) {\n\t\t\tthrow new Error(`Expected asset procedure instance with offline_id ${assetProcedureInstanceId} to exist`)\n\t\t}\n\n\t\tthis.dispatch(deleteAssetProcedureInstance(assetProcedureInstanceId))\n\n\t\t// TODO: delete asset procedure completions\n\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete asset procedure instance\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/asset-procedure-instances/${assetProcedureInstanceId}/`,\n\t\t\tblockers: [assetProcedureInstanceId],\n\t\t\tblocks: [],\n\t\t}).catch((e) => {\n\t\t\tthis.dispatch(addAssetProcedureInstance(assetProcedureInstance))\n\t\t\tthrow e\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<AssetProcedureInstance[]>({\n\t\t\tdescription: \"Get asset procedure instances\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-procedure-instances/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetProcedureInstances(result))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport {\n\taddAssetProcedure,\n\taddAssetProcedureInstances,\n\tdeleteAssetProcedure,\n\tdeleteAssetProcedureInstances,\n\tinitializeAssetProcedures,\n\tselectAssetProcedureById,\n\tselectAssetProcedureInstancesOfAssetProcedure,\n\tupdateAssetProcedure,\n} from \"../../store\"\nimport type { AssetProcedure, Created, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport type { BaseSDK } from \"../base\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\n\nexport abstract class AssetProcedureService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<AssetProcedure>): OptimisticModelResult<AssetProcedure> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser!.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAssetProcedure: Stored<AssetProcedure> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addAssetProcedure(offlineAssetProcedure))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetProcedure>>({\n\t\t\tdescription: \"Create asset procedure\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-procedures/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization_id: payload.organization.toString(),\n\t\t\t},\n\t\t\tpayload: { ...offlineAssetProcedure },\n\t\t\tblockers: [],\n\t\t\tblocks: [offlineAssetProcedure.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetProcedure(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetProcedure(offlineAssetProcedure.offline_id))\n\t\t\t})\n\n\t\treturn [offlineAssetProcedure, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<AssetProcedure>>>): OptimisticModelResult<AssetProcedure> {\n\t\tconst { store } = this.client\n\n\t\tconst assetProcedure = selectAssetProcedureById(payload.offline_id)(store.getState())\n\n\t\tif (!assetProcedure) {\n\t\t\tthrow new Error(`Expected asset procedure with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst updatedAssetProcedure: Stored<AssetProcedure> = {\n\t\t\t...assetProcedure,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateAssetProcedure(updatedAssetProcedure))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetProcedure>>({\n\t\t\tdescription: \"Update asset procedure\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/asset-procedures/${payload.offline_id}/`,\n\t\t\tpayload: {\n\t\t\t\ticon: payload.icon,\n\t\t\t\tcolor: payload.color,\n\t\t\t\tname: payload.name,\n\t\t\t\tdescription: payload.description,\n\t\t\t},\n\t\t\tblockers: [assetProcedure.offline_id],\n\t\t\tblocks: [assetProcedure.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetProcedure(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateAssetProcedure(assetProcedure))\n\t\t\t})\n\n\t\treturn [updatedAssetProcedure, promise]\n\t}\n\n\tasync remove(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst assetProcedure = selectAssetProcedureById(id)(state)\n\n\t\tif (!assetProcedure) {\n\t\t\tthrow new Error(`Expected asset procedure with offline_id ${id} to exist`)\n\t\t}\n\n\t\t// TODO: fetch stages to delete\n\t\tconst instancesOfAssetProcedure = selectAssetProcedureInstancesOfAssetProcedure(id)(state)\n\n\t\tthis.dispatch(deleteAssetProcedure(id))\n\t\tthis.dispatch(deleteAssetProcedureInstances(instancesOfAssetProcedure.map((instance) => instance.offline_id)))\n\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete asset procedure\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/asset-procedures/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t}).catch((e) => {\n\t\t\tthis.dispatch(addAssetProcedure(assetProcedure))\n\t\t\tthis.dispatch(addAssetProcedureInstances(instancesOfAssetProcedure))\n\t\t\tthrow e\n\t\t})\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<AssetProcedure[]>({\n\t\t\tdescription: \"Get asset procedures\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-procedures/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetProcedures(result))\n\t}\n}\n","import type {\n\tAssetProcedureFieldsAttachment,\n\tCreated,\n\tFileModelPayload,\n\tFilePayload,\n\tOvermapRootState,\n\tStored,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddAssetProcedureFieldsAttachments,\n\tdeleteAssetProcedureFieldsAttachments,\n\tinitializeAssetProcedureFieldsAttachments,\n\tupdateAssetProcedureFieldsAttachments,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class AssetProcedureFieldsAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync bulkAdd(\n\t\tpayloads: { fieldsRevisionId: string; fieldIdentifier: string; file: File }[],\n\t): Promise<OptimisticMultipleModelResult<AssetProcedureFieldsAttachment>> {\n\t\tinterface AttachmentPayload extends FileModelPayload {\n\t\t\toffline_id: string\n\t\t\tfield_identifier: string\n\t\t\tfields_revision: string\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser?.id\n\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\t\tconst offlineAssetProcedureFieldsAttachments: Stored<AssetProcedureFieldsAttachment>[] = []\n\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\n\t\tfor (const payload of payloads) {\n\t\t\tconst { fieldsRevisionId, fieldIdentifier, file } = payload\n\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\tif (!(filePayload.sha1 in filePayloads)) filePayloads[filePayload.sha1] = filePayload\n\n\t\t\tconst offlineAssetProcedureFieldsAttachment: Stored<AssetProcedureFieldsAttachment> = offline({\n\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\tfile_type: file.type,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tfields_revision: fieldsRevisionId,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t})\n\t\t\tofflineAssetProcedureFieldsAttachments.push(offlineAssetProcedureFieldsAttachment)\n\n\t\t\tconst attachmentPayload: AttachmentPayload = {\n\t\t\t\toffline_id: offlineAssetProcedureFieldsAttachment.offline_id,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\tfile_extension: filePayload.extension,\n\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\tfields_revision: fieldsRevisionId,\n\t\t\t}\n\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t}\n\n\t\tthis.dispatch(addAssetProcedureFieldsAttachments(offlineAssetProcedureFieldsAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<AssetProcedureFieldsAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: \"Add asset procedure fields attachments\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-procedure-fields-attachments/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblockers: offlineAssetProcedureFieldsAttachments.map((attachment) => attachment.fields_revision),\n\t\t\tblocks: offlineAssetProcedureFieldsAttachments.map((attachment) => attachment.offline_id),\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(updateAssetProcedureFieldsAttachments(result.attachments))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteAssetProcedureFieldsAttachments(\n\t\t\t\t\t\tofflineAssetProcedureFieldsAttachments.map((attachment) => attachment.offline_id),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t})\n\n\t\treturn [offlineAssetProcedureFieldsAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<AssetProcedureFieldsAttachment>[]>({\n\t\t\tdescription: \"Get asset procedure fields attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-procedure-fields-attachments/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetProcedureFieldsAttachments(result))\n\t}\n}\n","import type { AssetProcedureFields, Created, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddAssetProcedureFields,\n\tdeleteAssetProcedureFields,\n\tinitializeAssetProcedureFields,\n\tupdateAssetProcedureFields,\n} from \"../../store\"\n\nexport abstract class AssetProcedureFieldsService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<AssetProcedureFields>): OptimisticModelResult<AssetProcedureFields> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAssetProcedureFields: Stored<AssetProcedureFields> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addAssetProcedureFields(offlineAssetProcedureFields))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetProcedureFields>>({\n\t\t\tdescription: \"Add Asset Procedure Fields\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-procedure-fields/\",\n\t\t\tpayload: offlineAssetProcedureFields,\n\t\t\tblockers: [offlineAssetProcedureFields.asset_procedure],\n\t\t\tblocks: [offlineAssetProcedureFields.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((response) => {\n\t\t\t\tthis.dispatch(updateAssetProcedureFields(response))\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.dispatch(deleteAssetProcedureFields(offlineAssetProcedureFields.offline_id))\n\t\t\t\tthrow error\n\t\t\t})\n\n\t\treturn [offlineAssetProcedureFields, promise]\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<AssetProcedureFields[]>({\n\t\t\tdescription: \"Get Asset Procedure Fields\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-procedure-fields/\",\n\t\t\tqueryParams: {\n\t\t\t\torganization: organizationId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetProcedureFields(result))\n\t}\n}\n","import type {\n\tAssetProcedureFieldValuesAttachment,\n\tCreated,\n\tFileModelPayload,\n\tFilePayload,\n\tOvermapRootState,\n\tStored,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport { type PresignedUrlsResponse } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddAssetProcedureFieldValuesAttachments,\n\tdeleteAssetProcedureFieldValuesAttachments,\n\tinitializeAssetProcedureFieldValuesAttachments,\n\tselectAssetProcedureFieldValuesAttachmentsByIds,\n\tupdateAssetProcedureFieldValuesAttachments,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\nimport { chunkArray } from \"../../utils/array\"\n\nexport abstract class AssetProcedureFieldValuesAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync bulkAdd(\n\t\tpayloads: { fieldValuesId: string; fieldIdentifier: string; file: File }[],\n\t\tbatchSize?: number,\n\t): Promise<\n\t\t[Stored<AssetProcedureFieldValuesAttachment>[], Promise<Created<AssetProcedureFieldValuesAttachment>[]>[]]\n\t> {\n\t\tinterface AttachmentPayload extends FileModelPayload {\n\t\t\toffline_id: string\n\t\t\tfield_identifier: string\n\t\t\tfield_values: string\n\t\t}\n\n\t\tinterface Payload {\n\t\t\tsubmitted_at: string\n\t\t\tattachments: AttachmentPayload[]\n\t\t\tfiles: FilePayload[]\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser?.id\n\t\tconst batches = chunkArray(payloads, batchSize ?? payloads.length)\n\t\tconst offlineAssetProcedureFieldValuesAttachments: Stored<AssetProcedureFieldValuesAttachment>[] = []\n\t\tconst batchPayloads: Payload[] = []\n\n\t\tfor (const batch of batches) {\n\t\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\t\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\n\t\t\tfor (const payload of batch) {\n\t\t\t\tconst { fieldValuesId, fieldIdentifier, file } = payload\n\t\t\t\tconst filePayload = await this.getFilePayload(file)\n\n\t\t\t\tif (!(filePayload.sha1 in filePayloads)) filePayloads[filePayload.sha1] = filePayload\n\n\t\t\t\tconst offlineAssetProcedureFieldValuesAttachment: Stored<AssetProcedureFieldValuesAttachment> = offline(\n\t\t\t\t\t{\n\t\t\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\t\t\tfile_type: file.type,\n\t\t\t\t\t\tfile_name: file.name,\n\t\t\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\t\t\tcreated_by: createdBy,\n\t\t\t\t\t\tfield_values: fieldValuesId,\n\t\t\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t\tofflineAssetProcedureFieldValuesAttachments.push(offlineAssetProcedureFieldValuesAttachment)\n\n\t\t\t\tconst attachmentPayload: AttachmentPayload = {\n\t\t\t\t\toffline_id: offlineAssetProcedureFieldValuesAttachment.offline_id,\n\t\t\t\t\tfile_name: file.name,\n\t\t\t\t\tfile_sha1: filePayload.sha1,\n\t\t\t\t\tfile_extension: filePayload.extension,\n\t\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\t\tfield_values: fieldValuesId,\n\t\t\t\t}\n\t\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t\t}\n\n\t\t\tbatchPayloads.push({\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t})\n\t\t}\n\n\t\tthis.dispatch(addAssetProcedureFieldValuesAttachments(offlineAssetProcedureFieldValuesAttachments))\n\n\t\tconst promises = batchPayloads.map((payload) => {\n\t\t\treturn this.enqueueRequest<{\n\t\t\t\tattachments: Created<AssetProcedureFieldValuesAttachment>[]\n\t\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t\t}>({\n\t\t\t\tdescription: \"Add asset procedure field values attachments\",\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\turl: \"/asset-procedure-field-values-attachments/bulk/\",\n\t\t\t\tpayload: payload,\n\t\t\t\tblockers: payload.attachments.map((payload) => payload.field_values),\n\t\t\t\tblocks: payload.attachments.map((payload) => payload.offline_id),\n\t\t\t})\n\t\t})\n\n\t\tPromise.all(promises)\n\t\t\t.then((result) => {\n\t\t\t\tfor (const res of result) this.processPresignedUrls(res.presigned_urls)\n\t\t\t\tconst attachments = result.flatMap((res) => res.attachments)\n\t\t\t\tthis.dispatch(updateAssetProcedureFieldValuesAttachments(attachments))\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteAssetProcedureFieldValuesAttachments(\n\t\t\t\t\t\tofflineAssetProcedureFieldValuesAttachments.map((attachment) => attachment.offline_id),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\tthrow error\n\t\t\t})\n\n\t\treturn [\n\t\t\tofflineAssetProcedureFieldValuesAttachments,\n\t\t\tpromises.map((promise) => promise.then(({ attachments }) => attachments)),\n\t\t]\n\t}\n\n\tasync bulkDelete(ids: string[]): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst attachments = selectAssetProcedureFieldValuesAttachmentsByIds(ids)(state)\n\t\tthis.dispatch(deleteAssetProcedureFieldValuesAttachments(ids))\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete asset procedure field values attachments\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: \"/asset-procedure-field-values-attachments/bulk/\",\n\t\t\t\tpayload: { attachment_ids: ids },\n\t\t\t\tblockers: ids,\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addAssetProcedureFieldValuesAttachments(attachments))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<AssetProcedureFieldValuesAttachment>[]>({\n\t\t\tdescription: \"Get asset procedure field values attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-procedure-field-values-attachments/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetProcedureFieldValuesAttachments(result))\n\t}\n}\n","import type {\n\tAssetProcedureFieldValues,\n\tCreated,\n\tOffline,\n\tOvermapRootState,\n\tPayload,\n\tStored,\n\tSubmitted,\n} from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddAssetProcedureFieldValues,\n\taddAssetProcedureFieldValuesAttachments,\n\taddAssetProcedureFieldValuesMany,\n\tdeleteAssetProcedureFieldValues,\n\tdeleteAssetProcedureFieldValuesAttachments,\n\tdeleteAssetProcedureFieldValuesMany,\n\tinitializeAssetProcedureFieldValues,\n\tselectAssetProcedureFieldValuesById,\n\tselectAttachmentsOfAssetProcedureFieldValues,\n\tupdateAssetProcedureFieldValues,\n\tupdateAssetProcedureFieldValuesMany,\n} from \"../../store\"\nimport { separateFilesFromValues } from \"./FormSubmissionService\"\nimport { FieldValue } from \"@overmap-ai/forms\"\nimport { chunkArray } from \"../../utils/array\"\n\nexport abstract class AssetProcedureFieldValuesService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<AssetProcedureFieldValues>): OptimisticModelResult<AssetProcedureFieldValues> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst { values } = separateFilesFromValues(payload.values)\n\n\t\tconst offlineAssetProcedureFieldValues: Submitted<AssetProcedureFieldValues> = offline({\n\t\t\t...payload,\n\t\t\tvalues: values,\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t})\n\n\t\tconst promise = this.enqueueRequest<Created<AssetProcedureFieldValues>>({\n\t\t\tdescription: \"Add asset procedure field values\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/asset-procedure-field-values/\",\n\t\t\tpayload: offlineAssetProcedureFieldValues,\n\t\t\tblockers: [payload.asset, payload.fields_revision, payload.asset_procedure_instance],\n\t\t\tblocks: [offlineAssetProcedureFieldValues.offline_id],\n\t\t})\n\n\t\tthis.dispatch(addAssetProcedureFieldValues(offlineAssetProcedureFieldValues))\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetProcedureFieldValues(result))\n\t\t\t\treturn result\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetProcedureFieldValues(offlineAssetProcedureFieldValues.offline_id))\n\t\t\t})\n\n\t\treturn [offlineAssetProcedureFieldValues, promise]\n\t}\n\n\tbulkAdd(\n\t\tpayload: {\n\t\t\tvalues: Record<string, FieldValue>\n\t\t\tpayloads: {\n\t\t\t\tvalues: Record<string, FieldValue>\n\t\t\t\tasset: string\n\t\t\t\tfields_revision: string\n\t\t\t\tasset_procedure_instance: string\n\t\t\t\tpublished_at: string\n\t\t\t}[]\n\t\t},\n\t\tbatchSize?: number,\n\t): [Stored<AssetProcedureFieldValues>[], Promise<Created<AssetProcedureFieldValues>[]>[]] {\n\t\tinterface AssetProcedureFieldValuesBulkPayload {\n\t\t\toffline_id: string\n\t\t\tasset: string\n\t\t\tfields_revision: string\n\t\t\tasset_procedure_instance: string\n\t\t\tpublished_at: string\n\t\t\tvalues: Record<string, FieldValue>\n\t\t}\n\n\t\tinterface Payload {\n\t\t\tsubmitted_at: string\n\t\t\tvalues: Record<string, FieldValue>\n\t\t\tfield_values: AssetProcedureFieldValuesBulkPayload[]\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst { values } = separateFilesFromValues(payload.values)\n\t\tconst offlineAssetProcedureFieldValuesMany: Stored<AssetProcedureFieldValues>[] = []\n\t\tconst batches = chunkArray(payload.payloads, batchSize ?? payload.payloads.length)\n\t\tconst batchPayloads: Payload[] = []\n\n\t\tfor (const batch of batches) {\n\t\t\tconst assetProcedureFieldValuesPayloads: AssetProcedureFieldValuesBulkPayload[] = []\n\n\t\t\tfor (const payload of batch) {\n\t\t\t\tconst offlineAssetProcedureFieldValues: Stored<AssetProcedureFieldValues> = offline({\n\t\t\t\t\t...payload,\n\t\t\t\t\tvalues: separateFilesFromValues(payload.values).values,\n\t\t\t\t\tcreated_by: this.client.store.getState().userReducer.currentUser?.id,\n\t\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\t})\n\n\t\t\t\tofflineAssetProcedureFieldValuesMany.push(offlineAssetProcedureFieldValues)\n\n\t\t\t\tassetProcedureFieldValuesPayloads.push({\n\t\t\t\t\toffline_id: offlineAssetProcedureFieldValues.offline_id,\n\t\t\t\t\tasset: payload.asset,\n\t\t\t\t\tfields_revision: payload.fields_revision,\n\t\t\t\t\tasset_procedure_instance: payload.asset_procedure_instance,\n\t\t\t\t\tpublished_at: payload.published_at,\n\t\t\t\t\tvalues: offlineAssetProcedureFieldValues.values,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tbatchPayloads.push({\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tvalues: values,\n\t\t\t\tfield_values: assetProcedureFieldValuesPayloads,\n\t\t\t})\n\t\t}\n\n\t\tthis.dispatch(addAssetProcedureFieldValuesMany(offlineAssetProcedureFieldValuesMany))\n\n\t\tconst promises: Promise<Created<AssetProcedureFieldValues>[]>[] = []\n\n\t\tfor (const payload of batchPayloads) {\n\t\t\tconst assetIds = payload.field_values.map((x) => x.asset)\n\t\t\tconst assetProcedureFieldsIds = payload.field_values.map((x) => x.fields_revision)\n\t\t\tconst assetProcedureInstanceIds = payload.field_values.map((x) => x.asset_procedure_instance)\n\t\t\tconst assetProcedureFieldValuesIds = payload.field_values.map((x) => x.offline_id)\n\n\t\t\tconst promise = this.enqueueRequest<Created<AssetProcedureFieldValues>[]>({\n\t\t\t\tdescription: \"Bulk add asset procedure field values\",\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\turl: \"/asset-procedure-field-values/bulk/\",\n\t\t\t\tpayload: payload,\n\t\t\t\tblockers: [...assetIds, ...assetProcedureFieldsIds, ...assetProcedureInstanceIds],\n\t\t\t\tblocks: assetProcedureFieldValuesIds,\n\t\t\t})\n\n\t\t\tpromises.push(promise)\n\t\t}\n\n\t\tvoid Promise.all(promises)\n\t\t\t.then((results) => {\n\t\t\t\tthis.dispatch(updateAssetProcedureFieldValuesMany(results.flat()))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteAssetProcedureFieldValuesMany(offlineAssetProcedureFieldValuesMany.map((x) => x.offline_id)),\n\t\t\t\t)\n\t\t\t})\n\n\t\treturn [offlineAssetProcedureFieldValuesMany, promises]\n\t}\n\n\tupdate(\n\t\tpayload: Offline<Partial<Payload<AssetProcedureFieldValues>>>,\n\t): OptimisticModelResult<AssetProcedureFieldValues> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst assetProcedureFieldValues = selectAssetProcedureFieldValuesById(payload.offline_id)(state)\n\n\t\tif (!assetProcedureFieldValues) {\n\t\t\tthrow new Error(`Expected AssetProcedureFieldValues with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst { values } = separateFilesFromValues(payload.values ?? {})\n\n\t\tconst updatedAssetProcedureFieldValues: Stored<AssetProcedureFieldValues> = {\n\t\t\t...assetProcedureFieldValues,\n\t\t\t...payload,\n\t\t\t// values could also have a partial update\n\t\t\tvalues: {\n\t\t\t\t...assetProcedureFieldValues.values,\n\t\t\t\t...values,\n\t\t\t},\n\t\t}\n\n\t\tthis.dispatch(updateAssetProcedureFieldValues(updatedAssetProcedureFieldValues))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetProcedureFieldValues>>({\n\t\t\tdescription: \"Update asset procedure field values\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/asset-procedure-field-values/${payload.offline_id}/`,\n\t\t\tpayload: {\n\t\t\t\t...payload,\n\t\t\t\tvalues: {\n\t\t\t\t\t...assetProcedureFieldValues.values,\n\t\t\t\t\t...values,\n\t\t\t\t},\n\t\t\t},\n\t\t\tblockers: [\n\t\t\t\tupdatedAssetProcedureFieldValues.fields_revision,\n\t\t\t\tupdatedAssetProcedureFieldValues.asset,\n\t\t\t\tupdatedAssetProcedureFieldValues.asset_procedure_instance,\n\t\t\t],\n\t\t\tblocks: [updatedAssetProcedureFieldValues.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetProcedureFieldValues(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateAssetProcedureFieldValues(assetProcedureFieldValues))\n\t\t\t})\n\n\t\treturn [updatedAssetProcedureFieldValues, promise]\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst assetProcedureFieldValues = selectAssetProcedureFieldValuesById(id)(state)\n\n\t\tif (!assetProcedureFieldValues) {\n\t\t\tthrow new Error(`Expected submission with offline_id ${id} to exist`)\n\t\t}\n\n\t\tconst assetProcedureFieldValuesAttachments = selectAttachmentsOfAssetProcedureFieldValues(id)(state)!\n\n\t\tthis.dispatch(deleteAssetProcedureFieldValues(id))\n\t\tthis.dispatch(\n\t\t\tdeleteAssetProcedureFieldValuesAttachments(assetProcedureFieldValuesAttachments.map((x) => x.offline_id)),\n\t\t)\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete asset procedure field values\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/asset-procedure-field-values/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addAssetProcedureFieldValues(assetProcedureFieldValues))\n\t\t\tthis.dispatch(addAssetProcedureFieldValuesAttachments(assetProcedureFieldValuesAttachments))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<AssetProcedureFieldValues>[]>({\n\t\t\tdescription: \"Get asset procedure field values\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/asset-procedure-field-values/\",\n\t\t\tqueryParams: {\n\t\t\t\tproject: projectId.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetProcedureFieldValues(result))\n\t}\n}\n","import type { RegistrationPayload } from \"./users\"\nimport type { OfflineModel } from \"./base\"\n\nexport type EmailVerificationPayload = undefined | RegistrationPayload | Omit<RegistrationPayload, \"username\" | \"email\">\n\nexport interface EmailVerificationReturn {\n\tusername?: string\n\tproject?: number\n}\n\nexport enum VerificationCodeType {\n\tUSER_REGISTRATION = 0,\n\tAPPLICATION_INVITE = 2,\n\tPROJECT_INVITE = 4,\n\tORGANIZATION_INVITE = 6,\n\tADD_EMAIL_DOMAIN = 8,\n\tRESET_PASSWORD = 10,\n}\n\nexport interface VerificationCode extends OfflineModel {\n\tverification_code: string\n\tverification_type: VerificationCodeType\n\torganization?: number\n\tproject?: number\n\tuser?: number\n}\n"],"names":["HttpMethod","AttachmentModel","IssuePriority","IssueStatus","IssueUpdateChange","ProjectAccessLevel","OrganizationAccessLevel","PaddleCheckoutEvent","LicenseLevel","LicenseStatus","request","_a","uuidv4","randomString","VERSION_REDUCER_KEY","migration","initialState","today","document","clientStore","offline","clientSDK","coordinator","payload","issueAttachmentReducer","assetAttachmentReducer","assetTypeAttachmentReducer","documentAttachmentReducer","projectAttachmentReducer","formRevisionAttachmentReducer","formSubmissionAttachmentReducer","geoImageReducer","assetTypeFieldsAttachmentReducer","assetTypeFieldValuesAttachmentReducer","issueTypeFieldsAttachmentReducer","issueTypeFieldValuesAttachmentReducer","requestDetails","file","organization","promise","VerificationCodeType"],"mappings":"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","x_google_ignoreList":[20]}
|
|
1
|
+
{"version":3,"file":"overmap-core.js","sources":["../src/enums/api.ts","../src/enums/attachments.ts","../src/enums/issue.ts","../src/enums/access.ts","../src/enums/licenses.ts","../src/sdk/classes/OutboxCoordinator.ts","../src/sdk/errors.ts","../src/utils/coordinates.ts","../src/utils/file.ts","../src/utils/logging.ts","../src/utils/offline.ts","../src/utils/string.ts","../src/utils/utils.ts","../src/constants/defaults.ts","../src/constants/offline.ts","../src/constants/array.ts","../src/utils/optimization.ts","../src/utils/colors.ts","../src/utils/date.ts","../src/utils/async/DeferredPromise.ts","../node_modules/redux/es/redux.js","../src/store/migrations.ts","../src/store/slices/authSlice.ts","../src/store/adapter.ts","../src/store/slices/categorySlice.ts","../src/store/slices/assetSlice.ts","../src/store/slices/assetAttachmentSlice.ts","../src/store/slices/assetStageCompletionSlice.ts","../src/store/slices/assetStageSlice.ts","../src/store/slices/assetTypeSlice.ts","../src/store/slices/assetTypeAttachmentSlice.ts","../src/store/slices/issueSlice.ts","../src/store/slices/issueTypeSlice.ts","../src/store/slices/fileSlice.ts","../src/store/slices/userSlice.ts","../src/store/slices/organizationAccessSlice.ts","../src/store/slices/licenseSlice.ts","../src/store/slices/projectAccessSlice.ts","../src/store/slices/projectSlice.ts","../src/store/slices/organizationSlice.ts","../src/store/slices/outboxSlice.ts","../src/store/slices/projectFileSlice.ts","../src/store/slices/projectAttachmentSlice.ts","../src/store/slices/rehydratedSlice.ts","../src/utils/forms.ts","../src/store/slices/formRevisionSlice.ts","../src/store/slices/formSlice.ts","../src/store/slices/formSubmissionSlice.ts","../src/store/slices/formSubmissionAttachmentSlice.ts","../src/store/slices/formRevisionAttachmentSlice.ts","../src/store/slices/workspaceSlice.ts","../src/store/slices/emailDomainsSlice.ts","../src/store/slices/documentSlice.ts","../src/store/slices/documentAttachmentSlice.ts","../src/store/slices/teamSlice.ts","../src/store/slices/agentsSlice.ts","../src/store/slices/issueCommentSlice.ts","../src/store/slices/issueUpdateSlice.ts","../src/store/slices/issueAttachmentSlice.ts","../src/store/slices/versioningSlice.ts","../src/store/slices/geoImageSlice.ts","../src/store/slices/issueAssociationSlice.ts","../src/sdk/globals.ts","../src/sdk/services/BaseService.ts","../src/store/store.ts","../src/sdk/base.ts","../src/sdk/sdk.ts","../src/sdk/services/BaseAuthService.ts","../src/sdk/services/JWTAuthService.ts","../src/sdk/services/BaseApiService.ts","../src/sdk/services/CategoryService.ts","../src/utils/array.ts","../src/sdk/services/AssetService.ts","../src/sdk/services/AssetStageCompletionService.ts","../src/sdk/services/AssetStageService.ts","../src/sdk/services/BaseUploadService.ts","../src/sdk/services/BaseAttachmentService.ts","../src/sdk/services/AssetAttachmentService.ts","../src/sdk/services/AssetTypeService.ts","../src/sdk/services/AssetTypeAttachmentService.ts","../src/sdk/services/IssueCommentService.ts","../src/sdk/services/IssueUpdateService.ts","../src/sdk/services/IssueAttachmentService.ts","../src/sdk/services/IssueService.ts","../src/sdk/services/IssueTypeService.ts","../src/sdk/services/ProjectAccessService.ts","../src/sdk/services/ProjectFileService.ts","../src/sdk/services/ProjectAttachmentService.ts","../src/sdk/services/ProjectService.ts","../src/sdk/services/FormService.ts","../src/sdk/services/FormSubmissionService.ts","../src/sdk/services/WorkspaceService.ts","../src/sdk/services/OrganizationAccessService.ts","../src/sdk/services/FileService.ts","../src/sdk/services/EmailVerificationService.ts","../src/sdk/services/EmailDomainsService.ts","../src/sdk/services/OrganizationService.ts","../src/sdk/services/LicenseService.ts","../src/sdk/services/DocumentService.ts","../src/sdk/services/DocumentAttachmentService.ts","../src/sdk/services/AgentService.ts","../src/sdk/services/TeamService.ts","../src/sdk/services/UserService.ts","../src/sdk/services/GeoImageService.ts","../src/sdk/services/IssueAssociationService.ts","../src/typings/models/emailVerification.ts"],"sourcesContent":["export const enum HttpMethod {\n\tGET = \"GET\",\n\tPOST = \"POST\",\n\tPATCH = \"PATCH\",\n\tPUT = \"PUT\",\n\tDELETE = \"DELETE\",\n\t// TODO: Add support\n\t// OPTIONS = \"OPTIONS\",\n}\n","export enum AttachmentModel {\n\tIssue = \"issue\",\n\tAsset = \"asset\",\n\tAssetType = \"asset_type\",\n\tProject = \"project\",\n\tDocument = \"document\",\n}\n","export enum IssuePriority {\n\tLOWEST = 0,\n\tLOW = 2,\n\tMEDIUM = 4,\n\tHIGH = 6,\n\tHIGHEST = 8,\n}\n\nexport enum IssueStatus {\n\tBACKLOG = 0,\n\tSELECTED = 2,\n\tDONE = 4,\n}\n\nexport enum IssueUpdateChange {\n\tSTATUS = \"status\",\n\tPRIORITY = \"priority\",\n\tCATEGORY = \"category\",\n\tDESCRIPTION = \"description\",\n\tTITLE = \"title\",\n\tASSIGNED_TO = \"assigned_to\",\n\tDUE_DATE = \"due_date\",\n}\n","export enum ProjectAccessLevel {\n\tBASIC = 0,\n\tADMIN = 2,\n}\n\nexport enum OrganizationAccessLevel {\n\tBASIC = 0,\n\tADMIN = 2,\n}\n","export enum PaddleCheckoutEvent {\n\tCOMPLETED = \"checkout.completed\",\n\tCLOSED = \"checkout.closed\",\n}\n\nexport enum LicenseLevel {\n\tPRO = 0,\n}\n\nexport enum LicenseStatus {\n\tACTIVE = 0,\n\tPAUSED = 2,\n\tCANCELLED = 4,\n\tINACTIVE = 6,\n\tPAST_DUE = 8,\n}\n","import { DepGraph } from \"dependency-graph\"\nimport type { FullOfflineAction } from \"../../store\"\nimport { Outbox } from \"@redux-offline/redux-offline/lib/types\"\n\n// TODO: Tests:\n// - Bulk-create components, then delete one of those components. Ensure the dependency to the bulk-create is found.\n\nexport class OutboxCoordinator {\n\tgraph: DepGraph<FullOfflineAction>\n\trequestAttemptCounter: Record<string, number>\n\n\tconstructor() {\n\t\tthis.graph = new DepGraph()\n\t\tthis.requestAttemptCounter = {}\n\t}\n\n\t/**\n\t * Used when the app is loaded. Reconstructs the dependency graph based on an outbox from the redux-offline store.\n\t */\n\tstatic _fromOutbox(outbox: Outbox): OutboxCoordinator {\n\t\tconst ret = new OutboxCoordinator()\n\n\t\tfor (let i = 0; i < outbox.length; i++) {\n\t\t\tconst outboxItem = outbox[i] as FullOfflineAction | undefined\n\t\t\tif (!outboxItem) {\n\t\t\t\tconsole.error(\"Outbox item was undefined\")\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tret.sneakRequest(outboxItem)\n\t\t\t// Add any dependencies to requests that were added before this one\n\t\t\tfor (let j = 0; j < i; j++) {\n\t\t\t\tconst previousOutboxItem = outbox[j] as FullOfflineAction | undefined\n\t\t\t\tif (!previousOutboxItem) {\n\t\t\t\t\tconsole.error(\"Previous outbox item was undefined\")\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (previousOutboxItem.payload.uuid === outboxItem.payload.uuid) {\n\t\t\t\t\tcontinue // Skip self\n\t\t\t\t}\n\t\t\t\tif (previousOutboxItem.payload.blocks.some((block) => outboxItem.payload.blockers.includes(block))) {\n\t\t\t\t\tOutboxCoordinator._addDependency(\n\t\t\t\t\t\toutboxItem.payload.uuid,\n\t\t\t\t\t\tpreviousOutboxItem.payload.uuid,\n\t\t\t\t\t\tret.graph,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret\n\t}\n\n\t_addDependency(from: string, to: string) {\n\t\tOutboxCoordinator._addDependency(from, to, this.graph)\n\t}\n\n\tstatic _addDependency(from: string, to: string, graph: DepGraph<FullOfflineAction>) {\n\t\tif (from === to) {\n\t\t\tthrow new Error(`Tried to add dependency from node to itself: ${from}`)\n\t\t}\n\t\tconst fromExists = graph.hasNode(from)\n\t\tif (!fromExists) {\n\t\t\tthrow new Error(`Tried to add dependency from non-existent node: ${from} (to node: ${to})`)\n\t\t}\n\t\tconst toExists = graph.hasNode(to)\n\t\tif (!toExists) {\n\t\t\tthrow new Error(`Tried to add dependency to non-existent node: ${to} (from node: ${from})`)\n\t\t}\n\t\tgraph.addDependency(from, to)\n\t}\n\n\t/**\n\t * If there are one or more nodes in the graph, we find all nodes that match a dependency of the request and add a\n\t * dependency from the new request node to that node.\n\t */\n\taddRequest(request: FullOfflineAction) {\n\t\tthis.graph.addNode(request.payload.uuid, request)\n\n\t\tif (request.payload.blockers.length === 0 || this.graph.size() === 1) {\n\t\t\t// The request has no dependencies, or there are no other nodes in the graph, so there are no dependencies\n\t\t\t// to create.\n\t\t\treturn\n\t\t}\n\n\t\t// Create dependencies according to the request's blockers\n\t\tfor (const node of this.graph.overallOrder()) {\n\t\t\tif (node === request.payload.uuid) continue // Skip the node we just added\n\t\t\tconst details = this.graph.getNodeData(node)\n\t\t\t// 1. Any node matching this request's offline_id\n\t\t\tif (request.payload.blockers.some((blocker) => details.payload.blocks.includes(blocker))) {\n\t\t\t\tthis._addDependency(request.payload.uuid, node)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Inserts a request at the beginning of the queue. This could be used for requests that were popped, then failed,\n\t * and need to be re-enqueued at the front of the queue. Any requests that were previously blocked by this request\n\t * will be blocked by this request again. No blockers will be added to this request because it is assumed that the\n\t * request was already unblocked when it was popped.\n\t * @param request The request to insert at the beginning of the queue.\n\t */\n\tinsertRequest(request: FullOfflineAction) {\n\t\tthis.graph.addNode(request.payload.uuid, request)\n\n\t\t// Create dependencies according to the request's blockers\n\t\tfor (const node of this.graph.overallOrder()) {\n\t\t\tif (node === request.payload.uuid) continue // Skip the request we just inserted\n\t\t\tconst details = this.graph.getNodeData(node)\n\t\t\t// 1. Any node matching this request's offline_id\n\t\t\tif (details.payload.blockers.some((blocker) => request.payload.blocks.includes(blocker))) {\n\t\t\t\tthis._addDependency(node, request.payload.uuid)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Sneaks a request into the dependency graph without creating any blockers. Useful for reconstructing the graph\n\t * (from the offline store's outbox state) when the app is loaded.\n\t */\n\tsneakRequest(request: FullOfflineAction) {\n\t\tthis.graph.addNode(request.payload.uuid, request)\n\t}\n\n\t/**\n\t * Returns the next node in line to be sent. This is the unblocked node with the fewest number of attempts. If there\n\t * are multiple nodes with the same number of attempts, the first one (by insertion order) will be returned.\n\t */\n\t_getNextNode(): string | undefined {\n\t\tconst leafNodes = this.graph.overallOrder(true)\n\t\tlet minAttempts = Infinity\n\t\tlet minAttemptsNode: string | undefined\n\t\tfor (const node of leafNodes) {\n\t\t\tconst attempts = this.requestAttemptCounter[node] || 0\n\t\t\tif (attempts < minAttempts) {\n\t\t\t\tminAttempts = attempts\n\t\t\t\tminAttemptsNode = node\n\t\t\t}\n\t\t}\n\t\treturn minAttemptsNode\n\t}\n\n\t/**\n\t * Returns the next request in line to be sent without removing it.\n\t */\n\tpeek(): FullOfflineAction | undefined {\n\t\tconst nextNode = this._getNextNode()\n\t\tif (!nextNode) return undefined\n\t\treturn this.graph.getNodeData(nextNode)\n\t}\n\n\t/**\n\t * Removes a request from the graph. This should be called when a request is successfully sent.\n\t * @param uuid The UUID of the request to remove.\n\t */\n\tremove(uuid: string): void {\n\t\tthis.graph.removeNode(uuid)\n\t\tdelete this.requestAttemptCounter[uuid]\n\t}\n\n\t/**\n\t * Returns the next request in line to be sent and removes it from the graph.\n\t */\n\tpop(): FullOfflineAction | undefined {\n\t\tconst nextRequestDetails = this.peek()\n\t\tif (nextRequestDetails) {\n\t\t\tthis.graph.removeNode(nextRequestDetails.payload.uuid)\n\t\t}\n\t\treturn nextRequestDetails\n\t}\n\n\t/**\n\t * Gets the current queue for the outbox. Should be called to get a new value for the outbox slice every time a\n\t * request is enqueued. It will be used to render the outbox items in a single lane.\n\t */\n\tgetQueue(): FullOfflineAction[] {\n\t\tconst ret = this.graph.overallOrder().map((nodeName) => this.graph.getNodeData(nodeName))\n\n\t\t// We will return the normal overall order, except we put the request with the fewest number of attempts at the\n\t\t// front of the queue, assuming it is not blocked.\n\t\tconst nextNode = this._getNextNode()\n\t\tif (nextNode) {\n\t\t\tconst nextRequestDetails = this.graph.getNodeData(nextNode)\n\t\t\tconst nextRequestIndex = ret.findIndex(\n\t\t\t\t(request) => request.payload.uuid === nextRequestDetails.payload.uuid,\n\t\t\t)\n\t\t\tif (nextRequestIndex !== -1) {\n\t\t\t\tret.splice(nextRequestIndex, 1)\n\t\t\t\tret.unshift(nextRequestDetails)\n\t\t\t}\n\t\t}\n\n\t\treturn ret\n\t}\n\n\t/**\n\t * Gets a list of requests that can currently be sent (requests with no unresolved dependencies). Used to process\n\t * the next ready request in case the request at the front of the queue is failing.\n\t */\n\tgetReady(): FullOfflineAction[] {\n\t\tlet ret = this.graph.overallOrder(true).map((nodeName) => this.graph.getNodeData(nodeName))\n\t\t// First, order by insertion order\n\t\tret = ret.sort((a, b) => {\n\t\t\treturn a.meta.offline.effect.timestamp.localeCompare(b.meta.offline.effect.timestamp)\n\t\t})\n\t\t// Then, order by number of attempts\n\t\tret = ret.sort((a, b) => {\n\t\t\tconst aAttempts = this.requestAttemptCounter[a.payload.uuid] || 0\n\t\t\tconst bAttempts = this.requestAttemptCounter[b.payload.uuid] || 0\n\t\t\t// If these are equal, we want to keep the insertion order, which should be maintained from the previous\n\t\t\t// sort if we return 0.\n\t\t\treturn aAttempts - bAttempts\n\t\t})\n\t\treturn ret\n\t}\n\n\tregisterRetry(uuid: string): void {\n\t\tthis.requestAttemptCounter[uuid] = (this.requestAttemptCounter[uuid] || 0) + 1\n\t}\n}\n\n// TODO: Consider auto-discovering UUIDs instead of (or in addition to) explicitly passing them to `enqueueRequest`\n/**\n * Given a request, returns an array of discovered UUIDs referenced in the request.\n * Discovers UUIDs in the URL, body, and query string.\n * @param request\n */\n/*\nfunction _discoverUuids(request: RequestDetails): Set<string> {\n\t// We need to consider:\n\t// 1. Any UUID in the URL\n\t// 2. Any UUID in the body\n\t// 3. Any UUID in the query parameters\n\n\tconst ret = new Set<string>()\n\n\tfunction discoverUuidsInArray(values: unknown[]): void {\n\t\tfor (const value of values) {\n\t\t\tif (typeof value === \"string\" && value.length === 36 && UUID_REGEX.test(value)) {\n\t\t\t\tret.add(value)\n\t\t\t}\n\t\t}\n\t}\n\n\tconst urlParts = request.url.split(\"/\")\n\n\tdiscoverUuidsInArray(urlParts)\n\n\tif (request.payload) {\n\t\tdiscoverUuidsInArray(Object.values(request.payload))\n\t}\n\n\tif (request.queryParams) {\n\t\tdiscoverUuidsInArray(Object.values(request.queryParams))\n\t}\n\n\treturn ret\n}\n */\n","// Contains custom error classes used by the SDK\n\nimport request from \"superagent\"\n\nexport interface APIErrorOptions {\n\tresponse?: request.Response\n\tinnerError?: unknown // Most likely an Error\n\tmessage?: string\n\tdiscard?: boolean\n}\n\nconst UNKNOWN_ERROR_MESSAGE = \"An unknown error occurred\"\nconst MAX_ERROR_MESSAGE_LENGTH = 500\nconst _SPECIAL_KEYS = [\"non_field_errors\", \"detail\"]\n\n/**\n * Makes a best-effort attempt to extract an error message from a request.Response or an error object.\n * @param errorRes The response object from a request, if available\n * @param err The error object, if available\n */\nfunction extractErrorMessage(errorRes: request.Response | undefined, err: unknown): string | undefined {\n\tlet ret: string | undefined\n\tif (errorRes?.body) {\n\t\tif (typeof errorRes.body === \"object\") {\n\t\t\tconst responseBody = errorRes.body as {\n\t\t\t\terror?: string\n\t\t\t\tmessage?: string\n\t\t\t\tbody?: Record<string, string | string[]>\n\t\t\t}\n\t\t\tif (typeof responseBody.error === \"string\") {\n\t\t\t\tret = responseBody.error\n\t\t\t} else if (typeof responseBody.message === \"string\") {\n\t\t\t\tret = responseBody.message\n\t\t\t} else if (responseBody.body) {\n\t\t\t\t// The error message may be something like this:\n\t\t\t\t// \t\t{\n\t\t\t\t// \t\t\tname: [\"This name is already taken.\", \"This name is too short.\"],\n\t\t\t\t// \t\t\temail: \"This email is already taken\",\n\t\t\t\t//\t\t\tnon_field_errors: [\"This username is already taken.\"]\n\t\t\t\t// \t\t}\n\t\t\t\t// We want to convert this into:\n\t\t\t\t// \t\tName: This name is already taken.\n\t\t\t\t// \t\tName: This name is too short.\n\t\t\t\t// \t\tEmail: This email is already taken\n\t\t\t\t//\t\tThis username is already taken.\n\t\t\t\t// TODO: Support bold field names without using unsafe HTML\n\t\t\t\ttry {\n\t\t\t\t\tret = Object.entries(responseBody.body)\n\t\t\t\t\t\t.map(([key, value]) => {\n\t\t\t\t\t\t\tif (typeof value === \"string\") {\n\t\t\t\t\t\t\t\tif (_SPECIAL_KEYS.includes(key)) return value\n\t\t\t\t\t\t\t\treturn `${key}: ${value}`\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (Array.isArray(value)) {\n\t\t\t\t\t\t\t\tif (_SPECIAL_KEYS.includes(key)) return value.join(\"\\n\")\n\t\t\t\t\t\t\t\treturn value.map((v) => `${key}: ${v}`).join(\"\\n\")\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn `${key}: ${JSON.stringify(value)}`\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(\"\\n\")\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconsole.error(\"Failed to extract error message from response body\", e)\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (typeof errorRes.body === \"string\") {\n\t\t\tret = errorRes.body\n\t\t}\n\t} else if (errorRes?.text) {\n\t\tret = errorRes.text\n\t} else if (err instanceof Error) {\n\t\tret = err.message\n\t}\n\n\t// Check the length of the message. If it's too long, show a generic message instead.\n\t// This can happen if the backend returns a document instead of a JSON object.\n\tif (!ret || ret.length > MAX_ERROR_MESSAGE_LENGTH) {\n\t\treturn UNKNOWN_ERROR_MESSAGE\n\t}\n\treturn ret\n}\n\nexport class APIError extends Error {\n\t// NOTE: Needs to conform to NetworkError in @redux-offline/redux-offline, which has `status` and `response`.\n\tstatus: number\n\tresponse: request.Response | undefined\n\tmessage: string\n\toptions: APIErrorOptions\n\n\tconstructor(options: APIErrorOptions) {\n\t\tsuper(UNKNOWN_ERROR_MESSAGE)\n\t\tconst { response, innerError } = options\n\t\tthis.message = options.message ?? extractErrorMessage(response, innerError) ?? UNKNOWN_ERROR_MESSAGE\n\t\tthis.status = response?.status ?? 0\n\t\tthis.response = response\n\t\toptions.discard = options.discard ?? false\n\t\tthis.options = options\n\t}\n}\n","import L from \"leaflet\"\nimport { Bounds, Coordinates, MultiPointGeometry, PointGeometry } from \"../typings\"\n\n// Convert our Coordinates type into a Leaflet LatLngLiteral\nexport const coordinatesToLiteral = (coordinates: Coordinates): L.LatLngLiteral => {\n\treturn { lng: coordinates[0], lat: coordinates[1] }\n}\n\n// Convert a Leaflet LatLngLiteral into our Coordinates type\nexport const literalToCoordinates = (literal: L.LatLngLiteral): Coordinates => {\n\treturn [literal.lng, literal.lat]\n}\n\n/**\n * Flip coordinates from [lng, lat] to [lat, lng]\n */\nexport const flipCoordinates = (coordinates: L.LatLngTuple): Coordinates => {\n\treturn [coordinates[1], coordinates[0]]\n}\n\nexport const flipBounds = (bounds: Bounds): Bounds => {\n\treturn [flipCoordinates(bounds[0]), flipCoordinates(bounds[1])]\n}\n\nexport function offsetPositionByMeters(\n\toriginalPosition: L.LatLng,\n\tlatMeters: number,\n\tlngMeters: number,\n): L.LatLngLiteral {\n\tconst { lat, lng } = originalPosition\n\tconst earthRadius = 6378137 // Earth's radius in meters.\n\tconst metersPerDegree = (2 * Math.PI * earthRadius) / 360\n\t// The significance of one degree decreases the closer you get to a pole. This accounts for that.\n\tconst newLng = lng + lngMeters / metersPerDegree / Math.cos((lat * Math.PI) / 180)\n\tconst newLat = lat - latMeters / metersPerDegree\n\treturn { lat: newLat, lng: newLng }\n}\n\nexport const createPointGeometry = (coordinates: Coordinates): PointGeometry => {\n\treturn {\n\t\ttype: \"Point\",\n\t\tcoordinates,\n\t}\n}\n\nexport const coordinatesAreEqual = (a: Coordinates, b: Coordinates): boolean => {\n\treturn a[0] === b[0] && a[1] === b[1]\n}\n\n// export const coordinatesAreNearlyEqual = (a: Coordinates, b: Coordinates, thresholdMeters: number): boolean => {\n// return a === b\n// TODO: Fix\n// const diffLat = Math.abs(a[1] - b[1])\n// Length in km of 1° of latitude = always 111.32 km\n// const diffLatMeters = diffLat * 111320\n// if (diffLatMeters < thresholdMeters) return true\n// Length in km of 1° of longitude = 40075 km * cos(latitude) / 360'\n// const aVal = a[0] // Optimization\n// const diffLong = Math.abs(aVal - b[0])\n// const diffLongMeters = diffLong * ((40075000 * Math.cos(aVal)) / 360)\n// return diffLongMeters < thresholdMeters\n// }\n\n// This converts a Coordinate [lng, lat] to \"lat, lng\" string format with an option to round the numbers\nexport const coordinatesToText = (coordinates: Coordinates | null | undefined, decimalPlaces?: number) => {\n\tif (!coordinates) return \"(No Location)\"\n\tconst { lat, lng } = coordinatesToLiteral(coordinates)\n\tif (decimalPlaces) return `${lat.toFixed(decimalPlaces)}, ${lng.toFixed(decimalPlaces)}`\n\treturn `${lat}, ${lng}`\n}\n\nexport const coordinatesToUrlText = (coordinates: Coordinates) => {\n\tconst { lat, lng } = coordinatesToLiteral(coordinates)\n\treturn `${lat}%2C${lng}`\n}\n\n// Opens coordinates in Google maps\nexport const openCoordsInGoogleMaps = (coordinates: Coordinates) => {\n\tconst url = `https://www.google.com/maps/search/?api=1&query=${coordinatesToUrlText(coordinates)}`\n\twindow.open(url)\n}\n\nexport const openDirectionsInGoogleMaps = (startingPoint: Coordinates, destination: Coordinates) => {\n\tconst startingPointUrl = coordinatesToUrlText(startingPoint)\n\tconst destinationUrl = coordinatesToUrlText(destination)\n\tconst url = `https://www.google.com/maps/dir/?api=1&origin=${startingPointUrl}&destination=${destinationUrl}`\n\twindow.open(url)\n}\n\nexport const worldBounds: MultiPointGeometry = {\n\ttype: \"MultiPoint\",\n\tcoordinates: [\n\t\t[90, -180],\n\t\t[-90, 180],\n\t],\n}\n\nexport const createMultiPointGeometry = (coordinates: [Coordinates, Coordinates]): MultiPointGeometry => {\n\treturn {\n\t\ttype: \"MultiPoint\",\n\t\tcoordinates,\n\t}\n}\n","import { saveAs } from \"file-saver\"\nimport { FileUploadPayload } from \"../typings\"\n\n// See: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string\nfunction hex(buffer: ArrayBufferLike): string {\n\tconst hashArray = new Uint8Array(buffer)\n\n\treturn hashArray.reduce((data, byte) => data + byte.toString(16).padStart(2, \"0\"), \"\")\n}\n\nexport const getFileS3Key = async (file: File, hash?: string) => {\n\tif (!hash) {\n\t\thash = await hashFile(file)\n\t}\n\tlet fileType = file.type\n\tif (fileType.includes(\"/\")) {\n\t\tfileType = fileType.split(\"/\")[1]!\n\t}\n\tif (!fileType) {\n\t\tthrow new Error(`Could not extract file type from ${file.type}`)\n\t}\n\treturn `${hash}.${fileType}`\n}\n\nexport function hashFile(file: Blob): Promise<string> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst reader = new FileReader()\n\t\t// Provide an onload callback for this instance of FileReader\n\t\t// This is called once reader.readAsArrayBuffer() is done\n\t\treader.onload = () => {\n\t\t\tconst fileResult = reader.result as ArrayBuffer | null\n\t\t\tif (!fileResult) {\n\t\t\t\treject()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tvoid crypto.subtle.digest(\"SHA-1\", fileResult).then((hash) => {\n\t\t\t\tconst sha1result = hex(hash)\n\t\t\t\tresolve(sha1result)\n\t\t\t})\n\t\t}\n\n\t\t// calling reader.readAsArrayBuffer and providing a file should trigger the callback above\n\t\t// as soon as readAsArrayBuffer is complete\n\t\treader.readAsArrayBuffer(file)\n\t})\n}\n\nexport function getFileIdentifier(file: File): string {\n\tif (!file.name || !file.type || !file.size) {\n\t\tconst message = \"File has no name, type, and/or size\"\n\t\tconsole.error(`${message}`, file)\n\t\tthrow new Error(`${message}.`)\n\t}\n\treturn `${file.name}&${file.type}${file.size}`\n}\n\nexport function getRenamedFile(file: File, newName: string): File & { name: string } {\n\treturn new File([file], newName, { type: file.type })\n}\n\nexport function downloadInMemoryFile(filename: string, text: string) {\n\tconst element = document.createElement(\"a\")\n\telement.setAttribute(\"href\", \"data:text/plain;charset=utf-8,\" + encodeURIComponent(text))\n\telement.setAttribute(\"download\", filename)\n\n\telement.style.display = \"none\"\n\tdocument.body.appendChild(element)\n\n\telement.click()\n\n\tdocument.body.removeChild(element)\n}\n\n// TODO: implement to not block ui when hashing https://developer.chrome.com/blog/introducing-scheduler-yield-origin-trial\nexport const constructUploadedFilePayloads = async (files: File[]): Promise<FileUploadPayload[]> => {\n\tconst filePayloads: Record<string, FileUploadPayload> = {}\n\tfor (const file of files) {\n\t\tconst sha1 = await hashFile(file)\n\t\tfilePayloads[sha1] = {\n\t\t\tsha1,\n\t\t\textension: file.name.split(\".\").pop() || \"\",\n\t\t\tfile_type: file.type,\n\t\t\tsize: file.size,\n\t\t}\n\t}\n\treturn Object.values(filePayloads)\n}\n\nexport const fileToBlob = async (dataUrl: string): Promise<Blob> => {\n\t// TODO: Is this as reliable and supported as this?\n\t// https://www.nixtu.info/2013/06/how-to-upload-canvas-data-to-server.html\n\treturn (await fetch(dataUrl)).blob()\n}\n\nexport const blobToBase64 = (blob: Blob): Promise<string> => {\n\treturn new Promise((resolve, _) => {\n\t\tconst reader = new FileReader()\n\t\treader.onloadend = () => {\n\t\t\tresolve(reader.result?.toString() || \"\")\n\t\t}\n\t\treader.readAsDataURL(blob)\n\t})\n}\n\n// TODO:\n/** Converts a profile `file` and `fileSha1` into an img src that can be rendered. This relies on an API request. */\n\nexport function downloadFile(file: File) {\n\tconst blob = new Blob([file])\n\tsaveAs(blob, file.name)\n}\n","const logCache: Record<string, Record<string, boolean> | undefined> = {}\n\n/**\n * Logging the same message over and over again in a loop takes a lot of resources and makes the app laggy. This utility\n * function accepts a log ID (e.g. \"issue-has-no-index-workspace\") and an object ID (e.g. the offline_id of an issue),\n * and only logs the message on the first call with the same combination of logId and objId.\n * @param logId An arbitrary but unique identifier for this \"type of message\".\n * @param objId A unique identifier for the object the message regards. Can be an arbitrary string, e.g. \"current-user\"\n * or an actual object ID, e.g. the offline_id of an issue.\n * @param level The log level to use. For example, \"debug\" means `console.debug` will be called.\n * @param args The arguments to pass to the console log method.\n */\nexport function logOnlyOnce(\n\tlogId: string,\n\tobjId: string,\n\tlevel: \"debug\" | \"info\" | \"warn\" | \"error\",\n\t...args: unknown[]\n) {\n\tconst thisLogIdCache = logCache[logId]\n\tlet shouldLog = false\n\tif (!thisLogIdCache) {\n\t\tlogCache[logId] = { [objId]: true }\n\t\tshouldLog = true\n\t} else {\n\t\tconst hasLoggedForThisObject = thisLogIdCache[objId]\n\t\tif (!hasLoggedForThisObject) {\n\t\t\tthisLogIdCache[objId] = true\n\t\t\tshouldLog = true\n\t\t}\n\t}\n\tif (shouldLog) {\n\t\tconsole[level](...args)\n\t}\n}\n","import { Offline, OfflineModel } from \"../typings\"\nimport { v4 as uuidv4 } from \"uuid\"\n\n/**\n * Adds a generated UUID to the \"offline_id\" key of the object.\n * @param draft The model data to add the offline_id to\n */\nexport function offline<T>(draft: T): Offline<T> {\n\treturn { ...draft, offline_id: uuidv4() } as Offline<T>\n}\n\n/**\n * Converts an array of OfflineModel objects to a Record<string, TModel>, mapping an offline ID to the object with that\n * offline ID.\n * @param array An array of offline model instances\n */\nexport function toOfflineIdRecord<TModel extends OfflineModel>(array: TModel[]): Record<string, TModel> {\n\tconst asMapping: Record<string, TModel> = {}\n\tfor (const item of array) {\n\t\tasMapping[item.offline_id] = item\n\t}\n\treturn asMapping\n}\n","/**\n * Returns a file-safe string from arbitrary text. Will return maximum 255 characters, which is the longest safe\n * Long File Name (LFN).\n * WARNING! May give poor performance in big loops.\n * @param str The string to make safe for file names.\n * @param extension An extension (not including a period) to be added after a period at the end of the string. The\n * character limit of the returned string includes the extension, meaning characters from str will be removed to\n * accommodate it if necessary.\n * @param maxLength The maximum length of the resulting file name. Defaults to 255.\n */\nexport function toFileNameSafeString(str: string, extension: string | undefined = undefined, maxLength = 255): string {\n\tlet ret = str.replace(/[^a-z0-9_\\-.]/gi, \"_\").replace(/_{2,}/g, \"_\")\n\tif (!extension) {\n\t\tconst parts = str.split(\".\")\n\t\tif (parts.length > 1) {\n\t\t\textension = parts[parts.length - 1]\n\t\t}\n\t}\n\tif (extension && !extension.startsWith(\".\")) {\n\t\textension = \".\" + extension\n\t}\n\tconst extensionLengthWithPeriod = extension ? extension.length : 0\n\n\tif (ret.length + extensionLengthWithPeriod > maxLength) {\n\t\tret = ret.slice(0, maxLength - extensionLengthWithPeriod) + (extension || \"\")\n\t}\n\treturn ret\n}\n\nexport function spacesToDashesLower(value: string): string {\n\treturn value.toLowerCase().replace(\" \", \"-\")\n}\n\nexport function slugify(str: string, underscore = false) {\n\treturn str\n\t\t.normalize(\"NFKD\")\n\t\t.toLowerCase()\n\t\t.replace(/[^\\w\\s-]/g, \"\")\n\t\t.trim()\n\t\t.replace(/[-\\s]+/g, underscore ? \"_\" : \"-\")\n}\n\n/**\n * Given a string, returns a truncated version of it with an ellipsis character at the end if it is longer than\n * maxLength. The resulting string will be no longer than maxLength. Note that the ellipsis is only one character long.\n * @param str The string to truncate.\n * @param maxLength The maximum length of the resulting string, including the ellipsis.\n */\nexport function truncate(str: string, maxLength: number) {\n\tif (str.length <= maxLength) {\n\t\treturn str\n\t}\n\t// -1 to account for the ellipsis character\n\tconst subString = str.slice(0, maxLength - 1)\n\treturn subString.slice(0, subString.lastIndexOf(\" \")) + \"…\"\n}\n","import { Coordinates, IssueAttachment, OfflineModel, OvermapRootState } from \"../typings\"\n\ntype MemoizedSelectorWithArgs<TArgs, TRet> = (state: OvermapRootState, args: TArgs) => TRet\n\n// makes the createSelector function fit the current pattern for selectors with arguments\nexport const restructureCreateSelectorWithArgs =\n\t<TArgs, TRet>(selector: MemoizedSelectorWithArgs<TArgs, TRet>) =>\n\t(args: TArgs) =>\n\t(state: OvermapRootState) =>\n\t\tselector(state, args)\n\nexport function onlyUniqueOfflineIds(value: OfflineModel, index: number, self: OfflineModel[]) {\n\treturn self.findIndex((v) => v.offline_id === value.offline_id) === index\n}\n\nexport function onlyUniqueHashes(value: IssueAttachment, index: number, self: IssueAttachment[]) {\n\treturn (\n\t\tself.findIndex((v: IssueAttachment) => {\n\t\t\treturn v.file_sha1 === value.file_sha1\n\t\t}) === index\n\t)\n}\n\n/**\n *\n * @param bounds order: [northEast, southWest]\n * @param coordinates\n */\nexport function boundsContainPoint(bounds: [Coordinates, Coordinates], coordinates: Coordinates): boolean {\n\t// TODO: this is flipped for Marker (Geometry)\n\treturn (\n\t\tbounds[0][0] > coordinates[0] &&\n\t\tbounds[1][0] < coordinates[0] &&\n\t\tbounds[0][1] > coordinates[1] &&\n\t\tbounds[1][1] < coordinates[1]\n\t)\n}\n\nexport const emailRegex = /^.+@.+\\..+$/\n","import { IssuePriority, IssueStatus } from \"../enums\"\n\nexport const DEFAULT_ISSUE_STATUS = IssueStatus.BACKLOG\nexport const DEFAULT_ISSUE_PRIORITY = IssuePriority.MEDIUM\n","export const OUTBOX_RETRY_DELAY = 60000 // milliseconds\n","// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nexport const EMPTY_ARRAY: any[] = Object.freeze([]) // eslint-disable-line @typescript-eslint/no-explicit-any\n","import { EMPTY_ARRAY } from \"../constants\"\n\nlet debug = false\n\nconst REACT_APP_DEBUG_MEMOIZATION = (import.meta.env.REACT_APP_DEBUG_MEMOIZATION as string | undefined) || \"\"\n\nif ([\"true\", \"1\"].includes(REACT_APP_DEBUG_MEMOIZATION.toLowerCase())) {\n\tdebug = true\n}\n\nexport function shallowEqual(objA: Record<string, unknown>, objB: Record<string, unknown>) {\n\t// Check if they're the same object (objA is objB) -- just a quick reference check\n\tif (objA === objB) return true\n\n\tif (typeof objA !== typeof objB) {\n\t\treturn false\n\t}\n\n\tconst keysA = Object.keys(objA)\n\tconst keysB = Object.keys(objB)\n\n\t// Only calculate this once\n\tconst keysALength = keysA.length\n\tif (keysALength !== keysB.length) return false\n\n\tfor (let i = 0; i < keysALength; i++) {\n\t\tconst key = keysA[i]!\n\t\tif (!Object.prototype.hasOwnProperty.call(objB, key) || objA[key] !== objB[key]) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\nexport function memoize<T extends (...args: never[]) => unknown>(func: T): T {\n\t// Taken from https://www.sitepoint.com/implementing-memoization-in-javascript/\n\tconst memo = {}\n\n\treturn function () {\n\t\t// eslint-disable-next-line prefer-rest-params\n\t\tconst args = Array.prototype.slice.call(arguments) as never[]\n\n\t\t// SEE: https://stackoverflow.com/questions/10173956/how-to-use-array-as-key-in-javascript\n\n\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t// @ts-expect-error\n\t\tif (args in memo) {\n\t\t\tif (debug) {\n\t\t\t\tconsole.debug(`Memoization debug: Using memorized return value for ${func.toString()}(`, args, \")\")\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t\t// @ts-expect-error\n\t\t\treturn memo[args] as T\n\t\t} else {\n\t\t\tif (debug) {\n\t\t\t\tconsole.debug(`Memoization debug: Cache miss! Memoizing ${func.toString()}(`, args, \")\")\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t\t\t// @ts-expect-error\n\t\t\treturn (memo[args] = func.apply(this, args))\n\t\t}\n\t} as T\n}\n\n/**\n * Performs an equality check by contents in order.\n * Reference types like objects and arrays are compared by reference.\n */\nexport function areArraysEqual(first: unknown[], second: unknown[]) {\n\tif (first.length !== second.length) return false\n\tfor (let i = 0; i < first.length; i++) {\n\t\tif (first[i] !== second[i]) return false\n\t}\n\treturn true\n}\n\nexport const fallbackToEmptyArray = <T>(array: T[]) => {\n\treturn array.length === 0 ? (EMPTY_ARRAY as T[]) : array\n}\n","import { default as ColorCls } from \"color\"\nimport {\n\tamber,\n\tblue,\n\tbrown,\n\tcrimson,\n\tcyan,\n\tgold,\n\tgrass,\n\tgray,\n\tindigo,\n\tiris,\n\tjade,\n\tlime,\n\tmint,\n\torange,\n\tpink,\n\tplum,\n\tpurple,\n\tred,\n\tsky,\n\tviolet,\n\tyellow,\n} from \"@radix-ui/colors\"\nimport { CSSColor } from \"../typings\"\n\n// TODO: Move most of these constants into src/theme/variables.ts\nexport const primaryColor: CSSColor = \"#2D55E2\"\nexport const successColor: CSSColor = \"#349C55\"\nexport const warningColor: CSSColor = \"#FFA620\"\nexport const errorColor: CSSColor = \"#E24C4C\"\nexport const GREEN: CSSColor = \"#1fd155\"\nexport const YELLOW: CSSColor = \"#f5de14\"\nexport interface BadgeColors {\n\tbackgroundColor: CSSColor\n\ttextColor: CSSColor\n}\n\n// Colors used for color selection purposes\nexport const Colors: Record<string, CSSColor> = {\n\tgray: (gray as Record<string, CSSColor>).gray9!,\n\tgold: (gold as Record<string, CSSColor>).gold9!,\n\tbrown: (brown as Record<string, CSSColor>).brown9!,\n\tyellow: (yellow as Record<string, CSSColor>).yellow9!,\n\tamber: (amber as Record<string, CSSColor>).amber9!,\n\torange: (orange as Record<string, CSSColor>).orange9!,\n\tred: (red as Record<string, CSSColor>).red9!,\n\tcrimson: (crimson as Record<string, CSSColor>).crimson9!,\n\tpink: (pink as Record<string, CSSColor>).pink9!,\n\tplum: (plum as Record<string, CSSColor>).plum9!,\n\tpurple: (purple as Record<string, CSSColor>).purple9!,\n\tviolet: (violet as Record<string, CSSColor>).violet9!,\n\tiris: (iris as Record<string, CSSColor>).iris9!,\n\tindigo: (indigo as Record<string, CSSColor>).indigo9!,\n\tblue: (blue as Record<string, CSSColor>).blue9!,\n\tcyan: (cyan as Record<string, CSSColor>).cyan9!,\n\tjade: (jade as Record<string, CSSColor>).jade9!,\n\tgrass: (grass as Record<string, CSSColor>).grass9!,\n\tlime: (lime as Record<string, CSSColor>).lime9!,\n\tmint: (mint as Record<string, CSSColor>).mint9!,\n\tsky: (sky as Record<string, CSSColor>).sky9!,\n}\n\nexport const defaultBadgeColor: CSSColor = \"#868686\"\n\n// This function adjusts a given colour into two variations for use as badge colours\nexport const generateBadgeColors = (rawColor: CSSColor): BadgeColors => {\n\tconst color = ColorCls(rawColor)\n\tconst safety = ColorCls(YELLOW)\n\tconst backgroundColor: CSSColor = color.darken(0.09).hex() as CSSColor\n\t// If the color matches the special yellow safety color, make the text black\n\tconst textColor = color.hex() === safety.hex() ? \"#000000\" : \"#FFFFFF\"\n\t// Alternate style:\n\t// const backgroundColor = color.lighten(0.4).hex()\n\t// const textColor = color.darken(0.6).hex()\n\n\treturn { backgroundColor, textColor }\n}\n","import { memoize } from \"./optimization\"\n\n/** Only shows year if a past year */\nexport const getLocalDateString = memoize((date?: string | null | Date | number) => {\n\tif (!date) return \"\"\n\tconst asDate = new Date(date)\n\tconst isThisYear = asDate.getFullYear() === today.getFullYear()\n\tconst options: Intl.DateTimeFormatOptions = { day: \"numeric\", month: \"short\" }\n\tif (!isThisYear) options.year = \"numeric\"\n\treturn asDate.toLocaleDateString([], options)\n})\n\nconst relative = new Intl.RelativeTimeFormat([], { style: \"long\", numeric: \"auto\" })\nconst msInDay = 1000 * 86400\nconst today = new Date()\n\n/** Returns true if the given date is today */\nexport const isToday = (date: string | Date | number) => {\n\treturn new Date(date).toDateString() === today.toDateString()\n}\n\n/*\nDisplays a relative message \"in 2 days\" or \"today\" if within the given period (min, max)\nOtherwise, falls back to getLocalDateString()\n*/\nexport const getLocalRelativeDateString = memoize((date: string | Date | number, min: number, max: number) => {\n\tconst days = Math.round((new Date(date).getTime() - today.getTime()) / msInDay)\n\tif (days < min || days > max) return getLocalDateString(date)\n\treturn relative.format(days, \"days\")\n})\n","// https://gist.github.com/GFoley83/5877f6c09fbcfd62569c51dc91444cf0\n\n/**\n * A new instance of deferred is constructed by calling `new DeferredPromise<T>()`.\n * The purpose of the deferred object is to expose the associated Promise\n * instance APIs that can be used for signaling the successful\n * or unsuccessful completion, as well as the state of the task.\n * @export\n * @class DeferredPromise\n * @implements {Promise<T>}\n * @template T\n * @example\n * const deferred = new DeferredPromise<string>()\n * console.log(deferred.state) // \"pending\"\n *\n * deferred\n * .then(str => console.log(str))\n * .catch(err => console.error(err))\n *\n * deferred.resolve(\"Foo\")\n * console.log(deferred.state) // \"fulfilled\"\n * // deferred.reject(\"Bar\")\n */\nexport class DeferredPromise<T> implements Promise<T> {\n\t[Symbol.toStringTag] = \"Promise\"\n\n\tprivate _promise: Promise<T>\n\tprivate _resolve: null | ((value?: T | PromiseLike<T>) => void)\n\tprivate _reject: null | ((reason?: unknown) => void)\n\tprivate _state: \"pending\" | \"fulfilled\" | \"rejected\" = \"pending\"\n\n\tpublic get state(): \"pending\" | \"fulfilled\" | \"rejected\" {\n\t\treturn this._state\n\t}\n\n\tconstructor() {\n\t\tthis._resolve = null\n\t\tthis._reject = null\n\n\t\tthis._promise = new Promise<T>((resolve, reject) => {\n\t\t\tthis._resolve = resolve as (value?: T | PromiseLike<T>) => void\n\t\t\tthis._reject = reject\n\t\t})\n\t}\n\n\tpublic then<TResult1, TResult2>(\n\t\tonFulfilled?: (value: T) => TResult1 | PromiseLike<TResult1>,\n\t\tonRejected?: (reason: unknown) => TResult2 | PromiseLike<TResult2>,\n\t): Promise<TResult1 | TResult2> {\n\t\treturn this._promise.then(onFulfilled, onRejected)\n\t}\n\n\tpublic catch<TResult>(onRejected?: (reason: unknown) => TResult | PromiseLike<TResult>): Promise<T | TResult> {\n\t\treturn this._promise.catch(onRejected)\n\t}\n\n\tpublic resolve(value?: T | PromiseLike<T>): void {\n\t\tif (!this._resolve) throw new Error(\"No resolve callback\")\n\t\tthis._resolve(value)\n\t\tthis._state = \"fulfilled\"\n\t}\n\n\tpublic reject(reason?: unknown): void {\n\t\tif (!this._reject) throw reason\n\t\tthis._reject(reason)\n\t\tthis._state = \"rejected\"\n\t}\n\n\tpublic finally(_onFinally?: (() => void) | undefined | null): Promise<T> {\n\t\tthrow new Error(\"`finally` not implemented\")\n\t}\n}\n","import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';\n\n/**\n * Adapted from React: https://github.com/facebook/react/blob/master/packages/shared/formatProdErrorMessage.js\n *\n * Do not require this module directly! Use normal throw error calls. These messages will be replaced with error codes\n * during build.\n * @param {number} code\n */\nfunction formatProdErrorMessage(code) {\n return \"Minified Redux error #\" + code + \"; visit https://redux.js.org/Errors?code=\" + code + \" for the full message or \" + 'use the non-minified dev environment for full errors. ';\n}\n\n// Inlined version of the `symbol-observable` polyfill\nvar $$observable = (function () {\n return typeof Symbol === 'function' && Symbol.observable || '@@observable';\n})();\n\n/**\n * These are private action types reserved by Redux.\n * For any unknown actions, you must return the current state.\n * If the current state is undefined, you must return the initial state.\n * Do not reference these action types directly in your code.\n */\nvar randomString = function randomString() {\n return Math.random().toString(36).substring(7).split('').join('.');\n};\n\nvar ActionTypes = {\n INIT: \"@@redux/INIT\" + randomString(),\n REPLACE: \"@@redux/REPLACE\" + randomString(),\n PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {\n return \"@@redux/PROBE_UNKNOWN_ACTION\" + randomString();\n }\n};\n\n/**\n * @param {any} obj The object to inspect.\n * @returns {boolean} True if the argument appears to be a plain object.\n */\nfunction isPlainObject(obj) {\n if (typeof obj !== 'object' || obj === null) return false;\n var proto = obj;\n\n while (Object.getPrototypeOf(proto) !== null) {\n proto = Object.getPrototypeOf(proto);\n }\n\n return Object.getPrototypeOf(obj) === proto;\n}\n\n// Inlined / shortened version of `kindOf` from https://github.com/jonschlinkert/kind-of\nfunction miniKindOf(val) {\n if (val === void 0) return 'undefined';\n if (val === null) return 'null';\n var type = typeof val;\n\n switch (type) {\n case 'boolean':\n case 'string':\n case 'number':\n case 'symbol':\n case 'function':\n {\n return type;\n }\n }\n\n if (Array.isArray(val)) return 'array';\n if (isDate(val)) return 'date';\n if (isError(val)) return 'error';\n var constructorName = ctorName(val);\n\n switch (constructorName) {\n case 'Symbol':\n case 'Promise':\n case 'WeakMap':\n case 'WeakSet':\n case 'Map':\n case 'Set':\n return constructorName;\n } // other\n\n\n return type.slice(8, -1).toLowerCase().replace(/\\s/g, '');\n}\n\nfunction ctorName(val) {\n return typeof val.constructor === 'function' ? val.constructor.name : null;\n}\n\nfunction isError(val) {\n return val instanceof Error || typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number';\n}\n\nfunction isDate(val) {\n if (val instanceof Date) return true;\n return typeof val.toDateString === 'function' && typeof val.getDate === 'function' && typeof val.setDate === 'function';\n}\n\nfunction kindOf(val) {\n var typeOfVal = typeof val;\n\n if (process.env.NODE_ENV !== 'production') {\n typeOfVal = miniKindOf(val);\n }\n\n return typeOfVal;\n}\n\n/**\n * @deprecated\n *\n * **We recommend using the `configureStore` method\n * of the `@reduxjs/toolkit` package**, which replaces `createStore`.\n *\n * Redux Toolkit is our recommended approach for writing Redux logic today,\n * including store setup, reducers, data fetching, and more.\n *\n * **For more details, please read this Redux docs page:**\n * **https://redux.js.org/introduction/why-rtk-is-redux-today**\n *\n * `configureStore` from Redux Toolkit is an improved version of `createStore` that\n * simplifies setup and helps avoid common bugs.\n *\n * You should not be using the `redux` core package by itself today, except for learning purposes.\n * The `createStore` method from the core `redux` package will not be removed, but we encourage\n * all users to migrate to using Redux Toolkit for all Redux code.\n *\n * If you want to use `createStore` without this visual deprecation warning, use\n * the `legacy_createStore` import instead:\n *\n * `import { legacy_createStore as createStore} from 'redux'`\n *\n */\n\nfunction createStore(reducer, preloadedState, enhancer) {\n var _ref2;\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'function' || typeof enhancer === 'function' && typeof arguments[3] === 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(0) : 'It looks like you are passing several store enhancers to ' + 'createStore(). This is not supported. Instead, compose them ' + 'together to a single function. See https://redux.js.org/tutorials/fundamentals/part-4-store#creating-a-store-with-enhancers for an example.');\n }\n\n if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {\n enhancer = preloadedState;\n preloadedState = undefined;\n }\n\n if (typeof enhancer !== 'undefined') {\n if (typeof enhancer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(1) : \"Expected the enhancer to be a function. Instead, received: '\" + kindOf(enhancer) + \"'\");\n }\n\n return enhancer(createStore)(reducer, preloadedState);\n }\n\n if (typeof reducer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(2) : \"Expected the root reducer to be a function. Instead, received: '\" + kindOf(reducer) + \"'\");\n }\n\n var currentReducer = reducer;\n var currentState = preloadedState;\n var currentListeners = [];\n var nextListeners = currentListeners;\n var isDispatching = false;\n /**\n * This makes a shallow copy of currentListeners so we can use\n * nextListeners as a temporary list while dispatching.\n *\n * This prevents any bugs around consumers calling\n * subscribe/unsubscribe in the middle of a dispatch.\n */\n\n function ensureCanMutateNextListeners() {\n if (nextListeners === currentListeners) {\n nextListeners = currentListeners.slice();\n }\n }\n /**\n * Reads the state tree managed by the store.\n *\n * @returns {any} The current state tree of your application.\n */\n\n\n function getState() {\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(3) : 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from the store.');\n }\n\n return currentState;\n }\n /**\n * Adds a change listener. It will be called any time an action is dispatched,\n * and some part of the state tree may potentially have changed. You may then\n * call `getState()` to read the current state tree inside the callback.\n *\n * You may call `dispatch()` from a change listener, with the following\n * caveats:\n *\n * 1. The subscriptions are snapshotted just before every `dispatch()` call.\n * If you subscribe or unsubscribe while the listeners are being invoked, this\n * will not have any effect on the `dispatch()` that is currently in progress.\n * However, the next `dispatch()` call, whether nested or not, will use a more\n * recent snapshot of the subscription list.\n *\n * 2. The listener should not expect to see all state changes, as the state\n * might have been updated multiple times during a nested `dispatch()` before\n * the listener is called. It is, however, guaranteed that all subscribers\n * registered before the `dispatch()` started will be called with the latest\n * state by the time it exits.\n *\n * @param {Function} listener A callback to be invoked on every dispatch.\n * @returns {Function} A function to remove this change listener.\n */\n\n\n function subscribe(listener) {\n if (typeof listener !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(4) : \"Expected the listener to be a function. Instead, received: '\" + kindOf(listener) + \"'\");\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(5) : 'You may not call store.subscribe() while the reducer is executing. ' + 'If you would like to be notified after the store has been updated, subscribe from a ' + 'component and invoke store.getState() in the callback to access the latest state. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');\n }\n\n var isSubscribed = true;\n ensureCanMutateNextListeners();\n nextListeners.push(listener);\n return function unsubscribe() {\n if (!isSubscribed) {\n return;\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(6) : 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.');\n }\n\n isSubscribed = false;\n ensureCanMutateNextListeners();\n var index = nextListeners.indexOf(listener);\n nextListeners.splice(index, 1);\n currentListeners = null;\n };\n }\n /**\n * Dispatches an action. It is the only way to trigger a state change.\n *\n * The `reducer` function, used to create the store, will be called with the\n * current state tree and the given `action`. Its return value will\n * be considered the **next** state of the tree, and the change listeners\n * will be notified.\n *\n * The base implementation only supports plain object actions. If you want to\n * dispatch a Promise, an Observable, a thunk, or something else, you need to\n * wrap your store creating function into the corresponding middleware. For\n * example, see the documentation for the `redux-thunk` package. Even the\n * middleware will eventually dispatch plain object actions using this method.\n *\n * @param {Object} action A plain object representing “what changed”. It is\n * a good idea to keep actions serializable so you can record and replay user\n * sessions, or use the time travelling `redux-devtools`. An action must have\n * a `type` property which may not be `undefined`. It is a good idea to use\n * string constants for action types.\n *\n * @returns {Object} For convenience, the same action object you dispatched.\n *\n * Note that, if you use a custom middleware, it may wrap `dispatch()` to\n * return something else (for example, a Promise you can await).\n */\n\n\n function dispatch(action) {\n if (!isPlainObject(action)) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(7) : \"Actions must be plain objects. Instead, the actual type was: '\" + kindOf(action) + \"'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic#using-the-redux-thunk-middleware for examples.\");\n }\n\n if (typeof action.type === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(8) : 'Actions may not have an undefined \"type\" property. You may have misspelled an action type string constant.');\n }\n\n if (isDispatching) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(9) : 'Reducers may not dispatch actions.');\n }\n\n try {\n isDispatching = true;\n currentState = currentReducer(currentState, action);\n } finally {\n isDispatching = false;\n }\n\n var listeners = currentListeners = nextListeners;\n\n for (var i = 0; i < listeners.length; i++) {\n var listener = listeners[i];\n listener();\n }\n\n return action;\n }\n /**\n * Replaces the reducer currently used by the store to calculate the state.\n *\n * You might need this if your app implements code splitting and you want to\n * load some of the reducers dynamically. You might also need this if you\n * implement a hot reloading mechanism for Redux.\n *\n * @param {Function} nextReducer The reducer for the store to use instead.\n * @returns {void}\n */\n\n\n function replaceReducer(nextReducer) {\n if (typeof nextReducer !== 'function') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(10) : \"Expected the nextReducer to be a function. Instead, received: '\" + kindOf(nextReducer));\n }\n\n currentReducer = nextReducer; // This action has a similiar effect to ActionTypes.INIT.\n // Any reducers that existed in both the new and old rootReducer\n // will receive the previous state. This effectively populates\n // the new state tree with any relevant data from the old one.\n\n dispatch({\n type: ActionTypes.REPLACE\n });\n }\n /**\n * Interoperability point for observable/reactive libraries.\n * @returns {observable} A minimal observable of state changes.\n * For more information, see the observable proposal:\n * https://github.com/tc39/proposal-observable\n */\n\n\n function observable() {\n var _ref;\n\n var outerSubscribe = subscribe;\n return _ref = {\n /**\n * The minimal observable subscription method.\n * @param {Object} observer Any object that can be used as an observer.\n * The observer object should have a `next` method.\n * @returns {subscription} An object with an `unsubscribe` method that can\n * be used to unsubscribe the observable from the store, and prevent further\n * emission of values from the observable.\n */\n subscribe: function subscribe(observer) {\n if (typeof observer !== 'object' || observer === null) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(11) : \"Expected the observer to be an object. Instead, received: '\" + kindOf(observer) + \"'\");\n }\n\n function observeState() {\n if (observer.next) {\n observer.next(getState());\n }\n }\n\n observeState();\n var unsubscribe = outerSubscribe(observeState);\n return {\n unsubscribe: unsubscribe\n };\n }\n }, _ref[$$observable] = function () {\n return this;\n }, _ref;\n } // When a store is created, an \"INIT\" action is dispatched so that every\n // reducer returns their initial state. This effectively populates\n // the initial state tree.\n\n\n dispatch({\n type: ActionTypes.INIT\n });\n return _ref2 = {\n dispatch: dispatch,\n subscribe: subscribe,\n getState: getState,\n replaceReducer: replaceReducer\n }, _ref2[$$observable] = observable, _ref2;\n}\n/**\n * Creates a Redux store that holds the state tree.\n *\n * **We recommend using `configureStore` from the\n * `@reduxjs/toolkit` package**, which replaces `createStore`:\n * **https://redux.js.org/introduction/why-rtk-is-redux-today**\n *\n * The only way to change the data in the store is to call `dispatch()` on it.\n *\n * There should only be a single store in your app. To specify how different\n * parts of the state tree respond to actions, you may combine several reducers\n * into a single reducer function by using `combineReducers`.\n *\n * @param {Function} reducer A function that returns the next state tree, given\n * the current state tree and the action to handle.\n *\n * @param {any} [preloadedState] The initial state. You may optionally specify it\n * to hydrate the state from the server in universal apps, or to restore a\n * previously serialized user session.\n * If you use `combineReducers` to produce the root reducer function, this must be\n * an object with the same shape as `combineReducers` keys.\n *\n * @param {Function} [enhancer] The store enhancer. You may optionally specify it\n * to enhance the store with third-party capabilities such as middleware,\n * time travel, persistence, etc. The only store enhancer that ships with Redux\n * is `applyMiddleware()`.\n *\n * @returns {Store} A Redux store that lets you read the state, dispatch actions\n * and subscribe to changes.\n */\n\nvar legacy_createStore = createStore;\n\n/**\n * Prints a warning in the console if it exists.\n *\n * @param {String} message The warning message.\n * @returns {void}\n */\nfunction warning(message) {\n /* eslint-disable no-console */\n if (typeof console !== 'undefined' && typeof console.error === 'function') {\n console.error(message);\n }\n /* eslint-enable no-console */\n\n\n try {\n // This error was thrown as a convenience so that if you enable\n // \"break on all exceptions\" in your console,\n // it would pause the execution at this line.\n throw new Error(message);\n } catch (e) {} // eslint-disable-line no-empty\n\n}\n\nfunction getUnexpectedStateShapeWarningMessage(inputState, reducers, action, unexpectedKeyCache) {\n var reducerKeys = Object.keys(reducers);\n var argumentName = action && action.type === ActionTypes.INIT ? 'preloadedState argument passed to createStore' : 'previous state received by the reducer';\n\n if (reducerKeys.length === 0) {\n return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';\n }\n\n if (!isPlainObject(inputState)) {\n return \"The \" + argumentName + \" has unexpected type of \\\"\" + kindOf(inputState) + \"\\\". Expected argument to be an object with the following \" + (\"keys: \\\"\" + reducerKeys.join('\", \"') + \"\\\"\");\n }\n\n var unexpectedKeys = Object.keys(inputState).filter(function (key) {\n return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];\n });\n unexpectedKeys.forEach(function (key) {\n unexpectedKeyCache[key] = true;\n });\n if (action && action.type === ActionTypes.REPLACE) return;\n\n if (unexpectedKeys.length > 0) {\n return \"Unexpected \" + (unexpectedKeys.length > 1 ? 'keys' : 'key') + \" \" + (\"\\\"\" + unexpectedKeys.join('\", \"') + \"\\\" found in \" + argumentName + \". \") + \"Expected to find one of the known reducer keys instead: \" + (\"\\\"\" + reducerKeys.join('\", \"') + \"\\\". Unexpected keys will be ignored.\");\n }\n}\n\nfunction assertReducerShape(reducers) {\n Object.keys(reducers).forEach(function (key) {\n var reducer = reducers[key];\n var initialState = reducer(undefined, {\n type: ActionTypes.INIT\n });\n\n if (typeof initialState === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(12) : \"The slice reducer for key \\\"\" + key + \"\\\" returned undefined during initialization. \" + \"If the state passed to the reducer is undefined, you must \" + \"explicitly return the initial state. The initial state may \" + \"not be undefined. If you don't want to set a value for this reducer, \" + \"you can use null instead of undefined.\");\n }\n\n if (typeof reducer(undefined, {\n type: ActionTypes.PROBE_UNKNOWN_ACTION()\n }) === 'undefined') {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(13) : \"The slice reducer for key \\\"\" + key + \"\\\" returned undefined when probed with a random type. \" + (\"Don't try to handle '\" + ActionTypes.INIT + \"' or other actions in \\\"redux/*\\\" \") + \"namespace. They are considered private. Instead, you must return the \" + \"current state for any unknown actions, unless it is undefined, \" + \"in which case you must return the initial state, regardless of the \" + \"action type. The initial state may not be undefined, but can be null.\");\n }\n });\n}\n/**\n * Turns an object whose values are different reducer functions, into a single\n * reducer function. It will call every child reducer, and gather their results\n * into a single state object, whose keys correspond to the keys of the passed\n * reducer functions.\n *\n * @param {Object} reducers An object whose values correspond to different\n * reducer functions that need to be combined into one. One handy way to obtain\n * it is to use ES6 `import * as reducers` syntax. The reducers may never return\n * undefined for any action. Instead, they should return their initial state\n * if the state passed to them was undefined, and the current state for any\n * unrecognized action.\n *\n * @returns {Function} A reducer function that invokes every reducer inside the\n * passed object, and builds a state object with the same shape.\n */\n\n\nfunction combineReducers(reducers) {\n var reducerKeys = Object.keys(reducers);\n var finalReducers = {};\n\n for (var i = 0; i < reducerKeys.length; i++) {\n var key = reducerKeys[i];\n\n if (process.env.NODE_ENV !== 'production') {\n if (typeof reducers[key] === 'undefined') {\n warning(\"No reducer provided for key \\\"\" + key + \"\\\"\");\n }\n }\n\n if (typeof reducers[key] === 'function') {\n finalReducers[key] = reducers[key];\n }\n }\n\n var finalReducerKeys = Object.keys(finalReducers); // This is used to make sure we don't warn about the same\n // keys multiple times.\n\n var unexpectedKeyCache;\n\n if (process.env.NODE_ENV !== 'production') {\n unexpectedKeyCache = {};\n }\n\n var shapeAssertionError;\n\n try {\n assertReducerShape(finalReducers);\n } catch (e) {\n shapeAssertionError = e;\n }\n\n return function combination(state, action) {\n if (state === void 0) {\n state = {};\n }\n\n if (shapeAssertionError) {\n throw shapeAssertionError;\n }\n\n if (process.env.NODE_ENV !== 'production') {\n var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action, unexpectedKeyCache);\n\n if (warningMessage) {\n warning(warningMessage);\n }\n }\n\n var hasChanged = false;\n var nextState = {};\n\n for (var _i = 0; _i < finalReducerKeys.length; _i++) {\n var _key = finalReducerKeys[_i];\n var reducer = finalReducers[_key];\n var previousStateForKey = state[_key];\n var nextStateForKey = reducer(previousStateForKey, action);\n\n if (typeof nextStateForKey === 'undefined') {\n var actionType = action && action.type;\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(14) : \"When called with an action of type \" + (actionType ? \"\\\"\" + String(actionType) + \"\\\"\" : '(unknown type)') + \", the slice reducer for key \\\"\" + _key + \"\\\" returned undefined. \" + \"To ignore an action, you must explicitly return the previous state. \" + \"If you want this reducer to hold no value, you can return null instead of undefined.\");\n }\n\n nextState[_key] = nextStateForKey;\n hasChanged = hasChanged || nextStateForKey !== previousStateForKey;\n }\n\n hasChanged = hasChanged || finalReducerKeys.length !== Object.keys(state).length;\n return hasChanged ? nextState : state;\n };\n}\n\nfunction bindActionCreator(actionCreator, dispatch) {\n return function () {\n return dispatch(actionCreator.apply(this, arguments));\n };\n}\n/**\n * Turns an object whose values are action creators, into an object with the\n * same keys, but with every function wrapped into a `dispatch` call so they\n * may be invoked directly. This is just a convenience method, as you can call\n * `store.dispatch(MyActionCreators.doSomething())` yourself just fine.\n *\n * For convenience, you can also pass an action creator as the first argument,\n * and get a dispatch wrapped function in return.\n *\n * @param {Function|Object} actionCreators An object whose values are action\n * creator functions. One handy way to obtain it is to use ES6 `import * as`\n * syntax. You may also pass a single function.\n *\n * @param {Function} dispatch The `dispatch` function available on your Redux\n * store.\n *\n * @returns {Function|Object} The object mimicking the original object, but with\n * every action creator wrapped into the `dispatch` call. If you passed a\n * function as `actionCreators`, the return value will also be a single\n * function.\n */\n\n\nfunction bindActionCreators(actionCreators, dispatch) {\n if (typeof actionCreators === 'function') {\n return bindActionCreator(actionCreators, dispatch);\n }\n\n if (typeof actionCreators !== 'object' || actionCreators === null) {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(16) : \"bindActionCreators expected an object or a function, but instead received: '\" + kindOf(actionCreators) + \"'. \" + \"Did you write \\\"import ActionCreators from\\\" instead of \\\"import * as ActionCreators from\\\"?\");\n }\n\n var boundActionCreators = {};\n\n for (var key in actionCreators) {\n var actionCreator = actionCreators[key];\n\n if (typeof actionCreator === 'function') {\n boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);\n }\n }\n\n return boundActionCreators;\n}\n\n/**\n * Composes single-argument functions from right to left. The rightmost\n * function can take multiple arguments as it provides the signature for\n * the resulting composite function.\n *\n * @param {...Function} funcs The functions to compose.\n * @returns {Function} A function obtained by composing the argument functions\n * from right to left. For example, compose(f, g, h) is identical to doing\n * (...args) => f(g(h(...args))).\n */\nfunction compose() {\n for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {\n funcs[_key] = arguments[_key];\n }\n\n if (funcs.length === 0) {\n return function (arg) {\n return arg;\n };\n }\n\n if (funcs.length === 1) {\n return funcs[0];\n }\n\n return funcs.reduce(function (a, b) {\n return function () {\n return a(b.apply(void 0, arguments));\n };\n });\n}\n\n/**\n * Creates a store enhancer that applies middleware to the dispatch method\n * of the Redux store. This is handy for a variety of tasks, such as expressing\n * asynchronous actions in a concise manner, or logging every action payload.\n *\n * See `redux-thunk` package as an example of the Redux middleware.\n *\n * Because middleware is potentially asynchronous, this should be the first\n * store enhancer in the composition chain.\n *\n * Note that each middleware will be given the `dispatch` and `getState` functions\n * as named arguments.\n *\n * @param {...Function} middlewares The middleware chain to be applied.\n * @returns {Function} A store enhancer applying the middleware.\n */\n\nfunction applyMiddleware() {\n for (var _len = arguments.length, middlewares = new Array(_len), _key = 0; _key < _len; _key++) {\n middlewares[_key] = arguments[_key];\n }\n\n return function (createStore) {\n return function () {\n var store = createStore.apply(void 0, arguments);\n\n var _dispatch = function dispatch() {\n throw new Error(process.env.NODE_ENV === \"production\" ? formatProdErrorMessage(15) : 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.');\n };\n\n var middlewareAPI = {\n getState: store.getState,\n dispatch: function dispatch() {\n return _dispatch.apply(void 0, arguments);\n }\n };\n var chain = middlewares.map(function (middleware) {\n return middleware(middlewareAPI);\n });\n _dispatch = compose.apply(void 0, chain)(store.dispatch);\n return _objectSpread(_objectSpread({}, store), {}, {\n dispatch: _dispatch\n });\n };\n };\n}\n\nexport { ActionTypes as __DO_NOT_USE__ActionTypes, applyMiddleware, bindActionCreators, combineReducers, compose, createStore, legacy_createStore };\n","// TODO: This is deprecated and moved into redux-persist. See: https://github.com/wildlifela/redux-persist-migrate\n// It also doesn't seem to be doing much.\n\nimport type { Manifest, Migrator } from \"../typings\"\n\n// NOTE: If changing, also change it in store.ts (avoid circular imports)\nconst VERSION_REDUCER_KEY = \"versioning\"\n\ntype WrapMigrator = (migrator: Migrator) => Migrator\n\n// gets the most recent (largest) version number\nconst latestVersion = () => migrations.length - 1\n\n// if unset, set the app version to the latest\n// this is the case when someone opens the app for the first time\nconst initialVersioning: Migrator = (state) => {\n\tstate[VERSION_REDUCER_KEY] = { version: latestVersion() }\n\treturn state\n}\n\n// migration that signs the user out due to the redux store being changed in a breaking way\nconst signOut: Migrator = () => {\n\t// set the app version to the latest so that this migration is not run again\n\treturn initialVersioning({})\n}\n\n// Added a new state to the outbox slice\nconst createOutboxState: Migrator = (state) => {\n\tif (state.outboxReducer) {\n\t\tstate.outboxReducer.deletedRequests = []\n\t}\n\treturn state\n}\n\n// wraps migrations with the skipAfterInitialVersioning check for convenience\nconst wrapMigration: WrapMigrator = (migrator) => (state) => {\n\t// REASON: This happened to GCS\n\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\tif (state === undefined) {\n\t\tstate = {}\n\t}\n\n\tif (state[VERSION_REDUCER_KEY]?.version === latestVersion()) return state\n\n\treturn migrator(state)\n}\n\n// migrations take in a RootState, modify it, and then return the updated root state\n// add new migrations to the **end** of this array\n// ensure initialVersioning() is always the first migration\nconst migrations: Migrator[] = [initialVersioning, signOut, signOut, createOutboxState]\n\n// used by redux-persist-migrate to run the migrations when rehydrating the app\nexport const manifest: Manifest = Object.fromEntries(migrations.map((migration, i) => [i, wrapMigration(migration)]))\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { TokenPair } from \"sdk/typings\"\nimport type { BaseState } from \"../../typings\"\n\nexport interface AuthState {\n\taccessToken: string\n\trefreshToken: string\n\tisLoggedIn: boolean\n}\n\nconst initialState: AuthState = {\n\taccessToken: \"\",\n\trefreshToken: \"\",\n\tisLoggedIn: false,\n}\n\n/**\n * Stores the auth state of the app (tokens, and whether user is logged in or not)\n */\nexport const authSlice = createSlice({\n\tname: \"auth\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetTokens: (state, action: PayloadAction<TokenPair>) => {\n\t\t\tstate.accessToken = action.payload.accessToken\n\t\t\tstate.refreshToken = action.payload.refreshToken\n\t\t},\n\t\tclearTokens: (state) => {\n\t\t\tstate.accessToken = \"\"\n\t\t\tstate.refreshToken = \"\"\n\t\t},\n\t\tsetLoggedIn: (state, action: PayloadAction<boolean>) => {\n\t\t\tif (!action.payload) {\n\t\t\t\tauthSlice.caseReducers.clearTokens(state)\n\t\t\t}\n\t\t\tstate.isLoggedIn = action.payload\n\t\t},\n\t},\n})\n\nexport const { setTokens, clearTokens, setLoggedIn } = authSlice.actions\nexport const selectAccessToken = (state: BaseState) => state.authReducer.accessToken\nexport const selectIsLoggedIn = (state: BaseState) => state.authReducer.isLoggedIn\n\nexport const authReducer: Reducer<AuthState> = authSlice.reducer\n","import { PayloadAction } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"./typings\"\n\nexport interface OvermapModelAdapter<TModel> {\n\taddOne: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => void\n\taddMany: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => void\n\tsetOne: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => void\n\tsetMany: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => void\n\tupdateOne: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => void\n\tupdateMany: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => void\n\tdeleteOne: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<string>) => void\n\tdeleteMany: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<string[]>) => void\n\tinitialize: <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => void\n\tgetInitialState: <TState extends object>(state: TState) => TState & ModelState<TModel>\n}\n\nexport function createModelAdapter<TModel>(computeModelId: (model: TModel) => string): OvermapModelAdapter<TModel> {\n\tconst addOne = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => {\n\t\t// TODO: error check here if the model already exists?\n\t\tconst id = computeModelId(action.payload)\n\t\tstate.instances[id] = action.payload\n\t}\n\n\tconst addMany = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => {\n\t\tfor (const model of action.payload) {\n\t\t\t// TODO: error check here if the model already exists?\n\t\t\tconst id = computeModelId(model)\n\t\t\tstate.instances[id] = model\n\t\t}\n\t}\n\n\tconst setOne = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => {\n\t\tconst id = computeModelId(action.payload)\n\t\tstate.instances[id] = action.payload\n\t}\n\n\tconst setMany = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => {\n\t\tfor (const model of action.payload) {\n\t\t\tconst id = computeModelId(model)\n\t\t\tstate.instances[id] = model\n\t\t}\n\t}\n\n\tconst updateOne = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel>) => {\n\t\tconst id = computeModelId(action.payload)\n\t\tstate.instances[id] = action.payload\n\t}\n\n\tconst updateMany = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => {\n\t\tfor (const model of action.payload) {\n\t\t\tconst id = computeModelId(model)\n\t\t\tstate.instances[id] = model\n\t\t}\n\t}\n\n\tconst deleteOne = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<string>) => {\n\t\tdelete state.instances[action.payload]\n\t}\n\n\tconst deleteMany = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<string[]>) => {\n\t\tfor (const id of action.payload) {\n\t\t\tdelete state.instances[id]\n\t\t}\n\t}\n\n\tconst initialize = <TState extends ModelState<TModel>>(state: TState, action: PayloadAction<TModel[]>) => {\n\t\tstate.instances = {}\n\t\tfor (const model of action.payload) {\n\t\t\t// TODO: error check here if the model already exists?\n\t\t\tconst id = computeModelId(model)\n\t\t\tstate.instances[id] = model\n\t\t}\n\t}\n\n\tconst getInitialState = <TState extends object>(state: TState) => {\n\t\treturn {\n\t\t\t...state,\n\t\t\tinstances: {} as Record<string, TModel>,\n\t\t}\n\t}\n\n\treturn {\n\t\taddOne,\n\t\taddMany,\n\t\tsetOne,\n\t\tsetMany,\n\t\tupdateOne,\n\t\tupdateMany,\n\t\tdeleteOne,\n\t\tdeleteMany,\n\t\tinitialize,\n\t\tgetInitialState,\n\t}\n}\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { Category, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type CategoryState = ModelState<Stored<Category>>\n\nconst categoryAdapter = createModelAdapter<Stored<Category>>((category) => category.offline_id)\n\nconst initialState: CategoryState = categoryAdapter.getInitialState({})\n\nexport const categorySlice = createSlice({\n\tname: \"categories\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeCategories: categoryAdapter.initialize,\n\t\taddCategory: categoryAdapter.addOne,\n\t\tupdateCategory: categoryAdapter.updateOne,\n\t\tdeleteCategory: categoryAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeCategories, addCategory, updateCategory, deleteCategory } = categorySlice.actions\n\nexport const selectCategoryMapping = (state: OvermapRootState) => state.categoryReducer.instances\n\nexport const selectCategories = createSelector([selectCategoryMapping], (categoryMapping) => {\n\treturn Object.values(categoryMapping)\n})\n\nexport const selectCategoryById: OvermapSelectorWithArgs<string, Stored<Category> | undefined> =\n\t(id: Category[\"offline_id\"]) => (state) => {\n\t\treturn state.categoryReducer.instances[id]\n\t}\n\nexport const selectCategoriesByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectCategoryMapping, (_state, categoryIds: Category[\"offline_id\"][]) => categoryIds],\n\t\t(categoryMapping, categoryIds) => {\n\t\t\tconst categories: Stored<Category>[] = []\n\n\t\t\tfor (const categoryId of categoryIds) {\n\t\t\t\tconst category = categoryMapping[categoryId]\n\n\t\t\t\tif (category) {\n\t\t\t\t\tcategories.push(category)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\"selectCategoryByIds: No category exists with the id\", categoryId)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn fallbackToEmptyArray(categories)\n\t\t},\n\t),\n)\n\nexport const selectCategoriesOfWorkspace: OvermapSelectorWithArgs<string, Category[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectCategories, (_state, workspaceId: string) => workspaceId], (categories, workspaceId) =>\n\t\t\tcategories.filter((category) => category.workspace === workspaceId),\n\t\t),\n\t)\n\nexport const selectIssueCountOfCategory: OvermapSelectorWithArgs<string | null, number> =\n\t(categoryId) => (state: OvermapRootState) => {\n\t\treturn Object.values(state.issueReducer.instances).filter((issue) => issue.category === categoryId).length\n\t}\n\nexport const categoryReducer: Reducer<CategoryState> = categorySlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { Asset, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type AssetState = ModelState<Stored<Asset>>\n\nconst assetAdapter = createModelAdapter<Stored<Asset>>((asset) => asset.offline_id)\n\nconst initialState: AssetState = assetAdapter.getInitialState({})\n\nexport const assetSlice = createSlice({\n\tname: \"assets\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssets: assetAdapter.initialize,\n\t\taddAsset: assetAdapter.addOne,\n\t\taddAssets: assetAdapter.addMany,\n\t\tsetAsset: assetAdapter.setOne,\n\t\tsetAssets: assetAdapter.setMany,\n\t\tupdateAsset: assetAdapter.updateOne,\n\t\tupdateAssets: assetAdapter.updateMany,\n\t\tdeleteAsset: assetAdapter.deleteOne,\n\t\tdeleteAssets: assetAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssets,\n\taddAsset,\n\taddAssets,\n\tupdateAsset,\n\tupdateAssets,\n\tdeleteAsset,\n\tdeleteAssets,\n\tsetAsset,\n\tsetAssets,\n} = assetSlice.actions\n\nexport const selectAssetsMapping = (state: OvermapRootState) => state.assetReducer.instances\n\nexport const selectAssets = createSelector([selectAssetsMapping], (assetsMapping) => {\n\treturn Object.values(assetsMapping)\n})\n\nexport const selectAssetsOfAssetType: OvermapSelectorWithArgs<string, Asset[]> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssets, (_state, assetTypeId: string) => assetTypeId], (assets, assetTypeId) => {\n\t\treturn fallbackToEmptyArray(assets.filter((asset) => asset.asset_type === assetTypeId))\n\t}),\n)\n\nexport const selectAssetById: OvermapSelectorWithArgs<string, Asset | undefined> =\n\t(assetId) => (state: OvermapRootState) => {\n\t\treturn state.assetReducer.instances[assetId]\n\t}\n\nexport const selectAssetsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssetsMapping, (_, assetIds: string[]) => assetIds], (assetsMapping, assetIds) => {\n\t\tconst assets: Stored<Asset>[] = []\n\n\t\tfor (const assetId of assetIds) {\n\t\t\tconst asset = assetsMapping[assetId]\n\n\t\t\tif (asset) assets.push(asset)\n\t\t}\n\n\t\treturn fallbackToEmptyArray(assets)\n\t}),\n)\n\nexport const selectNumberOfAssetsOfAssetType: OvermapSelectorWithArgs<string, number> = (assetTypeId) => (state) => {\n\treturn selectAssetsOfAssetType(assetTypeId)(state).length\n}\n\nexport const assetReducer: Reducer<AssetState> = assetSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type { AssetAttachment, OvermapRootState, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type AssetAttachmentState = ModelState<Stored<AssetAttachment>>\n\nconst assetAttachmentAdapter = createModelAdapter<Stored<AssetAttachment>>((attachment) => attachment.offline_id)\n\nconst initialState = assetAttachmentAdapter.getInitialState({})\n\nexport const assetAttachmentSlice = createSlice({\n\tname: \"assetAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetAttachments: assetAttachmentAdapter.initialize,\n\t\taddAssetAttachment: assetAttachmentAdapter.addOne,\n\t\taddAssetAttachments: assetAttachmentAdapter.addMany,\n\t\tsetAssetAttachment: assetAttachmentAdapter.setOne,\n\t\tsetAssetAttachments: assetAttachmentAdapter.setMany,\n\t\tupdateAssetAttachment: assetAttachmentAdapter.updateOne,\n\t\tupdateAssetAttachments: assetAttachmentAdapter.updateMany,\n\t\tdeleteAssetAttachment: assetAttachmentAdapter.deleteOne,\n\t\tdeleteAssetAttachments: assetAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetAttachments,\n\taddAssetAttachment,\n\taddAssetAttachments,\n\tsetAssetAttachment,\n\tsetAssetAttachments,\n\tupdateAssetAttachment,\n\tupdateAssetAttachments,\n\tdeleteAssetAttachment,\n\tdeleteAssetAttachments,\n} = assetAttachmentSlice.actions\n\nexport const selectAssetAttachmentMapping = (state: OvermapRootState) => state.assetAttachmentReducer.instances\n\nexport const selectAssetAttachments: OvermapSelector<Stored<AssetAttachment>[]> = createSelector(\n\t[selectAssetAttachmentMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectAssetAttachmentById: OvermapSelectorWithArgs<string, Stored<AssetAttachment> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.assetAttachmentReducer.instances[id]\n\t}\n\nexport const selectAttachmentsOfAsset = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetAttachments, (_state: OvermapRootState, assetId: string) => assetId],\n\t\t(attachments, assetId) => {\n\t\t\treturn fallbackToEmptyArray(attachments.filter(({ asset }) => assetId === asset))\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfAssetByType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetAttachments, (_state: OvermapRootState, assetId: string) => assetId],\n\t\t(attachments, assetId) => {\n\t\t\tconst attachmentsOfAsset = attachments.filter(({ asset }) => assetId === asset)\n\t\t\tconst fileAttachments = attachmentsOfAsset.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => !file_type || !file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\tconst imageAttachments = attachmentsOfAsset.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => file_type && file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\treturn { fileAttachments, imageAttachments }\n\t\t},\n\t),\n)\n\nexport const assetAttachmentReducer: Reducer<AssetAttachmentState> = assetAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport {\n\tAsset,\n\tAssetStageCompletion,\n\tCompletedStagesMapping,\n\tOvermapRootState,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport { ModelState } from \"../typings\"\n\nexport type AssetStageCompletionState = ModelState<AssetStageCompletion>\n\nconst assetStageCompletionAdapter = createModelAdapter<AssetStageCompletion>(\n\t(stageCompletion) => stageCompletion.offline_id,\n)\n\nconst initialState: AssetStageCompletionState = assetStageCompletionAdapter.getInitialState({})\n\nexport const assetStageCompletionSlice = createSlice({\n\tname: \"assetStageCompletions\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetStageCompletions: assetStageCompletionAdapter.initialize,\n\t\taddAssetStageCompletion: assetStageCompletionAdapter.addOne,\n\t\taddAssetStageCompletions: assetStageCompletionAdapter.addMany,\n\t\tupdateAssetStageCompletion: assetStageCompletionAdapter.updateOne,\n\t\tupdateAssetStageCompletions: assetStageCompletionAdapter.updateMany,\n\t\tdeleteAssetStageCompletion: assetStageCompletionAdapter.deleteOne,\n\t\tdeleteAssetStageCompletions: assetStageCompletionAdapter.deleteMany,\n\t},\n})\nexport const {\n\tinitializeAssetStageCompletions,\n\taddAssetStageCompletion,\n\taddAssetStageCompletions,\n\tupdateAssetStageCompletion,\n\tupdateAssetStageCompletions,\n\tdeleteAssetStageCompletion,\n\tdeleteAssetStageCompletions,\n} = assetStageCompletionSlice.actions\n\nexport const selectAssetStageCompletionMapping = (state: OvermapRootState) => {\n\treturn state.assetStageCompletionReducer.instances\n}\n\nexport const selectCompletedStagesByAsset = createSelector(\n\t[selectAssetStageCompletionMapping],\n\t(completedStagesMapping) => {\n\t\tconst completedStagesByAsset: Record<string, Record<string, string>> = {}\n\n\t\tfor (const stageCompletion of Object.values(completedStagesMapping)) {\n\t\t\tconst { asset, stage, submitted_at } = stageCompletion\n\n\t\t\tif (!completedStagesByAsset[asset]) completedStagesByAsset[asset] = {}\n\n\t\t\tcompletedStagesByAsset[asset]![stage] = submitted_at\n\t\t}\n\t\treturn completedStagesByAsset satisfies CompletedStagesMapping\n\t},\n)\n\nexport const selectCompletedStageIdsForAsset: OvermapSelectorWithArgs<Asset, string[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectAssetStageCompletionMapping, (_state, asset: Asset) => asset],\n\t\t\t(completedStages, asset) => {\n\t\t\t\treturn Object.keys(completedStages[asset.offline_id] ?? {})\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectAssetStageCompletionById: OvermapSelectorWithArgs<\n\tstring,\n\tStored<AssetStageCompletion> | undefined\n> = (id) => (state) => {\n\treturn state.assetStageCompletionReducer.instances[id]\n}\n\nexport const selectAssetStageCompletionsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetStageCompletionMapping, (_, stageCompletionIds: string[]) => stageCompletionIds],\n\t\t(stageCompletionMapping, stageCompletionIds) => {\n\t\t\tconst stageCompletionIdsSet = new Set(stageCompletionIds)\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\tObject.values(stageCompletionMapping).filter((stageCompletion) =>\n\t\t\t\t\tstageCompletionIdsSet.has(stageCompletion.offline_id),\n\t\t\t\t),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const assetStageCompletionReducer: Reducer<AssetStageCompletionState> = assetStageCompletionSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AssetStage, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type AssetStageState = ModelState<Stored<AssetStage>>\n\nconst assetStageAdapter = createModelAdapter<Stored<AssetStage>>((assetStage) => assetStage.offline_id)\n\nconst initialState = assetStageAdapter.getInitialState({})\n\nexport const assetStageSlice = createSlice({\n\tname: \"assetStages\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetStages: assetStageAdapter.initialize,\n\t\tsetAssetStage: assetStageAdapter.setOne,\n\t\tsetAssetStages: assetStageAdapter.setMany,\n\t\taddAssetStage: assetStageAdapter.addOne,\n\t\taddAssetStages: assetStageAdapter.addMany,\n\t\tupdateAssetStage: assetStageAdapter.updateOne,\n\t\tupdateAssetStages: assetStageAdapter.updateMany,\n\t\tdeleteAssetStage: assetStageAdapter.deleteOne,\n\t\tdeleteAssetStages: assetStageAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetStages,\n\tsetAssetStage,\n\tsetAssetStages,\n\taddAssetStage,\n\taddAssetStages,\n\tupdateAssetStage,\n\tupdateAssetStages,\n\tdeleteAssetStage,\n\tdeleteAssetStages,\n} = assetStageSlice.actions\n\nexport const assetStageReducer: Reducer<AssetStageState> = assetStageSlice.reducer\n\nexport const selectStageMapping: OvermapSelector<Record<AssetStage[\"offline_id\"], AssetStage>> = (state) =>\n\tstate.assetStageReducer.instances\n\nexport const selectAssetStageById: OvermapSelectorWithArgs<string, AssetStage | undefined> = (id) => (state) => {\n\treturn state.assetStageReducer.instances[id]\n}\n\nexport const selectAssetStages = createSelector([selectStageMapping], (stageMapping) => {\n\treturn Object.values(stageMapping)\n})\n\nexport const selectAssetTypeStagesMapping: OvermapSelectorWithArgs<\n\tstring,\n\tRecord<string, AssetStage>\n> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectStageMapping, (_state, assetTypeId: string) => assetTypeId], (stagesMapping, assetTypeId) => {\n\t\tconst assetTypeStagesMapping: Record<string, AssetStage> = {}\n\t\tfor (const [stageId, stage] of Object.entries(stagesMapping)) {\n\t\t\tif (stage.asset_type === assetTypeId) {\n\t\t\t\tassetTypeStagesMapping[stageId] = stage\n\t\t\t}\n\t\t}\n\t\treturn assetTypeStagesMapping\n\t}),\n)\n\nexport const selectStagesOfAssetType: OvermapSelectorWithArgs<string, AssetStage[]> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAssetStages, (_state, assetTypeId: string) => assetTypeId], (stages, assetTypeId) => {\n\t\treturn fallbackToEmptyArray(\n\t\t\tstages.filter((stage) => stage.asset_type === assetTypeId).sort((a, b) => a.priority - b.priority),\n\t\t)\n\t}),\n)\n\nexport const selectAssetStagesByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectStageMapping, (_state, stageIds: string[]) => stageIds], (stageMapping, stageIds) => {\n\t\tconst assetStages: Stored<AssetStage>[] = []\n\n\t\tfor (const stageId of stageIds) {\n\t\t\tconst stage = stageMapping[stageId]\n\n\t\t\tif (stage) {\n\t\t\t\tassetStages.push(stage)\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"selectStagesFromStageIds: No stage exists with the id\", stageId)\n\t\t\t}\n\t\t}\n\n\t\treturn fallbackToEmptyArray(assetStages)\n\t}),\n)\n\n// Takes an array of stage ids and returns a record of stage ids to form ids, if the stage has a form\nexport const selectStageFormIdsFromStageIds: OvermapSelectorWithArgs<\n\tstring[],\n\tRecord<string, string>\n> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectStageMapping, (_state, stageIds: string[]) => stageIds], (stageMapping, stageIds) => {\n\t\tconst ret: Record<string, string> = {}\n\t\tfor (const stageId of stageIds) {\n\t\t\tconst stage = stageMapping[stageId]\n\t\t\tif (!stage) {\n\t\t\t\tthrow new Error(\"No stage exists with the id \" + stageId)\n\t\t\t}\n\t\t\tif (stage.form) {\n\t\t\t\tret[stageId] = stage.form\n\t\t\t}\n\t\t}\n\t\treturn ret\n\t}),\n)\n","import type { Reducer } from \"@reduxjs/toolkit\"\nimport { createSelector, createSlice } from \"@reduxjs/toolkit\"\nimport type { AssetType, OvermapRootState, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type AssetTypeState = ModelState<Stored<AssetType>>\n\nconst assetTypeAdapter = createModelAdapter<Stored<AssetType>>((assetType) => assetType.offline_id)\n\nconst initialState: AssetTypeState = assetTypeAdapter.getInitialState({})\n\nexport const assetTypeSlice = createSlice({\n\tname: \"assetTypes\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetTypes: assetTypeAdapter.initialize,\n\t\tsetAssetType: assetTypeAdapter.setOne,\n\t\tsetAssetTypes: assetTypeAdapter.setMany,\n\t\taddAssetType: assetTypeAdapter.addOne,\n\t\taddAssetTypes: assetTypeAdapter.addMany,\n\t\tupdateAssetType: assetTypeAdapter.updateOne,\n\t\tupdateAssetTypes: assetTypeAdapter.updateMany,\n\t\tdeleteAssetType: assetTypeAdapter.deleteOne,\n\t\tdeleteAssetTypes: assetTypeAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetTypes,\n\tsetAssetType,\n\tsetAssetTypes,\n\taddAssetType,\n\taddAssetTypes,\n\tupdateAssetType,\n\tupdateAssetTypes,\n\tdeleteAssetType,\n\tdeleteAssetTypes,\n} = assetTypeSlice.actions\n\nexport const selectAssetTypesMapping: OvermapSelector<Record<string, AssetType>> = (state: OvermapRootState) =>\n\tstate.assetTypeReducer.instances\n\nexport const selectAssetTypes: OvermapSelector<AssetType[]> = createSelector([selectAssetTypesMapping], (mapping) =>\n\tObject.values(mapping),\n)\n\nexport const selectAssetTypeById: OvermapSelectorWithArgs<AssetType[\"offline_id\"], Stored<AssetType> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.assetTypeReducer.instances[id]\n\t}\n\nexport const selectAssetTypesByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetTypesMapping, (_state, assetTypeIds: AssetType[\"offline_id\"][]) => assetTypeIds],\n\t\t(assetTypeMapping, assetTypeIds) => {\n\t\t\tconst assetTypes: Stored<AssetType>[] = []\n\n\t\t\tfor (const assetTypeId of assetTypeIds) {\n\t\t\t\tconst assetType = assetTypeMapping[assetTypeId]\n\n\t\t\t\tif (assetType) {\n\t\t\t\t\tassetTypes.push(assetType)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\"selectAssetTypesByIds: No assetType exists with the id\", assetTypeId)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn fallbackToEmptyArray(assetTypes)\n\t\t},\n\t),\n)\n\nexport const assetTypeReducer: Reducer<AssetTypeState> = assetTypeSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tAssetTypeAttachment,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type AssetTypeAttachmentState = ModelState<Stored<AssetTypeAttachment>>\n\nconst assetTypeAttachmentAdapter = createModelAdapter<Stored<AssetTypeAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState = assetTypeAttachmentAdapter.getInitialState({})\n\nexport const assetTypeAttachmentSlice = createSlice({\n\tname: \"assetTypeAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeAssetTypeAttachments: assetTypeAttachmentAdapter.initialize,\n\t\taddAssetTypeAttachment: assetTypeAttachmentAdapter.addOne,\n\t\taddAssetTypeAttachments: assetTypeAttachmentAdapter.addMany,\n\t\tsetAssetTypeAttachment: assetTypeAttachmentAdapter.setOne,\n\t\tsetAssetTypeAttachments: assetTypeAttachmentAdapter.setMany,\n\t\tupdateAssetTypeAttachment: assetTypeAttachmentAdapter.updateOne,\n\t\tupdateAssetTypeAttachments: assetTypeAttachmentAdapter.updateMany,\n\t\tdeleteAssetTypeAttachment: assetTypeAttachmentAdapter.deleteOne,\n\t\tdeleteAssetTypeAttachments: assetTypeAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeAssetTypeAttachments,\n\taddAssetTypeAttachment,\n\taddAssetTypeAttachments,\n\tsetAssetTypeAttachment,\n\tsetAssetTypeAttachments,\n\tupdateAssetTypeAttachment,\n\tupdateAssetTypeAttachments,\n\tdeleteAssetTypeAttachment,\n\tdeleteAssetTypeAttachments,\n} = assetTypeAttachmentSlice.actions\n\nexport const selectAssetTypeAttachmentMapping = (state: OvermapRootState) => state.assetTypeAttachmentReducer.instances\n\nexport const selectAssetTypeAttachments: OvermapSelector<Stored<AssetTypeAttachment>[]> = createSelector(\n\t[selectAssetTypeAttachmentMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectAssetTypeAttachmentById: OvermapSelectorWithArgs<string, Stored<AssetTypeAttachment> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.assetTypeAttachmentReducer.instances[id]\n\t}\n\nexport const selectAttachmentsOfAssetType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetTypeAttachments, (_state: OvermapRootState, assetTypeId: string) => assetTypeId],\n\t\t(attachments, assetTypeId) => {\n\t\t\treturn fallbackToEmptyArray(attachments.filter(({ asset_type }) => assetTypeId === asset_type))\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfAssetTypeByType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAssetTypeAttachments, (_state: OvermapRootState, assetTypeId: string) => assetTypeId],\n\t\t(attachments, assetTypeId) => {\n\t\t\tconst attachmentsOfAssetType = attachments.filter(({ asset_type }) => asset_type === assetTypeId)\n\t\t\tconst fileAttachments = attachmentsOfAssetType.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => !file_type || !file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\tconst imageAttachments = attachmentsOfAssetType.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => file_type && file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\treturn { fileAttachments, imageAttachments }\n\t\t},\n\t),\n)\n\nexport const assetTypeAttachmentReducer: Reducer<AssetTypeAttachmentState> = assetTypeAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { Issue, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type IssueState = ModelState<Stored<Issue>>\n\nconst issueAdapter = createModelAdapter<Stored<Issue>>((issue) => issue.offline_id)\n\nconst initialState: IssueState = issueAdapter.getInitialState({})\n\nexport const issueSlice = createSlice({\n\tname: \"issues\",\n\tinitialState,\n\textraReducers: (builder) =>\n\t\tbuilder.addCase(\"RESET\", (state) => {\n\t\t\tObject.assign(state, initialState)\n\t\t}),\n\treducers: {\n\t\tinitializeIssues: issueAdapter.initialize,\n\t\taddIssue: issueAdapter.addOne,\n\t\taddIssues: issueAdapter.addMany,\n\t\tupdateIssue: issueAdapter.updateOne,\n\t\tdeleteIssue: issueAdapter.deleteOne,\n\t\tdeleteIssues: issueAdapter.deleteMany,\n\t},\n})\n\nexport const { initializeIssues, addIssue, addIssues, updateIssue, deleteIssue, deleteIssues } = issueSlice.actions\n\nexport interface IssueFilterArgs {\n\tfilterByAssignedTo: boolean\n\tfilterByStatus: boolean\n\tfilterByCategory: boolean\n\tfilterByWorkspace: boolean\n}\n\nexport const selectIssueMapping = (state: OvermapRootState) => state.issueReducer.instances\n\nexport const selectIssueById: OvermapSelectorWithArgs<string, Stored<Issue> | undefined> = (id) => (state) => {\n\treturn state.issueReducer.instances[id]\n}\n\nexport const selectIssuesByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectIssueMapping, (_, issueIds: string[]) => issueIds], (issuesMapping, issueIds) => {\n\t\tconst issues: Stored<Issue>[] = []\n\n\t\tfor (const issueId of issueIds) {\n\t\t\tconst issue = issuesMapping[issueId]\n\t\t\tif (issue) {\n\t\t\t\tissues.push(issue)\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"selectIssuesByIds: No issue exists with the id\", issueId)\n\t\t\t}\n\t\t}\n\n\t\treturn fallbackToEmptyArray(issues)\n\t}),\n)\n\nexport const issueReducer: Reducer<IssueState> = issueSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tIssue,\n\tIssueType,\n\tOrganization,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\n// TODO: add attachment support for issue type descriptions\n\nexport type IssueTypeState = ModelState<Stored<IssueType>>\n\nconst issueTypeAdapter = createModelAdapter<Stored<IssueType>>((issueType) => issueType.offline_id)\n\nconst initialState: IssueTypeState = issueTypeAdapter.getInitialState({})\n\nexport const issueTypeSlice = createSlice({\n\tname: \"issueTypes\",\n\tinitialState,\n\textraReducers: (builder) =>\n\t\tbuilder.addCase(\"RESET\", (state) => {\n\t\t\tObject.assign(state, initialState)\n\t\t}),\n\treducers: {\n\t\tinitializeIssueTypes: issueTypeAdapter.initialize,\n\t\tsetIssueType: issueTypeAdapter.setOne,\n\t\taddIssueType: issueTypeAdapter.addOne,\n\t\tupdateIssueType: issueTypeAdapter.updateOne,\n\t\tremoveIssueType: issueTypeAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeIssueTypes, setIssueType, addIssueType, updateIssueType, removeIssueType } =\n\tissueTypeSlice.actions\n\nexport const selectIssueTypeMapping: OvermapSelector<IssueTypeState[\"instances\"]> = (state) => {\n\treturn state.issueTypeReducer.instances\n}\n\nexport const selectIssueTypes: OvermapSelector<Stored<IssueType>[]> = createSelector(\n\tselectIssueTypeMapping,\n\t(issueTypes) => {\n\t\treturn Object.values(issueTypes)\n\t},\n)\n\nexport const selectIssueTypeById: OvermapSelectorWithArgs<string, Stored<IssueType> | undefined> = (id) => (state) => {\n\treturn state.issueTypeReducer.instances[id]\n}\n\nexport const selectIssueTypesByIds: OvermapSelectorWithArgs<string[], Stored<IssueType>[]> =\n\t(issueTypeIds: string[]) => (state: OvermapRootState) => {\n\t\tconst issueTypes: Stored<IssueType>[] = []\n\n\t\tfor (const issueTypeId of issueTypeIds) {\n\t\t\tconst issueType = state.issueTypeReducer.instances[issueTypeId]\n\t\t\tif (issueType) {\n\t\t\t\tissueTypes.push(issueType)\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"selectIssueTypesByIds: No issue type exists with the id\", issueTypeId)\n\t\t\t}\n\t\t}\n\n\t\treturn issueTypes\n\t}\n\nexport const selectIssueTypesOfOrganization: OvermapSelectorWithArgs<Organization[\"id\"], Stored<IssueType>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectIssueTypes, (_, organizationId: number) => organizationId],\n\t\t\t(issueTypes, organizationId) => {\n\t\t\t\treturn fallbackToEmptyArray(issueTypes.filter((issueType) => issueType.organization === organizationId))\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectIssuesOfIssueType: OvermapSelectorWithArgs<IssueType[\"offline_id\"], Stored<Issue>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[(state: OvermapRootState) => state.issueReducer.instances, (_, issueTypeId: string) => issueTypeId],\n\t\t\t(issuesMapping, issueTypeId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tObject.values(issuesMapping).filter((issue) => issue.issue_type === issueTypeId),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectIssuesOfIssueTypeCount: OvermapSelectorWithArgs<IssueType[\"offline_id\"], number> =\n\t(issueTypeId: string) => (state) => {\n\t\treturn selectIssuesOfIssueType(issueTypeId)(state).length\n\t}\n\nexport const issueTypeReducer: Reducer<IssueTypeState> = issueTypeSlice.reducer\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { BaseState, SelectorWithArgs } from \"typings\"\n\ninterface S3UploadUrl {\n\turl: string\n\tfields: Record<string, string>\n\t/** the time the upload url expires */\n\texp?: number\n}\n\nexport interface FileState {\n\t// maps sha1 hash to upload URL\n\ts3Urls: Record<string, S3UploadUrl>\n}\n\ninterface S3UrlPayload {\n\tsha1: string\n\turl: string\n\tfields: Record<string, string>\n}\n\nconst initialState: FileState = {\n\ts3Urls: {},\n}\n\nconst msPerHour = 1000 * 60 * 60\nconst msPerWeek = msPerHour * 24 * 7\n\n/**\n * Stores the auth state of the app (tokens, and whether user is logged in or not)\n */\nexport const fileSlice = createSlice({\n\tname: \"file\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetUploadUrl: (state, action: PayloadAction<S3UrlPayload>) => {\n\t\t\tconst { url, fields, sha1 } = action.payload\n\t\t\tconst today = new Date()\n\t\t\tconst weekFromToday = new Date(today.getTime() + msPerWeek)\n\n\t\t\tstate.s3Urls[sha1] = {\n\t\t\t\turl,\n\t\t\t\tfields,\n\t\t\t\texp: weekFromToday.getTime(),\n\t\t\t}\n\t\t},\n\t},\n})\n\nexport const { setUploadUrl } = fileSlice.actions\n\nexport const selectUploadUrl: SelectorWithArgs<BaseState, string, S3UploadUrl | undefined> =\n\t(sha1: string) => (state) => {\n\t\tconst url = state.fileReducer.s3Urls[sha1]\n\t\tif (!url) {\n\t\t\treturn undefined\n\t\t}\n\n\t\tconst today = new Date().getTime()\n\t\tconst expiringWithinAnHour = (url.exp ?? today) - today < msPerHour\n\t\tif (expiringWithinAnHour) return undefined\n\n\t\treturn url\n\t}\n\nexport const fileReducer: Reducer<FileState> = fileSlice.reducer\n","import { createSelector, createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapRootState, OvermapSelectorWithArgs, User } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport interface UserState {\n\tcurrentUser: User | null\n\tusers: Record<number, User>\n}\n\nconst initialState: UserState = {\n\tusers: {},\n\tcurrentUser: null,\n}\n\nexport const userSlice = createSlice({\n\tname: \"users\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetUsers: (state, action: PayloadAction<User[]>) => {\n\t\t\tconst usersMapping: Record<string, User> = {}\n\t\t\taction.payload.forEach((user) => {\n\t\t\t\tusersMapping[user.id] = user\n\t\t\t})\n\t\t\tstate.users = usersMapping\n\t\t},\n\t\taddUsers: (state, action: PayloadAction<User[]>) => {\n\t\t\tfor (const user of action.payload) {\n\t\t\t\tstate.users[user.id] = user\n\t\t\t}\n\t\t},\n\t\tsetCurrentUser: (state, action: PayloadAction<User | null>) => {\n\t\t\tstate.currentUser = action.payload\n\t\t},\n\t\tsetProfilePicture: (state, action: PayloadAction<{ file?: string; file_sha1?: string }>) => {\n\t\t\tif (!state.currentUser) return\n\n\t\t\tstate.currentUser.profile.file = action.payload.file ?? null\n\t\t\tstate.currentUser.profile.file_sha1 = action.payload.file_sha1 ?? null\n\n\t\t\tconst currentUser = state.users[state.currentUser.id]\n\n\t\t\tif (!currentUser) {\n\t\t\t\tthrow new Error(\"Unable to find current user in users slice\")\n\t\t\t}\n\n\t\t\tcurrentUser.profile.file = action.payload.file ?? null\n\t\t\tcurrentUser.profile.file_sha1 = action.payload.file_sha1 ?? null\n\t\t},\n\n\t\tremoveUser: (state, action: PayloadAction<number>) => {\n\t\t\tdelete state.users[action.payload]\n\t\t},\n\t},\n})\n\nexport const { setCurrentUser, setProfilePicture, setUsers, addUsers, removeUser } = userSlice.actions\n\nexport const userReducer: Reducer<UserState> = userSlice.reducer\n\nexport const selectCurrentUser = (state: OvermapRootState) => state.userReducer.currentUser\n\nexport const selectUsersMapping = (state: OvermapRootState) => state.userReducer.users\n\nexport const selectUserById: OvermapSelectorWithArgs<number, User | undefined> = (id) => (state) => {\n\treturn state.userReducer.users[id]\n}\n\nexport const selectUsersByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectUsersMapping, (_state, userIds: number[]) => userIds], (usersMapping, userIds) => {\n\t\tconst users: User[] = []\n\n\t\tfor (const userId of userIds) {\n\t\t\tconst user = usersMapping[userId]\n\t\t\tif (user) {\n\t\t\t\tusers.push(user)\n\t\t\t} else {\n\t\t\t\tconsole.warn(\"selectUsersByIds: No user exists with the id\", userId)\n\t\t\t}\n\t\t}\n\n\t\treturn fallbackToEmptyArray(users)\n\t}),\n)\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapRootState, OvermapSelector, OvermapSelectorWithArgs } from \"typings\"\nimport type { OrganizationAccess, User } from \"typings/models\"\nimport { selectCurrentUser } from \"./userSlice\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type OrganizationAccessState = ModelState<OrganizationAccess>\n\nconst organizationAccessAdapter = createModelAdapter<OrganizationAccess>(\n\t(organizationAccess) => organizationAccess.offline_id,\n)\n\nconst initialState: OrganizationAccessState = organizationAccessAdapter.getInitialState({})\n\nexport const organizationAccessSlice = createSlice({\n\tname: \"organizationAccess\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeOrganizationAccesses: organizationAccessAdapter.initialize,\n\t\tupdateOrganizationAccess: organizationAccessAdapter.updateOne,\n\t\tdeleteOrganizationAccess: organizationAccessAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeOrganizationAccesses, updateOrganizationAccess, deleteOrganizationAccess } =\n\torganizationAccessSlice.actions\n\nexport const selectOrganizationAccesses = (state: OvermapRootState) => {\n\treturn state.organizationAccessReducer.instances\n}\n\nexport const selectOrganizationAccessById: OvermapSelectorWithArgs<string, OrganizationAccess | undefined> =\n\t(id) => (state) => {\n\t\treturn state.organizationAccessReducer.instances[id]\n\t}\n\nexport const selectActiveOrganizationAccess: OvermapSelector<OrganizationAccess | null> = createSelector(\n\t[selectCurrentUser, selectOrganizationAccesses],\n\t(currentUser, organizationAccesses) => {\n\t\tconst activeOrganizationAccess = Object.values(organizationAccesses).find(\n\t\t\t(organizationAccess: OrganizationAccess) => organizationAccess.user === currentUser?.id,\n\t\t)\n\t\treturn activeOrganizationAccess ?? null\n\t},\n)\n\nexport const selectOrganizationAccessForUser: OvermapSelectorWithArgs<User, OrganizationAccess | undefined> =\n\t(user) => (state) => {\n\t\treturn Object.values(state.organizationAccessReducer.instances).find(\n\t\t\t(organizationAccess: OrganizationAccess) => organizationAccess.user === user.id,\n\t\t)\n\t}\n\nexport const selectOrganizationAccessUserMapping = (state: OvermapRootState): Record<number, OrganizationAccess> => {\n\tconst organizationAccesses: Record<number, OrganizationAccess> = {}\n\tfor (const organizationAccess of Object.values(state.organizationAccessReducer.instances)) {\n\t\torganizationAccesses[organizationAccess.user] = organizationAccess\n\t}\n\treturn organizationAccesses\n}\n\nexport const organizationAccessReducer: Reducer<OrganizationAccessState> = organizationAccessSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { License, OvermapRootState, OvermapSelector, OvermapSelectorWithArgs } from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray } from \"../../utils\"\n\nexport type LicenseState = ModelState<License>\n\nconst licenseAdapter = createModelAdapter<License>((license) => license.offline_id)\n\nconst initialState: LicenseState = licenseAdapter.getInitialState({})\n\nexport const licenseSlice = createSlice({\n\tname: \"license\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeLicences: licenseAdapter.initialize,\n\t\taddLicenses: licenseAdapter.addMany,\n\t\tupdateLicense: licenseAdapter.updateOne,\n\t},\n})\n\nexport const { initializeLicences, addLicenses, updateLicense } = licenseSlice.actions\n\nexport const selectLicenses: OvermapSelector<Record<string, License>> = (state: OvermapRootState) => {\n\treturn state.licenseReducer.instances\n}\n\nexport const selectLicense: OvermapSelectorWithArgs<string, License | undefined> = (id) => (state) =>\n\tstate.licenseReducer.instances[id]\n\nexport const selectLicenseForProject: OvermapSelectorWithArgs<number, License | undefined> =\n\t(projectId: number) => (state: OvermapRootState) =>\n\t\tObject.values(state.licenseReducer.instances).find((license) => license.project === projectId)\n\nexport const selectActiveStatusLicenses: OvermapSelector<License[]> = createSelector(\n\t[selectLicenses],\n\t(licenses: Record<string, License>) => {\n\t\treturn fallbackToEmptyArray(Object.values(licenses).filter((license) => license.is_active))\n\t},\n)\n\nexport const selectLicensesForProjectsMapping: OvermapSelector<Record<number, License>> = createSelector(\n\t[selectLicenses],\n\t(licenses: Record<string, License>) =>\n\t\tObject.values(licenses)\n\t\t\t.filter((license) => license.project)\n\t\t\t.reduce((accum, license) => ({ ...accum, [license.project!]: license }), {}),\n)\n\nexport const licenseReducer: Reducer<LicenseState> = licenseSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tProjectAccess,\n\tStored,\n\tUser,\n} from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type ProjectAccessState = ModelState<ProjectAccess>\n\nconst projectAccessAdapter = createModelAdapter<ProjectAccess>((projectAccess) => projectAccess.offline_id)\n\nconst initialState: ProjectAccessState = projectAccessAdapter.getInitialState({})\n\nexport const projectAccessSlice = createSlice({\n\tname: \"projectAccess\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeProjectAccesses: projectAccessAdapter.initialize,\n\t\tupdateProjectAccess: projectAccessAdapter.updateOne,\n\t\tdeleteProjectAccess: projectAccessAdapter.deleteOne,\n\t\tdeleteProjectAccesses: projectAccessAdapter.deleteMany,\n\t},\n})\n\nexport const { initializeProjectAccesses, updateProjectAccess, deleteProjectAccess, deleteProjectAccesses } =\n\tprojectAccessSlice.actions\n\nexport const selectProjectAccessMapping = (state: OvermapRootState) => {\n\treturn state.projectAccessReducer.instances\n}\n\nexport const selectProjectAccesses: OvermapSelector<Stored<ProjectAccess>[]> = createSelector(\n\tselectProjectAccessMapping,\n\t(projectAccesses) => {\n\t\treturn Object.values(projectAccesses)\n\t},\n)\n\nexport const selectProjectAccessById: OvermapSelectorWithArgs<string, ProjectAccess | undefined> = (id) => (state) => {\n\treturn state.projectAccessReducer.instances[id]\n}\n\n// TODO: move to web\nexport const selectActiveProjectAccess: OvermapSelector<ProjectAccess | null> = (state: OvermapRootState) => {\n\tconst currentUser = state.userReducer.currentUser\n\tconst activeProjectId = state.projectReducer.activeProjectId\n\treturn (\n\t\tObject.values(state.projectAccessReducer.instances).find((projectAccess: ProjectAccess) => {\n\t\t\treturn projectAccess.user === currentUser?.id && projectAccess.project === activeProjectId\n\t\t}) ?? null\n\t)\n}\n\nexport const selectProjectAccessForUser: OvermapSelectorWithArgs<User, ProjectAccess | undefined> =\n\t(user: User) => (state: OvermapRootState) => {\n\t\treturn Object.values(state.projectAccessReducer.instances).find(\n\t\t\t(projectAccess: ProjectAccess) => projectAccess.user === user.id,\n\t\t)\n\t}\n\nexport const selectProjectAccessUserMapping: OvermapSelector<Record<string, ProjectAccess>> = (\n\tstate: OvermapRootState,\n) => {\n\tconst projectAccesses: Record<string, ProjectAccess> = {}\n\tfor (const projectAccess of Object.values(state.projectAccessReducer.instances)) {\n\t\tprojectAccesses[projectAccess.user] = projectAccess\n\t}\n\treturn projectAccesses\n}\n\nexport const projectAccessReducer: Reducer<ProjectAccessState> = projectAccessSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tOfflineIdMapping,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tProject,\n\tProjectAccess,\n\tUser,\n} from \"../../typings\"\nimport { selectProjectAccessMapping, selectProjectAccessUserMapping } from \"./projectAccessSlice\"\nimport { selectCurrentUser, selectUsersMapping } from \"./userSlice\"\nimport { ProjectAccessLevel } from \"../../enums\"\n\nexport interface ProjectState {\n\tprojects: Record<number, Project>\n\tactiveProjectId: number | null\n}\n\nconst initialState: ProjectState = {\n\tprojects: {},\n\tactiveProjectId: null,\n}\n\nexport const projectSlice = createSlice({\n\tname: \"projects\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetProjects: (state, action: { payload: Project[] }) => {\n\t\t\tconst projectsMap: Record<number, Project> = {}\n\t\t\taction.payload.forEach((project) => {\n\t\t\t\tprojectsMap[project.id] = project\n\t\t\t})\n\t\t\tstate.projects = projectsMap\n\t\t},\n\t\tsetActiveProjectId: (state, action: { payload: number | null }) => {\n\t\t\tstate.activeProjectId = action.payload\n\t\t},\n\t\tupdateOrCreateProject: (state, action: { payload: Project }) => {\n\t\t\tstate.projects[action.payload.id] = action.payload\n\t\t},\n\t\t// Takes a list of Projects and updates existing ones to match the payload, or adds them\n\t\t// to the store if they are not already present\n\t\tupdateOrCreateProjects: (state, action: { payload: Project[] }) => {\n\t\t\taction.payload.forEach((project) => {\n\t\t\t\tstate.projects[project.id] = project\n\t\t\t})\n\t\t},\n\t\tdeleteProject: (state, action: { payload: Project }) => {\n\t\t\tdelete state.projects[action.payload.id]\n\t\t},\n\t\tacceptProjectInvite: (state, action: { payload: number }) => {\n\t\t\tif (action.payload in state.projects) {\n\t\t\t\tstate.projects[action.payload]!.invited = false\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Accept project invite: user is not in this project\")\n\t\t\t}\n\t\t},\n\t\taddActiveProjectIssuesCount: (state, action: { payload: number }) => {\n\t\t\tif (!state.activeProjectId || !(state.activeProjectId in state.projects)) {\n\t\t\t\tthrow new Error(\"Update issues count: no active project\")\n\t\t\t}\n\n\t\t\tif (!state.projects[state.activeProjectId]!.issues_count) {\n\t\t\t\tstate.projects[state.activeProjectId]!.issues_count = action.payload\n\t\t\t} else {\n\t\t\t\tstate.projects[state.activeProjectId]!.issues_count! += action.payload\n\t\t\t}\n\t\t},\n\t\taddActiveProjectFormSubmissionsCount: (state, action: { payload: number }) => {\n\t\t\tif (state.activeProjectId && state.activeProjectId in state.projects) {\n\t\t\t\tif (!state.projects[state.activeProjectId]!.form_submissions_count) {\n\t\t\t\t\tstate.projects[state.activeProjectId]!.form_submissions_count = action.payload\n\t\t\t\t} else {\n\t\t\t\t\tstate.projects[state.activeProjectId]!.form_submissions_count! += action.payload\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new Error(\"Update form submissions count: no active project\")\n\t\t\t}\n\t\t},\n\t},\n})\n\nexport const {\n\tsetProjects,\n\tupdateOrCreateProject,\n\tupdateOrCreateProjects: addOrReplaceProjects,\n\tsetActiveProjectId,\n\tdeleteProject,\n\tacceptProjectInvite,\n\taddActiveProjectIssuesCount,\n\taddActiveProjectFormSubmissionsCount,\n} = projectSlice.actions\n\nexport const projectReducer: Reducer<ProjectState> = projectSlice.reducer\n\nexport const selectProjectMapping: OvermapSelector<Record<number, Project>> = (state: OvermapRootState) =>\n\tstate.projectReducer.projects\n\nexport const selectActiveProjectId = (state: OvermapRootState): number | null => state.projectReducer.activeProjectId\n\nexport const selectActiveProject = (state: OvermapRootState): Project | null => {\n\tconst activeProjectId = selectActiveProjectId(state)\n\tif (!activeProjectId) {\n\t\treturn null\n\t}\n\treturn state.projectReducer.projects[activeProjectId] ?? null\n}\n\nexport const selectProjectById: OvermapSelectorWithArgs<number, Project | undefined> = (id) => (state) => {\n\treturn state.projectReducer.projects[id]\n}\n\nexport const selectProjectUsersIds: OvermapSelector<number[]> = createSelector(\n\t[selectProjectAccessMapping],\n\t(projectAccesses: OfflineIdMapping<ProjectAccess>) =>\n\t\tObject.values(projectAccesses).map((projectAccess: ProjectAccess) => projectAccess.user),\n)\n\nexport const selectProjectUsersAsMapping: OvermapSelector<Record<number, User>> = createSelector(\n\t[selectProjectUsersIds, selectUsersMapping],\n\t(projectUserIds, users) => projectUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {}),\n)\n\nexport const selectSortedProjectUsers: OvermapSelector<User[]> = createSelector(\n\t[selectCurrentUser, selectProjectUsersAsMapping, selectProjectAccessUserMapping],\n\t(currentUser, userMapping, projectAccessMapping) => {\n\t\treturn Object.values(userMapping).sort((userA, userB) => {\n\t\t\tif (userA.id === currentUser?.id) {\n\t\t\t\treturn -1\n\t\t\t} else if (userB.id === currentUser?.id) {\n\t\t\t\treturn 1\n\t\t\t}\n\t\t\tconst projectAccessesA = projectAccessMapping[userA.id]\n\t\t\tconst projectAccessesB = projectAccessMapping[userB.id]\n\t\t\tif (projectAccessesA?.access_level === projectAccessesB?.access_level) {\n\t\t\t\treturn userA.username.localeCompare(userB.username)\n\t\t\t}\n\t\t\tif (projectAccessesA?.access_level === ProjectAccessLevel.ADMIN) {\n\t\t\t\treturn -1\n\t\t\t}\n\t\t\treturn 1\n\t\t})\n\t},\n)\n","import { createSelector, createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapSelector, OvermapSelectorWithArgs } from \"typings/store\"\nimport type {\n\tLicense,\n\tOfflineIdMapping,\n\tOrganization,\n\tOrganizationAccess,\n\tOvermapRootState,\n\tProject,\n\tUser,\n} from \"../../typings\"\nimport { selectCurrentUser, selectUsersMapping } from \"./userSlice\"\nimport { selectOrganizationAccesses, selectOrganizationAccessUserMapping } from \"./organizationAccessSlice\"\nimport { selectLicenses } from \"./licenseSlice\"\nimport { selectProjectMapping } from \"./projectSlice\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { OrganizationAccessLevel } from \"../../enums\"\n\nexport interface OrganizationState {\n\torganizations: Record<number, Organization>\n}\n\nconst initialState: OrganizationState = {\n\torganizations: {},\n}\n\nexport const organizationSlice = createSlice({\n\tname: \"organizations\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetOrganizations: (state, action: PayloadAction<Organization[]>) => {\n\t\t\tfor (const org of action.payload) {\n\t\t\t\tstate.organizations[org.id] = org\n\t\t\t}\n\t\t},\n\t},\n})\n\nexport const { setOrganizations } = organizationSlice.actions\n\nexport const selectOrganizationsMapping: OvermapSelector<Record<number, Organization>> = (state: OvermapRootState) => {\n\treturn state.organizationReducer.organizations\n}\n\nexport const selectOrganizations = createSelector([selectOrganizationsMapping], (organizationsMapping) => {\n\treturn Object.values(organizationsMapping)\n})\n\nexport const selectOrganizationById: OvermapSelectorWithArgs<number, Organization | undefined> = (id) => (state) => {\n\treturn state.organizationReducer.organizations[id]\n}\n\nexport const selectOrganizationsWithAccess: OvermapSelector<Organization[]> = createSelector(\n\t[selectOrganizations],\n\t(organizations: Record<number, Organization>) => {\n\t\treturn fallbackToEmptyArray(\n\t\t\tObject.values(organizations).filter((organization: Organization) => organization.has_access),\n\t\t)\n\t},\n)\n\nexport const selectOrganizationUsersIds: OvermapSelector<number[]> = createSelector(\n\t[selectOrganizationAccesses],\n\t(organizationAccesses: OfflineIdMapping<OrganizationAccess>) =>\n\t\tObject.values(organizationAccesses).map((organizationAccess: OrganizationAccess) => organizationAccess.user),\n)\n\nexport const selectProjectsOfOrganization: OvermapSelectorWithArgs<number, Project[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectProjectMapping, (_, organizationId: number) => organizationId],\n\t\t\t(projects, organizationId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tObject.values(projects).filter((project) => project.organization_owner === organizationId),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectLicensesOfOrganization: OvermapSelectorWithArgs<number, License[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector([selectLicenses, (_, organizationId: number) => organizationId], (licenses, organizationId) => {\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\tObject.values(licenses).filter((license) => license.organization_owner === organizationId),\n\t\t\t)\n\t\t}),\n\t)\n\nexport const selectOrganizationUsersAsMapping: OvermapSelector<Record<number, User>> = createSelector(\n\t[selectOrganizationUsersIds, selectUsersMapping],\n\t(organizationUserIds: number[], users: Record<number, User>) =>\n\t\torganizationUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {}),\n)\n\nexport const selectSortedOrganizationUsers: OvermapSelector<User[]> = createSelector(\n\t[selectCurrentUser, selectOrganizationUsersAsMapping, selectOrganizationAccessUserMapping],\n\t(currentUser, userMapping, organizationAccessMapping) => {\n\t\treturn Object.values(userMapping).sort((userA: User, userB: User) => {\n\t\t\tif (userA.id === currentUser?.id) {\n\t\t\t\treturn -1\n\t\t\t} else if (userB.id === currentUser?.id) {\n\t\t\t\treturn 1\n\t\t\t}\n\t\t\tconst organizationAccessesA: OrganizationAccess | undefined = organizationAccessMapping[userA.id]\n\t\t\tconst organizationAccessesB: OrganizationAccess | undefined = organizationAccessMapping[userB.id]\n\t\t\tif (organizationAccessesA?.access_level === organizationAccessesB?.access_level) {\n\t\t\t\treturn userA.username.localeCompare(userB.username)\n\t\t\t}\n\t\t\tif (organizationAccessesA?.access_level === OrganizationAccessLevel.ADMIN) {\n\t\t\t\treturn -1\n\t\t\t}\n\t\t\treturn 1\n\t\t})\n\t},\n)\n\nexport const organizationReducer: Reducer<OrganizationState> = organizationSlice.reducer\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { FullOfflineAction } from \"../store\"\nimport type { RequestDetails } from \"../../sdk\"\nimport { v4 as uuidv4 } from \"uuid\"\nimport { SDKRequest } from \"../../sdk\"\nimport type { OvermapRootState } from \"../../typings\"\n\nexport const createOfflineAction = (request: SDKRequest, baseUrl: string, serviceName: string): FullOfflineAction => {\n\tconst requestWithUuid = request.uuid ? (request as RequestDetails) : { ...request, uuid: uuidv4() }\n\treturn {\n\t\tpayload: requestWithUuid,\n\t\ttype: \"\",\n\t\tmeta: {\n\t\t\toffline: {\n\t\t\t\teffect: {\n\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\trequest: requestWithUuid,\n\t\t\t\t\tBASE_URL: baseUrl,\n\t\t\t\t\tserviceName: serviceName,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}\n}\n\nexport interface OutboxState {\n\t/** A list of requests marked for deletion. Once the offline slice encounters one of these, */\n\tdeletedRequests: string[]\n\t/** The timestamp of the last retry of an outgoing request. (Number of milliseconds since the epoch.) */\n\tlatestRetryTime: number\n}\n\nconst initialState: OutboxState = {\n\tdeletedRequests: [],\n\tlatestRetryTime: 0,\n}\n\n/**\n * This slice primarily exists as an interface to enqueue API requests to the redux-offline slice. Any dispatched action\n * with an `offline` field in its metadata will be handled by redux-offline. This slice is just a sensible place to\n * \"dump\" no-op actions for enqueueing requests to the outbox. At the same time, we can use this slice to keep track of\n * requests that have been marked for deletion, so that we can skip them instead of sending the request.\n */\nexport const outboxSlice = createSlice({\n\tname: \"outbox\",\n\tinitialState: initialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\t// enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox\n\t\t// Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store\n\t\t// Then this reducer enqueueRequest() is responsible for adding the actual request data to the outbox\n\t\tenqueueRequest: {\n\t\t\treducer: (state, _action: PayloadAction<RequestDetails>) => {\n\t\t\t\treturn state\n\t\t\t},\n\t\t\tprepare: (payload: SDKRequest & { BASE_URL: string; serviceName: string }): FullOfflineAction => {\n\t\t\t\tconsole.debug(\"Preparing to enqueue request\", payload)\n\t\t\t\tconst { BASE_URL, serviceName, ...rest } = payload\n\t\t\t\treturn createOfflineAction(rest, BASE_URL, serviceName)\n\t\t\t},\n\t\t},\n\t\tmarkForDeletion(state, action: PayloadAction<string>) {\n\t\t\tstate.deletedRequests.push(action.payload)\n\t\t},\n\t\tmarkAsDeleted(state, action: PayloadAction<string>) {\n\t\t\tconst index = state.deletedRequests.indexOf(action.payload)\n\t\t\tif (index !== -1) state.deletedRequests.splice(index, 1)\n\t\t},\n\t\t_setLatestRetryTime: (state, action: PayloadAction<number>) => {\n\t\t\tstate.latestRetryTime = action.payload\n\t\t},\n\t},\n})\n\nexport const selectDeletedRequests = (state: OvermapRootState) => state.outboxReducer.deletedRequests\nexport const selectLatestRetryTime = (state: OvermapRootState) => state.outboxReducer.latestRetryTime\n\nexport const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions\nexport const outboxReducer: Reducer<OutboxState> = outboxSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapRootState, OvermapSelectorWithArgs, ProjectFile, Stored } from \"../../typings\"\nimport { selectActiveProjectId } from \"./projectSlice\"\nimport { fallbackToEmptyArray } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type ProjectFileState = ModelState<Stored<ProjectFile>>\n\nconst projectFileAdapter = createModelAdapter<Stored<ProjectFile>>((file) => file.offline_id)\n\nconst initialState: ProjectFileState = projectFileAdapter.getInitialState({})\n\nexport const projectFileSlice = createSlice({\n\tname: \"projectFiles\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeProjectFiles: projectFileAdapter.initialize,\n\t\taddProjectFile: projectFileAdapter.addOne,\n\t\taddProjectFiles: projectFileAdapter.addMany,\n\t\tsetProjectFile: projectFileAdapter.setOne,\n\t\tsetProjectFiles: projectFileAdapter.setMany,\n\t\tupdateProjectFile: projectFileAdapter.updateOne,\n\t\tupdateProjectFiles: projectFileAdapter.updateMany,\n\t\tdeleteProjectFile: projectFileAdapter.deleteOne,\n\t\tdeleteProjectFiles: projectFileAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeProjectFiles,\n\taddProjectFile,\n\taddProjectFiles,\n\tsetProjectFile,\n\tsetProjectFiles,\n\tupdateProjectFile,\n\tupdateProjectFiles,\n\tdeleteProjectFile,\n\tdeleteProjectFiles,\n} = projectFileSlice.actions\n\nexport const selectProjectFileMapping = (state: OvermapRootState) => state.projectFileReducer.instances\n\nexport const selectProjectFiles = createSelector(\n\t[selectProjectFileMapping, selectActiveProjectId],\n\t(mapping, activeProjectId) => {\n\t\treturn fallbackToEmptyArray(\n\t\t\tObject.values(mapping)\n\t\t\t\t.filter((file) => file.project === activeProjectId)\n\t\t\t\t.sort((a, b) => a.z_index - b.z_index),\n\t\t)\n\t},\n)\n\nexport const selectProjectFileById: OvermapSelectorWithArgs<string, ProjectFile | undefined> = (id) => (state) => {\n\treturn state.projectFileReducer.instances[id]\n}\n\nexport const projectFileReducer: Reducer<ProjectFileState> = projectFileSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type {\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tProjectAttachment,\n\tStored,\n} from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type ProjectAttachmentState = ModelState<Stored<ProjectAttachment>>\n\nconst projectAttachmentAdapter = createModelAdapter<Stored<ProjectAttachment>>((attachment) => attachment.offline_id)\n\nconst initialState: ProjectAttachmentState = projectAttachmentAdapter.getInitialState({})\n\nexport const projectAttachmentSlice = createSlice({\n\tname: \"projectAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeProjectAttachments: projectAttachmentAdapter.initialize,\n\t\taddProjectAttachment: projectAttachmentAdapter.addOne,\n\t\taddProjectAttachments: projectAttachmentAdapter.addMany,\n\t\tsetProjectAttachment: projectAttachmentAdapter.setOne,\n\t\tsetProjectAttachments: projectAttachmentAdapter.setMany,\n\t\tupdateProjectAttachment: projectAttachmentAdapter.updateOne,\n\t\tupdateProjectAttachments: projectAttachmentAdapter.updateMany,\n\t\tdeleteProjectAttachment: projectAttachmentAdapter.deleteOne,\n\t\tdeleteProjectAttachments: projectAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeProjectAttachments,\n\taddProjectAttachment,\n\taddProjectAttachments,\n\tsetProjectAttachment,\n\tsetProjectAttachments,\n\tupdateProjectAttachment,\n\tupdateProjectAttachments,\n\tdeleteProjectAttachment,\n\tdeleteProjectAttachments,\n} = projectAttachmentSlice.actions\n\nexport const selectProjectAttachmentMapping = (state: OvermapRootState) => state.projectAttachmentReducer.instances\n\nexport const selectAllProjectAttachments: OvermapSelector<Stored<ProjectAttachment>[]> = createSelector(\n\t[selectProjectAttachmentMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectProjectAttachmentById: OvermapSelectorWithArgs<string, ProjectAttachment | undefined> =\n\t(id) => (state) => {\n\t\treturn state.projectAttachmentReducer.instances[id]\n\t}\n\nexport const selectAttachmentsOfProject = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectAllProjectAttachments, (_, projectId: number) => projectId], (attachments, projectId) => {\n\t\treturn fallbackToEmptyArray(attachments.filter(({ project }) => projectId === project))\n\t}),\n)\nexport const selectAttachmentsOfProjectByType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAllProjectAttachments, (_state: OvermapRootState, projectId: number) => projectId],\n\t\t(attachments, projectId) => {\n\t\t\tconst attachmentsOfProject = attachments.filter(({ project }) => projectId === project)\n\t\t\tconst fileAttachments = attachmentsOfProject.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => !file_type || !file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\tconst imageAttachments = attachmentsOfProject.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => file_type && file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\treturn { fileAttachments, imageAttachments }\n\t\t},\n\t),\n)\n\nexport const projectAttachmentReducer: Reducer<ProjectAttachmentState> = projectAttachmentSlice.reducer\n","import { createSlice, PayloadAction, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapRootState } from \"../../typings\"\n\n// TODO: this slice can be moved to /web ?\n\nexport interface RehydratedState {\n\tisRehydrated: boolean\n}\n\nconst initialState: RehydratedState = {\n\tisRehydrated: false,\n}\n\n// rehydratedSlice is used to indicate when the Redux store has finished rehydrating its state from localForage\n// Once finished, the app renders, which prevents the annoying login screen flickering issue\nexport const rehydratedSlice = createSlice({\n\tname: \"rehydrated\",\n\tinitialState,\n\t// The `reducers` field lets us define reducers and generate associated actions\n\treducers: {\n\t\tsetRehydrated: (state, action: PayloadAction<boolean>) => {\n\t\t\tstate.isRehydrated = action.payload\n\t\t},\n\t},\n})\n\nexport const { setRehydrated } = rehydratedSlice.actions\n\n// The function below is called a selector and allows us to select a value from\n// the state. Selectors can also be defined inline where they're used instead of\n// in the slice file. For example: `useSelector((state: RootState) => state.counter.value)`\nexport const selectRehydrated = (state: OvermapRootState) => state.rehydratedReducer.isRehydrated\n\nexport const rehydratedReducer: Reducer<RehydratedState> = rehydratedSlice.reducer\n","import { Stored, FormRevision } from \"../typings\"\n\nexport const formRevisionSortFn = (formRevisionA: Stored<FormRevision>, formRevisionB: Stored<FormRevision>) => {\n\tconst revisionA = formRevisionA.revision\n\tconst revisionB = formRevisionB.revision\n\n\tif (revisionA === \"Pending\" && revisionB === \"Pending\") {\n\t\treturn formRevisionA.submitted_at < formRevisionB.submitted_at ? -1 : 1\n\t} else if (revisionA === \"Pending\") {\n\t\treturn 1\n\t} else if (revisionB === \"Pending\") {\n\t\treturn -1\n\t} else {\n\t\treturn revisionA < revisionB ? -1 : 1\n\t}\n}\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tForm,\n\tFormRevision,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { formRevisionSortFn } from \"../../utils/forms\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type FormRevisionState = ModelState<Stored<FormRevision>>\n\nconst formRevisionAdapter = createModelAdapter<Stored<FormRevision>>((revision) => revision.offline_id)\n\nconst initialState: FormRevisionState = formRevisionAdapter.getInitialState({})\n\nexport const formRevisionsSlice = createSlice({\n\tname: \"formRevisions\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeFormRevisions: formRevisionAdapter.initialize,\n\t\tsetFormRevision: formRevisionAdapter.setOne,\n\t\taddFormRevision: formRevisionAdapter.addOne,\n\t\taddFormRevisions: formRevisionAdapter.addMany,\n\t\tdeleteFormRevision: formRevisionAdapter.deleteOne,\n\t\tdeleteFormRevisions: formRevisionAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tsetFormRevision,\n\tinitializeFormRevisions,\n\taddFormRevision,\n\taddFormRevisions,\n\tdeleteFormRevision,\n\tdeleteFormRevisions,\n} = formRevisionsSlice.actions\n\nexport const selectFormRevisionMapping = (state: OvermapRootState) => state.formRevisionReducer.instances\n\nexport const selectFormRevisions = createSelector([selectFormRevisionMapping], (formRevisions) =>\n\tObject.values(formRevisions),\n)\n\nexport const selectFormRevisionById: OvermapSelectorWithArgs<string, Stored<FormRevision> | undefined> =\n\t(formRevisionId: string) => (state: OvermapRootState) => {\n\t\treturn state.formRevisionReducer.instances[formRevisionId]\n\t}\n\n// takes user form state revisions instead of the whole state as an argument\nexport const _selectLatestFormRevision = (\n\tformRevisions: FormRevisionState[\"instances\"],\n\tformId: string,\n): Stored<FormRevision> => {\n\tlet ret: Stored<FormRevision> | null = null\n\n\tfor (const candidate of Object.values(formRevisions)) {\n\t\tif (candidate.form === formId && (!ret || ret.revision < candidate.revision)) {\n\t\t\tret = candidate\n\t\t}\n\t}\n\n\tif (!ret) {\n\t\tthrow new Error(\"No form revision found for form \" + formId)\n\t}\n\n\treturn ret\n}\n\nexport const selectLatestFormRevisionOfForm: OvermapSelectorWithArgs<string, Stored<FormRevision> | undefined> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectFormRevisionMapping, (_state: OvermapRootState, formId: string) => formId],\n\t\t\t(revisions, formId) => {\n\t\t\t\tconst revisionsOfForm = Object.values(revisions).filter((revision) => revision.form === formId)\n\n\t\t\t\tif (revisionsOfForm.length === 0) return undefined\n\n\t\t\t\tconst sortedRevisions = revisionsOfForm.sort(formRevisionSortFn)\n\n\t\t\t\tconst latestRevision = sortedRevisions[revisionsOfForm.length - 1]!\n\n\t\t\t\treturn revisions[latestRevision.offline_id]\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectFormRevisionsOfForm: OvermapSelectorWithArgs<string, Stored<FormRevision>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectFormRevisions, (_state: OvermapRootState, formId: string) => formId],\n\t\t\t(revisions, formId) => {\n\t\t\t\treturn fallbackToEmptyArray(revisions.filter((revision) => revision.form === formId))\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectLatestFormRevisionByForm: OvermapSelector<Record<Stored<Form>[\"offline_id\"], Stored<FormRevision>>> =\n\tcreateSelector([selectFormRevisionMapping], (revisions) => {\n\t\tconst latestRevisions: Record<string, FormRevision> = {}\n\t\tfor (const revision of Object.values(revisions)) {\n\t\t\tconst formId = revision.form\n\t\t\tconst currentLatestRevision = latestRevisions[formId]\n\t\t\tif (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {\n\t\t\t\tlatestRevisions[formId] = revision\n\t\t\t}\n\t\t}\n\t\treturn latestRevisions\n\t})\n\nexport const formRevisionReducer: Reducer<FormRevisionState> = formRevisionsSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { Form } from \"typings/models/forms\"\nimport type { SearchArgs } from \"typings/search\"\nimport type { OvermapSelector, OvermapSelectorWithArgs } from \"typings/store\"\nimport { restructureCreateSelectorWithArgs } from \"utils/utils\"\nimport type { OvermapRootState, Stored } from \"../../typings\"\nimport { _selectLatestFormRevision } from \"./formRevisionSlice\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { shallowEqual } from \"../../utils\"\n\nexport type FormState = ModelState<Stored<Form>>\n\nconst formAdapter = createModelAdapter<Stored<Form>>((form) => form.offline_id)\n\nconst initialState: FormState = formAdapter.getInitialState({})\n\nexport const formSlice = createSlice({\n\tname: \"forms\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeForms: formAdapter.initialize,\n\t\tsetForm: formAdapter.setOne,\n\t\taddForm: formAdapter.addOne,\n\t\taddForms: formAdapter.addMany,\n\t\tupdateForm: formAdapter.updateOne,\n\t\tdeleteForm: formAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeForms, setForm, addForm, addForms, updateForm, deleteForm } = formSlice.actions\n\nexport const formReducer: Reducer<FormState> = formSlice.reducer\n\nexport type FormSearchArgs = SearchArgs<{\n\t/** organization owner */\n\torganization?: number\n}>\n\nexport const selectFormMapping: OvermapSelector<Record<Stored<Form>[\"offline_id\"], Stored<Form>>> = (\n\tstate: OvermapRootState,\n) => {\n\treturn state.formReducer.instances\n}\n\nexport const selectForms = createSelector([selectFormMapping], (formsMapping) => {\n\treturn Object.values(formsMapping)\n})\n\nexport const selectFilteredForms: OvermapSelectorWithArgs<FormSearchArgs, Stored<Form>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[\n\t\t\t\t(state: OvermapRootState) => state.formReducer.instances,\n\t\t\t\t(state: OvermapRootState) => state.formRevisionReducer.instances,\n\t\t\t\t(_state: OvermapRootState, search: FormSearchArgs) => search,\n\t\t\t],\n\t\t\t(formsMapping, revisions, search) => {\n\t\t\t\tconst { searchTerm, maxResults, organization } = search\n\n\t\t\t\tconst regularMatches: Stored<Form>[] = []\n\n\t\t\t\tfor (const [formId, form] of Object.entries(formsMapping)) {\n\t\t\t\t\t// if filtering by organizations, skip forms with the wrong organization\n\t\t\t\t\tif (Number.isInteger(organization) && organization !== form.organization) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\t// find the latest revision for this form (note: expensive)\n\t\t\t\t\tconst latestRevision = _selectLatestFormRevision(revisions, formId)\n\n\t\t\t\t\tif (latestRevision.title.toLowerCase().includes(searchTerm.toLowerCase())) {\n\t\t\t\t\t\tregularMatches.push(form)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [...regularMatches.slice(0, maxResults)]\n\t\t\t},\n\t\t\t// as the argument is an object, we check the first level of properties for equality\n\t\t\t{ memoizeOptions: { equalityCheck: shallowEqual } },\n\t\t),\n\t)\n\nexport const selectFormById: OvermapSelectorWithArgs<string, Stored<Form> | undefined> =\n\t(formId: string) => (state: OvermapRootState) => {\n\t\treturn state.formReducer.instances[formId]\n\t}\n\nexport const selectFormOfAssetType: OvermapSelectorWithArgs<string, Stored<Form> | undefined> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectFormMapping, (_state: OvermapRootState, assetTypeId: string) => assetTypeId],\n\t\t\t(formsMapping, assetTypeId) => {\n\t\t\t\treturn Object.values(formsMapping).find((form) => form.asset_type === assetTypeId)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectFormOfIssueType: OvermapSelectorWithArgs<string, Stored<Form> | undefined> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectFormMapping, (_state: OvermapRootState, issueTypeId: string) => issueTypeId],\n\t\t\t(formsMapping, issueTypeId) => {\n\t\t\t\treturn Object.values(formsMapping).find((form) => form.issue_type === issueTypeId)\n\t\t\t},\n\t\t),\n\t)\n\n// Total number of user forms\nexport const selectFormsCount: OvermapSelector<number> = createSelector([selectFormMapping], (formsMapping) => {\n\treturn Object.keys(formsMapping).length\n})\n\n// Number of user forms not related to a asset type\nexport const selectGeneralFormCount: OvermapSelector<number> = createSelector([selectFormMapping], (formsMapping) => {\n\treturn Object.values(formsMapping).filter((form) => !form.asset_type).length\n})\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { FormSubmission, OvermapRootState, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { formRevisionSortFn } from \"../../utils/forms\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\nimport { selectAssetsMapping } from \"./assetSlice\"\nimport { selectFormRevisionMapping } from \"./formRevisionSlice\"\n\nexport type FormSubmissionState = ModelState<Stored<FormSubmission>>\n\nconst submissionAdapter = createModelAdapter<Stored<FormSubmission>>((submission) => submission.offline_id)\n\nconst initialState: FormSubmissionState = submissionAdapter.getInitialState({})\n\nexport const formSubmissionSlice = createSlice({\n\tname: \"formSubmissions\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeFormSubmissions: submissionAdapter.initialize,\n\t\tsetFormSubmission: submissionAdapter.setOne,\n\t\tsetFormSubmissions: submissionAdapter.setMany,\n\t\taddFormSubmission: submissionAdapter.addOne,\n\t\taddFormSubmissions: submissionAdapter.addMany,\n\t\tupdateFormSubmission: submissionAdapter.updateOne,\n\t\tupdateFormSubmissions: submissionAdapter.updateMany,\n\t\tdeleteFormSubmission: submissionAdapter.deleteOne,\n\t\tdeleteFormSubmissions: submissionAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeFormSubmissions,\n\tsetFormSubmission,\n\tsetFormSubmissions,\n\taddFormSubmission,\n\taddFormSubmissions,\n\tupdateFormSubmission,\n\tupdateFormSubmissions,\n\tdeleteFormSubmission,\n\tdeleteFormSubmissions,\n} = formSubmissionSlice.actions\n\nexport const selectFormSubmissionsMapping: OvermapSelector<FormSubmissionState[\"instances\"]> = (state) => {\n\treturn state.formSubmissionReducer.instances\n}\n\nexport const selectFormSubmissions: OvermapSelector<Stored<FormSubmission>[]> = createSelector(\n\t[selectFormSubmissionsMapping],\n\t(submissions) => {\n\t\treturn Object.values(submissions)\n\t},\n)\n\nexport const selectFormSubmissionById: OvermapSelectorWithArgs<string, Stored<FormSubmission> | undefined> =\n\t(submissionId) => (state: OvermapRootState) => {\n\t\treturn state.formSubmissionReducer.instances[submissionId]\n\t}\n\nexport const selectFormSubmissionsOfForm: OvermapSelectorWithArgs<string, Stored<FormSubmission>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[\n\t\t\t\tselectFormSubmissionsMapping,\n\t\t\t\tselectFormRevisionMapping,\n\t\t\t\t(_state: OvermapRootState, formId: string) => formId,\n\t\t\t],\n\t\t\t(submissionsMapping, revisionMapping, formId) => {\n\t\t\t\tconst revisionIds: Set<string> = new Set<string>()\n\n\t\t\t\tfor (const revision of Object.values(revisionMapping)) {\n\t\t\t\t\tif (revision.form !== formId) continue\n\t\t\t\t\trevisionIds.add(revision.offline_id)\n\t\t\t\t}\n\n\t\t\t\treturn Object.values(submissionsMapping).filter((submission) =>\n\t\t\t\t\trevisionIds.has(submission.form_revision),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectFormSubmissionsByFormRevisions: OvermapSelector<Record<string, Stored<FormSubmission>[]>> =\n\tcreateSelector([selectFormRevisionMapping, selectFormSubmissions], (revisions, submissions) => {\n\t\tconst submissionMapping: Record<string, Stored<FormSubmission>[]> = {}\n\t\tfor (const revisionId in revisions) {\n\t\t\tsubmissionMapping[revisionId] = []\n\t\t}\n\t\tfor (const submission of submissions) {\n\t\t\tsubmissionMapping[submission.form_revision]?.push(submission)\n\t\t}\n\t\treturn submissionMapping\n\t})\n\nexport const selectSortedFormSubmissionsOfForm: OvermapSelectorWithArgs<string, Stored<FormSubmission>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[\n\t\t\t\tselectFormRevisionMapping,\n\t\t\t\tselectFormSubmissionsByFormRevisions,\n\t\t\t\t(_state: OvermapRootState, formId: string) => formId,\n\t\t\t],\n\t\t\t(revisionsMapping, submissionsByRevision, formId) => {\n\t\t\t\tconst submissionsByFormRevisions: Record<string, Stored<FormSubmission>[]> = {}\n\n\t\t\t\tfor (const revisionId in revisionsMapping) {\n\t\t\t\t\tconst revision = revisionsMapping[revisionId]\n\t\t\t\t\tconst submissionsOfRevision = submissionsByRevision[revisionId]\n\t\t\t\t\tif (revision && submissionsOfRevision && revision.form === formId) {\n\t\t\t\t\t\tsubmissionsByFormRevisions[revisionId] = submissionsOfRevision.sort((a, b) =>\n\t\t\t\t\t\t\ta.submitted_at < b.submitted_at ? -1 : 1,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn Object.entries(submissionsByFormRevisions)\n\t\t\t\t\t.sort((a, b) => {\n\t\t\t\t\t\tconst aRevision = revisionsMapping[a[0]]!\n\t\t\t\t\t\tconst bRevision = revisionsMapping[b[0]]!\n\t\t\t\t\t\treturn formRevisionSortFn(aRevision, bRevision)\n\t\t\t\t\t})\n\t\t\t\t\t.map(([_revisionId, submissions]) => submissions)\n\t\t\t\t\t.flat()\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectFormSubmissionsOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectFormSubmissions, (_state: OvermapRootState, issueId: string) => issueId],\n\t\t(submissions, issueId) => {\n\t\t\treturn Object.values(submissions).filter((submission) => {\n\t\t\t\treturn submission.issue === issueId\n\t\t\t})\n\t\t},\n\t),\n)\n\nexport const selectAttachedFormSubmissionsOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[\n\t\t\t(state: OvermapRootState) => state.issueReducer.instances,\n\t\t\t(state: OvermapRootState) => state.formReducer.instances,\n\t\t\t(state: OvermapRootState) => state.formRevisionReducer.instances,\n\t\t\t(state: OvermapRootState) => state.formSubmissionReducer.instances,\n\t\t\t(_state: OvermapRootState, issueId: string) => issueId,\n\t\t],\n\t\t(issues, forms, formRevisions, submissions, issueId) => {\n\t\t\t// step 1: check if issue has an issue type\n\t\t\tconst issue = issues[issueId]\n\n\t\t\tif (!issue) return []\n\n\t\t\tif (!issue.issue_type) {\n\t\t\t\treturn Object.values(submissions).filter((submission) => submission.issue === issueId)\n\t\t\t}\n\n\t\t\t// step 2: find the ids for forms of the issue type\n\t\t\tconst issueTypeForms = new Set(\n\t\t\t\tObject.keys(forms).filter((formId) => forms[formId]!.issue_type === issue.issue_type),\n\t\t\t)\n\n\t\t\t// step 3: find the ids for form revisions of the forms\n\t\t\tconst issueTypeFormRevisions = new Set(\n\t\t\t\tObject.keys(formRevisions).filter((formRevisionId) =>\n\t\t\t\t\tissueTypeForms.has(formRevisions[formRevisionId]!.form),\n\t\t\t\t),\n\t\t\t)\n\n\t\t\t// step 4: filter out any submissions whos revision is in the set\n\t\t\treturn Object.values(submissions).filter(\n\t\t\t\t(submission) => submission.issue === issueId && !issueTypeFormRevisions.has(submission.form_revision),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const selectFormSubmissionsByIssues: OvermapSelectorWithArgs<\n\tstring[],\n\tRecord<string, Stored<FormSubmission>[]>\n> = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectFormSubmissions, (_state: OvermapRootState, issueIds: string[]) => issueIds],\n\t\t(submissions, issueIds) => {\n\t\t\tconst issueSubmissions: Record<string, Stored<FormSubmission>[]> = {}\n\t\t\tfor (const issueId of issueIds) {\n\t\t\t\tissueSubmissions[issueId] = []\n\t\t\t}\n\t\t\tfor (const submission of submissions) {\n\t\t\t\tif (submission.issue && issueIds.includes(submission.issue)) {\n\t\t\t\t\tissueSubmissions[submission.issue]?.push(submission)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn issueSubmissions\n\t\t},\n\t),\n)\n\nexport const selectFormSubmissionsOfAsset = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectFormSubmissions, (_state: OvermapRootState, assetId: string) => assetId],\n\t\t(submissions, assetId) => {\n\t\t\treturn submissions.filter((submission) => {\n\t\t\t\treturn submission.asset === assetId\n\t\t\t})\n\t\t},\n\t),\n)\n\nexport const selectAttachedFormSubmissionsOfAsset = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[\n\t\t\t(state: OvermapRootState) => state.assetReducer.instances,\n\t\t\t(state: OvermapRootState) => state.formReducer.instances,\n\t\t\t(state: OvermapRootState) => state.formRevisionReducer.instances,\n\t\t\t(state: OvermapRootState) => state.formSubmissionReducer.instances,\n\t\t\t(_state: OvermapRootState, assetId: string) => assetId,\n\t\t],\n\t\t(assets, forms, formRevisions, submissions, assetId) => {\n\t\t\t// step 1: check if asset has an asset type\n\t\t\tconst asset = assets[assetId]\n\n\t\t\tif (!asset) return []\n\n\t\t\tif (!asset.asset_type) {\n\t\t\t\treturn Object.values(submissions).filter((submission) => submission.asset === assetId)\n\t\t\t}\n\n\t\t\t// step 2: find the ids for forms of the asset type\n\t\t\tconst issueTypeForms = new Set(\n\t\t\t\tObject.keys(forms).filter((formId) => forms[formId]!.asset_type === asset.asset_type),\n\t\t\t)\n\n\t\t\t// step 3: find the ids for form revisions of the forms\n\t\t\tconst issueTypeFormRevisions = new Set(\n\t\t\t\tObject.keys(formRevisions).filter((formRevisionId) =>\n\t\t\t\t\tissueTypeForms.has(formRevisions[formRevisionId]!.form),\n\t\t\t\t),\n\t\t\t)\n\n\t\t\t// step 4: filter out any submissions whos revision is in the set\n\t\t\treturn Object.values(submissions).filter(\n\t\t\t\t(submission) => submission.asset === assetId && !issueTypeFormRevisions.has(submission.form_revision),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const selectFormSubmissionsByAssets: OvermapSelector<Record<string, Stored<FormSubmission>[]>> = createSelector(\n\t[selectFormSubmissionsMapping, selectAssetsMapping],\n\t(submissions, assets) => {\n\t\tconst assetSubmissionMapping: Record<string, FormSubmission[]> = {}\n\t\tfor (const assetId in assets) {\n\t\t\tassetSubmissionMapping[assetId] = []\n\t\t}\n\t\tfor (const submissionId in submissions) {\n\t\t\tconst submission = submissions[submissionId]!\n\t\t\tif (submission.asset) {\n\t\t\t\tassetSubmissionMapping[submission.asset]?.push(submission)\n\t\t\t}\n\t\t}\n\t\treturn assetSubmissionMapping\n\t},\n)\n\nexport const formSubmissionReducer: Reducer<FormSubmissionState> = formSubmissionSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type {\n\tFormSubmissionAttachment,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type FormSubmissionAttachmentState = ModelState<Stored<FormSubmissionAttachment>>\n\nconst formSubmissionAttachmentAdapter = createModelAdapter<Stored<FormSubmissionAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState: FormSubmissionAttachmentState = formSubmissionAttachmentAdapter.getInitialState({})\n\nexport const formSubmissionAttachmentSlice = createSlice({\n\tname: \"formSubmissionAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeFormSubmissionAttachments: formSubmissionAttachmentAdapter.initialize,\n\t\taddFormSubmissionAttachment: formSubmissionAttachmentAdapter.addOne,\n\t\taddFormSubmissionAttachments: formSubmissionAttachmentAdapter.addMany,\n\t\tsetFormSubmissionAttachment: formSubmissionAttachmentAdapter.setOne,\n\t\tsetFormSubmissionAttachments: formSubmissionAttachmentAdapter.setMany,\n\t\tupdateFormSubmissionAttachment: formSubmissionAttachmentAdapter.updateOne,\n\t\tupdateFormSubmissionAttachments: formSubmissionAttachmentAdapter.updateMany,\n\t\tdeleteFormSubmissionAttachment: formSubmissionAttachmentAdapter.deleteOne,\n\t\tdeleteFormSubmissionAttachments: formSubmissionAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeFormSubmissionAttachments,\n\taddFormSubmissionAttachment,\n\taddFormSubmissionAttachments,\n\tsetFormSubmissionAttachment,\n\tsetFormSubmissionAttachments,\n\tupdateFormSubmissionAttachment,\n\tupdateFormSubmissionAttachments,\n\tdeleteFormSubmissionAttachment,\n\tdeleteFormSubmissionAttachments,\n} = formSubmissionAttachmentSlice.actions\n\nexport const selectFormSubmissionAttachmentsMapping: OvermapSelector<FormSubmissionAttachmentState[\"instances\"]> = (\n\tstate,\n) => {\n\treturn state.formSubmissionAttachmentReducer.instances\n}\n\nexport const selectFormSubmissionAttachemntsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectFormSubmissionAttachmentsMapping, (_, attachmentIds: string[]) => attachmentIds],\n\t\t(mapping, attachmentIds) => {\n\t\t\tconst attachmentIdsSet = new Set(attachmentIds)\n\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\tObject.values(mapping).filter((attachment) => attachmentIdsSet.has(attachment.offline_id)),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfFormSubmission: OvermapSelectorWithArgs<string, Stored<FormSubmissionAttachment>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectFormSubmissionAttachmentsMapping, (_state: OvermapRootState, submissionId: string) => submissionId],\n\t\t\t(attachmentsMapping, submissionId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tObject.values(attachmentsMapping).filter((attachment) => attachment.submission === submissionId),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const formSubmissionAttachmentReducer: Reducer<FormSubmissionAttachmentState> =\n\tformSubmissionAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type { FormRevisionAttachment, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type FormRevisionAttachmentState = ModelState<Stored<FormRevisionAttachment>>\n\nconst formRevisionAttachmentAdapter = createModelAdapter<Stored<FormRevisionAttachment>>(\n\t(attachment) => attachment.offline_id,\n)\n\nconst initialState: FormRevisionAttachmentState = formRevisionAttachmentAdapter.getInitialState({})\n\nexport const formRevisionAttachmentSlice = createSlice({\n\tname: \"formRevisionAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeFormRevisionAttachments: formRevisionAttachmentAdapter.initialize,\n\t\taddFormRevisionAttachment: formRevisionAttachmentAdapter.addOne,\n\t\taddFormRevisionAttachments: formRevisionAttachmentAdapter.addMany,\n\t\tsetFormRevisionAttachment: formRevisionAttachmentAdapter.setOne,\n\t\tsetFormRevisionAttachments: formRevisionAttachmentAdapter.setMany,\n\t\tupdateFormRevisionAttachment: formRevisionAttachmentAdapter.updateOne,\n\t\tupdateFormRevisionAttachments: formRevisionAttachmentAdapter.updateMany,\n\t\tdeleteFormRevisionAttachment: formRevisionAttachmentAdapter.deleteOne,\n\t\tdeleteFormRevisionAttachments: formRevisionAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeFormRevisionAttachments,\n\taddFormRevisionAttachment,\n\taddFormRevisionAttachments,\n\tsetFormRevisionAttachment,\n\tsetFormRevisionAttachments,\n\tupdateFormRevisionAttachment,\n\tupdateFormRevisionAttachments,\n\tdeleteFormRevisionAttachment,\n\tdeleteFormRevisionAttachments,\n} = formRevisionAttachmentSlice.actions\n\nexport const selectFormRevisionAttachmentsMapping: OvermapSelector<FormRevisionAttachmentState[\"instances\"]> = (\n\tstate,\n) => {\n\treturn state.formRevisionAttachmentReducer.instances\n}\n\nexport const selectAttachmentsOfFormRevision: OvermapSelectorWithArgs<string, Stored<FormRevisionAttachment>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectFormRevisionAttachmentsMapping, (_state, revisionId: string) => revisionId],\n\t\t\t(attachments, revisionId) => {\n\t\t\t\treturn fallbackToEmptyArray(\n\t\t\t\t\tObject.values(attachments).filter((attachment) => attachment.revision === revisionId),\n\t\t\t\t)\n\t\t\t},\n\t\t),\n\t)\n\nexport const formRevisionAttachmentReducer: Reducer<FormRevisionAttachmentState> = formRevisionAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { OvermapRootState, OvermapSelector, OvermapSelectorWithArgs, Stored, Workspace } from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type WorkspaceState = ModelState<Stored<Workspace>>\n\nconst workspaceAdapter = createModelAdapter<Stored<Workspace>>((workspace) => workspace.offline_id)\n\nconst initialState: WorkspaceState = workspaceAdapter.getInitialState({})\n\nexport const workspaceSlice = createSlice({\n\tname: \"workspace\",\n\tinitialState,\n\treducers: {\n\t\tinitializeWorkspaces: workspaceAdapter.initialize,\n\t\tsetWorkspaces: workspaceAdapter.setMany,\n\t\taddWorkspace: workspaceAdapter.addOne,\n\t\tupdateWorkspace: workspaceAdapter.updateOne,\n\t\tdeleteWorkspace: workspaceAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeWorkspaces, setWorkspaces, addWorkspace, updateWorkspace, deleteWorkspace } =\n\tworkspaceSlice.actions\n\nexport const selectWorkspaceMapping: OvermapSelector<Record<string, Workspace>> = (state: OvermapRootState) =>\n\tstate.workspaceReducer.instances\n\nexport const selectWorkspaces = createSelector([selectWorkspaceMapping], (mapping) => Object.values(mapping))\n\nexport const selectMainWorkspace: OvermapSelector<Workspace | undefined> = createSelector(\n\t[selectWorkspaces],\n\t(workspaces) => {\n\t\treturn workspaces.find((workspace) => workspace.name.toLowerCase() === \"main\")\n\t},\n)\n\nexport const selectWorkspaceById: OvermapSelectorWithArgs<string, Stored<Workspace> | undefined> = (id) => (state) => {\n\treturn state.workspaceReducer.instances[id]\n}\n\nexport const selectPermittedWorkspaceIds: OvermapSelector<Set<string>> = createSelector(\n\t[selectWorkspaceMapping],\n\t(mapping) => {\n\t\treturn new Set(\n\t\t\tObject.values(mapping)\n\t\t\t\t.filter((workspace: Workspace) => workspace.permitted)\n\t\t\t\t.map((workspace: Workspace) => workspace.offline_id),\n\t\t)\n\t},\n)\n\nexport const workspaceReducer: Reducer<WorkspaceState> = workspaceSlice.reducer\n","import type { EmailDomain, OvermapRootState, OvermapSelector } from \"../../typings\"\nimport { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type EmailDomainState = ModelState<EmailDomain>\n\nconst emailDomainAdapter = createModelAdapter<EmailDomain>((emailDomain) => emailDomain.offline_id)\n\nconst initialState = emailDomainAdapter.getInitialState({})\n\nexport const emailDomainsSlice = createSlice({\n\tname: \"emailDomains\",\n\tinitialState,\n\treducers: {\n\t\tinitializeEmailDomains: emailDomainAdapter.initialize,\n\t\taddEmailDomain: emailDomainAdapter.addOne,\n\t\tdeleteEmailDomain: emailDomainAdapter.deleteOne,\n\t},\n})\n\nexport const { initializeEmailDomains, addEmailDomain, deleteEmailDomain } = emailDomainsSlice.actions\n\nexport const selectEmailDomainsAsMapping: OvermapSelector<Record<number, EmailDomain>> = (state: OvermapRootState) =>\n\tstate.emailDomainsReducer.instances\n\nexport const selectEmailDomains = createSelector([selectEmailDomainsAsMapping], (mapping) => Object.values(mapping))\n\nexport const selectEmailDomainsOfOrganization = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectEmailDomains, (_, organizationId: number) => organizationId],\n\t\t(emailDomains, organizationId) => {\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\temailDomains.filter((emailDomain) => emailDomain.organization === organizationId),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const emailDomainsReducer: Reducer<EmailDomainState> = emailDomainsSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tDocument,\n\tMovePosition,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport {\n\tfallbackToEmptyArray,\n\tonlyUniqueOfflineIds,\n\trestructureCreateSelectorWithArgs,\n\ttoOfflineIdRecord,\n} from \"../../utils\"\n\nexport interface DocumentState {\n\tdocuments: Record<string, Stored<Document>>\n}\n\nexport interface MoveDocumentPayload {\n\tdocumentId: Document[\"offline_id\"]\n\ttargetDocumentId: Document[\"offline_id\"] | null\n\tposition: MovePosition\n}\n\nconst initialState: DocumentState = {\n\tdocuments: {},\n}\n\nexport const documentSlice = createSlice({\n\tname: \"documents\",\n\tinitialState: initialState,\n\textraReducers: (builder) =>\n\t\tbuilder.addCase(\"RESET\", (state) => {\n\t\t\tObject.assign(state, initialState)\n\t\t}),\n\treducers: {\n\t\tsetDocuments: (state, action: { payload: Stored<Document>[] }) => {\n\t\t\tif (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {\n\t\t\t\tthrow new Error(\"Tried to use setIssues reducer with duplicate ID's\")\n\t\t\t}\n\t\t\tstate.documents = toOfflineIdRecord(action.payload)\n\t\t},\n\t\taddDocuments: (state, action: { payload: Stored<Document>[] }) => {\n\t\t\tfor (const document of action.payload) {\n\t\t\t\tif (document.offline_id in state.documents) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`attempting to add a document with offline_id ${document.offline_id} which already exists in state.documents.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const document of action.payload) {\n\t\t\t\tif (document.parent_document && !!state.documents[document.parent_document]) {\n\t\t\t\t\tconst parentDocument = state.documents[document.parent_document]!\n\t\t\t\t\tstate.documents[document.parent_document] = {\n\t\t\t\t\t\t...parentDocument,\n\t\t\t\t\t\tchildren_documents: [...parentDocument.children_documents, document.offline_id],\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstate.documents[document.offline_id] = document\n\t\t\t}\n\t\t},\n\t\tupdateDocuments: (state, action: { payload: Stored<Document>[] }) => {\n\t\t\tfor (const document of action.payload) {\n\t\t\t\tif (!(document.offline_id in state.documents)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`attempting to update a document with offline_id ${document.offline_id} which doesn't exists in state.documents.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const document of action.payload) {\n\t\t\t\tconst existingDocument = state.documents[document.offline_id]!\n\t\t\t\tif (document.organization !== undefined && document.organization !== existingDocument.organization) {\n\t\t\t\t\tthrow new Error(\"organization cannot be updated\")\n\t\t\t\t}\n\t\t\t\tif (document.project !== undefined && document.project !== existingDocument.project) {\n\t\t\t\t\tthrow new Error(\"project cannot be updated\")\n\t\t\t\t}\n\t\t\t\tstate.documents[document.offline_id] = {\n\t\t\t\t\t...existingDocument,\n\t\t\t\t\t...document,\n\t\t\t\t\t// Without the cast, TypeScript doesn't realize that we have guaranteed that the document doesn't\n\t\t\t\t\t// have both a project and an organization.\n\t\t\t\t} as Stored<Document>\n\t\t\t}\n\t\t},\n\t\tmoveDocument: (state, action: { payload: MoveDocumentPayload }) => {\n\t\t\tconst { documentId, targetDocumentId, position } = action.payload\n\t\t\tif (!(documentId in state.documents)) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`attempting to move a document with offline_id ${documentId} which doesn't exist in state.documents`,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\t// even if a document is being moved to the same parent, it needs to be removed since its position in its parent would be changing\n\t\t\tconst document = state.documents[documentId]!\n\t\t\tif (document.parent_document && state.documents[document.parent_document]) {\n\t\t\t\tconst { children_documents } = state.documents[document.parent_document]!\n\t\t\t\tstate.documents[document.parent_document]!.children_documents.splice(\n\t\t\t\t\tchildren_documents.indexOf(document.offline_id),\n\t\t\t\t\t1,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (targetDocumentId) {\n\t\t\t\tconst targetDocument = state.documents[targetDocumentId]\n\t\t\t\tconst newParentDocument = targetDocument?.parent_document\n\t\t\t\t\t? state.documents[targetDocument.parent_document]\n\t\t\t\t\t: null\n\n\t\t\t\tswitch (position) {\n\t\t\t\t\tcase \"left\":\n\t\t\t\t\t\tif (!newParentDocument) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\"attempting to move a document to the left of a document with no parent_document\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// if newParentDocument exists, then targetDocument must exist\n\t\t\t\t\t\tstate.documents[targetDocument!.parent_document!]!.children_documents.splice(\n\t\t\t\t\t\t\tnewParentDocument.children_documents.indexOf(targetDocument!.offline_id),\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tdocument.offline_id,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tstate.documents[documentId]!.parent_document = newParentDocument.offline_id\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"right\":\n\t\t\t\t\t\tif (!newParentDocument) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\"attempting to move a document to the left of a document with no parent_document\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// if newParentDocument exists, then targetDocument must exist\n\t\t\t\t\t\tstate.documents[targetDocument!.parent_document!]!.children_documents.splice(\n\t\t\t\t\t\t\tnewParentDocument.children_documents.indexOf(targetDocument!.offline_id) + 1,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tdocument.offline_id,\n\t\t\t\t\t\t)\n\t\t\t\t\t\tstate.documents[documentId]!.parent_document = newParentDocument.offline_id\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"left-child\":\n\t\t\t\t\t\tif (!targetDocument) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\"attempting to move a document to the left-child of a document that doesn't exist\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate.documents[targetDocumentId]!.children_documents.unshift(document.offline_id)\n\t\t\t\t\t\tstate.documents[documentId]!.parent_document = targetDocument.offline_id\n\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"right-child\":\n\t\t\t\t\t\tif (!targetDocument) {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\"attempting to move a document to the left-child of a document that doesn't exist\",\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate.documents[targetDocumentId]!.children_documents.push(document.offline_id)\n\t\t\t\t\t\tstate.documents[documentId]!.parent_document = targetDocument.offline_id\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstate.documents[documentId]!.parent_document = null\n\t\t\t}\n\t\t},\n\t\tremoveDocuments: (state, action: { payload: string[] }) => {\n\t\t\tfor (const documentId of action.payload) {\n\t\t\t\tif (!(documentId in state.documents)) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`attempting to delete a document with offline_id ${documentId} which doesn't exists in state.documents.`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const documentId of action.payload) {\n\t\t\t\tconst document = state.documents[documentId]!\n\t\t\t\tif (document.parent_document && !!state.documents[document.parent_document]) {\n\t\t\t\t\tconst parentDocument = state.documents[document.parent_document]!\n\t\t\t\t\tstate.documents[document.parent_document] = {\n\t\t\t\t\t\t...parentDocument,\n\t\t\t\t\t\tchildren_documents: parentDocument.children_documents.filter(\n\t\t\t\t\t\t\t(offline_id) => offline_id !== document.offline_id,\n\t\t\t\t\t\t),\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tdelete state.documents[documentId]\n\t\t\t}\n\t\t},\n\t},\n})\n\nexport const { setDocuments, addDocuments, updateDocuments, moveDocument, removeDocuments } = documentSlice.actions\n\nexport const selectDocumentsMapping: OvermapSelector<Record<string, Stored<Document>>> = (state: OvermapRootState) =>\n\tstate.documentsReducer.documents\n\nexport const selectDocuments: OvermapSelector<Stored<Document>[]> = createSelector(\n\t[selectDocumentsMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectDocumentById: OvermapSelectorWithArgs<string, Stored<Document> | undefined> =\n\t(documentId: Document[\"offline_id\"]) => (state) => {\n\t\treturn state.documentsReducer.documents[documentId]\n\t}\n\nexport const selectDocumentsByIds = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectDocumentsMapping, (_state, documentIds: Document[\"offline_id\"][]) => documentIds],\n\t\t(mapping, documentIds) => {\n\t\t\tconst documents: Stored<Document>[] = []\n\n\t\t\tfor (const documentId of documentIds) {\n\t\t\t\tconst document = mapping[documentId]\n\t\t\t\tif (document) {\n\t\t\t\t\tdocuments.push(document)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\"selectDocumentByIds: No document exists with the id\", documentId)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn fallbackToEmptyArray(documents)\n\t\t},\n\t),\n)\n\nexport const selectAncestorIdsOfDocument = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectDocumentsMapping, (_state, documentId: string) => documentId], (mapping, documentId) => {\n\t\tconst listOfAncestors: string[] = []\n\t\tconst document = mapping[documentId]\n\t\tif (!document || !document.parent_document) return listOfAncestors\n\n\t\tlet currentAncestor = mapping[document.parent_document]\n\n\t\twhile (currentAncestor) {\n\t\t\tlistOfAncestors.push(currentAncestor.offline_id)\n\t\t\tcurrentAncestor = mapping[currentAncestor.parent_document ?? \"\"]\n\t\t}\n\t\treturn fallbackToEmptyArray(listOfAncestors)\n\t}),\n)\n\nexport const selectRootDocuments = createSelector([selectDocuments], (documents) =>\n\tfallbackToEmptyArray(documents.filter((document) => !document.parent_document)),\n)\n\nexport const documentsReducer: Reducer<DocumentState> = documentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type {\n\tDocumentAttachment,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n} from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type DocumentAttachmentState = ModelState<Stored<DocumentAttachment>>\n\nconst documentAttachmentAdapter = createModelAdapter<Stored<DocumentAttachment>>((attachment) => attachment.offline_id)\n\nconst initialState = documentAttachmentAdapter.getInitialState({})\n\nexport const documentAttachmentSlice = createSlice({\n\tname: \"documentAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeDocumentAttachments: documentAttachmentAdapter.initialize,\n\t\taddDocumentAttachment: documentAttachmentAdapter.addOne,\n\t\taddDocumentAttachments: documentAttachmentAdapter.addMany,\n\t\tsetDocumentAttachment: documentAttachmentAdapter.setOne,\n\t\tsetDocumentAttachments: documentAttachmentAdapter.setMany,\n\t\tupdateDocumentAttachment: documentAttachmentAdapter.updateOne,\n\t\tupdateDocumentAttachments: documentAttachmentAdapter.updateMany,\n\t\tdeleteDocumentAttachment: documentAttachmentAdapter.deleteOne,\n\t\tdeleteDocumentAttachments: documentAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeDocumentAttachments,\n\taddDocumentAttachment,\n\taddDocumentAttachments,\n\tsetDocumentAttachment,\n\tsetDocumentAttachments,\n\tupdateDocumentAttachment,\n\tupdateDocumentAttachments,\n\tdeleteDocumentAttachment,\n\tdeleteDocumentAttachments,\n} = documentAttachmentSlice.actions\n\nexport const selectDocumentAttachmentMapping = (state: OvermapRootState) => state.documentAttachmentReducer.instances\n\nexport const selectAllDocumentAttachments: OvermapSelector<Stored<DocumentAttachment>[]> = createSelector(\n\t[selectDocumentAttachmentMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectDocumentAttachmentById: OvermapSelectorWithArgs<string, Stored<DocumentAttachment> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.documentAttachmentReducer.instances[id]\n\t}\n\nexport const selectAttachmentsOfDocument = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAllDocumentAttachments, (_state: OvermapRootState, documentId: string) => documentId],\n\t\t(attachments, documentId) => {\n\t\t\treturn fallbackToEmptyArray(attachments.filter(({ document }) => documentId === document))\n\t\t},\n\t),\n)\n\nexport const selectAttachmentsOfDocumentByType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectAllDocumentAttachments, (_state: OvermapRootState, documentId: string) => documentId],\n\t\t(attachments, documentId) => {\n\t\t\tconst attachmentsOfProject = attachments.filter(({ document }) => documentId === document)\n\t\t\tconst fileAttachments = attachmentsOfProject.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => !file_type || !file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\tconst imageAttachments = attachmentsOfProject.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => file_type && file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\treturn { fileAttachments, imageAttachments }\n\t\t},\n\t),\n)\n\nexport const documentAttachmentReducer: Reducer<DocumentAttachmentState> = documentAttachmentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type {\n\tOrganization,\n\tOvermapRootState,\n\tOvermapSelector,\n\tOvermapSelectorWithArgs,\n\tStored,\n\tTeam,\n\tUser,\n} from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type TeamState = ModelState<Stored<Team>>\n\nconst teamAdapter = createModelAdapter<Stored<Team>>((team) => team.offline_id)\n\nconst initialState: TeamState = teamAdapter.getInitialState({})\n\nexport const teamSlice = createSlice({\n\tname: \"teams\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tsetTeam: teamAdapter.setOne,\n\t\tinitializeTeams: teamAdapter.initialize,\n\t\taddTeam: teamAdapter.addOne,\n\t\tupdateTeam: teamAdapter.updateOne,\n\t\tdeleteTeam: teamAdapter.deleteOne,\n\t},\n})\n\nexport const { setTeam, initializeTeams, addTeam, updateTeam, deleteTeam } = teamSlice.actions\n\nexport const selectTeamsMapping: OvermapSelector<TeamState[\"instances\"]> = (state: OvermapRootState) =>\n\tstate.teamReducer.instances\n\nexport const selectTeams: OvermapSelector<Stored<Team>[]> = createSelector([selectTeamsMapping], (teams) => {\n\treturn Object.values(teams)\n})\n\nexport const selectTeamById: OvermapSelectorWithArgs<string, Stored<Team> | undefined> = (id) => (state) => {\n\treturn state.teamReducer.instances[id]\n}\n\nexport const selectTeamsByIds: OvermapSelectorWithArgs<string[], Stored<Team>[]> = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectTeamsMapping, (_state: OvermapRootState, teamIds: string[]) => teamIds],\n\t\t(mapping, teamIds) => {\n\t\t\tconst teams: Stored<Team>[] = []\n\n\t\t\tfor (const teamId of teamIds) {\n\t\t\t\tconst team = mapping[teamId]\n\n\t\t\t\tif (team) {\n\t\t\t\t\tteams.push(team)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.warn(\"selectTeamsByIds: No team exists with the id\", teamId)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn fallbackToEmptyArray(teams)\n\t\t},\n\t),\n)\n\nexport const selectTeamsOfOrganization: OvermapSelectorWithArgs<Organization[\"id\"], Stored<Team>[]> =\n\trestructureCreateSelectorWithArgs(\n\t\tcreateSelector(\n\t\t\t[selectTeams, (_state: OvermapRootState, organizationId: Organization[\"id\"]) => organizationId],\n\t\t\t(teams, organizationId) => {\n\t\t\t\treturn fallbackToEmptyArray(teams.filter((team) => team.organization === organizationId))\n\t\t\t},\n\t\t),\n\t)\n\nexport const selectTeamsOfUser: OvermapSelectorWithArgs<User[\"id\"], Stored<Team>[]> = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectTeams, (_state: OvermapRootState, userId: User[\"id\"]) => userId], (teams, userId) => {\n\t\treturn fallbackToEmptyArray(teams.filter((team) => team.members.includes(userId)))\n\t}),\n)\n\nexport const teamReducer: Reducer<TeamState> = teamSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { AgentUserConversation, OvermapRootState, OvermapSelector } from \"../../typings\"\nimport { restructureCreateSelectorWithArgs } from \"../../utils\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\n\nexport type AgentsState = ModelState<AgentUserConversation>\n\nconst agentUserConversationAdapter = createModelAdapter<AgentUserConversation>(\n\t(conversation) => conversation.offline_id,\n)\n\nconst initialState = agentUserConversationAdapter.getInitialState({})\n\nexport const agentsSlice = createSlice({\n\tname: \"agents\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeConversations: agentUserConversationAdapter.initialize,\n\t\taddConversation: agentUserConversationAdapter.addOne,\n\t\tsetConversation: agentUserConversationAdapter.setOne,\n\t\tupdateConversation: agentUserConversationAdapter.updateOne,\n\t},\n})\n\nexport const { initializeConversations, addConversation, setConversation, updateConversation } = agentsSlice.actions\nexport const selectConversationMapping = (state: OvermapRootState) => state.agentsReducer.instances\n\nexport const selectConversations: OvermapSelector<AgentUserConversation[]> = createSelector(\n\t[selectConversationMapping],\n\t(conversationMapping) => Object.values(conversationMapping),\n)\n\nexport const selectConversation = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectConversationMapping, (_state, conversationId: string) => conversationId],\n\t\t(conversationMapping, conversationId) => conversationMapping[conversationId],\n\t),\n)\n\nexport const agentsReducer: Reducer<AgentsState> = agentsSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { ModelState } from \"../typings\"\nimport type { IssueComment, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type IssueCommentState = ModelState<Stored<IssueComment>>\n\nconst issueCommentAdapter = createModelAdapter<Stored<IssueComment>>((comment) => comment.offline_id)\n\nconst initialState: IssueCommentState = issueCommentAdapter.getInitialState({})\n\nexport const issueCommentSlice = createSlice({\n\tname: \"issueComments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\taddIssueComment: issueCommentAdapter.addOne,\n\t\taddIssueComments: issueCommentAdapter.addMany,\n\t\tsetIssueComment: issueCommentAdapter.setOne,\n\t\tsetIssueComments: issueCommentAdapter.setMany,\n\t\tdeleteIssueComment: issueCommentAdapter.deleteOne,\n\t\tdeleteIssueComments: issueCommentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tsetIssueComments,\n\tsetIssueComment,\n\taddIssueComment,\n\taddIssueComments,\n\tdeleteIssueComment,\n\tdeleteIssueComments,\n} = issueCommentSlice.actions\n\nexport const selectIssueCommentMapping = (state: OvermapRootState) => state.issueCommentReducer.instances\n\nexport const selectIssueCommentById: OvermapSelectorWithArgs<string, Stored<IssueComment> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.issueCommentReducer.instances[id]\n\t}\n\nexport const selectCommentsOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectIssueCommentMapping, (_state, issueId: string) => issueId], (commentMapping, issueId) => {\n\t\treturn fallbackToEmptyArray(Object.values(commentMapping).filter((comment) => comment.issue === issueId))\n\t}),\n)\n\nexport const issueCommentReducer: Reducer<IssueCommentState> = issueCommentSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { IssueUpdate, OvermapRootState, Stored } from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type IssueUpdateState = ModelState<Stored<IssueUpdate>>\n\nconst issueUpdateAdapter = createModelAdapter<Stored<IssueUpdate>>((issueUpdate) => issueUpdate.offline_id)\n\nconst initialState: IssueUpdateState = issueUpdateAdapter.getInitialState({})\n\nexport const issueUpdateSlice = createSlice({\n\tname: \"issueUpdates\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeIssueUpdates: issueUpdateAdapter.setMany,\n\t\tsetIssueUpdate: issueUpdateAdapter.setOne,\n\t\taddIssueUpdate: issueUpdateAdapter.addOne,\n\t\taddIssueUpdates: issueUpdateAdapter.addMany,\n\t\tdeleteIssueUpdate: issueUpdateAdapter.deleteOne,\n\t\tdeleteIssueUpdates: issueUpdateAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeIssueUpdates,\n\tsetIssueUpdate,\n\taddIssueUpdate,\n\taddIssueUpdates,\n\tdeleteIssueUpdate,\n\tdeleteIssueUpdates,\n} = issueUpdateSlice.actions\n\nexport const selectIssueUpdateMapping = (state: OvermapRootState) => state.issueUpdateReducer.instances\n\nexport const selectIssueUpdatesOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueUpdateMapping, (_state: OvermapRootState, issueId: string) => issueId],\n\t\t(updates, issueId) => {\n\t\t\treturn fallbackToEmptyArray(Object.values(updates).filter((update) => update.issue === issueId))\n\t\t},\n\t),\n)\n\nexport const issueUpdateReducer: Reducer<IssueUpdateState> = issueUpdateSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { IssueAttachment, OvermapRootState, OvermapSelector, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport type { ModelState } from \"../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type IssueAttachmentState = ModelState<Stored<IssueAttachment>>\n\nconst issueAttachmentAdapter = createModelAdapter<Stored<IssueAttachment>>((attachment) => attachment.offline_id)\n\nconst initialState: IssueAttachmentState = issueAttachmentAdapter.getInitialState({})\n\nexport const issueAttachmentSlice = createSlice({\n\tname: \"issueAttachments\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeIssueAttachments: issueAttachmentAdapter.initialize,\n\t\taddIssueAttachment: issueAttachmentAdapter.addOne,\n\t\taddIssueAttachments: issueAttachmentAdapter.addMany,\n\t\tsetIssueAttachment: issueAttachmentAdapter.setOne,\n\t\tsetIssueAttachments: issueAttachmentAdapter.setMany,\n\t\tupdateIssueAttachment: issueAttachmentAdapter.updateOne,\n\t\tupdateIssueAttachments: issueAttachmentAdapter.updateMany,\n\t\tdeleteIssueAttachment: issueAttachmentAdapter.deleteOne,\n\t\tdeleteIssueAttachments: issueAttachmentAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeIssueAttachments,\n\taddIssueAttachment,\n\taddIssueAttachments,\n\tsetIssueAttachment,\n\tsetIssueAttachments,\n\tupdateIssueAttachment,\n\tupdateIssueAttachments,\n\tdeleteIssueAttachment,\n\tdeleteIssueAttachments,\n} = issueAttachmentSlice.actions\n\nexport const selectIssueAttachmentMapping = (state: OvermapRootState) => state.issueAttachmentReducer.instances\nexport const selectIssueAttachments: OvermapSelector<Stored<IssueAttachment>[]> = createSelector(\n\t[selectIssueAttachmentMapping],\n\t(mapping) => Object.values(mapping),\n)\n\nexport const selectAttachmentsOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueAttachments, (_state: OvermapRootState, issueId: string) => issueId],\n\t\t(attachments, issueId) => {\n\t\t\treturn fallbackToEmptyArray(attachments.filter(({ issue }) => issueId === issue))\n\t\t},\n\t),\n)\n\nexport const selectIssueAttachmentById: OvermapSelectorWithArgs<string, Stored<IssueAttachment> | undefined> =\n\t(id) => (root) => {\n\t\treturn root.issueAttachmentReducer.instances[id]\n\t}\n\nexport const selectAttachmentsOfIssueByType = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueAttachments, (_state: OvermapRootState, issueId: string) => issueId],\n\t\t(attachments, issueId) => {\n\t\t\tconst attachmentsOfIssue = attachments.filter(({ issue }) => issue === issueId)\n\t\t\tconst fileAttachments = attachmentsOfIssue.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => !file_type || !file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\tconst imageAttachments = attachmentsOfIssue.filter(\n\t\t\t\t// this null check here is necessary, there are cases where file_type is null or undefined\n\t\t\t\t({ file_type }) => file_type && file_type.startsWith(\"image/\"),\n\t\t\t)\n\t\t\treturn { fileAttachments, imageAttachments }\n\t\t},\n\t),\n)\n\nexport const issueAttachmentReducer: Reducer<IssueAttachmentState> = issueAttachmentSlice.reducer\n","import { createSlice, Reducer } from \"@reduxjs/toolkit\"\n\nexport interface VersioningState {\n\tversion: number\n}\n\nconst initialState: VersioningState = {\n\tversion: 0,\n}\n\n/**\n * Version of the offline redux store\n */\nexport const versioningSlice = createSlice({\n\tname: \"versioning\",\n\tinitialState,\n\treducers: {},\n})\n\nexport const versioningReducer: Reducer<VersioningState> = versioningSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { GeoImage, OvermapRootState, Stored } from \"../../typings\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\n\nexport type GeoImageSliceState = ModelState<Stored<GeoImage>>\n\nconst geoImageAdapter = createModelAdapter<GeoImage>((model) => model.offline_id)\n\nconst initialState: GeoImageSliceState = geoImageAdapter.getInitialState({})\n\nexport const geoImageSlice = createSlice({\n\tname: \"geoImages\",\n\tinitialState,\n\textraReducers: (builder) => {\n\t\tbuilder.addCase(\"RESET\", (state) => {\n\t\t\tObject.assign(state, initialState)\n\t\t})\n\t},\n\treducers: {\n\t\tinitializeGeoImages: geoImageAdapter.initialize,\n\t\tsetGeoImage: geoImageAdapter.setOne,\n\t\tsetGeoImages: geoImageAdapter.setMany,\n\t\taddGeoImage: geoImageAdapter.addOne,\n\t\taddGeoImages: geoImageAdapter.addMany,\n\t\tupdateGeoImage: geoImageAdapter.updateOne,\n\t\tupdateGeoImages: geoImageAdapter.updateMany,\n\t\tdeleteGeoImage: geoImageAdapter.deleteOne,\n\t\tdeleteGeoImages: geoImageAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeGeoImages,\n\tsetGeoImage,\n\tsetGeoImages,\n\taddGeoImage,\n\taddGeoImages,\n\tupdateGeoImage,\n\tupdateGeoImages,\n\tdeleteGeoImage,\n\tdeleteGeoImages,\n} = geoImageSlice.actions\n\nexport const selectGeoImageMapping = (state: OvermapRootState) => state.geoImageReducer.instances\n\nexport const selectGeoImages = (state: OvermapRootState) => Object.values(state.geoImageReducer.instances)\n\nexport const selectGeoImageById = (id: string) => (state: OvermapRootState) => {\n\treturn state.geoImageReducer.instances[id]\n}\n\nexport const selectGeoImagesOfProject = restructureCreateSelectorWithArgs(\n\tcreateSelector([selectGeoImages, (_, projectId: number) => projectId], (mapImages, projectId) => {\n\t\treturn fallbackToEmptyArray(mapImages.filter((mapImage) => mapImage.project === projectId))\n\t}),\n)\n\nexport const geoImageReducer: Reducer<GeoImageSliceState> = geoImageSlice.reducer\n","import { createSelector, createSlice, Reducer } from \"@reduxjs/toolkit\"\nimport type { IssueAssociation, OvermapRootState, OvermapSelectorWithArgs, Stored } from \"../../typings\"\nimport { fallbackToEmptyArray, restructureCreateSelectorWithArgs } from \"../../utils\"\nimport { createModelAdapter } from \"../adapter\"\nimport type { ModelState } from \"../typings\"\n\nexport type IssueAssociationSliceState = ModelState<Stored<IssueAssociation>>\n\nconst issueAssociationAdapter = createModelAdapter<Stored<IssueAssociation>>((assoc) => assoc.offline_id)\n\nconst initialState: IssueAssociationSliceState = issueAssociationAdapter.getInitialState({})\n\nexport const issueAssociationSlice = createSlice({\n\tname: \"issueAssociations\",\n\tinitialState,\n\textraReducers: (builder) => builder.addCase(\"RESET\", (state) => Object.assign(state, initialState)),\n\treducers: {\n\t\tinitializeIssueAssociations: issueAssociationAdapter.initialize,\n\t\taddIssueAssociation: issueAssociationAdapter.addOne,\n\t\taddIssueAssociations: issueAssociationAdapter.addMany,\n\t\tsetIssueAssociation: issueAssociationAdapter.setOne,\n\t\tsetIssueAssociations: issueAssociationAdapter.setMany,\n\t\tupdateIssueAssociation: issueAssociationAdapter.updateOne,\n\t\tupdateIssueAssociations: issueAssociationAdapter.updateMany,\n\t\tdeleteIssueAssociation: issueAssociationAdapter.deleteOne,\n\t\tdeleteIssueAssociations: issueAssociationAdapter.deleteMany,\n\t},\n})\n\nexport const {\n\tinitializeIssueAssociations,\n\tsetIssueAssociations,\n\tsetIssueAssociation,\n\tupdateIssueAssociation,\n\tupdateIssueAssociations,\n\taddIssueAssociation,\n\taddIssueAssociations,\n\tdeleteIssueAssociation,\n\tdeleteIssueAssociations,\n} = issueAssociationSlice.actions\n\nexport const selectIssueAssociationMapping = (state: OvermapRootState): Record<string, Stored<IssueAssociation>> =>\n\tstate.issueAssociationReducer.instances\n\nexport const selectIssueAssociations = createSelector([selectIssueAssociationMapping], (associations) => {\n\treturn Object.values(associations)\n})\n\nexport const selectIssueAssociationById: OvermapSelectorWithArgs<string, Stored<IssueAssociation> | undefined> =\n\t(id) => (state) => {\n\t\treturn state.issueAssociationReducer.instances[id]\n\t}\n\nexport const selectIssueAssociationsToIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueAssociationMapping, (_state, issueId: string) => issueId],\n\t\t(associationMapping, issueId) => {\n\t\t\treturn fallbackToEmptyArray(\n\t\t\t\tObject.values(associationMapping).filter((assoc) => assoc.associated_issue === issueId),\n\t\t\t)\n\t\t},\n\t),\n)\n\nexport const selectIssueAssociationsOfIssue = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueAssociationMapping, (_state, issueId: string) => issueId],\n\t\t(associationMapping, issueId) => {\n\t\t\treturn fallbackToEmptyArray(Object.values(associationMapping).filter((assoc) => assoc.issue === issueId))\n\t\t},\n\t),\n)\n\nexport const selectIssueAssociationsOfAsset = restructureCreateSelectorWithArgs(\n\tcreateSelector(\n\t\t[selectIssueAssociationMapping, (_state, assetId: string) => assetId],\n\t\t(associationMapping, assetId) => {\n\t\t\treturn fallbackToEmptyArray(Object.values(associationMapping).filter((assoc) => assoc.asset === assetId))\n\t\t},\n\t),\n)\n\nexport const issueAssociationReducer: Reducer<IssueAssociationSliceState> = issueAssociationSlice.reducer\n","import { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore\"\nimport type { BaseState } from \"../typings\"\nimport type { BaseSDK } from \"./base\"\n\n/** The client store is the store passed to the SDKProvider\n * and is used where the SDKProvider is not available.\n */\nlet clientStore: ToolkitStore<BaseState> | undefined\n\nexport function setClientStore<TState extends BaseState>(store: ToolkitStore<TState>) {\n\tclientStore = store\n}\n\nexport function getClientStore(): ToolkitStore<BaseState> | undefined {\n\treturn clientStore\n}\n\nlet clientSDK: BaseSDK<BaseState> | undefined\n\nexport function setClientSDK<TState extends BaseState>(sdkCtor: BaseSDK<TState>) {\n\tclientSDK = sdkCtor\n}\n\nexport function getClientSDK(): BaseSDK<BaseState> | undefined {\n\treturn clientSDK\n}\n","import { AnyAction } from \"@reduxjs/toolkit\"\nimport type { BaseSDK } from \"../base\"\nimport type { BaseState } from \"../../typings\"\nimport type { SDKRequest } from \"../typings\"\n\nexport const CLASS_NAME_TO_SERVICE: Record<string, BaseService<BaseState, BaseSDK<BaseState>>> = {}\n\n/**\n * Abstract base class for building a service that can enqueue API requests\n */\nexport abstract class BaseService<TStore extends BaseState, TSDK extends BaseSDK<TStore>> {\n\tprotected readonly client: TSDK\n\tabstract readonly host: string\n\n\tprotected constructor(sdk: TSDK) {\n\t\tCLASS_NAME_TO_SERVICE[this.constructor.name] = this\n\t\tthis.client = sdk\n\t}\n\n\tprotected async enqueueRequest<TResult>(requestDetails: SDKRequest): Promise<TResult> {\n\t\t// enqueueRequest is a wrapper for _enqueueRequest that ensures the result is not an APIError unless\n\t\t// `.catch()` is triggered.\n\t\treturn this.client.enqueueRequest(requestDetails, this.host, this.constructor.name)\n\t}\n\n\tprotected dispatch(action: AnyAction) {\n\t\tthis.client.store.dispatch(action)\n\t}\n}\n","import { compose, Reducer } from \"redux\"\nimport { offline } from \"@redux-offline/redux-offline\"\nimport offlineConfig from \"@redux-offline/redux-offline/lib/defaults\"\nimport localforage from \"localforage\"\n\n// TODO: Fix\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-expect-error\nimport createMigration from \"redux-persist-migrate\"\n\nimport { combineReducers } from \"@reduxjs/toolkit\"\nimport {\n\tConfig,\n\tOfflineAction,\n\tOfflineMetadata,\n\tOfflineState,\n\tResultAction,\n} from \"@redux-offline/redux-offline/lib/types\"\nimport request from \"superagent\"\nimport { HttpMethod } from \"../enums\"\nimport { manifest } from \"./migrations\"\n\n// There are two \"blobs\": The Blob type from the \"buffer\" package (part of node),\n// and the Blob type from the browser. For some reason, superagent uses the \"buffer\"\n// version after moving code from hemora-web to overmap-core. This overwrites the name\n// \"Blob\". There are minor differences between the two interfaces (remove the type casting\n// of the `file` argument to `req.field()` in performRequest() to see the error), but it's\n// unlikely that we'll run into any problems.\nimport { Blob } from \"buffer\"\nimport {\n\tAPIError,\n\tBaseApiService,\n\ttype BaseSDK,\n\ttype OfflineMetaEffect,\n\tOutboxCoordinator,\n\tRequestDetails,\n} from \"../sdk\"\nimport { ToastProps, unsafeShowToast } from \"@overmap-ai/blocks\"\nimport {\n\t_setLatestRetryTime,\n\tagentsReducer,\n\tAgentsState,\n\tassetAttachmentReducer,\n\tAssetAttachmentState,\n\tassetReducer,\n\tassetStageCompletionReducer,\n\tAssetStageCompletionState,\n\tassetStageReducer,\n\tAssetStageState,\n\tAssetState,\n\tassetTypeAttachmentReducer,\n\tAssetTypeAttachmentState,\n\tassetTypeReducer,\n\tAssetTypeState,\n\tauthReducer,\n\tAuthState,\n\tcategoryReducer,\n\tCategoryState,\n\tdocumentAttachmentReducer,\n\tDocumentAttachmentState,\n\tdocumentsReducer,\n\tDocumentState,\n\temailDomainsReducer,\n\tEmailDomainState,\n\tfileReducer,\n\tFileState,\n\tformReducer,\n\tformRevisionAttachmentReducer,\n\tFormRevisionAttachmentState,\n\tformRevisionReducer,\n\tFormRevisionState,\n\tFormState,\n\tformSubmissionAttachmentReducer,\n\tFormSubmissionAttachmentState,\n\tformSubmissionReducer,\n\tFormSubmissionState,\n\tgeoImageReducer,\n\tGeoImageSliceState,\n\tissueAssociationReducer,\n\tIssueAssociationSliceState,\n\tissueAttachmentReducer,\n\tIssueAttachmentState,\n\tissueCommentReducer,\n\tIssueCommentState,\n\tissueReducer,\n\tIssueState,\n\tissueTypeReducer,\n\tIssueTypeState,\n\tissueUpdateReducer,\n\tIssueUpdateState,\n\tlicenseReducer,\n\tLicenseState,\n\tmarkAsDeleted,\n\torganizationAccessReducer,\n\tOrganizationAccessState,\n\torganizationReducer,\n\tOrganizationState,\n\toutboxReducer,\n\tOutboxState,\n\tprojectAccessReducer,\n\tProjectAccessState,\n\tprojectAttachmentReducer,\n\tProjectAttachmentState,\n\tprojectFileReducer,\n\tProjectFileState,\n\tprojectReducer,\n\tProjectState,\n\trehydratedReducer,\n\tRehydratedState,\n\tteamReducer,\n\tTeamState,\n\tuserReducer,\n\tUserState,\n\tversioningReducer,\n\tVersioningState,\n\tworkspaceReducer,\n\tWorkspaceState,\n} from \"./slices\"\nimport { OUTBOX_RETRY_DELAY } from \"../constants\"\nimport type { BaseState, OvermapRootState } from \"../typings\"\nimport { getClientSDK, getClientStore } from \"../sdk/globals\"\nimport { CLASS_NAME_TO_SERVICE } from \"../sdk/services/BaseService\"\n\n// NOTE: If changing, also change it in migrations.ts (avoid circular imports)\nexport const VERSION_REDUCER_KEY = \"versioning\"\n\nexport const overmapReducers = {\n\t// TODO: attachmentReducer,\n\t[VERSION_REDUCER_KEY]: versioningReducer,\n\tfileReducer,\n\tauthReducer,\n\tcategoryReducer,\n\tassetReducer,\n\tassetAttachmentReducer,\n\tassetStageCompletionReducer,\n\tassetStageReducer,\n\tassetTypeReducer,\n\tassetTypeAttachmentReducer,\n\tissueReducer,\n\tissueAttachmentReducer,\n\tissueTypeReducer,\n\torganizationReducer,\n\toutboxReducer,\n\tprojectReducer,\n\tprojectAttachmentReducer,\n\tprojectAccessReducer,\n\torganizationAccessReducer,\n\tprojectFileReducer,\n\trehydratedReducer,\n\tformReducer,\n\tformRevisionReducer,\n\tformRevisionAttachmentReducer,\n\tformSubmissionAttachmentReducer,\n\tformSubmissionReducer,\n\tuserReducer,\n\tworkspaceReducer,\n\temailDomainsReducer,\n\tlicenseReducer,\n\tdocumentsReducer,\n\tdocumentAttachmentReducer,\n\tteamReducer,\n\tagentsReducer,\n\tissueCommentReducer,\n\tissueUpdateReducer,\n\tgeoImageReducer,\n\tissueAssociationReducer,\n} as {\n\tversioning: Reducer<VersioningState>\n\tfileReducer: Reducer<FileState>\n\tauthReducer: Reducer<AuthState>\n\tcategoryReducer: Reducer<CategoryState>\n\tassetReducer: Reducer<AssetState>\n\tassetAttachmentReducer: Reducer<AssetAttachmentState>\n\tassetStageCompletionReducer: Reducer<AssetStageCompletionState>\n\tassetStageReducer: Reducer<AssetStageState>\n\tassetTypeReducer: Reducer<AssetTypeState>\n\tassetTypeAttachmentReducer: Reducer<AssetTypeAttachmentState>\n\tissueReducer: Reducer<IssueState>\n\tissueTypeReducer: Reducer<IssueTypeState>\n\torganizationReducer: Reducer<OrganizationState>\n\toutboxReducer: Reducer<OutboxState>\n\tprojectReducer: Reducer<ProjectState>\n\tprojectAttachmentReducer: Reducer<ProjectAttachmentState>\n\tprojectAccessReducer: Reducer<ProjectAccessState>\n\torganizationAccessReducer: Reducer<OrganizationAccessState>\n\tprojectFileReducer: Reducer<ProjectFileState>\n\trehydratedReducer: Reducer<RehydratedState>\n\tformReducer: Reducer<FormState>\n\tuserReducer: Reducer<UserState>\n\tformRevisionReducer: Reducer<FormRevisionState>\n\tformRevisionAttachmentReducer: Reducer<FormRevisionAttachmentState>\n\tformSubmissionAttachmentReducer: Reducer<FormSubmissionAttachmentState>\n\tformSubmissionReducer: Reducer<FormSubmissionState>\n\tworkspaceReducer: Reducer<WorkspaceState>\n\temailDomainsReducer: Reducer<EmailDomainState>\n\tlicenseReducer: Reducer<LicenseState>\n\tdocumentsReducer: Reducer<DocumentState>\n\tdocumentAttachmentReducer: Reducer<DocumentAttachmentState>\n\tteamReducer: Reducer<TeamState>\n\tagentsReducer: Reducer<AgentsState>\n\tissueCommentReducer: Reducer<IssueCommentState>\n\tissueUpdateReducer: Reducer<IssueUpdateState>\n\tissueAttachmentReducer: Reducer<IssueAttachmentState>\n\tgeoImageReducer: Reducer<GeoImageSliceState>\n\tissueAssociationReducer: Reducer<IssueAssociationSliceState>\n}\n\nconst overmapReducer = combineReducers(overmapReducers)\n\n// Special action to revert all slices to their initial state. A reducer for this is added to each slice using\n// `extraReducers` in the slice definition.\nexport const resetStore = \"RESET\"\n\n// NOTE: Leaving this here for now until stories are removed from /core which requires a store to be set up.\n// not being used in /web\nexport const overmapRootReducer: Reducer<OvermapRootState> = (state, action): OvermapRootState => {\n\t// TODO: dont know if this is needed?\n\tif (action.type === \"auth/setLoggedIn\" && !action.payload) {\n\t\treturn overmapReducer(undefined, action) as OvermapRootState\n\t}\n\n\treturn overmapReducer(state, action) as OvermapRootState\n}\n\nexport interface FullOfflineMetadata extends OfflineMetadata {\n\teffect: OfflineMetaEffect\n}\n\nexport interface FullOfflineAction extends OfflineAction {\n\tmeta: { offline: FullOfflineMetadata }\n\t// Redundantly store request details in the unused `payload` property to make TypeScript happy\n\tpayload: RequestDetails\n}\n\nlet __OUTBOX_COORDINATOR: OutboxCoordinator | null = null\n\nexport function getOutboxCoordinator(): OutboxCoordinator | null {\n\tconst clientStore = getClientStore()\n\tif (!clientStore) {\n\t\tconsole.warn(\"Client store not set; cannot get outbox coordinator yet.\")\n\t\treturn null\n\t}\n\tif (__OUTBOX_COORDINATOR) {\n\t\treturn __OUTBOX_COORDINATOR\n\t}\n\tconst outbox = clientStore.getState().offline.outbox\n\tconst coordinator = OutboxCoordinator._fromOutbox(outbox)\n\t__OUTBOX_COORDINATOR = coordinator\n\treturn coordinator\n}\n\n// This callback is run when the Redux store has finished rehydrating itself from localForage\n// We signal to the rest of the app that hydration has finished\nconst persistCallback = (err: null | Error) => {\n\tif (err) throw err\n\tconst clientStore = getClientStore()\n\tif (clientStore) {\n\t\tclientStore.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\n\t} else {\n\t\tconsole.error(\"Client store not set\")\n\t}\n}\n\nexport const enqueue: Config[\"queue\"][\"enqueue\"] = (_array, item, _context) => {\n\tconst coordinator = getOutboxCoordinator()\n\tif (!coordinator) {\n\t\tconsole.warn(\"Outbox coordinator not set; cannot enqueue request yet.\")\n\t\treturn []\n\t}\n\tcoordinator.addRequest(item as FullOfflineAction)\n\treturn coordinator.getQueue()\n}\n\nexport const dequeue: Config[\"queue\"][\"dequeue\"] = (_array, item, _context) => {\n\tconst coordinator = getOutboxCoordinator()\n\tif (!coordinator) {\n\t\tconsole.warn(\"Outbox coordinator not set; cannot dequeue request yet.\")\n\t\treturn []\n\t}\n\t// The redux-offline type leaves out the \"offlineAction\" property\n\ttype BadMetaType = ResultAction[\"meta\"]\n\ttype CorrectedMetaType = BadMetaType & { offlineAction: FullOfflineAction }\n\tconst meta = item.meta as CorrectedMetaType\n\tconst uuid = meta.offlineAction.payload.uuid\n\tcoordinator.remove(uuid)\n\treturn coordinator.getQueue()\n}\n\n// This is called an \"effect reconciler\", and it turns an offline action into a real API request\nasync function effect(_effect: OfflineMetaEffect, action: FullOfflineAction) {\n\t// REASON: Handling of unexpected case\n\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\tif (!action.payload) {\n\t\tthrow new Error(\"Received empty payload\")\n\t}\n\n\t// We pass the action through a chain of middleware, which can do some useful things and then perform the action.\n\t// `runMiddleware` returns a Promise<Response> if everything goes well.\n\treturn runMiddleware(action)\n}\n\nconst customConfig: Partial<Config> = {\n\t...offlineConfig,\n\teffect: effect as Config[\"effect\"],\n\t// Casting needed because we are saving FullOfflineAction objects, not just OfflineAction objects,\n\t// but redux-offline does not know this.\n\tdiscard: discard as Config[\"discard\"],\n\treturnPromises: true,\n\tpersistCallback,\n\tretry: retry as Config[\"retry\"],\n\t// Modify the configuration of the offline store to use localforage\n\t// which uses IndexedDB by default (persists even on mobile when installed as a PWA, unlike localStorage)\n\tpersistOptions: { storage: localforage },\n\t// TODO: custom enqueue implementation to take care of intelligently cancelling \"create/delete same issue\",\n\t// and custom dequeue for e.g. if user insists on removing a failed a \"create issue\", then remove the \"edit\n\t// that same issue\"\n\tqueue: {\n\t\t...offlineConfig.queue,\n\t\tenqueue,\n\t\tdequeue,\n\t\t// Bad typing, undefined is actually fine, and the action is a FullOfflineAction, not just an OfflineAction.\n\t\tpeek: (...args) => peek(...(args as Parameters<typeof peek>))!,\n\t} satisfies Config[\"queue\"],\n}\n\n// migration to compose into store\nconst migration = createMigration(manifest, VERSION_REDUCER_KEY) as (_: unknown) => unknown\n\n/**\n * Enhancer for the Redux store that adds offline support and needed middleware for overmap.\n * Add to your store's `enhancers` array.\n */\nexport const overmapEnhancer = compose(offline(customConfig), migration)\n\n/**\n * Makes a best-effort attempt to extract a request.Response from an error object.\n * @param error The error object\n */\nfunction extractResponseFromError(error: unknown): request.Response | undefined {\n\tfunction isResponse(response: unknown): response is request.Response {\n\t\t// Just some keys we know are on a request.Response\n\t\tconst knownKeys = [\"ok\", \"redirect\", \"clientError\", \"serverError\", \"error\"]\n\t\treturn typeof response === \"object\" && response !== null && knownKeys.every((key) => key in response)\n\t}\n\n\tif (isResponse(error)) return error\n\tif (typeof error === \"object\" && error !== null) {\n\t\tconst typedError = error as { response?: { response?: request.Response } }\n\t\tif (isResponse(typedError.response)) return typedError.response\n\t\tif (typedError.response && isResponse(typedError.response.response)) return typedError.response.response\n\t}\n\treturn undefined\n}\n\n// Executes an offline action by making the API request specified in the action's offline metadata\nexport async function performRequest(action: FullOfflineAction, client: BaseSDK<BaseState>): Promise<request.Response> {\n\tconst serviceOfRequest = CLASS_NAME_TO_SERVICE[action.meta.offline.effect.serviceName]\n\n\tif (!serviceOfRequest) {\n\t\tthrow new Error(`Service ${action.meta.offline.effect.serviceName} not found`)\n\t}\n\n\tconst isApiService = serviceOfRequest instanceof BaseApiService\n\n\tconst state = client.store.getState()\n\tif (state.outboxReducer.deletedRequests.includes(action.payload.uuid)) {\n\t\t// The request has been marked for deletion, so we don't want to perform it.\n\t\t// Instead, throw an error, so it will be retried and discarded in the `discard` function.\n\t\tthrow new Error(\"Request was marked for deletion\")\n\t}\n\n\tif (isApiService && action.payload.checkAuth !== false) {\n\t\tawait serviceOfRequest.auth.prepareAuth()\n\t}\n\n\tconst defaultSettings = {\n\t\tqueryParams: \"\",\n\t\tisAuthNeeded: true,\n\t}\n\n\tconst offlineEffect = action.meta.offline.effect\n\tconst { payload, headers, method, queryParams, attachmentHash, isExternalUrl, isAuthNeeded, isResponseBlob } = {\n\t\t...defaultSettings,\n\t\t...offlineEffect.request,\n\t}\n\tconst requestDetails = offlineEffect.request\n\tlet url = requestDetails.url\n\tconst file = attachmentHash ? await client.files.fetchCache(attachmentHash) : undefined\n\n\tif (attachmentHash && !file) {\n\t\tthrow new Error(`Cannot upload file ${attachmentHash} because it's not cached.`)\n\t}\n\n\tif ((!isExternalUrl || import.meta.env.DEV) && !url.startsWith(\"http\")) {\n\t\tif (!url.startsWith(\"/\") && !url.startsWith(\"blob:\")) {\n\t\t\turl = \"/\" + url\n\t\t\tif (import.meta.env.DEV) {\n\t\t\t\tconsole.trace(`You have passed a host-relative URL: ${url}`)\n\t\t\t}\n\t\t}\n\t\turl = action.meta.offline.effect.BASE_URL + url\n\t}\n\n\tconst addPayload = (req: request.SuperAgentRequest) => {\n\t\tif (attachmentHash) {\n\t\t\tconst s3url = requestDetails.s3url\n\t\t\tif (!s3url) throw new Error(`No S3 URL for file ${attachmentHash}`)\n\t\t\tif (\"warning\" in s3url) throw new Error(`S3 URL warning for file ${attachmentHash}`)\n\t\t\tif (!file) throw new Error(`No file for file ${attachmentHash}`)\n\t\t\tconst s3Sha1Checksum = s3url.fields[\"x-amz-checksum-sha1\"]\n\t\t\tif (!s3Sha1Checksum) throw new Error(`No checksum for file ${attachmentHash}`)\n\t\t\treturn req\n\t\t\t\t.set(\"x-amz-checksum-sha1\", s3Sha1Checksum)\n\t\t\t\t.field({ ...payload, ...s3url.fields })\n\t\t\t\t.attach(\"file\", file as unknown as Blob)\n\t\t}\n\t\treturn req.send(payload)\n\t}\n\n\tconst methodRequestMapping: Record<HttpMethod, () => request.SuperAgentRequest> = {\n\t\t[HttpMethod.GET]: () => {\n\t\t\tif (isResponseBlob) {\n\t\t\t\treturn request.get(url.toString()).responseType(\"blob\")\n\t\t\t}\n\t\t\treturn request.get(url.toString())\n\t\t},\n\t\t[HttpMethod.POST]: () => {\n\t\t\tconst ret = request.post(url.toString())\n\t\t\treturn addPayload(ret)\n\t\t},\n\t\t[HttpMethod.PATCH]: () => {\n\t\t\tconst ret = request.patch(url.toString())\n\t\t\treturn addPayload(ret)\n\t\t},\n\t\t[HttpMethod.PUT]: () => {\n\t\t\tconst ret = request.put(url.toString())\n\t\t\treturn addPayload(ret)\n\t\t},\n\t\t[HttpMethod.DELETE]: () => {\n\t\t\tconst ret = request.delete(url.toString())\n\t\t\treturn addPayload(ret)\n\t\t},\n\t}\n\n\tconst selectedRequest = methodRequestMapping[method]\n\n\tlet requestToSend = selectedRequest()\n\tif (isAuthNeeded && isApiService) {\n\t\tconst authHeader = serviceOfRequest.auth.getAuthHeader()\n\t\trequestToSend = requestToSend.set(\"Authorization\", authHeader)\n\t}\n\tif (headers) {\n\t\trequestToSend = requestToSend.set(headers)\n\t}\n\n\ttry {\n\t\treturn await requestToSend.query(queryParams)\n\t} catch (error) {\n\t\t// Observed error types: Error, request.Response\n\t\t// If it's an Error, it has a `response.response` property that is a request.Response.\n\t\tconst errorResponse = extractResponseFromError(error)\n\t\tconst status: number | undefined = errorResponse?.status\n\n\t\tif (isApiService && status === 401) {\n\t\t\tawait serviceOfRequest.auth.handleUnauthorized(requestToSend, errorResponse!)\n\t\t\treturn requestToSend.query(queryParams)\n\t\t}\n\n\t\t// TODO: Error codes for all APIErrors.\n\t\t// TODO: Constant for all messages.\n\t\tthrow new APIError({ response: errorResponse, innerError: error, discard: discardStatuses.includes(status!) })\n\t}\n}\n\ninterface MiddlewareChainer {\n\tthen: (next: OfflineMiddleware) => MiddlewareChainer\n\tcompile: () => OfflineMiddleware[]\n}\n\nclass MiddlewareChainerPrivate {\n\t_all: OfflineMiddleware[]\n\t_previous?: OfflineMiddleware\n\n\tconstructor(current: OfflineMiddleware) {\n\t\tthis._all = [current]\n\t\tthis._previous = current\n\t\tthis.then = this.then.bind(this)\n\t\tthis.compile = this.compile.bind(this)\n\t}\n\n\tthen(next: OfflineMiddleware): MiddlewareChainer {\n\t\tif (this._previous) this._previous.next = next // \"next\" is now \"current\"\n\t\tthis._all.push(next)\n\t\tthis._previous = next // \"next\" is now \"previous\"\n\n\t\treturn {\n\t\t\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\t\t\tthen: this.then,\n\t\t\t// eslint-disable-next-line @typescript-eslint/unbound-method\n\t\t\tcompile: this.compile,\n\t\t}\n\t}\n\n\tcompile() {\n\t\treturn this._all\n\t}\n}\n\nabstract class OfflineMiddleware {\n\tnext: OfflineMiddleware | null\n\n\tconstructor() {\n\t\tthis.next = null\n\t}\n\n\tthen(next: OfflineMiddleware): MiddlewareChainer {\n\t\treturn new MiddlewareChainerPrivate(this).then(next)\n\t}\n\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\n\t\tif (this.next) {\n\t\t\treturn this.next.run(action)\n\t\t} else {\n\t\t\tconsole.debug(\"Middleware finished. Performing request:\", action)\n\n\t\t\tconst clientStore = getClientStore()\n\t\t\tif (!clientStore) throw new Error(\"Client store not set\")\n\n\t\t\tconst clientSDK = getClientSDK()\n\t\t\tif (!clientSDK) throw new Error(\"Client SDK not set\")\n\n\t\t\t// At the end of the middleware chain, we want to perform the action\n\t\t\treturn performRequest(action, clientSDK)\n\t\t}\n\t}\n}\n\nclass OfflineAnalyticsMiddleware extends OfflineMiddleware {\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\n\t\t// TODO: Store some statistics on which actions are called and enqueue reports periodically\n\t\treturn super.run(action)\n\t}\n}\n\nclass RateLimitingMiddleware extends OfflineMiddleware {\n\tasync run(action: FullOfflineAction): Promise<request.Response | null> {\n\t\t// TODO: Consider rate limits (enable offline mode programmatically to reduce rate)\n\t\treturn super.run(action)\n\t}\n}\n\nconst allMiddleware = new OfflineAnalyticsMiddleware().then(new RateLimitingMiddleware()).compile()\n\nfunction runMiddleware(action: FullOfflineAction) {\n\treturn allMiddleware[0]?.run(action)\n}\n\n// These status codes are due to a fundamental problem that can never be corrected except by manual intervention.\n// TODO: 400 (Bad Request) should result in the user being given a chance to amend their request to be valid.\nconst discardStatuses = [400, 409, 403, 404, 405, 500]\nconst statusMessages: Record<number, ToastProps | undefined> = {\n\t403: { title: \"Forbidden\", description: \"You are not authorized to perform this action.\", accentColor: \"red\" },\n\t404: { title: \"Not found\", description: \"The requested resource was not found.\", accentColor: \"red\" },\n\t405: {\n\t\ttitle: \"Not supported\",\n\t\tdescription: \"It's not you. It's us. Sorry for the inconvenience.\",\n\t\taccentColor: \"red\",\n\t},\n\t500: {\n\t\ttitle: \"Server error\",\n\t\tdescription:\n\t\t\t\"Our server seems to be experiencing problems at the moment. We have been alerted and will fix the \" +\n\t\t\t\"problem as soon as possible.\",\n\t\taccentColor: \"red\",\n\t},\n}\n\n// Discard function is used by Redux Offline to decide whether to discard an action or not, based on the error\n// that the effect reconciler threw and/or the action\nexport function discard(reason: unknown, action: FullOfflineAction, retries = 0): boolean {\n\t// TODO: If 401, renew auth and return false\n\t// TODO: If 400, set state to rescue mode, allowing the user to fix the request and retry (or discard)\n\n\tconsole.debug(\n\t\t\"Considering discarding request due to error:\",\n\t\treason,\n\t\t`(${typeof reason})`,\n\t\t\"\\nAction:\",\n\t\taction,\n\t\t\"\\nRetries:\",\n\t\tretries,\n\t)\n\n\tif (!(reason instanceof Error)) {\n\t\tconsole.error(\n\t\t\t\"ENCOUNTERED NON-ERROR ERROR:\",\n\t\t\treason,\n\t\t\t\"(throwing immediately, which may lead to unexpected behavior)\",\n\t\t)\n\t\tthrow reason\n\t}\n\n\tconst clientStore = getClientStore()\n\tconst state = clientStore!.getState()\n\tconst deletedRequests = state.outboxReducer.deletedRequests\n\tconst uuid = action.payload.uuid\n\n\t// NOTE: Doesn't really return true, but TypeScript doesn't need to know that.\n\t// Adding a `return true` would be meaningless since we are throwing the passed error.\n\tfunction rollbackAndThrow(): true {\n\t\tclientStore!.dispatch(markAsDeleted(uuid))\n\t\tconst coordinator = getOutboxCoordinator()\n\t\tif (!coordinator) {\n\t\t\tthrow new Error(\"Outbox coordinator not set\")\n\t\t}\n\t\tcoordinator.remove(action.payload.uuid)\n\t\tconst rollbackAction = action.meta.offline.rollback\n\t\tif (rollbackAction) {\n\t\t\tconsole.warn(\"Rolling back request due to SDK error:\", action)\n\t\t\tclientStore!.dispatch(rollbackAction)\n\t\t}\n\t\tthrow reason\n\t}\n\n\tif (reason instanceof APIError && reason.options.discard) {\n\t\tconsole.debug(\"Discarding request due to explicit discard:\", action)\n\t\treturn rollbackAndThrow()\n\t}\n\n\tif (deletedRequests.includes(uuid)) {\n\t\tconsole.debug(\"Discarding request due to deletion:\", action)\n\t\treturn rollbackAndThrow()\n\t}\n\n\tif (reason instanceof APIError) {\n\t\tconst status: number | undefined = reason.status || reason.response?.status\n\t\tif (!status) {\n\t\t\tconsole.warn(\"Error has no status code:\", reason)\n\t\t}\n\t\tif (status !== undefined && discardStatuses.includes(status)) {\n\t\t\tconsole.warn(\"Discarding request due to error:\", reason, \"\\nAction:\", action)\n\t\t\tconst message = statusMessages[status]\n\t\t\tif (message) {\n\t\t\t\tif (unsafeShowToast) {\n\t\t\t\t\tunsafeShowToast(message)\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(`Could not display toast for status ${status} because there is no toast handle.`)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst coordinator = getOutboxCoordinator()\n\t\t\tif (!coordinator) {\n\t\t\t\tthrow new Error(\"Outbox coordinator not set\")\n\t\t\t}\n\t\t\tcoordinator.remove(action.payload.uuid)\n\t\t\treason.options.discard = true\n\t\t\trollbackAndThrow()\n\t\t}\n\t}\n\n\tconsole.debug(\"Registering a retry for request:\", action.payload.uuid)\n\t// All failures due to any other reason should be retried indefinitely. It will not block the outbox thanks to\n\t// OutboxCoordinator.\n\tconst coordinator = getOutboxCoordinator()\n\tif (!coordinator) {\n\t\tthrow new Error(\"Outbox coordinator not set\")\n\t}\n\tcoordinator.registerRetry(action.payload.uuid)\n\treturn false\n}\n\n// Peek function is used by Redux Offline to determine the next action of the outbox to execute.\n// We are overriding the default implementation (return array[0]) with our own to support our graph-based outbox.\nfunction peek(\n\t_array: FullOfflineAction[],\n\t_item: unknown,\n\t_context: { offline: OfflineState },\n): OfflineAction | undefined {\n\treturn getOutboxCoordinator()?.peek()\n}\n\n// Retry function is used by Redux Offline to determine how long to retry an action, given number of retries\nfunction retry(_action: FullOfflineAction, _retries: number): number | undefined {\n\t// Always retry, but wait a few seconds after a failed request. We have our own custom discard/retry logic.\n\tgetClientStore()!.dispatch(_setLatestRetryTime(new Date().getTime()))\n\treturn OUTBOX_RETRY_DELAY\n}\n\n// export type AppThunk<ReturnType = void> = ThunkAction<ReturnType, RootState, unknown, Action<string>>\n","// The shape of an object that describes the details of an API request\nimport { FileService } from \"./services\"\nimport { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore\"\nimport request from \"superagent\"\nimport { v4 as uuidv4 } from \"uuid\"\nimport { OfflineMetaEffect, SDKRequest } from \"./typings\"\nimport { APIError } from \"./errors\"\nimport { DeferredPromise } from \"../utils\"\nimport { discard, enqueueRequest, FullOfflineAction, performRequest } from \"../store\"\nimport type { BaseState } from \"../typings\"\n\n// This is a bundle of the services that our app uses. These can be used in tandem with the types\n// declared above in order to execute requests to the backend (queued or otherwise). To use it,\n// you can declare a \"PlaceholderName-Service.ts\" and have CRUD methods to send to the backend,\n// and call it by using `sdk.PlaceHolderName.CRUD_METHOD`\nexport abstract class BaseSDK<TState extends BaseState> {\n\treadonly store: ToolkitStore<TState>\n\tabstract readonly files: FileService<TState, BaseSDK<TState>>\n\n\tprotected constructor(store: ToolkitStore<TState>) {\n\t\tthis.store = store\n\t}\n\n\tpublic async enqueueRequest<TResult>(\n\t\trequestDetails: SDKRequest,\n\t\thost: string,\n\t\tserviceName: string,\n\t): Promise<TResult> {\n\t\t// enqueueRequest is a wrapper for _enqueueRequest that ensures the result is not an APIError unless\n\t\t// `.catch()` is triggered.\n\t\treturn this._enqueueRequest<TResult>(requestDetails, host, serviceName).then((result) => {\n\t\t\tif (result instanceof APIError) {\n\t\t\t\tthrow result\n\t\t\t}\n\t\t\treturn result\n\t\t})\n\t}\n\n\tprivate _enqueueRequest<TResult>(\n\t\trequestDetails: SDKRequest,\n\t\thost: string,\n\t\tserviceName: string,\n\t): DeferredPromise<TResult | APIError> {\n\t\t// We'll receive a Response object, but we want to return just the body of the response. This means\n\t\t// that we must inject a callback in the middle. We will use two promises:\n\t\tconst promise = new DeferredPromise<TResult | APIError>()\n\n\t\t// We dispatch an action that will eventually result in a request.\n\t\tconst requestDetailsWithBaseUrl = { ...requestDetails, BASE_URL: host, serviceName: serviceName }\n\n\t\tif (requestDetails.immediate) {\n\t\t\tconst requestWithUuid = {\n\t\t\t\t...requestDetailsWithBaseUrl,\n\t\t\t\tuuid: requestDetails.uuid ?? uuidv4(),\n\t\t\t}\n\t\t\t// TODO: Does this result in sending the request multiple times?\n\t\t\t// Should performRequest accept pure requestDetails?\n\t\t\t// (It shouldn't result in dupes because we're not dispatching an action.)\n\t\t\tconst fullOfflineAction: FullOfflineAction = {\n\t\t\t\tpayload: requestWithUuid,\n\t\t\t\ttype: \"\",\n\t\t\t\tmeta: {\n\t\t\t\t\toffline: {\n\t\t\t\t\t\teffect: {\n\t\t\t\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\t\t\t\trequest: requestWithUuid,\n\t\t\t\t\t\t\tBASE_URL: host,\n\t\t\t\t\t\t\tserviceName: serviceName,\n\t\t\t\t\t\t} satisfies OfflineMetaEffect,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t\tperformRequest(fullOfflineAction, this)\n\t\t\t\t.then((result) => {\n\t\t\t\t\tpromise.resolve(result.body as TResult)\n\t\t\t\t})\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tdiscard(error, fullOfflineAction)\n\t\t\t\t\tpromise.reject(error)\n\t\t\t\t})\n\t\t} else {\n\t\t\tconst innerPromise: Promise<request.Response> = this.store.dispatch(\n\t\t\t\tenqueueRequest(requestDetailsWithBaseUrl),\n\t\t\t) as unknown as Promise<request.Response>\n\n\t\t\tconst successOrUndefinedHandler = (response: request.Response | undefined) => {\n\t\t\t\tif (response) {\n\t\t\t\t\tpromise.resolve(response.body as TResult)\n\t\t\t\t} else {\n\t\t\t\t\tconst error = new APIError({\n\t\t\t\t\t\tmessage: \"Could not get a response from the server.\",\n\t\t\t\t\t\tresponse: response satisfies undefined,\n\t\t\t\t\t\tdiscard: true,\n\t\t\t\t\t})\n\t\t\t\t\tpromise.reject(error)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Handles errors from the inner promise (which performs the request) and rejects the outer promise, which has\n\t\t\t * been returned to the caller by the time this is triggered. This handler is only expected to be triggered if\n\t\t\t * the request has been discarded from the outbox.\n\t\t\t * @param error The error that caused the request to be discarded. Expected to be an APIError instance.\n\t\t\t */\n\t\t\tconst errorHandler = (error: unknown) => {\n\t\t\t\tif (error instanceof APIError) {\n\t\t\t\t\terror.options.discard = true\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\"Received an unexpected error while processing a request:\",\n\t\t\t\t\t\terror,\n\t\t\t\t\t\t\"\\nConverting error to APIError and discarding.\",\n\t\t\t\t\t)\n\t\t\t\t\terror = new APIError({\n\t\t\t\t\t\tmessage: \"An error occurred while processing the request.\",\n\t\t\t\t\t\tinnerError: error,\n\t\t\t\t\t\tdiscard: true,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tpromise.reject(error)\n\t\t\t}\n\n\t\t\tinnerPromise.then(successOrUndefinedHandler, errorHandler)\n\t\t}\n\n\t\treturn promise\n\t}\n\n\t// NOTE: these are currently expected to be present in the base SDK, not sure if that is desired\n}\n","import type { BaseSDK } from \"./base\"\nimport { ToolkitStore } from \"@reduxjs/toolkit/dist/configureStore\"\nimport type { BaseState } from \"../typings\"\nimport { setClientSDK, setClientStore } from \"./globals\"\nimport type { OvermapSDKConstructor } from \"./typings\"\n\nexport const initSDK = <TState extends BaseState, TSDK extends BaseSDK<TState>>(\n\tstore: ToolkitStore<TState>,\n\tsdk: OvermapSDKConstructor<TState, TSDK>,\n) => {\n\tconst sdkInstance = new sdk(store)\n\tsetClientSDK(sdkInstance)\n\tsetClientStore(store)\n\n\treturn sdkInstance\n}\n","import { Response, SuperAgentRequest } from \"superagent\"\nimport type { BaseState } from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseService } from \"./BaseService\"\n\nexport abstract class BaseAuthService<TStore extends BaseState, TSDK extends BaseSDK<TStore>> extends BaseService<\n\tTStore,\n\tTSDK\n> {\n\tprotected constructor(sdk: TSDK) {\n\t\tsuper(sdk)\n\t}\n\n\tabstract initAuth(payload: object): Promise<void>\n\n\tabstract clearAuth(): void\n\n\tabstract prepareAuth(): Promise<void>\n\n\tabstract getAuthHeader(): string\n\n\tabstract handleUnauthorized(request: SuperAgentRequest, response: Response): Promise<void>\n}\n","import { markForDeletion, resetStore, setLoggedIn } from \"../../store\"\nimport { RESET_STATE } from \"@redux-offline/redux-offline/lib/constants\"\nimport request from \"superagent\"\nimport jwtDecode, { JwtPayload } from \"jwt-decode\"\nimport type { BaseState } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport { v4 as uuidv4 } from \"uuid\"\nimport { APIError } from \"../errors\"\nimport type { BaseSDK } from \"../base\"\nimport type { TokenPair } from \"../typings\"\nimport { BaseAuthService } from \"./BaseAuthService\"\n\n// Number of seconds until expiry that we consider as \"expiring soon\"\nconst EXPIRING_SOON_THRESHOLD = 1800\n\n// TODO: Rename `accessToken` and `refreshToken` to `access` and `refresh` respectively, then remove this function and\n// just return the response directly.\nfunction parseTokens(response: { access: string; refresh: string }): TokenPair {\n\tif (!response.access) throw new Error(\"Missing access token\")\n\tif (!response.refresh) throw new Error(\"Missing refresh token\")\n\treturn { accessToken: response.access, refreshToken: response.refresh }\n}\n\n/**\n * Handles login, logout and renewing tokens\n */\nexport abstract class JWTService<TState extends BaseState, TSDK extends BaseSDK<TState>> extends BaseAuthService<\n\tTState,\n\tTSDK\n> {\n\t// AUTH below\n\tprotected abstract initTokensUrl: string\n\tprotected abstract refreshTokensUrl: string\n\tprotected abstract setTokens: (tokens: TokenPair) => void\n\tprotected abstract clearTokens: () => void\n\tprotected abstract getAccessToken: () => string\n\tprotected abstract getRefreshToken: () => string\n\n\t// _getTokenPair and _getRenewedTokens don't need to use enqueueRequest from the BaseApiService because\n\t// they are very simple. However, if we need robust error handling or want these operations to queue in the Outbox,\n\t// we will use enqueueRequest.\n\n\t/**\n\t * Takes refresh token and gets a new token pair\n\t * @async\n\t * @param {string} refreshToken The refresh token used to get new tokens\n\t * @returns {Promise<TokenPair>} The new access and refresh tokens\n\t */\n\tprivate _getRenewedTokens = async (refreshToken: string): Promise<TokenPair | undefined> => {\n\t\tinterface MaybeTokenPair {\n\t\t\taccess?: string\n\t\t\trefresh?: string\n\t\t}\n\n\t\tconst promise = this.enqueueRequest<MaybeTokenPair>({\n\t\t\tdescription: \"Get renewed tokens\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: this.refreshTokensUrl,\n\t\t\tpayload: { refresh: refreshToken },\n\t\t\tisAuthNeeded: false,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t\t// Don't wait for an auth check since this is a refresh token request.\n\t\t\tcheckAuth: false,\n\t\t\t// Don't wait for other requests to finish, or we might end up in a deadlock.\n\t\t\timmediate: true,\n\t\t})\n\n\t\tlet response: MaybeTokenPair | undefined = undefined\n\t\ttry {\n\t\t\tresponse = await promise\n\t\t} catch (e) {\n\t\t\t// TODO: See TODOs in `renewTokens`\n\t\t\t// Log out if the request fails\n\t\t\tconsole.error(\"Could not renew tokens; clearing auth\", e)\n\t\t\tthis.clearAuth()\n\t\t\treturn undefined\n\t\t}\n\n\t\tif (!response.access) throw new Error(\"Missing access token\")\n\n\t\treturn { accessToken: response.access, refreshToken: response.refresh ?? this.getRefreshToken() }\n\t}\n\n\t/**\n\t * Logs the user out\n\t */\n\tclearAuth() {\n\t\t// This also sends an action to the store.ts rootReducer function, allowing\n\t\t// the store to be reset upon sending an undefined state to the other\n\t\t// reducers.\n\t\tconsole.debug(this.constructor.name, \"clearing auth;\")\n\n\t\tthis.dispatch(setLoggedIn(false))\n\t\tthis.clearTokens()\n\t\t// Clear the outbox\n\t\tthis.dispatch({ type: RESET_STATE })\n\t\t// TODO: Consider using only one of the two approaches\n\t\t// For good measure:\n\t\tthis.dispatch({ type: resetStore })\n\t}\n\n\t/**\n\t * Attempts to renew tokens\n\t */\n\tasync renewTokens() {\n\t\tconst dyingRefreshToken = this.getRefreshToken()\n\t\tif (!dyingRefreshToken) {\n\t\t\tthrow new Error(\"No refresh token found\")\n\t\t}\n\n\t\tconsole.debug(this.constructor.name, \"renewing tokens\")\n\n\t\ttry {\n\t\t\tconst tokens = await this._getRenewedTokens(dyingRefreshToken)\n\t\t\tif (!tokens) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tconsole.log(\"Got renewed tokens\")\n\t\t\tthis.setTokens(tokens)\n\t\t} catch (e) {\n\t\t\t// TODO: Why is this not being triggered when the request fails inside _getRenewedTokens?\n\t\t\t// TODO: This is temporary behaviour, replace it with login button on outbox failed requests\n\t\t\t// that failed because of a 401 Unauthorized\n\t\t\tconsole.error(\"Could not renew tokens; clearing auth\", e)\n\t\t\tthis.clearAuth()\n\t\t\tthrow e\n\t\t}\n\t}\n\n\ttokenIsExpiringSoon(): boolean {\n\t\tconst accessToken = this.getAccessToken()\n\t\tif (!accessToken) {\n\t\t\t// If the access token doesn't exist, it's not expiring.\n\t\t\treturn false\n\t\t}\n\t\t// Convert the current date from milliseconds to seconds (divide by 1000)\n\t\tconst currentDate = Date.now() / 1000\n\t\t// Find the expiration date of access token (in seconds)\n\t\tlet expiryDate: number\n\t\t// jwtDecode may throw an error if the access token is an empty string (logged out)\n\t\ttry {\n\t\t\t// REASON: Bad types\n\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error,@typescript-eslint/ban-ts-comment\n\t\t\t// @ts-ignore\n\n\t\t\texpiryDate = jwtDecode<JwtPayload>(accessToken).exp ?? currentDate\n\t\t} catch {\n\t\t\t// Enforce expiration if unable to decode token\n\t\t\texpiryDate = currentDate\n\t\t}\n\t\tconst secondsUntilExpiry = expiryDate - currentDate\n\t\treturn secondsUntilExpiry < EXPIRING_SOON_THRESHOLD\n\t}\n\n\tpublic getAuthHeader() {\n\t\tconst accessToken = this.getAccessToken()\n\t\treturn `Bearer ${accessToken}`\n\t}\n\n\tpublic async prepareAuth() {\n\t\tif (!this.tokenIsExpiringSoon()) return\n\n\t\tconsole.debug(this.constructor.name, \"preparing auth\")\n\t\ttry {\n\t\t\tawait this.renewTokens()\n\t\t} catch (e) {\n\t\t\tif (e instanceof APIError) {\n\t\t\t\t// Renewing tokens has failed; we should sign out the user.\n\t\t\t\tthis.clearAuth()\n\t\t\t}\n\t\t\treturn Promise.reject(e)\n\t\t}\n\t}\n\n\t/* if not successfull in gracefully handling an unauthorized response, throw and APIError */\n\tpublic async handleUnauthorized(request: request.SuperAgentRequest, response: request.Response) {\n\t\tconst state = this.client.store.getState()\n\t\t// Without this check, we end up in a loop:\n\t\t// client.auth.renewTokens() -> enqueue -> performRequest -> status === 401 -> client.auth.renewTokens()\n\t\t// See [1] below\n\t\tif (request.url.endsWith(\"/token/refresh/\")) {\n\t\t\t// If the refresh token has expired, we can't do anything.\n\t\t\tif (state.authReducer.isLoggedIn) {\n\t\t\t\t// This is only expected when signing in for the first time with invalid credentials.\n\t\t\t\tconsole.warn(\"No signed-in user to sign out.\")\n\t\t\t}\n\t\t\tthis.clearAuth()\n\t\t\tthrow new APIError({\n\t\t\t\tmessage: \"You have been signed out due to inactivity.\",\n\t\t\t\tresponse: response,\n\t\t\t\tdiscard: true,\n\t\t\t})\n\t\t}\n\t\tif (state.authReducer.isLoggedIn) {\n\t\t\tawait this.renewTokens()\n\t\t} else {\n\t\t\t// If the user is not logged in, we can't renew tokens.\n\t\t\t// Assume this is a login attempt with invalid credentials.\n\t\t\tconsole.debug(\"Forbidden; user is not logged in.\")\n\t\t\tthrow new APIError({\n\t\t\t\tmessage: \"Incorrect username or password.\",\n\t\t\t\tresponse: response,\n\t\t\t\tdiscard: true,\n\t\t\t})\n\t\t}\n\t}\n\n\tasync initAuth(payload: object): Promise<undefined> {\n\t\t// false: Don't log out on failure because we're not currently logged in. Instead, throw and show an error.\n\t\tconst uuid = uuidv4()\n\n\t\tconsole.debug(this.constructor.name, \"Initiating auth\")\n\t\tconst promise = this.enqueueRequest<{ access: string; refresh: string }>({\n\t\t\tuuid,\n\t\t\tdescription: \"Get token pair\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: this.initTokensUrl,\n\t\t\tpayload: payload,\n\t\t\tisAuthNeeded: false,\n\t\t\tcheckAuth: false,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t}).then(parseTokens)\n\n\t\t// The goal: Cancel the request if it takes too long\n\t\tconst timeout = 5 // seconds\n\t\tlet timedOut = false\n\n\t\tconst timeoutPromise = new Promise<undefined>((_, reject) => {\n\t\t\tsetTimeout(() => {\n\t\t\t\ttimedOut = true\n\t\t\t\tthis.dispatch(markForDeletion(uuid))\n\t\t\t\treject(new APIError({ message: `Request timed out after ${timeout} seconds` }))\n\t\t\t}, timeout * 1000)\n\t\t})\n\n\t\tconst successPromise: Promise<undefined> = promise.then((tokens) => {\n\t\t\tif (timedOut) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tthis.setTokens(tokens)\n\t\t})\n\n\t\treturn Promise.race([timeoutPromise, successPromise])\n\t}\n}\n","import type { BaseSDK } from \"../base\"\nimport type { BaseState } from \"../../typings\"\nimport { BaseAuthService } from \"./BaseAuthService\"\nimport { BaseService } from \"./BaseService\"\n\n/**\n * Abstract base class for building a service that can enqueue API requests\n */\nexport abstract class BaseApiService<TStore extends BaseState, TSDK extends BaseSDK<TStore>> extends BaseService<\n\tTStore,\n\tTSDK\n> {\n\treadonly auth: BaseAuthService<TStore, TSDK>\n\n\tconstructor(sdk: TSDK, auth: BaseAuthService<TStore, TSDK>) {\n\t\tsuper(sdk)\n\t\tthis.auth = auth\n\t}\n}\n","import type { Category, Created, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport { addCategory, deleteCategory, initializeCategories, selectCategoryById, updateCategory } from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class CategoryService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<Category>): OptimisticModelResult<Category> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineCategory: Stored<Category> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addCategory(offlineCategory))\n\n\t\tconst promise = this.enqueueRequest<Created<Category>>({\n\t\t\tdescription: \"Create Category\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/categories/\",\n\t\t\tqueryParams: {\n\t\t\t\tworkspace_id: payload.workspace.toString(),\n\t\t\t},\n\t\t\tpayload: offlineCategory,\n\t\t\tblockers: [payload.workspace],\n\t\t\tblocks: [offlineCategory.offline_id],\n\t\t})\n\t\treturn [offlineCategory, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Category>>>): OptimisticModelResult<Category> {\n\t\tconst state = this.client.store.getState()\n\t\tconst existingCategory = selectCategoryById(payload.offline_id)(state)\n\n\t\tif (!existingCategory) {\n\t\t\tthrow new Error(`Expected an existing category with offline_id ${payload.offline_id}`)\n\t\t}\n\n\t\tconst optimisticCategory: Stored<Category> = { ...existingCategory, ...payload }\n\n\t\tthis.dispatch(updateCategory(optimisticCategory))\n\n\t\tconst promise = this.enqueueRequest<Created<Category>>({\n\t\t\tdescription: \"Edit Category\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/categories/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\treturn [optimisticCategory, promise]\n\t}\n\n\tremove(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst category = selectCategoryById(id)(store.getState())\n\n\t\tif (!category) {\n\t\t\tthrow new Error(`No category with id ${id} found in the store`)\n\t\t}\n\n\t\tthis.dispatch(deleteCategory(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete Category\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/categories/${category.offline_id}/`,\n\t\t\tblockers: [category.offline_id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addCategory(category))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<Created<Category>[]>({\n\t\t\tdescription: \"Get categories\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/categories/`,\n\t\t\tblocks: [],\n\t\t\tblockers: [],\n\t\t})\n\t\tthis.dispatch(initializeCategories(result))\n\t}\n}\n","export function chunkArray<T>(arr: T[], chunkSize: number) {\n\tconst chunks: T[][] = []\n\tlet index = 0\n\tconst arrLength = arr.length\n\n\twhile (index < arrLength) {\n\t\tchunks.push(arr.slice(index, (index += chunkSize)))\n\t}\n\n\treturn chunks\n}\n","import { v4 as uuidv4 } from \"uuid\"\nimport type { Asset, Created, Offline, OvermapRootState, Payload, PointGeometry, Stored } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddAsset,\n\taddAssetAttachments,\n\taddAssets,\n\taddFormSubmissions,\n\taddIssueAssociations,\n\tdeleteAsset,\n\tdeleteAssetAttachments,\n\tdeleteFormSubmissions,\n\tdeleteIssueAssociations,\n\tinitializeAssets,\n\tselectAssetById,\n\tselectAttachmentsOfAsset,\n\tselectFormSubmissionsOfAsset,\n\tselectIssueAssociationsOfAsset,\n\tupdateAsset,\n} from \"../../store\"\nimport { chunkArray } from \"../../utils/array\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class AssetService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\t// Basic CRUD functions\n\tadd(payload: Payload<Asset>): OptimisticModelResult<Asset> {\n\t\tconst { store } = this.client\n\n\t\tif (!payload.canvas_marker && !payload.geo_marker) {\n\t\t\tthrow new Error(\"Asset must have either a canvas_marker or geo_marker\")\n\t\t}\n\n\t\tconst createdBy = store.getState().userReducer.currentUser!.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAsset: Stored<Asset> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addAsset(offlineAsset))\n\n\t\tconst promise = this.enqueueRequest<Created<Asset>>({\n\t\t\tdescription: \"Create asset\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/assets/\",\n\t\t\tpayload: {\n\t\t\t\toffline_id: offlineAsset.offline_id,\n\t\t\t\tsubmitted_at: offlineAsset.submitted_at,\n\t\t\t\tgeo_marker: offlineAsset.geo_marker,\n\t\t\t\tcanvas_marker: offlineAsset.canvas_marker,\n\t\t\t\tlabel: offlineAsset.label,\n\t\t\t\tdescription: offlineAsset.description,\n\t\t\t\tasset_type: offlineAsset.asset_type,\n\t\t\t},\n\t\t\tblockers: [offlineAsset.asset_type],\n\t\t\tblocks: [offlineAsset.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((createdAsset) => {\n\t\t\t\tthis.dispatch(updateAsset(createdAsset))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAsset(offlineAsset.offline_id))\n\t\t\t})\n\n\t\treturn [offlineAsset, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Asset>>>): OptimisticModelResult<Asset> {\n\t\tconst { store } = this.client\n\n\t\tconst asset = selectAssetById(payload.offline_id)(store.getState())\n\n\t\tif (!asset) {\n\t\t\tthrow new Error(`No asset with id ${payload.offline_id} found in the store`)\n\t\t}\n\n\t\tconst updatedAsset: Stored<Asset> = {\n\t\t\t...asset,\n\t\t\t...payload,\n\t\t}\n\n\t\tif (!updatedAsset.canvas_marker && !updatedAsset.geo_marker) {\n\t\t\tthrow new Error(\"Asset must have either a canvas_marker or geo_marker\")\n\t\t}\n\n\t\tthis.dispatch(updateAsset(updatedAsset))\n\n\t\tconst promise = this.enqueueRequest<Asset>({\n\t\t\tdescription: \"Edit asset\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/assets/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAsset(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateAsset(asset))\n\t\t\t})\n\n\t\treturn [updatedAsset, promise]\n\t}\n\n\tasync remove(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\t\tconst assetToBeDeleted = selectAssetById(id)(state)\n\n\t\tif (!assetToBeDeleted) throw new Error(`No asset with id ${id} found in the store`)\n\n\t\tconst attachmentsOfAssets = selectAttachmentsOfAsset(id)(state)\n\t\tconst formSubmissionsOfAssets = selectFormSubmissionsOfAsset(id)(state)\n\t\tconst issueAssociations = selectIssueAssociationsOfAsset(id)(state)\n\n\t\tthis.dispatch(deleteAsset(id))\n\n\t\t// remove any attachments of asset from the store\n\t\tif (attachmentsOfAssets.length > 0) {\n\t\t\tconst attachmentsOfAssetIds = attachmentsOfAssets.map(({ offline_id }) => offline_id)\n\t\t\tthis.dispatch(deleteAssetAttachments(attachmentsOfAssetIds))\n\t\t}\n\n\t\t// remove any form submissions of asset from the store\n\t\tif (formSubmissionsOfAssets.length > 0) {\n\t\t\tconst formSubmissionsOfAssetIds = formSubmissionsOfAssets.map(({ offline_id }) => offline_id)\n\t\t\tthis.dispatch(deleteFormSubmissions(formSubmissionsOfAssetIds))\n\t\t}\n\n\t\tif (issueAssociations.length > 0) {\n\t\t\tconst issueAssociationsIds = issueAssociations.map(({ offline_id }) => offline_id)\n\t\t\tthis.dispatch(deleteIssueAssociations(issueAssociationsIds))\n\t\t}\n\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete asset\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/assets/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t}).catch((err) => {\n\t\t\tthis.dispatch(addAsset(assetToBeDeleted))\n\t\t\tthis.dispatch(addAssetAttachments(attachmentsOfAssets))\n\t\t\tthis.dispatch(addFormSubmissions(formSubmissionsOfAssets))\n\t\t\tthis.dispatch(addIssueAssociations(issueAssociations))\n\t\t\tthrow err\n\t\t})\n\t}\n\n\tbulkAdd(\n\t\tpayloads: Omit<Payload<Asset>, \"asset_type\">[],\n\t\tassetTypeId: string,\n\t\t// TODO: should we validate this?\n\t\tbatchSize: number,\n\t): Promise<Created<Asset>[]>[] {\n\t\tinterface BulkAddAssetPayload {\n\t\t\toffline_id: string\n\t\t\tlabel?: string | null\n\t\t\tdescription?: string | null\n\t\t\tgeo_marker?: PointGeometry | null\n\t\t\tcanvas_marker?: PointGeometry | null\n\t\t}\n\n\t\tinterface BulkAddAssetsPayload {\n\t\t\ttransaction_id: string\n\t\t\tassets: BulkAddAssetPayload[]\n\t\t\tasset_type: string\n\t\t\tsubmitted_at: string\n\t\t}\n\n\t\tinterface BulkAddAssetBatch {\n\t\t\tbatchId: string\n\t\t\tpayload: BulkAddAssetsPayload\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst transactionId = uuidv4()\n\n\t\tconst assetBatches: BulkAddAssetBatch[] = chunkArray(payloads, batchSize).map((assetBatch) => {\n\t\t\tconst assetPayloads: BulkAddAssetPayload[] = assetBatch.map((assetPayload) => offline(assetPayload))\n\n\t\t\treturn {\n\t\t\t\tbatchId: uuidv4(),\n\t\t\t\tpayload: {\n\t\t\t\t\ttransaction_id: transactionId,\n\t\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\t\tasset_type: assetTypeId,\n\t\t\t\t\tassets: assetPayloads,\n\t\t\t\t},\n\t\t\t}\n\t\t})\n\n\t\tconst batchPromises: Promise<Created<Asset>[]>[] = []\n\t\tlet prevBatchId: string | null = null\n\n\t\tfor (const assetBatch of assetBatches) {\n\t\t\tconst { batchId, payload } = assetBatch\n\n\t\t\tconst batchAssetOfflineIds = payload.assets.map((c) => c.offline_id)\n\n\t\t\tconst blockers = [assetTypeId]\n\t\t\tif (prevBatchId) blockers.push(prevBatchId)\n\n\t\t\tconst blocks = batchAssetOfflineIds\n\t\t\tblocks.push(batchId)\n\n\t\t\tconst promise = this.enqueueRequest<Created<Asset>[]>({\n\t\t\t\tdescription: \"Batch create assets\",\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\turl: \"/assets/bulk/\",\n\t\t\t\tpayload: payload,\n\t\t\t\tblockers: blockers,\n\t\t\t\tblocks: blocks,\n\t\t\t})\n\n\t\t\tprevBatchId = assetBatch.batchId\n\n\t\t\tbatchPromises.push(promise)\n\t\t}\n\n\t\tvoid Promise.all(batchPromises).then((result) => {\n\t\t\tconst allCreatedAssets = result.flat()\n\t\t\tthis.dispatch(addAssets(allCreatedAssets))\n\t\t})\n\n\t\treturn batchPromises\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Asset[]>({\n\t\t\tdescription: \"Get assets\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/assets/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssets(result))\n\t}\n}\n","import {\n\taddAssetStageCompletion,\n\taddAssetStageCompletions,\n\tdeleteAssetStageCompletion,\n\tdeleteAssetStageCompletions,\n\tinitializeAssetStageCompletions,\n\tselectAssetStageCompletionById,\n\tselectAssetStageCompletionsByIds,\n\tupdateAssetStageCompletion,\n\tupdateAssetStageCompletions,\n} from \"../../store\"\nimport type { OptimisticModelResult, OptimisticMultipleModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport type { AssetStageCompletion, Created, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class AssetStageCompletionService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<AssetStageCompletion>): OptimisticModelResult<AssetStageCompletion> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser!.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineStageCompletion: Stored<AssetStageCompletion> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addAssetStageCompletion(offlineStageCompletion))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetStageCompletion>>({\n\t\t\tdescription: \"Add asset stage completion\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/assets/completions/\",\n\t\t\tpayload: {\n\t\t\t\toffline_id: offlineStageCompletion.offline_id,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tasset: payload.asset,\n\t\t\t\tstage: payload.stage,\n\t\t\t},\n\t\t\tblockers: [payload.asset, payload.stage],\n\t\t\tblocks: [offlineStageCompletion.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetStageCompletion(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetStageCompletion(offlineStageCompletion.offline_id))\n\t\t\t})\n\n\t\treturn [offlineStageCompletion, promise]\n\t}\n\n\tdelete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst assetStageCompletion = selectAssetStageCompletionById(id)(store.getState())\n\n\t\tif (!assetStageCompletion) {\n\t\t\tthrow new Error(`Expected asset stage completion with id ${id} to exist`)\n\t\t}\n\n\t\tthis.dispatch(deleteAssetStageCompletion(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete asset stage completion\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/assets/completions/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addAssetStageCompletion(assetStageCompletion))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tbulkAdd(payloads: Payload<AssetStageCompletion>[]): OptimisticMultipleModelResult<AssetStageCompletion> {\n\t\tconst { store } = this.client\n\n\t\tinterface BulkAddAssetStageCompletionPayload {\n\t\t\toffline_id: string\n\t\t\tasset: string\n\t\t\tstage: string\n\t\t}\n\n\t\tinterface BulkAddAssetStageCompletionsPayload {\n\t\t\tsubmitted_at: string\n\t\t\tcompletions: Payload<AssetStageCompletion>[]\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = store.getState().userReducer.currentUser!.id\n\n\t\tconst payload: BulkAddAssetStageCompletionPayload[] = payloads.map((payload) => offline(payload))\n\n\t\tconst offlineStageCompletions = payload.map((completion) => {\n\t\t\treturn {\n\t\t\t\t...completion,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t}\n\t\t})\n\n\t\tconst offlineIds = offlineStageCompletions.map(({ offline_id }) => offline_id)\n\n\t\tthis.dispatch(addAssetStageCompletions(offlineStageCompletions))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetStageCompletion>[]>({\n\t\t\tdescription: \"Bulk create asset stage completions\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/assets/completions/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tcompletions: payload,\n\t\t\t} satisfies BulkAddAssetStageCompletionsPayload,\n\t\t\tblockers: [...payloads.map((c) => c.asset), ...payloads.map((c) => c.stage)],\n\t\t\tblocks: offlineIds,\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetStageCompletions(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetStageCompletions(offlineIds))\n\t\t\t})\n\n\t\treturn [offlineStageCompletions, promise]\n\t}\n\n\tbulkDelete(ids: string[]): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst assetStageCompletions = selectAssetStageCompletionsByIds(ids)(store.getState())\n\n\t\tthis.dispatch(deleteAssetStageCompletions(ids))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Deleting asset stage completions\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: \"/assets/completions/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tcompletion_ids: ids,\n\t\t\t},\n\t\t\tblockers: ids,\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addAssetStageCompletions(assetStageCompletions))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<AssetStageCompletion>[]>({\n\t\t\tdescription: \"Get asset stage completions\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/asset-stage-completions/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetStageCompletions(result))\n\t}\n}\n","import type { AssetStage, Created, CSSColor, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddAssetStages,\n\tdeleteAssetStages,\n\tinitializeAssetStages,\n\tselectAssetStageById,\n\tselectAssetStagesByIds,\n\tsetAssetStage,\n\tupdateAssetStage,\n\tupdateAssetStages,\n} from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\nimport { OptimisticModelResult, OptimisticMultipleModelResult } from \"../typings\"\n\nexport abstract class AssetStageService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tbulkAdd(\n\t\tstagesToSubmit: Omit<Payload<AssetStage>, \"asset_type\">[],\n\t\tassetTypeId: string,\n\t): OptimisticMultipleModelResult<AssetStage> {\n\t\tinterface BulkAddAssetStagePayload {\n\t\t\toffline_id: string\n\t\t\tname?: string | null\n\t\t\tdescription?: string | null\n\t\t\tpriority: number\n\t\t\tcolor: CSSColor\n\t\t}\n\n\t\tinterface BulkAddAssetStagesPayload {\n\t\t\tstages: BulkAddAssetStagePayload[]\n\t\t\tasset_type: string\n\t\t\tsubmitted_at: string\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser!.id\n\n\t\tconst payload: BulkAddAssetStagePayload[] = stagesToSubmit.map((stage) => {\n\t\t\treturn offline(stage)\n\t\t})\n\n\t\tconst offlineStages: AssetStage[] = payload.map((stage) => {\n\t\t\treturn { ...stage, asset_type: assetTypeId, created_by: createdBy, submitted_at: submittedAt }\n\t\t})\n\n\t\tthis.dispatch(addAssetStages(offlineStages))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetStage>[]>({\n\t\t\tdescription: \"Add asset stages\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/assets/stages/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tasset_type: assetTypeId,\n\t\t\t\tstages: payload,\n\t\t\t} satisfies BulkAddAssetStagesPayload,\n\t\t\tblockers: [assetTypeId],\n\t\t\tblocks: payload.map(({ offline_id }) => offline_id),\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetStages(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetStages(offlineStages.map(({ offline_id }) => offline_id)))\n\t\t\t})\n\n\t\treturn [offlineStages, promise]\n\t}\n\n\tasync bulkUpdate(stagesToUpdate: AssetStage[], assetTypeId: string): Promise<AssetStage[]> {\n\t\tconst store = this.client.store\n\t\tconst state = store.getState()\n\t\tconst prevStages = selectAssetStagesByIds(stagesToUpdate.map(({ offline_id }) => offline_id))(state)\n\n\t\tthis.dispatch(updateAssetStages(stagesToUpdate))\n\n\t\treturn this.enqueueRequest<AssetStage[]>({\n\t\t\tdescription: \"Edit asset stages\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/assets/types/${assetTypeId}/bulk-update-stages/`,\n\t\t\tpayload: {\n\t\t\t\tstages: stagesToUpdate,\n\t\t\t},\n\t\t\tblockers: [assetTypeId],\n\t\t\tblocks: stagesToUpdate.map(({ offline_id }) => offline_id),\n\t\t}).catch((e) => {\n\t\t\t// restore stages in store if request fails\n\t\t\tthis.dispatch(updateAssetStages(prevStages))\n\t\t\tthrow e\n\t\t})\n\t}\n\n\tasync bulkDelete(idsToDelete: string[]): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst assetStages = selectAssetStagesByIds(idsToDelete)(store.getState())\n\n\t\tthis.dispatch(deleteAssetStages(idsToDelete))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete asset stages\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: \"/assets/stages/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tstage_ids: idsToDelete,\n\t\t\t},\n\t\t\tblockers: idsToDelete,\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addAssetStages(assetStages))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<AssetStage>>>): OptimisticModelResult<AssetStage> {\n\t\tconst { store } = this.client\n\n\t\tconst assetStage = selectAssetStageById(payload.offline_id)(store.getState())\n\n\t\tif (!assetStage) throw new Error(`No asset stage with id ${payload.offline_id} found in the store`)\n\n\t\tconst updatedAssetStage: Stored<AssetStage> = {\n\t\t\t...assetStage,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateAssetStage(updatedAssetStage))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetStage>>({\n\t\t\tdescription: \"Update asset stage\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/assets/stages/${assetStage.offline_id}/`,\n\t\t\tpayload: {\n\t\t\t\tname: payload.name,\n\t\t\t\tdescription: payload.description,\n\t\t\t\tpriority: payload.priority,\n\t\t\t\tcolor: payload.color,\n\t\t\t},\n\t\t\tblockers: [assetStage.offline_id],\n\t\t\tblocks: [assetStage.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetStage(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(setAssetStage(assetStage))\n\t\t\t})\n\n\t\treturn [updatedAssetStage, promise]\n\t}\n\n\tasync linkForm(stageId: string, formId: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst stage = store.getState().assetStageReducer.instances[stageId]\n\n\t\tif (!stage) {\n\t\t\tthrow new Error(`No asset stage with id ${stageId} found in the store`)\n\t\t}\n\n\t\tthis.dispatch(updateAssetStage({ ...stage, form: formId }))\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest({\n\t\t\t\tdescription: \"Link asset stage to form\",\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\turl: `/assets/stages/${stageId}/associate-with-form/`,\n\t\t\t\tpayload: { form: formId },\n\t\t\t\tblockers: [stageId, formId],\n\t\t\t\tblocks: [stageId],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(setAssetStage(stage))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync unlinkForm(stageId: string, formId: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst stage = store.getState().assetStageReducer.instances[stageId]\n\n\t\tif (!stage) {\n\t\t\tthrow new Error(`No asset stage with id ${stageId} found in the store`)\n\t\t}\n\n\t\tthis.dispatch(updateAssetStage({ ...stage, form: undefined }))\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest({\n\t\t\t\tdescription: \"Unlink asset stage from form\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/assets/stages/${stageId}/associate-with-form/`,\n\t\t\t\tblockers: [stageId, formId],\n\t\t\t\tblocks: [stageId],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(setAssetStage(stage))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<AssetStage[]>({\n\t\t\tdescription: \"Get asset stages\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/asset-stages/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeAssetStages(result))\n\t}\n}\n","import { BaseApiService } from \"./BaseApiService\"\nimport { HttpMethod } from \"../../enums\"\nimport type { PresignedUrlsResponse, SDKRequest } from \"../typings\"\nimport type { OvermapRootState } from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class BaseUploadService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tprotected getNumberOfAttachmentsWithSha1(sha1: string) {\n\t\tconst {\n\t\t\tissueAttachmentReducer,\n\t\t\tassetAttachmentReducer,\n\t\t\tassetTypeAttachmentReducer,\n\t\t\tdocumentAttachmentReducer,\n\t\t\tprojectAttachmentReducer,\n\t\t\tformRevisionAttachmentReducer,\n\t\t\tformSubmissionAttachmentReducer,\n\t\t\tgeoImageReducer,\n\t\t} = this.client.store.getState()\n\n\t\t// creating an array of objects with the file_sha1 property\n\t\t// TODO: @Audiopolis, probably makes sense to also include projectFiles in here?\n\t\tconst objectsWithSha1: { file_sha1: string }[] = ([] as { file_sha1: string }[]).concat(\n\t\t\tObject.values(issueAttachmentReducer.instances),\n\t\t\tObject.values(assetAttachmentReducer.instances),\n\t\t\tObject.values(assetTypeAttachmentReducer.instances),\n\t\t\tObject.values(documentAttachmentReducer.instances),\n\t\t\tObject.values(projectAttachmentReducer.instances),\n\t\t\tObject.values(formRevisionAttachmentReducer.instances),\n\t\t\tObject.values(formSubmissionAttachmentReducer.instances),\n\t\t\tObject.values(geoImageReducer.instances),\n\t\t)\n\n\t\treturn objectsWithSha1.filter((object) => object.file_sha1 === sha1).length\n\t}\n\n\tprotected processPresignedUrls(presignedUrls: PresignedUrlsResponse): Record<string, Promise<undefined>> {\n\t\tconst promisesBySha1: Record<string, Promise<undefined>> = {}\n\n\t\tfor (const [sha1, presignedUrl] of Object.entries(presignedUrls)) {\n\t\t\tpromisesBySha1[sha1] = this.enqueueRequest<undefined>({\n\t\t\t\turl: presignedUrl.url,\n\t\t\t\tdescription: \"Upload file to S3\",\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\tisExternalUrl: true,\n\t\t\t\tisAuthNeeded: false,\n\t\t\t\tattachmentHash: sha1,\n\t\t\t\t// TODO: can we use the sha1 as the blocker?\n\t\t\t\tblockers: [`s3-${presignedUrl.fields.key}`],\n\t\t\t\tblocks: [sha1],\n\t\t\t\ts3url: presignedUrl,\n\t\t\t} satisfies SDKRequest)\n\t\t}\n\n\t\treturn promisesBySha1\n\t}\n}\n","import { ActionCreatorWithPayload } from \"@reduxjs/toolkit\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { AttachmentModel, HttpMethod } from \"../../enums\"\nimport type {\n\tAttachment,\n\tCreated,\n\tOfflineModel,\n\tOvermapRootState,\n\tOvermapSelectorWithArgs,\n\tStored,\n\tSubmitted,\n} from \"../../typings\"\nimport { hashFile } from \"../../utils\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\n\nexport interface AttachmentPayload {\n\toffline_id: OfflineModel[\"offline_id\"]\n\tname: Attachment[\"file_name\"]\n\tsha1: Attachment[\"file_sha1\"]\n\tdescription: Attachment[\"description\"]\n}\n\nexport interface FilePayload {\n\tsha1: Attachment[\"file_sha1\"]\n\tfile_type: string\n\textension: string\n\tsize: number\n}\n\nexport interface BuildOfflineAttachmentData<TModelId> {\n\tfile: File\n\t// passing sha1 here so dont have to hash multiple times\n\tsha1: string\n\tsubmittedAt: string\n\tcreatedBy?: number\n\tdescription?: string\n\t// this the offline_id passed in from the attachFiles method\n\tmodelId: TModelId\n}\n\nconst AttachmentModelMeta: Record<\n\tAttachmentModel,\n\t{ attachUrlPrefix: string; deleteUrlPrefix: string; name: string; fetchUrlPostfix: string }\n> = {\n\t[AttachmentModel.Issue]: {\n\t\tname: \"issue\",\n\t\tattachUrlPrefix: \"/issues\",\n\t\tdeleteUrlPrefix: \"/issues\",\n\t\tfetchUrlPostfix: \"/issue-attachments\",\n\t},\n\t[AttachmentModel.Asset]: {\n\t\tname: \"asset\",\n\t\tattachUrlPrefix: \"/assets\",\n\t\tdeleteUrlPrefix: \"/assets\",\n\t\tfetchUrlPostfix: \"/asset-attachments\",\n\t},\n\t[AttachmentModel.AssetType]: {\n\t\tname: \"asset type\",\n\t\tattachUrlPrefix: \"/assets/types\",\n\t\tdeleteUrlPrefix: \"/assets/types\",\n\t\tfetchUrlPostfix: \"/asset-type-attachments\",\n\t},\n\t[AttachmentModel.Project]: {\n\t\tname: \"project\",\n\t\tattachUrlPrefix: \"/projects\",\n\t\tdeleteUrlPrefix: \"/projects\",\n\t\tfetchUrlPostfix: \"/attachments\",\n\t},\n\t[AttachmentModel.Document]: {\n\t\tname: \"document\",\n\t\tattachUrlPrefix: \"/documents\",\n\t\tdeleteUrlPrefix: \"/documents\",\n\t\tfetchUrlPostfix: \"/document-attachments\",\n\t},\n}\n\nexport abstract class BaseAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n\tTModelId extends string | number,\n\tTAttachment extends Attachment,\n> extends BaseUploadService<TState, TSDK> {\n\tabstract readonly attachmentModel: AttachmentModel\n\n\t// redux actions\n\tabstract readonly initializeAttachments: ActionCreatorWithPayload<Submitted<TAttachment>[]>\n\tabstract readonly addAttachments: ActionCreatorWithPayload<Submitted<TAttachment>[]>\n\tabstract readonly updateAttachments: ActionCreatorWithPayload<Submitted<TAttachment>[]>\n\tabstract readonly removeAttachments: ActionCreatorWithPayload<string[]>\n\tabstract readonly setAttachment: ActionCreatorWithPayload<Stored<TAttachment>>\n\tabstract readonly removeAttachment: ActionCreatorWithPayload<string>\n\n\t// redux selectors\n\tabstract readonly selectAttachment: OvermapSelectorWithArgs<string, Stored<TAttachment> | undefined>\n\n\tprotected async attachFiles(\n\t\tfiles: File[],\n\t\tmodelId: TModelId,\n\t\tbuildOfflineAttachment: (data: BuildOfflineAttachmentData<TModelId>) => Stored<TAttachment>,\n\t): Promise<OptimisticMultipleModelResult<TAttachment>> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAttachments: Stored<TAttachment>[] = []\n\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\n\t\tfor (const file of files) {\n\t\t\t// has file once\n\t\t\tconst sha1 = await hashFile(file)\n\n\t\t\t// if the file is already being uploaded, skip it\n\t\t\tif (!(sha1 in filePayloads)) {\n\t\t\t\tfilePayloads[sha1] = {\n\t\t\t\t\tsha1,\n\t\t\t\t\tfile_type: file.type,\n\t\t\t\t\textension: file.name.split(\".\").pop()!,\n\t\t\t\t\tsize: file.size,\n\t\t\t\t}\n\t\t\t\tawait this.client.files.addCache(file, sha1)\n\t\t\t}\n\n\t\t\t// construct offline attachment\n\t\t\tconst offlineAttachment = buildOfflineAttachment({\n\t\t\t\tfile,\n\t\t\t\tsha1,\n\t\t\t\tsubmittedAt,\n\t\t\t\tcreatedBy: createdBy,\n\t\t\t\tdescription: \"\",\n\t\t\t\tmodelId: modelId,\n\t\t\t})\n\t\t\tofflineAttachments.push(offlineAttachment)\n\n\t\t\t// construct attachment payload\n\t\t\tattachmentPayloads.push({\n\t\t\t\toffline_id: offlineAttachment.offline_id,\n\t\t\t\tname: offlineAttachment.file_name,\n\t\t\t\tsha1: offlineAttachment.file_sha1,\n\t\t\t\tdescription: offlineAttachment.description,\n\t\t\t})\n\t\t}\n\n\t\tthis.dispatch(this.addAttachments(offlineAttachments))\n\n\t\tconst meta = AttachmentModelMeta[this.attachmentModel]\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<TAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: `Attach files to ${meta.name}`,\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `${meta.attachUrlPrefix}/${modelId}/attach/`,\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblocks: offlineAttachments.map((attachment) => attachment.offline_id),\n\t\t\tblockers: offlineAttachments.map((attachment) => attachment.file_sha1),\n\t\t})\n\n\t\tpromise\n\t\t\t.then(({ attachments, presigned_urls }) => {\n\t\t\t\tthis.dispatch(this.updateAttachments(attachments))\n\t\t\t\tthis.processPresignedUrls(presigned_urls)\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(this.removeAttachments(offlineAttachments.map((attachment) => attachment.offline_id)))\n\t\t\t})\n\n\t\treturn [offlineAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tprotected async deleteAttachment(attachmendId: string): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst attachment = this.selectAttachment(attachmendId)(store.getState())\n\n\t\tif (!attachment) {\n\t\t\tthrow new Error(\n\t\t\t\t`Attempting to delete attachment with offline_id ${attachmendId} that does not exist in the store`,\n\t\t\t)\n\t\t}\n\n\t\tthis.dispatch(this.removeAttachment(attachment.offline_id))\n\n\t\tconst meta = AttachmentModelMeta[this.attachmentModel]\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete attachment\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `${meta.deleteUrlPrefix}/attachments/${attachmendId}/`,\n\t\t\tblockers: [attachmendId],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise\n\t\t\t.then(() => {\n\t\t\t\tif (this.getNumberOfAttachmentsWithSha1(attachment.file_sha1) === 0) {\n\t\t\t\t\tvoid this.client.files.removeCache(attachment.file_sha1)\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(this.setAttachment(attachment))\n\t\t\t})\n\n\t\treturn promise\n\t}\n\n\t// Note that currently the fetching of attachments for all models dependds on the active projectId. This may change in the future. And\n\t// so for some attachment model services, this method will have to be overridden.\n\tasync refreshStore(projectId: number, _organizationId?: number): Promise<void> {\n\t\tconst meta = AttachmentModelMeta[this.attachmentModel]\n\n\t\tconst result = await this.enqueueRequest<Created<TAttachment>[]>({\n\t\t\tdescription: `Get ${meta.name} attachments`,\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}${meta.fetchUrlPostfix}/`,\n\t\t\tblocks: [],\n\t\t\tblockers: [],\n\t\t})\n\n\t\tthis.dispatch(this.initializeAttachments(result))\n\t}\n}\n","import { BaseAttachmentService, BuildOfflineAttachmentData } from \"./BaseAttachmentService\"\nimport type { AssetAttachment, Stored, OvermapRootState } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport type { OptimisticMultipleModelResult } from \"../typings\"\nimport {\n\taddAssetAttachments,\n\tdeleteAssetAttachments,\n\tdeleteAssetAttachment,\n\tselectAssetAttachmentById,\n\tsetAssetAttachment,\n\tupdateAssetAttachments,\n\tinitializeAssetAttachments,\n} from \"../../store\"\nimport type { BaseSDK } from \"../base\"\nimport { AttachmentModel } from \"../../enums\"\n\nexport abstract class AssetAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseAttachmentService<TState, TSDK, string, AssetAttachment> {\n\tattachmentModel = AttachmentModel.Asset\n\n\tinitializeAttachments = initializeAssetAttachments\n\taddAttachments = addAssetAttachments\n\tupdateAttachments = updateAssetAttachments\n\tremoveAttachments = deleteAssetAttachments\n\tremoveAttachment = deleteAssetAttachment\n\tsetAttachment = setAssetAttachment\n\n\tselectAttachment = selectAssetAttachmentById\n\n\tprivate buildOfflineAttachment(data: BuildOfflineAttachmentData<string>) {\n\t\treturn offline({\n\t\t\tfile: URL.createObjectURL(data.file),\n\t\t\tfile_sha1: data.sha1,\n\t\t\tcreated_by: data.createdBy,\n\t\t\tfile_name: data.file.name,\n\t\t\tfile_type: data.file.type,\n\t\t\tsubmitted_at: data.submittedAt,\n\t\t\tdescription: data.description,\n\t\t\tasset: data.modelId,\n\t\t}) satisfies Stored<AssetAttachment>\n\t}\n\n\tasync attachFilesToAsset(files: File[], assetId: string): Promise<OptimisticMultipleModelResult<AssetAttachment>> {\n\t\treturn this.attachFiles(files, assetId, this.buildOfflineAttachment.bind(this))\n\t}\n\n\tasync deleteAssetAttachment(attachmentId: string): Promise<void> {\n\t\treturn this.deleteAttachment(attachmentId)\n\t}\n}\n","import { offline } from \"../../utils\"\nimport {\n\taddAssets,\n\taddAssetStages,\n\taddAssetType,\n\taddAssetTypeAttachments,\n\tdeleteAssets,\n\tdeleteAssetStages,\n\tdeleteAssetType,\n\tdeleteAssetTypeAttachments,\n\tinitializeAssetTypes,\n\tselectAssetsOfAssetType,\n\tselectAssetTypeById,\n\tselectAttachmentsOfAssetType,\n\tselectStagesOfAssetType,\n\tupdateAssetType,\n} from \"../../store\"\nimport type { AssetStage, AssetType, Created, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class AssetTypeService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<AssetType>): OptimisticModelResult<AssetType> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser!.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAssetType: Stored<AssetType> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addAssetType(offlineAssetType))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetType>>({\n\t\t\tdescription: \"Create asset type\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/projects/${payload.project}/asset-types/`,\n\t\t\tpayload: { ...offlineAssetType },\n\t\t\tblockers: [],\n\t\t\tblocks: [offlineAssetType.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetType(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteAssetType(offlineAssetType.offline_id))\n\t\t\t})\n\n\t\treturn [offlineAssetType, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<AssetType>>>): OptimisticModelResult<AssetType> {\n\t\tconst { store } = this.client\n\n\t\tconst assetType = selectAssetTypeById(payload.offline_id)(store.getState())\n\n\t\tif (!assetType) {\n\t\t\tthrow new Error(`Expected asset type with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst updatedAssetType: Stored<AssetType> = {\n\t\t\t...assetType,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateAssetType(updatedAssetType))\n\n\t\tconst promise = this.enqueueRequest<Created<AssetType>>({\n\t\t\tdescription: \"Update asset type\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/assets/types/${payload.offline_id}/`,\n\t\t\tpayload: {\n\t\t\t\ticon: payload.icon,\n\t\t\t\tcolor: payload.color,\n\t\t\t\tname: payload.name,\n\t\t\t\tdescription: payload.description,\n\t\t\t},\n\t\t\tblockers: [assetType.offline_id],\n\t\t\tblocks: [assetType.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateAssetType(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateAssetType(assetType))\n\t\t\t})\n\n\t\treturn [updatedAssetType, promise]\n\t}\n\n\tasync delete(assetTypeId: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst assetType = selectAssetTypeById(assetTypeId)(state)\n\n\t\tif (!assetType) {\n\t\t\tthrow new Error(`Expected asset type with offline_id ${assetTypeId} to exist`)\n\t\t}\n\n\t\tconst assetsOfAssetType = selectAssetsOfAssetType(assetTypeId)(state)\n\t\tconst stagesOfAssetType = selectStagesOfAssetType(assetTypeId)(state)\n\t\tconst attachmentsOfAssetType = selectAttachmentsOfAssetType(assetTypeId)(state)\n\n\t\tthis.dispatch(deleteAssetType(assetTypeId))\n\t\tthis.dispatch(deleteAssets(assetsOfAssetType.map((asset) => asset.offline_id)))\n\t\tthis.dispatch(deleteAssetStages(stagesOfAssetType.map((assetStage: AssetStage) => assetStage.offline_id)))\n\t\tthis.dispatch(deleteAssetTypeAttachments(attachmentsOfAssetType.map(({ offline_id }) => offline_id)))\n\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete asset type\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/assets/types/${assetTypeId}/`,\n\t\t\tblockers: [assetTypeId],\n\t\t\tblocks: [],\n\t\t}).catch((e) => {\n\t\t\tthis.dispatch(addAssetType(assetType))\n\t\t\tthis.dispatch(addAssets(assetsOfAssetType))\n\t\t\tthis.dispatch(addAssetStages(stagesOfAssetType))\n\t\t\tthis.dispatch(addAssetTypeAttachments(attachmentsOfAssetType))\n\t\t\tthrow e\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<AssetType[]>({\n\t\t\tdescription: \"Get asset types\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/asset-types/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(initializeAssetTypes(result))\n\t}\n}\n","import { BaseAttachmentService, BuildOfflineAttachmentData } from \"./BaseAttachmentService\"\nimport {\n\taddAssetTypeAttachments,\n\tdeleteAssetTypeAttachments,\n\tdeleteAssetTypeAttachment,\n\tselectAssetTypeAttachmentById,\n\tsetAssetTypeAttachment,\n\tupdateAssetTypeAttachments,\n\tinitializeAssetTypeAttachments,\n} from \"../../store\"\nimport type { AssetTypeAttachment, Stored, OvermapRootState } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport type { OptimisticMultipleModelResult } from \"../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { AttachmentModel } from \"../../enums\"\n\nexport abstract class AssetTypeAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseAttachmentService<TState, TSDK, string, AssetTypeAttachment> {\n\tattachmentModel = AttachmentModel.AssetType\n\n\tinitializeAttachments = initializeAssetTypeAttachments\n\taddAttachments = addAssetTypeAttachments\n\tupdateAttachments = updateAssetTypeAttachments\n\tremoveAttachments = deleteAssetTypeAttachments\n\tremoveAttachment = deleteAssetTypeAttachment\n\tsetAttachment = setAssetTypeAttachment\n\n\tselectAttachment = selectAssetTypeAttachmentById\n\n\tprivate buildOfflineAttachment(data: BuildOfflineAttachmentData<string>) {\n\t\treturn offline({\n\t\t\tfile: URL.createObjectURL(data.file),\n\t\t\tfile_sha1: data.sha1,\n\t\t\tcreated_by: data.createdBy,\n\t\t\tfile_name: data.file.name,\n\t\t\tfile_type: data.file.type,\n\t\t\tsubmitted_at: data.submittedAt,\n\t\t\tdescription: data.description,\n\t\t\tasset_type: data.modelId,\n\t\t}) satisfies Stored<AssetTypeAttachment>\n\t}\n\n\tasync attachFilesToAssetType(\n\t\tfiles: File[],\n\t\tassetTypeId: string,\n\t): Promise<OptimisticMultipleModelResult<AssetTypeAttachment>> {\n\t\treturn this.attachFiles(files, assetTypeId, this.buildOfflineAttachment.bind(this))\n\t}\n\n\tasync deleteAssetTypeAttachment(attachmentId: string): Promise<void> {\n\t\treturn this.deleteAttachment(attachmentId)\n\t}\n}\n","import type { Created, IssueComment, Offline, OvermapRootState, Payload, Stored, Submitted } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport {\n\taddIssueComment,\n\tdeleteIssueComment,\n\tselectIssueCommentById,\n\tsetIssueComment,\n\tsetIssueComments,\n} from \"../../store\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class IssueCommentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Omit<Payload<IssueComment>, \"author\">): OptimisticModelResult<IssueComment> {\n\t\tconst { store } = this.client\n\n\t\tconst offlineComment: Submitted<IssueComment> = offline({\n\t\t\t...payload,\n\t\t\tauthor: store.getState().userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t})\n\n\t\tthis.dispatch(addIssueComment(offlineComment))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueComment>>({\n\t\t\tdescription: \"Add issue comment\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/issues/${payload.issue}/comment/`,\n\t\t\tpayload: offlineComment,\n\t\t\tblockers: [payload.issue],\n\t\t\tblocks: [offlineComment.offline_id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(deleteIssueComment(offlineComment.offline_id))\n\t\t})\n\n\t\treturn [offlineComment, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<IssueComment>>>): OptimisticModelResult<IssueComment> {\n\t\tconst { store } = this.client\n\n\t\tconst commentToUpdate = selectIssueCommentById(payload.offline_id)(store.getState())\n\n\t\tif (!commentToUpdate) {\n\t\t\tthrow new Error(`Comment with offline_id ${payload.offline_id} not found in store`)\n\t\t}\n\n\t\tconst updatedComment: Stored<IssueComment> = {\n\t\t\t...commentToUpdate,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(setIssueComment(updatedComment))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueComment>>({\n\t\t\tdescription: \"Edit issue comment\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/issues/comments/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(setIssueComment(commentToUpdate))\n\t\t})\n\n\t\treturn [updatedComment, promise]\n\t}\n\n\tremove(id: string): Promise<undefined> {\n\t\tconst commentToRemove = this.client.store.getState().issueCommentReducer.instances[id]\n\n\t\tif (!commentToRemove) {\n\t\t\tthrow new Error(`Comment with offline_id ${id} not found in store`)\n\t\t}\n\n\t\tthis.dispatch(deleteIssueComment(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete comment\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/issues/comments/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addIssueComment(commentToRemove))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<IssueComment>[]>({\n\t\t\tdescription: \"Get comments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/comments/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(setIssueComments(result))\n\t}\n}\n","import type { Created, IssueUpdate, OvermapRootState } from \"../../typings\"\nimport { onlyUniqueOfflineIds } from \"../../utils\"\nimport { HttpMethod } from \"../../enums\"\nimport { initializeIssueUpdates } from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class IssueUpdateService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<IssueUpdate>[]>({\n\t\t\tdescription: \"Get issue updates\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/issues/updates/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tlet filteredResult = result.filter(onlyUniqueOfflineIds)\n\t\tfilteredResult = filteredResult.map((comment) => {\n\t\t\treturn { ...comment }\n\t\t})\n\t\tif (result.length !== filteredResult.length) {\n\t\t\tconsole.error(\n\t\t\t\t`Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`,\n\t\t\t)\n\t\t}\n\t\tthis.dispatch(initializeIssueUpdates(filteredResult))\n\t}\n}\n","import { BaseAttachmentService, BuildOfflineAttachmentData } from \"./BaseAttachmentService\"\nimport type { OptimisticMultipleModelResult } from \"../typings\"\nimport type { IssueAttachment, OvermapRootState, Stored } from \"../../typings\"\nimport {\n\taddIssueAttachments,\n\tdeleteIssueAttachments,\n\tdeleteIssueAttachment,\n\tselectIssueAttachmentById,\n\tsetIssueAttachment,\n\tupdateIssueAttachments,\n\tinitializeIssueAttachments,\n} from \"../../store\"\nimport { offline } from \"../../utils\"\nimport type { BaseSDK } from \"../base\"\nimport { AttachmentModel } from \"../../enums\"\n\nexport abstract class IssueAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseAttachmentService<TState, TSDK, string, IssueAttachment> {\n\tattachmentModel = AttachmentModel.Issue\n\n\tinitializeAttachments = initializeIssueAttachments\n\taddAttachments = addIssueAttachments\n\tupdateAttachments = updateIssueAttachments\n\tremoveAttachments = deleteIssueAttachments\n\tremoveAttachment = deleteIssueAttachment\n\tsetAttachment = setIssueAttachment\n\n\tselectAttachment = selectIssueAttachmentById\n\n\tprivate buildOfflineAttachment(data: BuildOfflineAttachmentData<string>) {\n\t\treturn offline({\n\t\t\tfile: URL.createObjectURL(data.file),\n\t\t\tfile_sha1: data.sha1,\n\t\t\tcreated_by: data.createdBy,\n\t\t\tfile_name: data.file.name,\n\t\t\tfile_type: data.file.type,\n\t\t\tsubmitted_at: data.submittedAt,\n\t\t\tdescription: data.description,\n\t\t\tissue: data.modelId,\n\t\t}) satisfies Stored<IssueAttachment>\n\t}\n\n\tasync attachFilesToIssue(files: File[], issueId: string): Promise<OptimisticMultipleModelResult<IssueAttachment>> {\n\t\treturn this.attachFiles(files, issueId, this.buildOfflineAttachment.bind(this))\n\t}\n\n\tasync deleteIssueAttachment(attachmentId: string): Promise<void> {\n\t\treturn this.deleteAttachment(attachmentId)\n\t}\n}\n","import type { OptimisticModelResult } from \"../typings\"\nimport type {\n\tCategory,\n\tCreated,\n\tIssue,\n\tIssueAssociation,\n\tIssueUpdate,\n\tOffline,\n\tOvermapRootState,\n\tPayload,\n\tStored,\n\tSubmitted,\n\tUser,\n} from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddActiveProjectIssuesCount,\n\taddFormSubmissions,\n\taddIssue,\n\taddIssueAssociations,\n\taddIssueAttachments,\n\taddIssueUpdate,\n\taddIssueUpdates,\n\tdeleteFormSubmissions,\n\tdeleteIssue,\n\tdeleteIssueAssociations,\n\tdeleteIssueAttachments,\n\tdeleteIssueUpdate,\n\tdeleteIssueUpdates,\n\tinitializeIssues,\n\tselectAttachmentsOfIssue,\n\tselectFormSubmissionsOfIssue,\n\tselectIssueAssociationsOfIssue,\n\tselectIssueAssociationsToIssue,\n\tselectIssueById,\n\tselectIssueUpdatesOfIssue,\n\tupdateIssue,\n} from \"../../store\"\nimport { HttpMethod, IssueUpdateChange } from \"../../enums\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\n/**\n * Handles CRUD operations on issues\n */\nexport abstract class IssueService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\t// Basic CRUD functions\n\n\tadd(payload: Payload<Issue>): OptimisticModelResult<Issue> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = state.userReducer.currentUser?.id\n\n\t\tconst offlineIssue: Submitted<Issue> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: submittedAt,\n\t\t\tcreated_by: createdBy,\n\t\t})\n\n\t\tthis.dispatch(addIssue(offlineIssue))\n\t\tthis.dispatch(addActiveProjectIssuesCount(1))\n\n\t\tconst promise = this.enqueueRequest<Created<Issue>>({\n\t\t\tdescription: \"Create issue\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/issues/\",\n\t\t\tqueryParams: {\n\t\t\t\tworkspace_id: payload.index_workspace,\n\t\t\t\t...(payload.issue_type ? { issue_type: payload.issue_type } : {}),\n\t\t\t},\n\t\t\tpayload: offlineIssue,\n\t\t\tblockers: [\"add-issue\", ...(offlineIssue.index_workspace ? [offlineIssue.index_workspace] : [])],\n\t\t\tblocks: [offlineIssue.offline_id],\n\t\t})\n\t\tvoid promise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateIssue(result)) // Updates the index in the store\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthis.dispatch(deleteIssue(offlineIssue.offline_id))\n\t\t\t\tthis.dispatch(addActiveProjectIssuesCount(-1))\n\t\t\t\tthrow error\n\t\t\t})\n\t\treturn [offlineIssue, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Issue>>>): OptimisticModelResult<Issue> {\n\t\tconst state = this.client.store.getState()\n\t\tconst issueToBeUpdated = selectIssueById(payload.offline_id)(state)\n\n\t\tif (!issueToBeUpdated) {\n\t\t\tthrow new Error(\n\t\t\t\t`Attempting to update an issue with offline_id ${payload.offline_id} that doesn't exist in the store`,\n\t\t\t)\n\t\t}\n\n\t\tconst updatedIssue: Stored<Issue> = { ...issueToBeUpdated, ...payload }\n\n\t\tthis.dispatch(updateIssue(updatedIssue))\n\n\t\tconst changes: IssueUpdate[\"changes\"] = {}\n\t\t// NOTE: order here mirrors the backend order\n\t\tfor (const issueUpdateChange of [\n\t\t\tIssueUpdateChange.TITLE,\n\t\t\tIssueUpdateChange.DESCRIPTION,\n\t\t\tIssueUpdateChange.STATUS,\n\t\t\tIssueUpdateChange.CATEGORY,\n\t\t\tIssueUpdateChange.PRIORITY,\n\t\t\tIssueUpdateChange.ASSIGNED_TO,\n\t\t\tIssueUpdateChange.DUE_DATE,\n\t\t]) {\n\t\t\tif (issueUpdateChange in payload && payload[issueUpdateChange] !== issueToBeUpdated[issueUpdateChange]) {\n\t\t\t\tswitch (issueUpdateChange) {\n\t\t\t\t\tcase \"category\": {\n\t\t\t\t\t\tlet categoryOrNull: Category | null = null\n\t\t\t\t\t\tconst categoryIdOrNull = payload[issueUpdateChange]\n\t\t\t\t\t\tif (categoryIdOrNull) {\n\t\t\t\t\t\t\tcategoryOrNull = state.categoryReducer.instances[categoryIdOrNull] ?? null\n\n\t\t\t\t\t\t\tif (!categoryOrNull)\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t`Trying to update issue category to ${categoryIdOrNull} which does not exist in store`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchanges[issueUpdateChange] = categoryOrNull\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tname: categoryOrNull.name,\n\t\t\t\t\t\t\t\t\tcolor: categoryOrNull.color,\n\t\t\t\t\t\t\t\t\toffline_id: categoryOrNull.offline_id,\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: null\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase \"assigned_to\": {\n\t\t\t\t\t\tlet userOrNull: User | null = null\n\t\t\t\t\t\tconst userIdOrNull = payload[issueUpdateChange]\n\t\t\t\t\t\tif (userIdOrNull) {\n\t\t\t\t\t\t\tuserOrNull = state.userReducer.users[userIdOrNull] ?? null\n\n\t\t\t\t\t\t\tif (!userOrNull)\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t`Trying to update issue assigned_to to ${userIdOrNull} which does not exist in store`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchanges[issueUpdateChange] = userOrNull\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tfull_name: userOrNull.username,\n\t\t\t\t\t\t\t\t\tid: userOrNull.id,\n\t\t\t\t\t\t\t }\n\t\t\t\t\t\t\t: null\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tcase \"description\":\n\t\t\t\t\t\tchanges[issueUpdateChange] = payload[issueUpdateChange] ?? null\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\tchanges[issueUpdateChange] = payload[issueUpdateChange] ?? null\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"priority\":\n\t\t\t\t\t\tchanges[issueUpdateChange] = payload[issueUpdateChange]!\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"status\":\n\t\t\t\t\t\tchanges[issueUpdateChange] = payload[issueUpdateChange]!\n\t\t\t\t\t\tbreak\n\t\t\t\t\tcase \"due_date\":\n\t\t\t\t\t\tchanges[issueUpdateChange] = payload[issueUpdateChange]\n\t\t\t\t\t\t\t? (payload[issueUpdateChange] as string)\n\t\t\t\t\t\t\t: null\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst offlineIssueUpdate: Stored<IssueUpdate> = offline({\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\tissue: issueToBeUpdated.offline_id,\n\t\t\tchanges: changes,\n\t\t})\n\n\t\tthis.dispatch(addIssueUpdate(offlineIssueUpdate))\n\n\t\tconst promise = this.enqueueRequest<Created<Issue>>({\n\t\t\tdescription: \"Edit issue\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/issues/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\t// the patch failed, revert issue back, remove offline issue update\n\t\t\tthis.dispatch(updateIssue(issueToBeUpdated))\n\t\t\tthis.dispatch(deleteIssueUpdate(offlineIssueUpdate.offline_id))\n\t\t})\n\n\t\treturn [updatedIssue, promise]\n\t}\n\n\tasync remove(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst backup = selectIssueById(id)(state)\n\n\t\tif (!backup) {\n\t\t\tthrow new Error(`No issue with id ${id} found in the store`)\n\t\t}\n\n\t\tconst attachmentsOfIssue = selectAttachmentsOfIssue(id)(state)\n\t\tconst updatesOfIssue = selectIssueUpdatesOfIssue(id)(state)\n\t\tconst formSubmissionsOfIssue = selectFormSubmissionsOfIssue(id)(state)\n\n\t\tconst issueAssociationsRecord: Record<string, Stored<IssueAssociation>> = {}\n\n\t\tfor (const issueAssociation of selectIssueAssociationsToIssue(id)(state))\n\t\t\tissueAssociationsRecord[issueAssociation.offline_id] = issueAssociation\n\t\tfor (const issueAssociation of selectIssueAssociationsOfIssue(id)(state))\n\t\t\tissueAssociationsRecord[issueAssociation.offline_id] = issueAssociation\n\n\t\tconst issueAssociations = Object.values(issueAssociationsRecord)\n\n\t\tthis.dispatch(deleteIssue(id))\n\t\tthis.dispatch(addActiveProjectIssuesCount(-1))\n\t\tif (attachmentsOfIssue.length > 0)\n\t\t\tthis.dispatch(deleteIssueAttachments(attachmentsOfIssue.map(({ offline_id }) => offline_id)))\n\t\tif (updatesOfIssue.length > 0)\n\t\t\tthis.dispatch(deleteIssueUpdates(updatesOfIssue.map(({ offline_id }) => offline_id)))\n\t\tif (formSubmissionsOfIssue.length > 0)\n\t\t\tthis.dispatch(deleteFormSubmissions(formSubmissionsOfIssue.map(({ offline_id }) => offline_id)))\n\t\tif (issueAssociations.length > 0)\n\t\t\tthis.dispatch(deleteIssueAssociations(issueAssociations.map(({ offline_id }) => offline_id)))\n\n\t\t// TODO: remove Issue comments in similar pattern above\n\n\t\ttry {\n\t\t\t// REASON: Need to await to trigger the catch block.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n\t\t\treturn await this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete issue\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/issues/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addIssue(backup))\n\t\t\tthis.dispatch(addIssueAttachments(attachmentsOfIssue))\n\t\t\tthis.dispatch(addIssueUpdates(updatesOfIssue))\n\t\t\tthis.dispatch(addActiveProjectIssuesCount(1))\n\t\t\tthis.dispatch(addFormSubmissions(formSubmissionsOfIssue))\n\t\t\tthis.dispatch(addIssueAssociations(issueAssociations))\n\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<Created<Issue>[]>({\n\t\t\tdescription: \"Get issues\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/issues/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssues(result))\n\t}\n}\n","import type { OptimisticModelResult } from \"../typings\"\nimport type { Created, IssueType, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport { offline } from \"../../utils\"\nimport {\n\taddIssues,\n\taddIssueType,\n\tdeleteIssues,\n\tinitializeIssueTypes,\n\tremoveIssueType,\n\tselectIssuesOfIssueType,\n\tselectIssueTypeById,\n\tsetIssueType,\n\tupdateIssueType,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class IssueTypeService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<IssueType>): OptimisticModelResult<IssueType> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst offlineIssueType: Stored<IssueType> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t})\n\n\t\tthis.dispatch(addIssueType(offlineIssueType))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueType>>({\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/organizations/${payload.organization}/issue-types/`,\n\t\t\t// Sending only whats needed here\n\t\t\tpayload: {\n\t\t\t\toffline_id: offlineIssueType.offline_id,\n\t\t\t\tsubmitted_at: offlineIssueType.submitted_at,\n\t\t\t\ticon: offlineIssueType.icon,\n\t\t\t\tcolor: offlineIssueType.color,\n\t\t\t\tname: offlineIssueType.name,\n\t\t\t\tdescription: offlineIssueType.description,\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [offlineIssueType.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((createdIssueType) => {\n\t\t\t\tthis.dispatch(setIssueType(createdIssueType))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(removeIssueType(offlineIssueType.offline_id))\n\t\t\t})\n\n\t\treturn [offlineIssueType, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<IssueType>>>): OptimisticModelResult<IssueType> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst issueTypeToBeUpdated = selectIssueTypeById(payload.offline_id)(state)\n\n\t\tif (!issueTypeToBeUpdated) {\n\t\t\tthrow new Error(`IssueType with offline_id ${payload.offline_id} does not exist in the store.`)\n\t\t}\n\n\t\tconst offlineUpdatedIssueType: Stored<IssueType> = {\n\t\t\t...issueTypeToBeUpdated,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateIssueType(offlineUpdatedIssueType))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueType>>({\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/issues/types/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((updatedIssueType) => {\n\t\t\t\tthis.dispatch(setIssueType(updatedIssueType))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(setIssueType(issueTypeToBeUpdated))\n\t\t\t})\n\n\t\treturn [offlineUpdatedIssueType, promise]\n\t}\n\n\tdelete(id: string): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst issueTypeToDelete = selectIssueTypeById(id)(state)\n\n\t\tif (!issueTypeToDelete) {\n\t\t\tthrow new Error(`IssueType with offline_id ${id} does not exist in the store.`)\n\t\t}\n\n\t\tconst issuesOfIssueType = selectIssuesOfIssueType(id)(state)\n\n\t\tthis.dispatch(removeIssueType(id))\n\n\t\tthis.dispatch(deleteIssues(issuesOfIssueType.map((issue) => issue.offline_id)))\n\n\t\t// TODO: probably want to remove any forms, revisions and submissions associated with the issue type\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/issues/types/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(setIssueType(issueTypeToDelete))\n\t\t\tthis.dispatch(addIssues(issuesOfIssueType))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\t// TODO: fetch for projects too\n\n\t\tconst result = await this.enqueueRequest<Created<IssueType>[]>({\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/issue-types/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssueTypes(result))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport { deleteProjectAccess, initializeProjectAccesses, updateProjectAccess } from \"../../store\"\nimport type { OvermapRootState, ProjectAccess } from \"../../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\n/**\n * Handles the creation of ProjectAccess Service\n */\nexport abstract class ProjectAccessService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync update(projectAccess: ProjectAccess): Promise<ProjectAccess> {\n\t\tthis.dispatch(updateProjectAccess(projectAccess))\n\n\t\treturn this.enqueueRequest<ProjectAccess>({\n\t\t\tdescription: \"Edit project access\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/access/${projectAccess.offline_id}/`,\n\t\t\tpayload: projectAccess,\n\t\t\tblockers: [projectAccess.offline_id, \"change-access-level\"],\n\t\t\tblocks: [projectAccess.offline_id],\n\t\t})\n\t}\n\n\t// TODO: Re-add user to project if removal fails\n\tasync remove(id: string): Promise<undefined> {\n\t\tthis.dispatch(deleteProjectAccess(id))\n\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete project access\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/access/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<ProjectAccess[]>({\n\t\t\tdescription: \"Get project accesses\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/access/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeProjectAccesses(result))\n\t}\n}\n","import { HttpMethod } from \"enums/api\"\nimport type { Created, Offline, OvermapRootState, ProjectFile, ProjectFilePayload, Stored } from \"../../typings\"\nimport type { OptimisticGenericResult, OptimisticModelResult, PresignedUrlsResponse } from \"../typings\"\nimport {\n\tdeleteProjectFile,\n\tinitializeProjectFiles,\n\tselectProjectFileById,\n\tupdateProjectFile,\n} from \"store/slices/projectFileSlice\"\nimport type { BaseSDK } from \"../base\"\nimport { hashFile, offline } from \"../../utils\"\nimport { FilePayload } from \"./BaseAttachmentService\"\nimport { BaseUploadService } from \"./BaseUploadService\"\n\n/**\n * Handles creation and caching of ProjectFiles\n */\nexport abstract class ProjectFileService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync add(payload: ProjectFilePayload): Promise<OptimisticGenericResult<ProjectFile>> {\n\t\tconst { file, ...payloadWithoutFile } = payload\n\n\t\tconst sha1 = await hashFile(file)\n\n\t\tconst filePayload: FilePayload = {\n\t\t\tsha1,\n\t\t\tfile_type: file.type,\n\t\t\textension: file.name.split(\".\").pop()!,\n\t\t\tsize: file.size,\n\t\t}\n\n\t\tconst offlineProjectFile: Stored<ProjectFile> = offline({\n\t\t\t...payloadWithoutFile,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\tfile_name: file.name,\n\t\t\tfile_sha1: sha1,\n\t\t\tfile: URL.createObjectURL(file),\n\t\t})\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tproject_file: Created<ProjectFile>\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/projects/${payload.project}/files/`,\n\t\t\tpayload: {\n\t\t\t\toffline_id: offlineProjectFile.offline_id,\n\t\t\t\tsubmitted_at: offlineProjectFile.submitted_at,\n\t\t\t\tz_index: offlineProjectFile.z_index,\n\t\t\t\tcanvas_bounds: offlineProjectFile.canvas_bounds,\n\t\t\t\tbounds: offlineProjectFile.bounds,\n\t\t\t\tfile_name: offlineProjectFile.file_name,\n\t\t\t\tfile_sha1: offlineProjectFile.file_sha1,\n\t\t\t\tfile: offlineProjectFile.file,\n\t\t\t\tfile_payload: filePayload,\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [offlineProjectFile.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(updateProjectFile(result.project_file))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteProjectFile(offlineProjectFile.offline_id))\n\t\t\t})\n\n\t\treturn [offlineProjectFile, promise.then((result) => result.project_file)]\n\t}\n\n\tupdate(\n\t\tpayload: Offline<Partial<Omit<ProjectFilePayload, \"project\" | \"file\">>>,\n\t): OptimisticModelResult<ProjectFile> {\n\t\tconst { store } = this.client\n\n\t\tconst projectFile = selectProjectFileById(payload.offline_id)(store.getState())\n\n\t\tif (!projectFile) {\n\t\t\tthrow new Error(`Project file with id ${payload.offline_id} not found`)\n\t\t}\n\n\t\tconst updatedProjectFile: Stored<ProjectFile> = {\n\t\t\t...projectFile,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateProjectFile(updatedProjectFile))\n\n\t\tconst promise = this.enqueueRequest<Created<ProjectFile>>({\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/projects/files/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateProjectFile(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateProjectFile(projectFile))\n\t\t\t})\n\n\t\treturn [updatedProjectFile, promise]\n\t}\n\n\tdelete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst projectFileToDelete = selectProjectFileById(id)(store.getState())\n\n\t\tif (!projectFileToDelete) {\n\t\t\tthrow new Error(`Project file with id ${id} not found`)\n\t\t}\n\n\t\tthis.dispatch(deleteProjectFile(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/projects/files/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(updateProjectFile(projectFileToDelete))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<ProjectFile>[]>({\n\t\t\tdescription: \"Get project files\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/files/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeProjectFiles(result))\n\t}\n}\n","import { BaseAttachmentService, BuildOfflineAttachmentData } from \"./BaseAttachmentService\"\nimport { offline } from \"../../utils\"\nimport type { OvermapRootState, ProjectAttachment, Stored } from \"../../typings\"\nimport type { OptimisticMultipleModelResult } from \"../typings\"\nimport {\n\taddProjectAttachments,\n\tdeleteProjectAttachment,\n\tdeleteProjectAttachments,\n\tinitializeProjectAttachments,\n\tselectProjectAttachmentById,\n\tsetProjectAttachment,\n\tupdateProjectAttachments,\n} from \"../../store\"\nimport type { BaseSDK } from \"../base\"\nimport { AttachmentModel } from \"../../enums\"\n\nexport abstract class ProjectAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseAttachmentService<TState, TSDK, number, ProjectAttachment> {\n\tattachmentModel = AttachmentModel.Project\n\n\tinitializeAttachments = initializeProjectAttachments\n\taddAttachments = addProjectAttachments\n\tupdateAttachments = updateProjectAttachments\n\tremoveAttachments = deleteProjectAttachments\n\tremoveAttachment = deleteProjectAttachment\n\tsetAttachment = setProjectAttachment\n\n\tselectAttachment = selectProjectAttachmentById\n\n\tprivate buildOfflineAttachment(data: BuildOfflineAttachmentData<number>) {\n\t\treturn offline({\n\t\t\tfile: URL.createObjectURL(data.file),\n\t\t\tfile_sha1: data.sha1,\n\t\t\tcreated_by: data.createdBy,\n\t\t\tfile_name: data.file.name,\n\t\t\tfile_type: data.file.type,\n\t\t\tsubmitted_at: data.submittedAt,\n\t\t\tdescription: data.description,\n\t\t\tproject: data.modelId,\n\t\t}) satisfies Stored<ProjectAttachment>\n\t}\n\n\tasync attachFilesToProject(\n\t\tfiles: File[],\n\t\tprojectId: number,\n\t): Promise<OptimisticMultipleModelResult<ProjectAttachment>> {\n\t\treturn this.attachFiles(files, projectId, this.buildOfflineAttachment.bind(this))\n\t}\n\n\tasync deleteProjectAttachment(attachmentId: string): Promise<void> {\n\t\treturn this.deleteAttachment(attachmentId)\n\t}\n}\n","import { HttpMethod } from \"enums/api\"\nimport type { Created, License, OvermapRootState, Payload, Project } from \"../../typings\"\nimport { v4 as uuidv4 } from \"uuid\"\nimport {\n\tacceptProjectInvite,\n\tdeleteProject,\n\tdeleteProjectAccesses,\n\tdeleteProjectAttachments,\n\tdeleteProjectFiles,\n\tinitializeProjectAccesses,\n\tinitializeProjectFiles,\n\tselectAttachmentsOfProject,\n\tselectLicenseForProject,\n\tselectProjectAccesses,\n\tselectProjectFiles,\n\tselectProjectMapping,\n\tsetProjectAttachments,\n\tsetProjects,\n\tupdateLicense,\n\tupdateOrCreateProject,\n} from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\ninterface JoinProjectResponse {\n\tusername: string\n}\n\nexport abstract class ProjectService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync add(payload: Payload<Project>): Promise<Project> {\n\t\tif (!payload.bounds && !payload.canvas_bounds) {\n\t\t\tthrow new Error(\"Project must either have bounds or canvas_bounds set\")\n\t\t}\n\n\t\treturn await this.enqueueRequest<Created<Project>>({\n\t\t\tdescription: \"Create project\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/projects/\",\n\t\t\tpayload: {\n\t\t\t\tname: payload.name,\n\t\t\t\tbounds: payload.bounds,\n\t\t\t\torganization_owner: payload.organization_owner,\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync update(project: Project): Promise<Project> {\n\t\tif (!project.bounds && !project.canvas_bounds) {\n\t\t\tthrow new Error(\"Project must either have bounds or canvas_bounds set\")\n\t\t}\n\n\t\tthis.dispatch(updateOrCreateProject(project))\n\t\treturn await this.enqueueRequest<Project>({\n\t\t\tdescription: \"Update project\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/projects/${project.id}/`,\n\t\t\tpayload: {\n\t\t\t\tname: project.name,\n\t\t\t\tbounds: project.bounds,\n\t\t\t},\n\t\t\tblockers: [project.id.toString()],\n\t\t\tblocks: [project.id.toString()],\n\t\t})\n\t}\n\n\tasync delete(projectId: number): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\t\tconst projects = selectProjectMapping(state)\n\t\tconst project = projects[projectId]\n\t\tif (!project) {\n\t\t\tthrow new Error(\"Expected project to exist\")\n\t\t}\n\n\t\t// TODO: this shouldnt be an optimistic result\n\t\t// Selector needed to restore if the request fails\n\t\tconst projectFiles = selectProjectFiles(state).filter((file) => file.project === projectId)\n\t\tthis.dispatch(deleteProjectFiles(projectFiles.map(({ offline_id }) => offline_id)))\n\n\t\t// Selector needed to restore if the request fails\n\t\tconst attachmentsOfProject = selectAttachmentsOfProject(project.id)(state)\n\t\tthis.dispatch(deleteProjectAttachments(attachmentsOfProject.map(({ offline_id }) => offline_id)))\n\n\t\t// Selector needed to restore if the request fails\n\t\tconst projectAccesses = selectProjectAccesses(state)\n\t\tthis.dispatch(deleteProjectAccesses(projectAccesses.map(({ offline_id }) => offline_id)))\n\n\t\t// Necessary to prevent no projects view from showing when project is deleted\n\t\tthis.dispatch({ type: \"rehydrated/setRehydrated\", payload: false })\n\t\tthis.dispatch(deleteProject(project))\n\n\t\tconst license = selectLicenseForProject(project.id)(state)\n\t\t// Detach license from project\n\t\tif (license) {\n\t\t\tthis.dispatch(updateLicense({ ...license, project: null } as License))\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete project\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/projects/${projectId}/`,\n\t\t\t\tblockers: [projectId.toString()],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t\tthis.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\n\t\t} catch (e) {\n\t\t\tthis.dispatch(setProjects(Object.values(projects)))\n\t\t\tthis.dispatch(initializeProjectAccesses(Object.values(projectAccesses)))\n\t\t\tthis.dispatch(initializeProjectFiles(projectFiles))\n\t\t\tthis.dispatch(setProjectAttachments(attachmentsOfProject))\n\t\t\tthis.dispatch({ type: \"rehydrated/setRehydrated\", payload: true })\n\t\t\tif (license) {\n\t\t\t\tthis.dispatch(updateLicense({ ...license, project: project.id } as License))\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tinvite(projectId: number, email: string): Promise<undefined> {\n\t\tconst offline_id: string = uuidv4()\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Invite user to project\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/projects/${projectId}/invite/${email}/`,\n\t\t\tpayload: {\n\t\t\t\toffline_id,\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [offline_id],\n\t\t})\n\t}\n\n\tjoinProject(projectId: number, userId: number, inviteCode: string): Promise<JoinProjectResponse> {\n\t\treturn this.enqueueRequest<JoinProjectResponse>({\n\t\t\tdescription: \"Join project\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/join-project/${userId}/${inviteCode}/`,\n\t\t\tisAuthNeeded: false,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync acceptInvite(projectId: number): Promise<void> {\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Accept project invite\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/projects/${projectId}/accept-invite/`,\n\t\t\tblockers: [projectId.toString()],\n\t\t\tblocks: [projectId.toString()],\n\t\t}).then(() => {\n\t\t\tthis.dispatch(acceptProjectInvite(projectId))\n\t\t})\n\t}\n}\n","import { HttpMethod } from \"enums/api\"\nimport { addForm, deleteForm, initializeForms, selectFormById } from \"store/slices/formSlice\"\nimport type {\n\tForm,\n\tFormRevision,\n\tFormRevisionAttachment,\n\tFormRevisionPayload,\n\tOvermapRootState,\n\tStored,\n\tSubmitted,\n\tCreated,\n} from \"../../typings\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { offline } from \"utils/offline\"\nimport { hashFile } from \"../../utils\"\nimport {\n\taddFormRevision,\n\taddFormRevisionAttachments,\n\taddFormRevisions,\n\taddFormSubmissions,\n\tdeleteFormRevision,\n\tdeleteFormRevisionAttachments,\n\tdeleteFormRevisions,\n\tdeleteFormSubmissions,\n\tinitializeFormRevisionAttachments,\n\tinitializeFormRevisions,\n\tselectFormRevisionsOfForm,\n\tselectFormSubmissionsOfForm,\n\tsetFormRevision,\n\tupdateFormRevisionAttachments,\n} from \"../../store\"\nimport type { BaseSDK } from \"../base\"\nimport { FilePayload } from \"./BaseAttachmentService\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport { ISerializedField, ISerializedOnlyField } from \"@overmap-ai/forms\"\n\n/**\n * Finds and separates image files from form revision fields. The image attribute is deleted from the field objects and\n * is returned separately from the image files as they are stored in a different table.\n */\nconst separateImageFromFields = async (fields: ISerializedField[]) => {\n\tconst images: Record<string, File> = {} // key: field identifier, value: File\n\tconst newFields: ISerializedField[] = [] // fields without image attribute\n\tfor (const section of fields) {\n\t\tif (section.type !== \"section\") {\n\t\t\tthrow new Error(`Expected ISerializedField type to be a section. Got ${section.type} instead.`)\n\t\t}\n\n\t\tconst { fields: sectionFields } = section\n\t\tconst newSectionFields: ISerializedOnlyField[] = []\n\t\tfor (const field of sectionFields) {\n\t\t\tif (field.image) {\n\t\t\t\tif (field.image instanceof Promise) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\timages[field.identifier] = await field.image\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.error(\"Failed to get image from promise\", e)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\timages[field.identifier] = field.image\n\t\t\t\t}\n\t\t\t\tdelete field.image\n\t\t\t}\n\t\t\tnewSectionFields.push(field)\n\t\t}\n\t\tnewFields.push({ ...section, fields: newSectionFields })\n\t}\n\n\treturn { fields: newFields, images }\n}\n\nexport abstract class FormService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tprivate async bulkAddRevisionAttachments(\n\t\trevisionId: string,\n\t\tfiles: Record<string, File>,\n\t): Promise<OptimisticMultipleModelResult<FormRevisionAttachment>> {\n\t\tinterface AttachmentPayload {\n\t\t\toffline_id: string\n\t\t\tname: string\n\t\t\tsha1: string\n\t\t\tfield_identifier: string\n\t\t\tdesscription?: string\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser?.id\n\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\t\tconst offlineFormRevisionAttachments: Stored<FormRevisionAttachment>[] = []\n\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\n\t\tfor (const [fieldIdentifier, file] of Object.entries(files)) {\n\t\t\tconst sha1 = await hashFile(file)\n\n\t\t\tif (!(sha1 in filePayloads)) {\n\t\t\t\tfilePayloads[sha1] = {\n\t\t\t\t\tsha1,\n\t\t\t\t\tfile_type: file.type,\n\t\t\t\t\textension: file.name.split(\".\").pop()!,\n\t\t\t\t\tsize: file.size,\n\t\t\t\t}\n\t\t\t\tawait this.client.files.addCache(file, sha1)\n\t\t\t}\n\n\t\t\tconst offlineFormRevisionAttachment: Stored<FormRevisionAttachment> = offline({\n\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\tfile_type: file.type,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: sha1,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\trevision: revisionId,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t})\n\t\t\tofflineFormRevisionAttachments.push(offlineFormRevisionAttachment)\n\n\t\t\tconst attachmentPayload: AttachmentPayload = {\n\t\t\t\toffline_id: offlineFormRevisionAttachment.offline_id,\n\t\t\t\tname: file.name,\n\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\tsha1,\n\t\t\t}\n\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t}\n\n\t\tthis.dispatch(addFormRevisionAttachments(offlineFormRevisionAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<FormRevisionAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: \"Attach files to form revision\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/forms/revisions/${revisionId}/attachments/bulk/`,\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblockers: [revisionId],\n\t\t\tblocks: offlineFormRevisionAttachments.map((attachment) => attachment.offline_id),\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(updateFormRevisionAttachments(result.attachments))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteFormRevisionAttachments(\n\t\t\t\t\t\tofflineFormRevisionAttachments.map((attachment) => attachment.offline_id),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t})\n\n\t\treturn [offlineFormRevisionAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tprivate async add(\n\t\townerId: string,\n\t\tform: Submitted<Form>,\n\t\tinitialRevision: FormRevisionPayload,\n\t\turlPrefix: string,\n\t): Promise<\n\t\t[\n\t\t\tStored<Form>,\n\t\t\tStored<FormRevision>,\n\t\t\tStored<FormRevisionAttachment>[],\n\t\t\tPromise<Created<FormRevision>>,\n\t\t\tPromise<Created<FormRevisionAttachment>[]>,\n\t\t]\n\t> {\n\t\tinterface CreateFormPayload {\n\t\t\toffline_id: string\n\t\t\tsubmitted_at: string\n\t\t\tinitial_revision: {\n\t\t\t\toffline_id: string\n\t\t\t\tsubmitted_at: string\n\t\t\t\ttitle: string\n\t\t\t\tdescription?: string\n\t\t\t\tfields: ISerializedField[]\n\t\t\t}\n\t\t}\n\n\t\tconst { fields, images } = await separateImageFromFields(initialRevision.fields)\n\n\t\tconst offlineFormRevision: Submitted<FormRevision> = offline({\n\t\t\t...initialRevision,\n\t\t\tfields: fields,\n\t\t\tcreated_by: form.created_by,\n\t\t\tform: form.offline_id,\n\t\t\tsubmitted_at: form.submitted_at,\n\t\t\trevision: \"Pending\",\n\t\t})\n\n\t\tthis.dispatch(addForm(form))\n\t\tthis.dispatch(addFormRevision(offlineFormRevision))\n\n\t\tconst formPromise = this.enqueueRequest<Created<FormRevision>>({\n\t\t\tdescription: \"Create form\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: urlPrefix,\n\t\t\tpayload: {\n\t\t\t\t// Sending exactly what is currently needed for the endpoint\n\t\t\t\toffline_id: form.offline_id,\n\t\t\t\tsubmitted_at: form.submitted_at,\n\t\t\t\tinitial_revision: {\n\t\t\t\t\toffline_id: offlineFormRevision.offline_id,\n\t\t\t\t\tsubmitted_at: offlineFormRevision.submitted_at,\n\t\t\t\t\ttitle: offlineFormRevision.title,\n\t\t\t\t\tdescription: offlineFormRevision.description,\n\t\t\t\t\tfields: offlineFormRevision.fields,\n\t\t\t\t},\n\t\t\t} satisfies CreateFormPayload,\n\t\t\tblockers: [ownerId],\n\t\t\tblocks: [form.offline_id, offlineFormRevision.offline_id],\n\t\t})\n\n\t\tconst [offlineFormRevisionAttachments, attachmentsPromise] = await this.bulkAddRevisionAttachments(\n\t\t\tofflineFormRevision.offline_id,\n\t\t\timages,\n\t\t)\n\n\t\tvoid formPromise.catch((e) => {\n\t\t\tthis.dispatch(deleteForm(form.offline_id))\n\t\t\tthis.dispatch(deleteFormRevision(offlineFormRevision.offline_id))\n\t\t\t// TODO: remove form revision attachments\n\t\t\tthrow e\n\t\t})\n\n\t\treturn [form, offlineFormRevision, offlineFormRevisionAttachments, formPromise, attachmentsPromise]\n\t}\n\n\taddForOrganization(organizationId: number, initialRevision: FormRevisionPayload) {\n\t\tconst state: OvermapRootState = this.client.store.getState()\n\n\t\tconst offlineForm: Submitted<Form> = offline({\n\t\t\tfavorite: false,\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\torganization: organizationId,\n\t\t})\n\n\t\treturn this.add(\n\t\t\torganizationId.toString(),\n\t\t\tofflineForm,\n\t\t\tinitialRevision,\n\t\t\t`/organizations/${organizationId}/create-form/`,\n\t\t)\n\t}\n\n\taddForProject(projectId: number, initialRevision: FormRevisionPayload) {\n\t\tconst state: OvermapRootState = this.client.store.getState()\n\n\t\tconst offlineForm: Submitted<Form> = offline({\n\t\t\tfavorite: false,\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\tproject: projectId,\n\t\t})\n\n\t\treturn this.add(projectId.toString(), offlineForm, initialRevision, `/projects/${projectId}/create-form/`)\n\t}\n\n\taddForIssueType(issueTypeId: string, initialRevision: FormRevisionPayload) {\n\t\tconst state: OvermapRootState = this.client.store.getState()\n\n\t\tconst offlineForm: Submitted<Form> = offline({\n\t\t\tfavorite: false,\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\tissue_type: issueTypeId,\n\t\t})\n\n\t\treturn this.add(issueTypeId, offlineForm, initialRevision, `/issues/types/${issueTypeId}/create-form/`)\n\t}\n\n\taddForAssetType(assetTypeId: string, initialRevision: FormRevisionPayload) {\n\t\tconst state: OvermapRootState = this.client.store.getState()\n\n\t\tconst offlineForm: Submitted<Form> = offline({\n\t\t\tfavorite: false,\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\tasset_type: assetTypeId,\n\t\t})\n\n\t\treturn this.add(assetTypeId, offlineForm, initialRevision, `/assets/types/${assetTypeId}/create-form/`)\n\t}\n\n\tasync createRevision(\n\t\tformId: string,\n\t\trevision: FormRevisionPayload,\n\t): Promise<\n\t\t[\n\t\t\tStored<FormRevision>,\n\t\t\tStored<FormRevisionAttachment>[],\n\t\t\tPromise<Created<FormRevision>>,\n\t\t\tPromise<Created<FormRevisionAttachment>[]>,\n\t\t]\n\t> {\n\t\tconst offlineRevision = offline(revision)\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst createdBy = state.userReducer.currentUser?.id\n\n\t\tconst { fields, images } = await separateImageFromFields(offlineRevision.fields)\n\n\t\tconst fullRevision: Stored<FormRevision> = {\n\t\t\t...offlineRevision,\n\t\t\tfields: fields,\n\t\t\tcreated_by: createdBy,\n\t\t\trevision: \"Pending\",\n\t\t\tform: formId,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t}\n\n\t\tthis.dispatch(addFormRevision(fullRevision))\n\n\t\tconst promise = this.enqueueRequest<Created<FormRevision>>({\n\t\t\tdescription: \"Create form revision\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/forms/${formId}/`,\n\t\t\tpayload: {\n\t\t\t\tinitial_revision: {\n\t\t\t\t\toffline_id: fullRevision.offline_id,\n\t\t\t\t\tsubmitted_at: fullRevision.submitted_at,\n\t\t\t\t\ttitle: fullRevision.title,\n\t\t\t\t\tdescription: fullRevision.description,\n\t\t\t\t\tfields: fullRevision.fields,\n\t\t\t\t},\n\t\t\t},\n\t\t\tblockers: [formId],\n\t\t\tblocks: [offlineRevision.offline_id],\n\t\t})\n\n\t\tconst [offlineFormRevisionAttachments, attachmentsPromise] = await this.bulkAddRevisionAttachments(\n\t\t\tfullRevision.offline_id,\n\t\t\timages,\n\t\t)\n\n\t\tvoid promise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(setFormRevision(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteFormRevision(fullRevision.offline_id))\n\t\t\t})\n\n\t\treturn [fullRevision, offlineFormRevisionAttachments, promise, attachmentsPromise]\n\t}\n\n\tasync delete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\t\tconst form = selectFormById(id)(state)\n\t\tif (!form) {\n\t\t\tthrow new Error(\"Expected form to exist\")\n\t\t}\n\t\t// Delete all submissions for this form\n\t\tconst formSubmissions = selectFormSubmissionsOfForm(id)(state)\n\t\tif (formSubmissions.length > 0) {\n\t\t\tthis.dispatch(deleteFormSubmissions(formSubmissions.map(({ offline_id }) => offline_id)))\n\t\t}\n\n\t\t// Delete all revisions for this form\n\t\tconst formRevisions = selectFormRevisionsOfForm(id)(state)\n\t\tif (formRevisions.length > 0) {\n\t\t\tthis.dispatch(deleteFormRevisions(formRevisions.map(({ offline_id }) => offline_id)))\n\t\t}\n\n\t\t// Delete the form itself\n\t\tthis.dispatch(deleteForm(id))\n\n\t\ttry {\n\t\t\t// REASON: Need to await to trigger the catch block.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n\t\t\treturn await this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete form\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/forms/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addForm(form))\n\t\t\tif (formRevisions.length > 0) {\n\t\t\t\tthis.dispatch(addFormRevisions(formRevisions))\n\t\t\t}\n\t\t\tif (formSubmissions.length > 0) {\n\t\t\t\tthis.dispatch(addFormSubmissions(formSubmissions))\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tinterface FormDataResponse {\n\t\t\tforms: Created<Form>[]\n\t\t\trevisions: Created<FormRevision>[]\n\t\t\tattachments: Created<FormRevisionAttachment>[]\n\t\t}\n\n\t\tconst forms: Created<Form>[] = []\n\t\tconst revisions: Created<FormRevision>[] = []\n\t\tconst attachments: Created<FormRevisionAttachment>[] = []\n\n\t\tconst projectFormsResult = await this.enqueueRequest<FormDataResponse>({\n\t\t\tdescription: \"Fetch project forms\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/forms/`,\n\t\t\tblockers: [projectId.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const form of projectFormsResult.forms) forms.push(form)\n\t\tfor (const revision of projectFormsResult.revisions) revisions.push(revision)\n\t\tfor (const attachment of projectFormsResult.attachments) attachments.push(attachment)\n\n\t\tconst organizationFormsResult = await this.enqueueRequest<FormDataResponse>({\n\t\t\tdescription: \"Fetch organization forms\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/organizations/forms/`,\n\t\t\tblockers: [projectId.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const form of organizationFormsResult.forms) forms.push(form)\n\t\tfor (const revision of organizationFormsResult.revisions) revisions.push(revision)\n\t\tfor (const attachment of organizationFormsResult.attachments) attachments.push(attachment)\n\n\t\tconst assetTypeFormsResult = await this.enqueueRequest<FormDataResponse>({\n\t\t\tdescription: \"Fetch asset type forms\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/asset-types/forms/`,\n\t\t\tblockers: [projectId.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const form of assetTypeFormsResult.forms) forms.push(form)\n\t\tfor (const revision of assetTypeFormsResult.revisions) revisions.push(revision)\n\t\tfor (const attachment of assetTypeFormsResult.attachments) attachments.push(attachment)\n\n\t\tconst issueTypeFormsResult = await this.enqueueRequest<FormDataResponse>({\n\t\t\tdescription: \"Fetch issue type forms\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/issue-types/forms/`,\n\t\t\tblockers: [projectId.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const form of issueTypeFormsResult.forms) forms.push(form)\n\t\tfor (const revision of issueTypeFormsResult.revisions) revisions.push(revision)\n\t\tfor (const attachment of issueTypeFormsResult.attachments) attachments.push(attachment)\n\n\t\tthis.dispatch(initializeForms(forms))\n\t\tthis.dispatch(initializeFormRevisions(revisions))\n\t\tthis.dispatch(initializeFormRevisionAttachments(attachments))\n\t}\n}\n","import type {\n\tCreated,\n\tFormSubmission,\n\tFormSubmissionAttachment,\n\tOffline,\n\tOvermapRootState,\n\tPayload,\n\tStored,\n\tSubmitted,\n} from \"../../typings\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { HttpMethod } from \"enums/api\"\nimport { hashFile, offline } from \"utils\"\nimport { v4 as uuidv4 } from \"uuid\"\nimport {\n\taddActiveProjectFormSubmissionsCount,\n\taddFormSubmission,\n\taddFormSubmissionAttachments,\n\taddFormSubmissions,\n\tdeleteFormSubmission,\n\tdeleteFormSubmissionAttachments,\n\tinitializeFormSubmissionAttachments,\n\tinitializeFormSubmissions,\n\tselectAttachmentsOfFormSubmission,\n\tselectFormSubmissionAttachemntsByIds,\n\tselectFormSubmissionById,\n\tsetFormSubmission,\n\tupdateFormSubmission,\n\tupdateFormSubmissionAttachments,\n} from \"../../store\"\nimport { chunkArray } from \"../../utils/array\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport { FilePayload } from \"./BaseAttachmentService\"\nimport { FieldValue } from \"@overmap-ai/forms\"\n\nconst isArrayOfFiles = (value: unknown): value is File[] => {\n\treturn Array.isArray(value) && value[0] instanceof File\n}\n\n// returns a new object with the files separated from the values, files is a dictionary with the key being the\n// field identifier and the value being the list of files for that field\nconst separateFilesFromValues = (values: Record<string, FieldValue>) => {\n\tconst files: Record<string, File[]> = {}\n\tconst newValues: Record<string, FieldValue> = {}\n\n\tfor (const key in values) {\n\t\tconst value = values[key]\n\n\t\t// TODO: Not sure if this top condition is possible, but leaving it in for now\n\t\tif (value instanceof File) {\n\t\t\tfiles[key] = [value]\n\t\t} else if (isArrayOfFiles(value)) {\n\t\t\tfiles[key] = value\n\t\t} else if (value !== undefined) {\n\t\t\tnewValues[key] = value\n\t\t}\n\t}\n\n\treturn { values: newValues, files }\n}\n\ninterface BulkAddRequestReturnValue {\n\tsubmissions: Created<FormSubmission>[]\n\tattachments: Created<FormSubmissionAttachment>[]\n\tpresigned_urls: PresignedUrlsResponse\n}\n\nexport abstract class FormSubmissionService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tprivate async bulkAddSubmissionAttachments(\n\t\tsubmissionId: string,\n\t\tfiles: Record<string, File[]>,\n\t): Promise<OptimisticMultipleModelResult<FormSubmissionAttachment>> {\n\t\tinterface AttachmentPayload {\n\t\t\toffline_id: string\n\t\t\tname: string\n\t\t\tsha1: string\n\t\t\tfield_identifier: string\n\t\t\tdesscription?: string\n\t\t}\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = this.client.store.getState().userReducer.currentUser?.id\n\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\t\tconst offlineFormSubmissionAttachments: Stored<FormSubmissionAttachment>[] = []\n\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\n\t\tfor (const [fieldIdentifier, filesArray] of Object.entries(files)) {\n\t\t\tfor (const file of filesArray) {\n\t\t\t\tconst sha1 = await hashFile(file)\n\n\t\t\t\tif (!(sha1 in filePayloads)) {\n\t\t\t\t\tfilePayloads[sha1] = {\n\t\t\t\t\t\tsha1,\n\t\t\t\t\t\tfile_type: file.type,\n\t\t\t\t\t\textension: file.name.split(\".\").pop()!,\n\t\t\t\t\t\tsize: file.size,\n\t\t\t\t\t}\n\t\t\t\t\tawait this.client.files.addCache(file, sha1)\n\t\t\t\t}\n\n\t\t\t\tconst offlineFormSubmissionAttachment: Stored<FormSubmissionAttachment> = offline({\n\t\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\t\tfile_type: file.type,\n\t\t\t\t\tfile_name: file.name,\n\t\t\t\t\tfile_sha1: sha1,\n\t\t\t\t\tcreated_by: createdBy,\n\t\t\t\t\tsubmission: submissionId,\n\t\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\t})\n\t\t\t\tofflineFormSubmissionAttachments.push(offlineFormSubmissionAttachment)\n\n\t\t\t\tconst attachmentPayload: AttachmentPayload = {\n\t\t\t\t\toffline_id: offlineFormSubmissionAttachment.offline_id,\n\t\t\t\t\tname: file.name,\n\t\t\t\t\tsha1,\n\t\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\t}\n\t\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t\t}\n\t\t}\n\n\t\tthis.dispatch(addFormSubmissionAttachments(offlineFormSubmissionAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<FormSubmissionAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: \"Attach files to form submission\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/forms/submissions/${submissionId}/attachments/bulk/`,\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblockers: [submissionId],\n\t\t\tblocks: offlineFormSubmissionAttachments.map((attachment) => attachment.offline_id),\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(updateFormSubmissionAttachments(result.attachments))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(\n\t\t\t\t\tdeleteFormSubmissionAttachments(\n\t\t\t\t\t\tofflineFormSubmissionAttachments.map((attachment) => attachment.offline_id),\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t})\n\n\t\treturn [offlineFormSubmissionAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tprivate async bulkDeleteSubmissionAttachments(submissionId: string, attachmentsIds: string[]): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst formSubmissionAttachments = selectFormSubmissionAttachemntsByIds(attachmentsIds)(state)\n\n\t\tthis.dispatch(deleteFormSubmissionAttachments(attachmentsIds))\n\n\t\ttry {\n\t\t\tawait this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete form submission attachments\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/forms/submissions/${submissionId}/attachments/bulk/`,\n\t\t\t\tpayload: { attachments: attachmentsIds },\n\t\t\t\tblockers: [submissionId, ...attachmentsIds],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addFormSubmissionAttachments(formSubmissionAttachments))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\t// Outer promise is for hashing and caching files for submission attachments\n\tasync add(\n\t\tpayload: Payload<FormSubmission>,\n\t): Promise<\n\t\t[\n\t\t\tStored<FormSubmission>,\n\t\t\tStored<FormSubmissionAttachment>[],\n\t\t\tPromise<Created<FormSubmission>>,\n\t\t\tPromise<Created<FormSubmissionAttachment>[]>,\n\t\t]\n\t> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst { values, files } = separateFilesFromValues(payload.values)\n\n\t\tconst offlineSubmission: Submitted<FormSubmission> = offline({\n\t\t\t...payload,\n\t\t\tvalues: values,\n\t\t\tcreated_by: state.userReducer.currentUser?.id,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t})\n\n\t\tconst promise = this.enqueueRequest<Created<FormSubmission>>({\n\t\t\tdescription: \"Respond to form\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/forms/revisions/${payload.form_revision}/respond/`,\n\t\t\tpayload: offlineSubmission,\n\t\t\tblockers: [payload.issue, payload.asset, payload.asset_stage, \"add-form-entry\"].filter(\n\t\t\t\t(x) => x !== undefined,\n\t\t\t) as string[],\n\t\t\tblocks: [offlineSubmission.offline_id],\n\t\t})\n\n\t\tthis.dispatch(addFormSubmission(offlineSubmission))\n\n\t\tconst [offlineFormSubmissionAttachments, attachmentsPromise] = await this.bulkAddSubmissionAttachments(\n\t\t\tofflineSubmission.offline_id,\n\t\t\tfiles,\n\t\t)\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(addActiveProjectFormSubmissionsCount(1))\n\t\t\t\tthis.dispatch(setFormSubmission(result))\n\t\t\t\treturn result\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteFormSubmission(offlineSubmission.offline_id))\n\t\t\t\tthis.dispatch(addActiveProjectFormSubmissionsCount(-1))\n\t\t\t})\n\n\t\treturn [offlineSubmission, offlineFormSubmissionAttachments, promise, attachmentsPromise]\n\t}\n\n\t// Note currently the bulkAdd method is specific to form submissions for assets\n\t// TODO: adapt the support bulk adding to any model type\n\tasync bulkAdd(\n\t\targs: {\n\t\t\tformRevision: string\n\t\t\tcommonFieldValues: Record<string, FieldValue>\n\t\t\tfieldValuesByAsset: Record<string, Record<string, FieldValue>>\n\t\t},\n\t\tbatchSize: number,\n\t): Promise<Promise<BulkAddRequestReturnValue>[]> {\n\t\tinterface SubmissionPayload {\n\t\t\toffline_id: string\n\t\t\tasset_id: string\n\t\t\tform_data: Record<string, FieldValue>\n\t\t}\n\n\t\tinterface AttachmenPayload {\n\t\t\toffline_id: string\n\t\t\tsubmission_id: string\n\t\t\tsha1: string\n\t\t\tname: string\n\t\t\tfield_identifier: string\n\t\t}\n\n\t\tinterface FilePayload {\n\t\t\tsha1: string\n\t\t\textension: string\n\t\t\tfile_type: string\n\t\t\tsize: number\n\t\t}\n\n\t\tinterface BulkAddPayload {\n\t\t\ttransaction_id: string\n\t\t\tform_data: Record<string, FieldValue>\n\t\t\tsubmitted_at: string\n\t\t\tsubmissions: SubmissionPayload[]\n\t\t\tattachments: AttachmenPayload[]\n\t\t\tfiles: FilePayload[]\n\t\t}\n\n\t\tinterface BulkAddBatch {\n\t\t\tbatchId: string\n\t\t\tpayload: BulkAddPayload\n\t\t}\n\t\t// Things we need to do:\n\t\t// 1. separate any files from the submitted form values\n\t\t// 2. create offline submissions\n\t\t// 3. create offline attachments\n\t\t// 4. deduplicate any files\n\t\tconst { formRevision, commonFieldValues, fieldValuesByAsset } = args\n\n\t\tconst allFilesRecord: Record<string, FilePayload> = {}\n\n\t\tconst { values: fileSeperatedCommonFieldValues, files: commonFiles } =\n\t\t\tseparateFilesFromValues(commonFieldValues)\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst transactionId = uuidv4()\n\n\t\tconst assetIdBatches = chunkArray(Object.keys(fieldValuesByAsset), batchSize)\n\n\t\tconst bulkAddBatches: BulkAddBatch[] = await Promise.all(\n\t\t\tassetIdBatches.map(async (assetIdBatch) => {\n\t\t\t\tconst batchId = uuidv4()\n\t\t\t\tconst submissionPayloads: SubmissionPayload[] = []\n\t\t\t\tconst attachmentPayloads: AttachmenPayload[] = []\n\t\t\t\tconst files: Record<string, File[]> = { ...commonFiles }\n\n\t\t\t\tfor (const assetId of assetIdBatch) {\n\t\t\t\t\tconst { values: fileSeperatedSubmissionSpecificValues, files: submissionSpecificFiles } =\n\t\t\t\t\t\tseparateFilesFromValues(fieldValuesByAsset[assetId] ?? {})\n\n\t\t\t\t\tObject.assign(files, submissionSpecificFiles)\n\n\t\t\t\t\tconst submissionPayload: SubmissionPayload = offline({\n\t\t\t\t\t\tasset_id: assetId,\n\t\t\t\t\t\tform_data: fileSeperatedSubmissionSpecificValues,\n\t\t\t\t\t})\n\n\t\t\t\t\tsubmissionPayloads.push(submissionPayload)\n\n\t\t\t\t\tfor (const [fieldIdentifier, fileArray] of Object.entries(files)) {\n\t\t\t\t\t\tfor (const file of fileArray) {\n\t\t\t\t\t\t\tconst sha1 = await hashFile(file)\n\t\t\t\t\t\t\tawait this.client.files.addCache(file, sha1)\n\n\t\t\t\t\t\t\tconst attachmentPayload: AttachmenPayload = offline({\n\t\t\t\t\t\t\t\tsubmission_id: submissionPayload.offline_id,\n\t\t\t\t\t\t\t\tsha1,\n\t\t\t\t\t\t\t\tname: file.name,\n\t\t\t\t\t\t\t\tfield_identifier: fieldIdentifier,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tattachmentPayloads.push(attachmentPayload)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst filePaylods: FilePayload[] = []\n\n\t\t\t\tfor (const file of Object.values(files).flat()) {\n\t\t\t\t\tconst sha1 = await hashFile(file)\n\t\t\t\t\tconst filePayload: FilePayload = {\n\t\t\t\t\t\tsha1,\n\t\t\t\t\t\textension: file.name.split(\".\").pop() || \"\",\n\t\t\t\t\t\tfile_type: file.type,\n\t\t\t\t\t\tsize: file.size,\n\t\t\t\t\t}\n\t\t\t\t\tallFilesRecord[sha1] = filePayload\n\t\t\t\t\tfilePaylods.push(filePayload)\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tbatchId,\n\t\t\t\t\tpayload: {\n\t\t\t\t\t\ttransaction_id: transactionId,\n\t\t\t\t\t\tform_data: fileSeperatedCommonFieldValues,\n\t\t\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\t\t\tsubmissions: submissionPayloads,\n\t\t\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\t\t\tfiles: filePaylods,\n\t\t\t\t\t},\n\t\t\t\t} satisfies BulkAddBatch\n\t\t\t}),\n\t\t)\n\n\t\tconst batchPromises: Promise<BulkAddRequestReturnValue>[] = []\n\t\tlet prevBatchId: string | null = null\n\n\t\tfor (const batch of bulkAddBatches) {\n\t\t\tconst { payload, batchId } = batch\n\n\t\t\tconst batchAssetIds = payload.submissions.map((x) => x.asset_id)\n\t\t\tconst batchSubmissionOfflineIds = payload.submissions.map((x) => x.offline_id)\n\t\t\tconst batchAttachmentsOfflineIds = payload.attachments.map((x) => x.offline_id)\n\n\t\t\tconst blockers = batchAssetIds\n\t\t\tif (prevBatchId) blockers.push(prevBatchId)\n\n\t\t\tconst blocks = [...batchSubmissionOfflineIds, ...batchAttachmentsOfflineIds, batchId]\n\n\t\t\tconst promise = this.enqueueRequest<{\n\t\t\t\tsubmissions: Created<FormSubmission>[]\n\t\t\t\tattachments: Created<FormSubmissionAttachment>[]\n\t\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t\t}>({\n\t\t\t\tdescription: \"Bulk add form submissions\",\n\t\t\t\tmethod: HttpMethod.POST,\n\t\t\t\turl: `/forms/revisions/${formRevision}/bulk-respond/`,\n\t\t\t\tpayload: payload,\n\t\t\t\tblockers: blockers,\n\t\t\t\tblocks: blocks,\n\t\t\t})\n\n\t\t\tvoid promise.then(({ presigned_urls }) => {\n\t\t\t\tthis.processPresignedUrls(presigned_urls)\n\t\t\t})\n\n\t\t\tprevBatchId = batchId\n\n\t\t\tbatchPromises.push(promise)\n\t\t}\n\n\t\t// Only on success of every batch request, add the submissions and attachments to the store\n\t\tvoid Promise.all(batchPromises).then((results) => {\n\t\t\tconst createdSubmissions: Created<FormSubmission>[] = []\n\t\t\tconst createdAttachments: Created<FormSubmissionAttachment>[] = []\n\n\t\t\tfor (const result of results) {\n\t\t\t\tfor (const createdSubmission of result.submissions) createdSubmissions.push(createdSubmission)\n\t\t\t\tfor (const createdAttachment of result.attachments) createdAttachments.push(createdAttachment)\n\t\t\t}\n\n\t\t\tthis.dispatch(addFormSubmissions(createdSubmissions))\n\t\t\tthis.dispatch(addFormSubmissionAttachments(createdAttachments))\n\t\t})\n\n\t\treturn batchPromises\n\t}\n\n\tasync update(\n\t\tpayload: Offline<Partial<Payload<FormSubmission>>>,\n\t): Promise<\n\t\t[\n\t\t\tStored<FormSubmission>,\n\t\t\tStored<FormSubmissionAttachment>[],\n\t\t\tPromise<Created<FormSubmission>>,\n\t\t\tPromise<Created<FormSubmissionAttachment>[]>,\n\t\t\tPromise<void>,\n\t\t]\n\t> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst submissionToBeUpdated = selectFormSubmissionById(payload.offline_id)(state)\n\n\t\tif (!submissionToBeUpdated) {\n\t\t\tthrow new Error(`Expected submission with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst { values, files } = separateFilesFromValues(payload.values ?? {})\n\n\t\tconst updatedSubmission: Stored<FormSubmission> = {\n\t\t\t...submissionToBeUpdated,\n\t\t\t...payload,\n\t\t\t// values could also have a partial update\n\t\t\tvalues: {\n\t\t\t\t...submissionToBeUpdated.values,\n\t\t\t\t...values,\n\t\t\t},\n\t\t}\n\n\t\tthis.dispatch(updateFormSubmission(updatedSubmission))\n\n\t\tconst promise = this.enqueueRequest<Created<FormSubmission>>({\n\t\t\tdescription: \"Delete user form submissions\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/forms/submissions/${updatedSubmission.offline_id}/`,\n\t\t\t// TODO: send just payload when FormSubmissionDeserializer is updated to handle partial updates\n\t\t\tpayload: updatedSubmission,\n\t\t\tblockers: [updatedSubmission.offline_id],\n\t\t\tblocks: [updatedSubmission.offline_id],\n\t\t})\n\n\t\tconst formSubmissionAttachments = selectAttachmentsOfFormSubmission(payload.offline_id)(state)!\n\t\tconst formSubmissionAttachmentIdsToBeDeleted: string[] = []\n\n\t\tfor (const attachment of formSubmissionAttachments) {\n\t\t\tif (attachment.field_identifier in files) {\n\t\t\t\tformSubmissionAttachmentIdsToBeDeleted.push(attachment.offline_id)\n\t\t\t}\n\t\t}\n\n\t\tconst [offlineFormSubmissionAttachments, attachmentsPromise] = await this.bulkAddSubmissionAttachments(\n\t\t\tpayload.offline_id,\n\t\t\tfiles,\n\t\t)\n\n\t\tconst deleteAttachmentsPromise = this.bulkDeleteSubmissionAttachments(\n\t\t\tpayload.offline_id,\n\t\t\tformSubmissionAttachmentIdsToBeDeleted,\n\t\t)\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(setFormSubmission(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(setFormSubmission(submissionToBeUpdated))\n\t\t\t})\n\n\t\treturn [\n\t\t\tupdatedSubmission,\n\t\t\tofflineFormSubmissionAttachments,\n\t\t\tpromise,\n\t\t\tattachmentsPromise,\n\t\t\tdeleteAttachmentsPromise,\n\t\t]\n\t}\n\n\tasync delete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst submissionToBeDeleted = selectFormSubmissionById(id)(state)\n\n\t\tif (!submissionToBeDeleted) {\n\t\t\tthrow new Error(`Expected submission with offline_id ${id} to exist`)\n\t\t}\n\n\t\tconst submissionAttachments = selectAttachmentsOfFormSubmission(id)(state)!\n\n\t\tthis.dispatch(deleteFormSubmission(id))\n\t\tthis.dispatch(addActiveProjectFormSubmissionsCount(-1))\n\t\tthis.dispatch(deleteFormSubmissionAttachments(submissionAttachments.map((x) => x.offline_id)))\n\n\t\ttry {\n\t\t\t// REASON: Need to await to trigger the catch block.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n\t\t\treturn await this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete user form submissions\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/forms/submissions/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(addActiveProjectFormSubmissionsCount(1))\n\t\t\tthis.dispatch(addFormSubmission(submissionToBeDeleted))\n\t\t\tthis.dispatch(addFormSubmissionAttachments(submissionAttachments))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst formSubmissions: Record<string, Created<FormSubmission>> = {}\n\n\t\tconst modelSubmissions = await this.enqueueRequest<Created<FormSubmission>[]>({\n\t\t\tdescription: \"Fetch model submissions\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/forms/in-project/${projectId}/submissions/model/latest/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const modelSubmission of modelSubmissions) {\n\t\t\tformSubmissions[modelSubmission.offline_id] = modelSubmission\n\t\t}\n\n\t\tconst standaloneSubmissions = await this.enqueueRequest<Created<FormSubmission>[]>({\n\t\t\tdescription: \"Fetch standalone submissions\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/forms/in-project/${projectId}/submissions/standalone/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const standaloneSubmission of standaloneSubmissions) {\n\t\t\tformSubmissions[standaloneSubmission.offline_id] = standaloneSubmission\n\t\t}\n\n\t\tthis.dispatch(initializeFormSubmissions(Object.values(formSubmissions)))\n\n\t\tconst attachments: Record<string, Created<FormSubmissionAttachment>> = {}\n\n\t\tconst modelAttachments = await this.enqueueRequest<Created<FormSubmissionAttachment>[]>({\n\t\t\tdescription: \"Fetch model submission attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/forms/in-project/${projectId}/attachments/model/latest/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const modelAttachment of modelAttachments) {\n\t\t\tattachments[modelAttachment.offline_id] = modelAttachment\n\t\t}\n\n\t\tconst standaloneAttachments = await this.enqueueRequest<Created<FormSubmissionAttachment>[]>({\n\t\t\tdescription: \"Fetch standalone submission attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/forms/in-project/${projectId}/attachments/standalone/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const standaloneAttachent of standaloneAttachments) {\n\t\t\tattachments[standaloneAttachent.offline_id] = standaloneAttachent\n\t\t}\n\n\t\tthis.dispatch(initializeFormSubmissionAttachments(Object.values(attachments)))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport { addWorkspace, deleteWorkspace, initializeWorkspaces, selectWorkspaceById, updateWorkspace } from \"../../store\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport type { Created, Offline, OvermapRootState, Payload, Stored, Workspace } from \"../../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\nimport { offline } from \"../../utils\"\n\nexport abstract class WorkspaceService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<Workspace>): OptimisticModelResult<Workspace> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\n\t\tconst offlineWorkspace: Stored<Workspace> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\tcreated_by: createdBy,\n\t\t})\n\n\t\tthis.dispatch(addWorkspace(offlineWorkspace))\n\n\t\tconst promise = this.enqueueRequest<Created<Workspace>>({\n\t\t\tdescription: \"Create Workspace\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/projects/${payload.project}/workspaces/`,\n\t\t\tpayload: offlineWorkspace,\n\t\t\tblockers: [\"add-workspace\"],\n\t\t\tblocks: [offlineWorkspace.offline_id],\n\t\t})\n\n\t\tvoid promise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateWorkspace(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteWorkspace(offlineWorkspace.offline_id))\n\t\t\t})\n\n\t\treturn [offlineWorkspace, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Workspace>>>): OptimisticModelResult<Workspace> {\n\t\tconst { store } = this.client\n\n\t\tconst workspace = selectWorkspaceById(payload.offline_id)(store.getState())\n\n\t\tif (!workspace) {\n\t\t\tthrow new Error(`Expected an existing workspace with offline_id ${payload.offline_id}`)\n\t\t}\n\n\t\tconst updatedWorkspace: Stored<Workspace> = { ...workspace, ...payload }\n\n\t\tthis.dispatch(updateWorkspace(updatedWorkspace))\n\n\t\tconst promise = this.enqueueRequest<Created<Workspace>>({\n\t\t\tdescription: \"Update Workspace\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/workspaces/${workspace.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [workspace.offline_id],\n\t\t\tblocks: [workspace.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateWorkspace(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateWorkspace(workspace))\n\t\t\t})\n\n\t\treturn [workspace, promise]\n\t}\n\n\tdelete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\n\t\tconst originalWorkspace = selectWorkspaceById(id)(store.getState())\n\n\t\tif (!originalWorkspace) {\n\t\t\tthrow new Error(`Expected an existing workspace with id ${id}`)\n\t\t}\n\n\t\tthis.dispatch(deleteWorkspace(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete Workspace\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/workspaces/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tvoid promise.catch((reason) => {\n\t\t\tthis.dispatch(addWorkspace(originalWorkspace))\n\t\t\tthrow reason\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<Created<Workspace>[]>({\n\t\t\tdescription: \"Get workspaces\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/workspaces/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeWorkspaces(result))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport type { OrganizationAccess, Created, OvermapRootState } from \"../../typings\"\nimport {\n\tinitializeOrganizationAccesses,\n\tdeleteOrganizationAccess,\n\tremoveUser,\n\tupdateOrganizationAccess,\n} from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\n/**\n * Handles the creation of OrganizationAccess Service\n */\nexport abstract class OrganizationAccessService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync update(organizationAccess: OrganizationAccess): Promise<OrganizationAccess> {\n\t\tconst promise = this.enqueueRequest<Created<OrganizationAccess>>({\n\t\t\tdescription: \"Edit organization access\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/organizations/${organizationAccess.organization}/access/${organizationAccess.offline_id}/`,\n\t\t\tpayload: organizationAccess,\n\t\t\tblockers: [organizationAccess.offline_id],\n\t\t\tblocks: [organizationAccess.offline_id],\n\t\t})\n\n\t\tvoid promise.then(() => {\n\t\t\tthis.dispatch(updateOrganizationAccess(organizationAccess))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync remove(organizationAccess: OrganizationAccess): Promise<undefined> {\n\t\tthis.dispatch(deleteOrganizationAccess(organizationAccess.offline_id))\n\t\tthis.dispatch(removeUser(organizationAccess.user))\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Remove organization access\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/organizations/${organizationAccess.organization}/access/${organizationAccess.offline_id}/`,\n\t\t\tblockers: [organizationAccess.offline_id],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<OrganizationAccess[]>({\n\t\t\tdescription: \"Get organization accesses\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/access/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeOrganizationAccesses(result))\n\t}\n}\n","import { BaseApiService } from \"./BaseApiService\"\n\n// TODO: add more methods, add error handling, add quota management etc, make it work for any Attachment\n// Goal is to not use more than 80% of quota, as full utilization would stop the Redux offline store from\n// functioning properly as well\nimport { DBSchema, IDBPDatabase, openDB } from \"idb\"\nimport { HttpMethod } from \"enums\"\nimport { fileToBlob, getFileS3Key, getRenamedFile, hashFile } from \"utils\"\nimport { selectUploadUrl, setUploadUrl } from \"store/slices/fileSlice\"\nimport { APIError } from \"../errors\"\nimport type { SDKRequest } from \"../typings\"\nimport type { BaseSDK } from \"../base\"\nimport type { BaseState } from \"../../typings\"\n\nexport interface GetS3UrlSuccessResponse {\n\turl: string\n\tfields: Record<string, string>\n}\n\ninterface GetS3UrlWarningResponse {\n\twarning: string\n}\n\nexport type GetS3UrlResponse = GetS3UrlSuccessResponse | GetS3UrlWarningResponse\n\ninterface DatabaseFileProperties {\n\tfile_name: string\n\tfile_sha1: string\n\t/** When uploading, this is the s3 key of the file.\n\t * When downloading, this is the s3 public url.\n\t */\n\tfile: string\n}\n\ninterface FileCacheDB extends DBSchema {\n\tfiles: {\n\t\tvalue: File\n\t\tkey: string\n\t}\n}\n\nconst cachedRequestPromises: Record<string, Promise<File> | undefined> = {}\n// Used to minimize writing to the cache.\nconst _cachedKeys = new Set<string>()\n\n// <ANALYTICS>\nlet _filePutCacheHits = 0\nlet _filePutCacheMisses = 0\nlet _totalCount = 0\nconst summarizeEvery = 20\n// </ANALYTICS>\n\nexport abstract class FileService<TState extends BaseState, TSDK extends BaseSDK<TState>> extends BaseApiService<\n\tTState,\n\tTSDK\n> {\n\thost = import.meta.env.REACT_APP_API_URL as string\n\t// NOTE: If you alter the schema (of the IndexedDB database) in any way, you must increment the version in order to\n\t// migrate the store. This allows idb to automatically migrate the user's existing data to the new schema.\n\tprivate _dbPromise = openDB<FileCacheDB>(\"fileCache\", 1, {\n\t\tupgrade(db) {\n\t\t\tdb.createObjectStore(\"files\")\n\t\t},\n\t})\n\n\tprivate async renewUploadUrl(sha1: string): Promise<GetS3UrlResponse> {\n\t\tconst file = await this.fetchCache(sha1)\n\t\tif (!file) throw new Error(`File with sha1 ${sha1} not found in cache`)\n\t\tconst key = await getFileS3Key(file, sha1)\n\n\t\tconst s3UploadUrl = await this.enqueueRequest<GetS3UrlResponse>({\n\t\t\tdescription: \"Get S3 URL\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/authentication/files/presigned-upload-url/\",\n\t\t\tqueryParams: {\n\t\t\t\tsha1: await hashFile(file),\n\t\t\t\tfile_type: file.type,\n\t\t\t\textension: file.name.split(\".\").pop(),\n\t\t\t\tsize: file.size.toString(),\n\t\t\t},\n\t\t\tblockers: [],\n\t\t\tblocks: [`s3-${key}`],\n\t\t})\n\n\t\tif (\"url\" in s3UploadUrl) {\n\t\t\t// TODO: Why save it to the store?\n\t\t\tthis.dispatch(setUploadUrl({ sha1, ...s3UploadUrl }))\n\t\t}\n\t\treturn s3UploadUrl\n\t}\n\n\t/**\n\t * Adds a file to the cache using the sha1 hash as the key and returns the sha1 hash.\n\t * @param file The file to add to the cache\n\t * TODO: This should be removed once the bug described in [1] is fixed.\n\t * @param sha1 The sha1 hash of the file to cache.\n\t */\n\tasync addCache(file: File, sha1: string): Promise<void> {\n\t\tif (_cachedKeys.has(sha1)) {\n\t\t\treturn\n\t\t}\n\t\t// TODO: Check\n\t\tif (!file.type) {\n\t\t\tconst parts = file.name.split(\".\")\n\t\t\tconst extension = parts[parts.length - 1]\n\t\t\tfile = new File([file], file.name, { type: extension })\n\t\t}\n\t\tif (!file.name || !file.size || !file.type) {\n\t\t\tthrow new Error(\"Cannot add files to cache that do not have a name, size and type.\")\n\t\t}\n\t\tconst fileStorage: IDBPDatabase<FileCacheDB> = await this._dbPromise\n\t\t// TODO: Is this an improvement or not?\n\t\tconst alreadyCached = !!(await fileStorage.get(\"files\", sha1))\n\t\tif (!alreadyCached) {\n\t\t\tawait fileStorage.put(\"files\", file, sha1)\n\t\t\t_filePutCacheMisses++\n\t\t} else {\n\t\t\tconsole.error(\"File already cached (this is unexpected at this point):\", file.name, sha1)\n\t\t\t_filePutCacheHits++\n\t\t}\n\t\t_cachedKeys.add(sha1)\n\t\t_totalCount++\n\t\tif (_totalCount % summarizeEvery === 0) {\n\t\t\t// TODO: If this ends up hitting the console more often than not, they `alreadyCached` check might be more\n\t\t\t// performant than overwriting the identical file in the database. Because all file names saved are based\n\t\t\t// on the sha1 hash, we can guarantee that the files are identical, so there is no point in overwriting.\n\t\t\tconsole.debug(\n\t\t\t\t\"File cache summary: \" +\n\t\t\t\t\t`${_filePutCacheHits} hits and ${_filePutCacheMisses} misses, ` +\n\t\t\t\t\t`${(_filePutCacheHits / (_filePutCacheHits + _filePutCacheMisses)) * 100}% hit rate over ` +\n\t\t\t\t\t`${_totalCount} calls to addCache.`,\n\t\t\t)\n\t\t}\n\t}\n\n\tasync removeCache(sha1: string): Promise<void> {\n\t\tawait (await this._dbPromise).delete(\"files\", sha1)\n\t\t_cachedKeys.delete(sha1)\n\t}\n\n\tasync fetchCache(sha1: string): Promise<File | undefined> {\n\t\treturn (await this._dbPromise).get(\"files\", sha1)\n\t}\n\n\tasync getOrRenewUploadUrl(sha1: string): Promise<GetS3UrlResponse> {\n\t\tconst state = this.client.store.getState()\n\t\tconst uploadUrl = selectUploadUrl(sha1)(state)\n\n\t\treturn uploadUrl ?? (await this.renewUploadUrl(sha1))\n\t}\n\n\t/** Ensure the file has been added to the file cache before calling `uploadFileToS3()` */\n\tasync uploadFileToS3(sha1: string): Promise<[DatabaseFileProperties, Promise<undefined>]> {\n\t\tconst file = await this.fetchCache(sha1)\n\n\t\tif (!file) throw new Error(`File with sha1 ${sha1} not found in cache`)\n\n\t\tconst key = await getFileS3Key(file, sha1)\n\t\tconst dbFileProperties: DatabaseFileProperties = {\n\t\t\tfile_name: file.name,\n\t\t\tfile_sha1: sha1,\n\t\t\tfile: key,\n\t\t}\n\t\tconst fileUploadUrlResponse: GetS3UrlResponse = await this.getOrRenewUploadUrl(sha1)\n\n\t\tif (\"warning\" in fileUploadUrlResponse) {\n\t\t\tif (fileUploadUrlResponse.warning === \"already_uploaded\") {\n\t\t\t\treturn [dbFileProperties, Promise.resolve(undefined).then()]\n\t\t\t}\n\t\t\tthrow new Error(fileUploadUrlResponse.warning)\n\t\t}\n\n\t\tconst url = fileUploadUrlResponse.url\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\turl,\n\t\t\tdescription: \"Upload file\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\tisExternalUrl: true,\n\t\t\tisAuthNeeded: false,\n\t\t\tattachmentHash: sha1,\n\t\t\tblockers: [`s3-${key}`],\n\t\t\tblocks: [sha1],\n\t\t\ts3url: fileUploadUrlResponse,\n\t\t} satisfies SDKRequest)\n\n\t\treturn [dbFileProperties, promise]\n\t}\n\n\t/**\n\t * Fetches a file based on its URL and SHA1. SHA1 values should be known ahead of time because the SHA1 and URL of\n\t * any file is stored in a FileModelMixin (see backend). If the expected SHA1 doesn't match the actual SHA1 of the\n\t * file, an error will be thrown.\n\t * @param url The URL from which to get the file.\n\t * @param expectedSha1 The expected SHA1 of the file. If this doesn't match the actual SHA1 of the file, an error\n\t * will be thrown.\n\t * @param downloadedName (Optional) The name to give the file after download. Set to the name of an attachment, for\n\t * example.\n\t */\n\tasync fetchFileFromUrl(url: string, expectedSha1: string, downloadedName?: string | undefined): Promise<File> {\n\t\tconst requestCacheKey: string = url.split(\"?\")[0] ?? url\n\n\t\tconst cachedResult = await this.fetchCache(expectedSha1)\n\n\t\tif (cachedResult) {\n\t\t\tif (!cachedResult.name) {\n\t\t\t\tthrow new Error(\"Cached file unexpectedly has no name.\")\n\t\t\t}\n\t\t\treturn cachedResult\n\t\t}\n\n\t\tif (url.startsWith(\"blob:\")) {\n\t\t\tconst blob = await fileToBlob(url)\n\t\t\tconst file = new File([blob], downloadedName ?? expectedSha1, { type: blob.type })\n\t\t\tawait this.addCache(file, expectedSha1)\n\t\t\treturn file\n\t\t}\n\n\t\tlet promise = cachedRequestPromises[requestCacheKey]\n\t\tlet isFirstRequest = true\n\n\t\tif (!promise) {\n\t\t\tpromise = new Promise((resolve) => {\n\t\t\t\tvoid this.enqueueRequest<Blob>({\n\t\t\t\t\tdescription: \"Download file\",\n\t\t\t\t\tmethod: HttpMethod.GET,\n\t\t\t\t\turl,\n\t\t\t\t\t// If in development, we should assume the files are saved at localhost by the Django development server.\n\t\t\t\t\t// Setting this to true will lead to localhost:8000 being prepended to the URL.\n\t\t\t\t\tisExternalUrl: import.meta.env.PROD || url.startsWith(\"https://\"),\n\t\t\t\t\tisResponseBlob: true,\n\t\t\t\t\tisAuthNeeded: false,\n\t\t\t\t\tblockers: [expectedSha1],\n\t\t\t\t\tblocks: [expectedSha1],\n\t\t\t\t}).then((blob) => {\n\t\t\t\t\tconst blobToFile = new File([blob], downloadedName ?? expectedSha1, { type: blob.type })\n\t\t\t\t\tresolve(blobToFile)\n\t\t\t\t})\n\t\t\t})\n\t\t\tcachedRequestPromises[requestCacheKey] = promise\n\t\t} else {\n\t\t\tisFirstRequest = false\n\t\t}\n\n\t\tlet file: File\n\n\t\ttry {\n\t\t\tfile = await promise\n\t\t} catch (e) {\n\t\t\tif (isFirstRequest && e instanceof APIError) {\n\t\t\t\t// Don't cache failed promises\n\t\t\t\tdelete cachedRequestPromises[requestCacheKey]\n\t\t\t}\n\t\t\tthrow e\n\t\t}\n\n\t\tif (isFirstRequest) {\n\t\t\t// The first request for this image (in case there are concurrent ones) has the responsibility to cache the\n\t\t\t// file itself.\n\t\t\tconst actualSha1 = await hashFile(file)\n\t\t\tif (actualSha1 !== expectedSha1) {\n\t\t\t\tconst message = `The hash of the file returned from the server (${actualSha1}) does not match the \n\t\t\t\t\texpected hash (${expectedSha1}). This can happen if you're using a local development server and the \n\t\t\t\t\tisExternalUrl flag in the request details is set to true, because instead of requesting the local\n\t\t\t\t\tREST API, you will be requesting localhost:80 (where this app runs), resulting in a transformed blob\n\t\t\t\t\t(with an offline_id attached) being returned. Alternatively, you may be running with \n\t\t\t\t\timport.meta.env.PROD, which will result in some file requests being treated as\n\t\t\t\t\texternal URLs and therefore not prepended with VITE_API_URL.`\n\n\t\t\t\tthrow new Error(message)\n\t\t\t}\n\t\t\t// All files need a name. Otherwise, they might end up with duplicated keys in the PrimeReact FileUpload\n\t\t\t// asset (it uses the name, size and type as the key).\n\t\t\tconst extension = file.type.split(\"/\")[1]\n\t\t\tif (!extension) {\n\t\t\t\tthrow new Error(\"File has no extension\")\n\t\t\t}\n\t\t\tconst fileName = downloadedName ?? actualSha1 + \".\" + extension\n\n\t\t\tfile = getRenamedFile(file, fileName)\n\n\t\t\tif (!file.name) {\n\t\t\t\tthrow new Error(\"Failed to set file's name\")\n\t\t\t}\n\n\t\t\tawait this.addCache(file, actualSha1)\n\n\t\t\t// Overwrite the cached promise, so it returns the renamed file\n\t\t\tcachedRequestPromises[requestCacheKey] = new Promise((resolve) => {\n\t\t\t\tresolve(file)\n\t\t\t})\n\t\t}\n\n\t\treturn file\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\nimport type {\n\tEmailVerificationPayload,\n\tEmailVerificationReturn,\n\tOvermapRootState,\n\tVerificationCode,\n} from \"../../typings\"\n\nexport abstract class EmailVerificationService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync getVerificationCode(verificationCode: string): Promise<VerificationCode> {\n\t\treturn this.enqueueRequest<VerificationCode>({\n\t\t\tdescription: \"Get verification code\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/verification/email-verification/${verificationCode}/`,\n\t\t\tisAuthNeeded: false,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tvalidateVerificationCode(\n\t\tverificationCode: string,\n\t\tpayload: EmailVerificationPayload | undefined = undefined,\n\t): Promise<EmailVerificationReturn> {\n\t\treturn this.enqueueRequest<EmailVerificationReturn>({\n\t\t\tdescription: \"Validate verification code\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/verification/email-verification/${verificationCode}/`,\n\t\t\tisAuthNeeded: false,\n\t\t\tpayload,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport { initializeEmailDomains, deleteEmailDomain, addEmailDomain } from \"../../store\"\nimport type { Created, EmailDomain, OvermapRootState } from \"../../typings\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class EmailDomainsService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync add(orgId: number, email: string): Promise<undefined> {\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Add email domain to organization\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/organizations/${orgId}/email-domains/`,\n\t\t\tpayload: { email },\n\t\t\tblockers: [orgId.toString(), \"create-org\"],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync remove(emailDomain: EmailDomain): Promise<undefined> {\n\t\tthis.dispatch(deleteEmailDomain(emailDomain.offline_id))\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Remove email domain from organization\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/organizations/${emailDomain.organization}/email-domains/${emailDomain.offline_id}/`,\n\t\t\tblockers: [emailDomain.domain],\n\t\t\tblocks: [],\n\t\t}).catch((e) => {\n\t\t\tthis.dispatch(addEmailDomain(emailDomain))\n\t\t\tthrow e\n\t\t})\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<undefined> {\n\t\tconst result = await this.enqueueRequest<Created<EmailDomain>[]>({\n\t\t\tdescription: \"Fetch email domains for organization\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/email-domains/`,\n\t\t\tblockers: [organizationId.toString()],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeEmailDomains(result))\n\t}\n}\n","import type { Organization, OvermapRootState } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport { setOrganizations } from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class OrganizationService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tcreate(name: string): Promise<Organization> {\n\t\treturn this.enqueueRequest<Organization>({\n\t\t\tdescription: \"Create organization\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/organizations/\",\n\t\t\tpayload: { name },\n\t\t\tblockers: [],\n\t\t\tblocks: [`add-org-${name}`, \"create-org\"],\n\t\t})\n\t}\n\n\tasync update(organization: Organization): Promise<Organization> {\n\t\treturn this.enqueueRequest<Organization>({\n\t\t\tdescription: \"Edit organization\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/organizations/${organization.id}/`,\n\t\t\tpayload: organization,\n\t\t\tblockers: [`add-org-${organization.name}`, organization.id.toString()],\n\t\t\tblocks: [organization.id.toString()],\n\t\t})\n\t}\n\n\tasync invite(organizationId: number, email: string): Promise<undefined> {\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Invite user to organization\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/organizations/${organizationId}/invite/${email}/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number, organizationId: number): Promise<void> {\n\t\tconst organizationsRecord: Record<number, Organization> = {}\n\n\t\tconst projectOrganizations = await this.enqueueRequest<Organization[]>({\n\t\t\tdescription: \"Get organizations\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/organizations/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const organization of projectOrganizations) {\n\t\t\torganizationsRecord[organization.id] = organization\n\t\t}\n\n\t\tconst organization = await this.enqueueRequest<Organization>({\n\t\t\tdescription: \"Get organization\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\torganizationsRecord[organization.id] = organization\n\n\t\tthis.dispatch(setOrganizations(Object.values(organizationsRecord)))\n\t}\n}\n","import type { License, OvermapRootState, Project, Transaction } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport { initializeLicences, updateLicense } from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class LicenseService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync getLicense(license: License): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Get license\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/billing/${license.offline_id}/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.organization_owner ? license.organization_owner.toString() : \"\"],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\n\tasync pauseLicense(license: License): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Pause license\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/billing/${license.offline_id}/suspend/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.organization_owner ? license.organization_owner.toString() : \"\"],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\tasync resumeLicense(license: License): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Resume license\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/billing/${license.offline_id}/suspend/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.organization_owner ? license.organization_owner.toString() : \"\"],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\n\tasync cancelLicense(license: License): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Cancel license\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/billing/${license.offline_id}/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.organization_owner ? license.organization_owner.toString() : \"\"],\n\t\t\tblocks: [],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\n\tasync attachLicenseToProject(license: License, project: Project): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Attach license\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/billing/${license.offline_id}/project/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tpayload: { project: project.id },\n\t\t\tblockers: [\n\t\t\t\tlicense.organization_owner ? license.organization_owner.toString() : \"\",\n\t\t\t\tproject.id ? project.id.toString() : \"\",\n\t\t\t],\n\t\t\tblocks: [\"add-issue\", \"add-form-entry\", \"change-access-level\", \"add-workspace\"],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\n\tasync detachLicenseFromProject(license: License): Promise<License> {\n\t\tconst result = await this.enqueueRequest<License>({\n\t\t\tdescription: \"Detach license\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/billing/${license.offline_id}/project/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.organization_owner ? license.organization_owner.toString() : \"\"],\n\t\t\tblocks: [\"add-issue\", \"add-form-entry\", \"change-access-level\", \"add-workspace\"],\n\t\t})\n\t\tthis.dispatch(updateLicense(result))\n\t\treturn result\n\t}\n\n\tasync getLatestTransaction(license: License): Promise<Transaction> {\n\t\treturn await this.enqueueRequest<Transaction>({\n\t\t\tdescription: \"Get latest transaction\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/billing/${license.offline_id}/transaction/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [license.offline_id],\n\t\t\tblocks: [license.offline_id],\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number, organizationId: number): Promise<void> {\n\t\tconst licencesRecord: Record<string, License> = {}\n\n\t\tconst organizationLicences = await this.enqueueRequest<License[]>({\n\t\t\tdescription: \"Get licenses\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/licenses/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [organizationId.toString()],\n\t\t\tblocks: [\"add-issue\", \"add-form-entry\", \"change-access-level\", \"add-workspace\"],\n\t\t})\n\n\t\tfor (const license of organizationLicences) {\n\t\t\tlicencesRecord[license.offline_id] = license\n\t\t}\n\n\t\tconst projectLicences = await this.enqueueRequest<License[]>({\n\t\t\tdescription: \"Get licenses\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/licenses/`,\n\t\t\tisAuthNeeded: true,\n\t\t\tblockers: [projectId.toString()],\n\t\t\tblocks: [\"add-issue\", \"add-form-entry\", \"change-access-level\", \"add-workspace\"],\n\t\t})\n\n\t\tfor (const license of projectLicences) {\n\t\t\tlicencesRecord[license.offline_id] = license\n\t\t}\n\n\t\tthis.dispatch(initializeLicences(Object.values(licencesRecord)))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport {\n\taddDocuments,\n\tmoveDocument,\n\tremoveDocuments,\n\tselectDocumentById,\n\tselectDocumentsMapping,\n\tsetDocuments,\n\tupdateDocuments,\n} from \"../../store\"\nimport type { Created, Document, MovePosition, Offline, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class DocumentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tadd(payload: Payload<Document>): OptimisticModelResult<Document> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineDocument: Stored<Document> = offline({\n\t\t\t...payload,\n\t\t\tcreated_by: createdBy,\n\t\t\tsubmitted_at: submittedAt,\n\t\t})\n\n\t\tthis.dispatch(addDocuments([offlineDocument]))\n\n\t\tconst promise = this.enqueueRequest<Document>({\n\t\t\tdescription: \"Create Document\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/documents/\",\n\t\t\tpayload: offlineDocument,\n\t\t\tqueryParams: {\n\t\t\t\tparent_document: offlineDocument.parent_document ?? undefined,\n\t\t\t},\n\t\t\t// if adding as a child of another document, need that document to exist first\n\t\t\tblockers: offlineDocument.parent_document ? [offlineDocument.parent_document] : [],\n\t\t\tblocks: [offlineDocument.offline_id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(removeDocuments([offlineDocument.offline_id]))\n\t\t})\n\n\t\treturn [offlineDocument, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Document>>>): OptimisticModelResult<Document> {\n\t\tconst { store } = this.client\n\t\tconst documentToBeUpdated = store.getState().documentsReducer.documents[payload.offline_id]\n\n\t\tif (!documentToBeUpdated) {\n\t\t\tthrow new Error(\n\t\t\t\t`attempting to update a document with offline_id ${payload.offline_id} that does not exist in store.documents`,\n\t\t\t)\n\t\t}\n\n\t\tconst updatedDocument: Stored<Document> = {\n\t\t\t...documentToBeUpdated,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateDocuments([updatedDocument]))\n\n\t\tconst promise = this.enqueueRequest<Document>({\n\t\t\tdescription: \"Update Document\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/documents/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tupdateDocuments([documentToBeUpdated])\n\t\t})\n\n\t\treturn [updatedDocument, promise]\n\t}\n\n\tmove(documentId: string, targetDocumentId: string | null, position: MovePosition): Promise<Document[]> {\n\t\tconst { store } = this.client\n\t\tconst documentsMapping = selectDocumentsMapping(store.getState())\n\t\t/** the documents that need to be reverted if the move operation fails are:\n\t\t * 1. the document itself (could have attempted to change parents, changing to parent_document property)\n\t\t * 2. the parent of the document (the document could have been moved to a different parent, changing the old parents children_documents property)\n\t\t * 3. the target document (could have been the desired new parent document, changing the children_documents property)\n\t\t * 4. the parent of the target document (could have been the desired new parent document, changing the children_documents property) */\n\t\tconst documentsToRevertIfMoveFails: Document[] = []\n\n\t\tconst documentBeingMoved = documentsMapping[documentId]\n\t\tif (!documentBeingMoved) {\n\t\t\tthrow new Error(\n\t\t\t\t`attempting to move a document with offline_id ${documentId} that does not exist in store.documents`,\n\t\t\t)\n\t\t}\n\t\tdocumentsToRevertIfMoveFails.push(documentBeingMoved)\n\n\t\tif (documentBeingMoved.parent_document) {\n\t\t\tdocumentsToRevertIfMoveFails.push(documentsMapping[documentBeingMoved.parent_document]!)\n\t\t}\n\n\t\tif (targetDocumentId) {\n\t\t\tconst targetDocument = documentsMapping[targetDocumentId]\n\t\t\tif (!targetDocument) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`attempting to move a document to target with offline_id ${targetDocumentId} that does not exist in store.documents`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tdocumentsToRevertIfMoveFails.push(targetDocument)\n\n\t\t\tif (targetDocument.parent_document) {\n\t\t\t\tdocumentsToRevertIfMoveFails.push(documentsMapping[targetDocument.parent_document]!)\n\t\t\t}\n\t\t}\n\n\t\tthis.dispatch(moveDocument({ documentId, targetDocumentId, position }))\n\n\t\tconst promise = this.enqueueRequest<Document[]>({\n\t\t\tdescription: \"Move Document\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/documents/${documentId}/move/`,\n\t\t\tqueryParams: {\n\t\t\t\ttarget: targetDocumentId ?? undefined,\n\t\t\t\tposition,\n\t\t\t},\n\t\t\tblockers: [documentId],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(updateDocuments(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateDocuments(documentsToRevertIfMoveFails))\n\t\t\t})\n\n\t\treturn promise\n\t}\n\n\tdelete(id: string): Promise<Document[]> {\n\t\tconst { store } = this.client\n\t\tconst documentsMapping = selectDocumentsMapping(store.getState())\n\t\tconst documentToBeDeleted = selectDocumentById(id)(store.getState())\n\t\tif (!documentToBeDeleted) {\n\t\t\tthrow new Error(\n\t\t\t\t`attempting to delete a document with offline_id ${id} that does not exist in store.documents`,\n\t\t\t)\n\t\t}\n\t\tconst parentDocument = documentToBeDeleted.parent_document\n\t\t\t? documentsMapping[documentToBeDeleted.parent_document]\n\t\t\t: undefined\n\n\t\tthis.dispatch(removeDocuments([id]))\n\t\tconst promise = this.enqueueRequest<Created<Document>[]>({\n\t\t\tdescription: \"Delete Document\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/documents/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((documentsToUpdate) => {\n\t\t\t\tthis.dispatch(updateDocuments(documentsToUpdate))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(updateDocuments([documentToBeDeleted]))\n\t\t\t\tif (parentDocument) {\n\t\t\t\t\tthis.dispatch(updateDocuments([parentDocument]))\n\t\t\t\t}\n\t\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number, organizationId: number): Promise<void> {\n\t\t// NOTE: below fetches are guaranteed to not have any common documents between them since documents are owned exclusively by either a project or an organization\n\n\t\tconst projectDocumentsPromise = this.enqueueRequest<Created<Document>[]>({\n\t\t\tdescription: \"Get project documents\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/documents/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tconst organizationDocumentsPromise = this.enqueueRequest<Created<Document>[]>({\n\t\t\tdescription: \"Get organization documents\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/documents/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\t// Load project documents first because they are more likely to be seen\n\t\tthis.dispatch(setDocuments(await projectDocumentsPromise))\n\n\t\t// Load organization documents\n\t\tthis.dispatch(addDocuments(await organizationDocumentsPromise))\n\t}\n}\n","import {\n\tAttachmentPayload,\n\tBaseAttachmentService,\n\tBuildOfflineAttachmentData,\n\tFilePayload,\n} from \"./BaseAttachmentService\"\nimport {\n\taddDocumentAttachments,\n\tdeleteDocumentAttachment,\n\tdeleteDocumentAttachments,\n\tinitializeDocumentAttachments,\n\tselectDocumentAttachmentById,\n\tsetDocumentAttachment,\n\tupdateDocumentAttachments,\n} from \"../../store\"\nimport type { Created, DocumentAttachment, OvermapRootState, Stored } from \"../../typings\"\nimport { hashFile, offline } from \"../../utils\"\nimport type { OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { AttachmentModel, HttpMethod } from \"../../enums\"\n\nexport abstract class DocumentAttachmentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseAttachmentService<TState, TSDK, string, DocumentAttachment> {\n\tattachmentModel = AttachmentModel.Document\n\n\tinitializeAttachments = initializeDocumentAttachments\n\taddAttachments = addDocumentAttachments\n\tupdateAttachments = updateDocumentAttachments\n\tremoveAttachments = deleteDocumentAttachments\n\tremoveAttachment = deleteDocumentAttachment\n\tsetAttachment = setDocumentAttachment\n\n\tselectAttachment = selectDocumentAttachmentById\n\n\tprivate buildOfflineAttachment(data: BuildOfflineAttachmentData<string>) {\n\t\treturn offline({\n\t\t\tfile: URL.createObjectURL(data.file),\n\t\t\tfile_sha1: data.sha1,\n\t\t\tcreated_by: data.createdBy,\n\t\t\tfile_name: data.file.name,\n\t\t\tfile_type: data.file.type,\n\t\t\tsubmitted_at: data.submittedAt,\n\t\t\tdescription: data.description,\n\t\t\tdocument: data.modelId,\n\t\t}) satisfies Stored<DocumentAttachment>\n\t}\n\n\t// NOTE: overriding the method from BaseAttachmentService since document attachments get vectorized\n\tasync attachFilesToDocument(\n\t\tfiles: File[],\n\t\tdocumentId: string,\n\t): Promise<OptimisticMultipleModelResult<DocumentAttachment>> {\n\t\tconst { store } = this.client\n\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst submittedAt = new Date().toISOString()\n\n\t\tconst offlineAttachments: Stored<DocumentAttachment>[] = []\n\t\tconst attachmentPayloads: AttachmentPayload[] = []\n\t\tconst filePayloads: Record<FilePayload[\"sha1\"], FilePayload> = {}\n\n\t\t// track what attachments are associated with which sha1 so we can make them readable after processing presigned S3 urls\n\t\tconst sha1ToAttachmentIds: Record<string, string[]> = {}\n\n\t\tfor (const file of files) {\n\t\t\tconst sha1 = await hashFile(file)\n\n\t\t\tif (!(sha1 in filePayloads)) {\n\t\t\t\tfilePayloads[sha1] = {\n\t\t\t\t\tsha1,\n\t\t\t\t\tfile_type: file.type,\n\t\t\t\t\textension: file.name.split(\".\").pop()!,\n\t\t\t\t\tsize: file.size,\n\t\t\t\t}\n\n\t\t\t\tsha1ToAttachmentIds[sha1] = []\n\n\t\t\t\tawait this.client.files.addCache(file, sha1)\n\t\t\t}\n\n\t\t\tconst offlineAttachment = this.buildOfflineAttachment({\n\t\t\t\tfile,\n\t\t\t\tsha1,\n\t\t\t\tsubmittedAt,\n\t\t\t\tcreatedBy: createdBy,\n\t\t\t\tdescription: \"\",\n\t\t\t\tmodelId: documentId,\n\t\t\t})\n\t\t\tofflineAttachments.push(offlineAttachment)\n\n\t\t\tattachmentPayloads.push({\n\t\t\t\toffline_id: offlineAttachment.offline_id,\n\t\t\t\tname: offlineAttachment.file_name,\n\t\t\t\tsha1: offlineAttachment.file_sha1,\n\t\t\t\tdescription: offlineAttachment.description,\n\t\t\t})\n\n\t\t\tsha1ToAttachmentIds[sha1]!.push(offlineAttachment.offline_id)\n\t\t}\n\n\t\tthis.dispatch(this.addAttachments(offlineAttachments))\n\n\t\tconst promise = this.enqueueRequest<{\n\t\t\tattachments: Created<DocumentAttachment>[]\n\t\t\tpresigned_urls: PresignedUrlsResponse\n\t\t}>({\n\t\t\tdescription: \"Attach files to document\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/documents/${documentId}/attach/`,\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tattachments: attachmentPayloads,\n\t\t\t\tfiles: Object.values(filePayloads),\n\t\t\t},\n\t\t\tblocks: offlineAttachments.map((attachment) => attachment.offline_id),\n\t\t\tblockers: offlineAttachments.map((attachment) => attachment.file_sha1),\n\t\t})\n\n\t\tpromise\n\t\t\t.then(({ attachments, presigned_urls }) => {\n\t\t\t\tthis.dispatch(this.updateAttachments(attachments))\n\t\t\t\tconst promisesBySha1 = this.processPresignedUrls(presigned_urls)\n\n\t\t\t\tfor (const [sha1, promise] of Object.entries(promisesBySha1)) {\n\t\t\t\t\t// If successfully uploaded to S3, make each attachment readable\n\t\t\t\t\tvoid promise.then(() => {\n\t\t\t\t\t\tconst attachmentIds = sha1ToAttachmentIds[sha1]!\n\n\t\t\t\t\t\tfor (const attachmentId of attachmentIds) {\n\t\t\t\t\t\t\tthis.makeReadable(attachmentId)\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(this.removeAttachments(offlineAttachments.map((attachment) => attachment.offline_id)))\n\t\t\t})\n\n\t\treturn [offlineAttachments, promise.then(({ attachments }) => attachments)]\n\t}\n\n\tasync deleteDocumentAttachment(attachmentId: string): Promise<void> {\n\t\treturn this.deleteAttachment(attachmentId)\n\t}\n\n\tprivate makeReadable(attachmnentId: string) {\n\t\tvoid this.enqueueRequest({\n\t\t\tdescription: \"Add attachment to AI assistant\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/documents/attachments/${attachmnentId}/`,\n\t\t\tpayload: {\n\t\t\t\treadable_to_assistant: true,\n\t\t\t},\n\t\t\t// passing through \"index-document-attachment\" so at most one document attachment being indexed at a time\n\t\t\tblockers: [\"index-document-attachment\", attachmnentId],\n\t\t\tblocks: [\"index-document-attachment\"],\n\t\t})\n\t}\n\n\toverride async refreshStore(projectId: number, organizationId: number): Promise<void> {\n\t\tconst projectDocumentAttachments = await this.enqueueRequest<Created<DocumentAttachment>[]>({\n\t\t\tdescription: \"Get document attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/document-attachments/`,\n\t\t\tblocks: [],\n\t\t\tblockers: [],\n\t\t})\n\n\t\tthis.dispatch(this.initializeAttachments(projectDocumentAttachments))\n\n\t\tconst organizationDocumentAttachments = await this.enqueueRequest<Created<DocumentAttachment>[]>({\n\t\t\tdescription: \"Get document attachments\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/document-attachments/`,\n\t\t\tblocks: [],\n\t\t\tblockers: [],\n\t\t})\n\n\t\tthis.dispatch(this.addAttachments(organizationDocumentAttachments))\n\t}\n}\n","import type { AgentUserConversation, Created, OvermapRootState } from \"../../typings\"\nimport { HttpMethod } from \"../../enums\"\nimport { addConversation, initializeConversations, setConversation, updateConversation } from \"../../store\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class AgentService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseApiService<TState, TSDK> {\n\tasync startConversation(prompt: string): Promise<AgentUserConversation> {\n\t\tconst activeProjectId = this.client.store.getState().projectReducer.activeProjectId\n\t\treturn this.enqueueRequest<AgentUserConversation>({\n\t\t\tdescription: \"Start agent conversation\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/agents/prompt/\",\n\t\t\tpayload: {\n\t\t\t\tprompt,\n\t\t\t\tactive_project: activeProjectId,\n\t\t\t},\n\t\t\tblockers: [\"prompt\"],\n\t\t\tblocks: [\"prompt\"],\n\t\t}).then((response) => {\n\t\t\tthis.dispatch(addConversation(response))\n\t\t\treturn response\n\t\t})\n\t}\n\n\t/**\n\t * Prompt the agent with a message.\n\t * @param prompt The message to prompt the agent with.\n\t * @param conversationId If continuing an existing message, the UUID of that conversation.\n\t */\n\tasync continueConversation(prompt: string, conversationId: AgentUserConversation[\"offline_id\"]): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst activeProjectId = store.getState().projectReducer.activeProjectId\n\n\t\treturn this.enqueueRequest<Created<AgentUserConversation>>({\n\t\t\tdescription: \"Prompt agent\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/agents/prompt/\",\n\t\t\tpayload: {\n\t\t\t\tprompt: prompt,\n\t\t\t\tactive_project: activeProjectId,\n\t\t\t},\n\t\t\tblockers: [\"prompt\"],\n\t\t\tblocks: [\"prompt\"],\n\t\t\tqueryParams: { conversation_id: conversationId },\n\t\t}).then((response) => {\n\t\t\tthis.dispatch(updateConversation(response))\n\t\t})\n\t}\n\n\tasync fetchDetails(conversationId: AgentUserConversation[\"offline_id\"]): Promise<void> {\n\t\treturn this.enqueueRequest<AgentUserConversation>({\n\t\t\tdescription: \"Get agent conversation\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/agents/conversations/${conversationId}/`,\n\t\t\tblockers: [\"conversation\"],\n\t\t\tblocks: [\"conversation\"],\n\t\t}).then((response) => {\n\t\t\tthis.dispatch(setConversation(response))\n\t\t})\n\t}\n\n\tasync rate(responseId: string, rating: 1 | 5): Promise<undefined> {\n\t\treturn this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Rate agent response\",\n\t\t\tmethod: HttpMethod.PUT,\n\t\t\turl: `/agents/responses/${responseId}/rate/`,\n\t\t\tpayload: { rating },\n\t\t\tblockers: [\"rate\"],\n\t\t\tblocks: [\"rate\"],\n\t\t})\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<AgentUserConversation[]>({\n\t\t\tdescription: \"Get agent conversation history\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/agent-conversations/`,\n\t\t\tblockers: [\"agent-conversations\"],\n\t\t\tblocks: [\"agent-conversations\"],\n\t\t})\n\t\tthis.dispatch(initializeConversations(result))\n\t}\n}\n","import type { Created, Offline, OvermapRootState, Payload, Submitted, Team, User } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport { offline } from \"../../utils\"\nimport { addTeam, deleteTeam, initializeTeams, selectTeamById, setTeam, updateTeam } from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\nimport { BaseApiService } from \"./BaseApiService\"\nimport type { BaseSDK } from \"../base\"\n\nexport abstract class TeamService<TState extends OvermapRootState, TSDK extends BaseSDK<TState>> extends BaseApiService<\n\tTState,\n\tTSDK\n> {\n\tadd(payload: Payload<Team>): OptimisticModelResult<Team> {\n\t\tconst offlineTeam: Submitted<Team> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: new Date().toISOString(),\n\t\t\t// TODO: uncomment once supported\n\t\t\t// created_by: state.userReducer.currentUser.id,\n\t\t})\n\n\t\tthis.dispatch(addTeam(offlineTeam))\n\n\t\tconst promise = this.enqueueRequest<Team>({\n\t\t\tdescription: \"Create team\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: `/organizations/${payload.organization}/teams/`,\n\t\t\tpayload: offlineTeam,\n\t\t\t// No blocks since users and organizations are not offline\n\t\t\tblockers: [],\n\t\t\tblocks: [offlineTeam.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((createdTeam) => {\n\t\t\t\tthis.dispatch(setTeam(createdTeam))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteTeam(offlineTeam.offline_id))\n\t\t\t})\n\n\t\treturn [offlineTeam, promise]\n\t}\n\n\tupdate(payload: Offline<Partial<Payload<Team>>>): OptimisticModelResult<Team> {\n\t\tconst { store } = this.client\n\n\t\tconst teamToBeUpdated = selectTeamById(payload.offline_id)(store.getState())\n\n\t\tif (!teamToBeUpdated) {\n\t\t\tthrow new Error(`Expected team with offline_id ${payload.offline_id} to exist`)\n\t\t}\n\n\t\tconst offlineUpdatedTeam: Submitted<Team> = {\n\t\t\t...teamToBeUpdated,\n\t\t\t...payload,\n\t\t}\n\n\t\tthis.dispatch(updateTeam(offlineUpdatedTeam))\n\n\t\tconst promise = this.enqueueRequest<Team>({\n\t\t\tdescription: \"Update team\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/organizations/teams/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblockers: [payload.offline_id],\n\t\t\tblocks: [payload.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((updatedTeam) => {\n\t\t\t\t// sync the updated team with the store\n\t\t\t\tthis.dispatch(setTeam(updatedTeam))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(setTeam(teamToBeUpdated))\n\t\t\t})\n\n\t\treturn [offlineUpdatedTeam, promise]\n\t}\n\n\tasync delete(id: string): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst team = selectTeamById(id)(state)\n\n\t\tif (!team) {\n\t\t\tthrow new Error(`Expected team with id ${id} to exist`)\n\t\t}\n\n\t\tthis.dispatch(deleteTeam(id))\n\n\t\ttry {\n\t\t\t// REASON: Need to await to trigger the catch block.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n\t\t\treturn await this.enqueueRequest<undefined>({\n\t\t\t\tdescription: \"Delete team\",\n\t\t\t\tmethod: HttpMethod.DELETE,\n\t\t\t\turl: `/organizations/teams/${id}/`,\n\t\t\t\tblockers: [id],\n\t\t\t\tblocks: [id],\n\t\t\t})\n\t\t} catch (e) {\n\t\t\tthis.dispatch(setTeam(team))\n\t\t\tthrow e\n\t\t}\n\t}\n\n\tasync setMembers(teamId: string, members: User[\"id\"][]): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst team = selectTeamById(teamId)(store.getState())\n\n\t\tif (!team) {\n\t\t\tthrow new Error(`Expected team with id ${teamId} to exist`)\n\t\t}\n\n\t\tif (members.length !== new Set(members).size) {\n\t\t\tthrow new Error(\"Duplicate members found in the list\")\n\t\t}\n\n\t\tthis.dispatch(updateTeam({ ...team, members }))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Set team members\",\n\t\t\tmethod: HttpMethod.PUT,\n\t\t\turl: `/organizations/teams/${teamId}/set-members/`,\n\t\t\tpayload: {\n\t\t\t\tusers: members,\n\t\t\t},\n\t\t\tblockers: [teamId],\n\t\t\tblocks: [teamId],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(setTeam(team))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync addMembers(teamId: string, members: User[\"id\"][]): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst team = selectTeamById(teamId)(store.getState())\n\n\t\tif (!team) {\n\t\t\tthrow new Error(`Expected team with id ${teamId} to exist`)\n\t\t}\n\n\t\tconst newMembers = [...team.members, ...members]\n\n\t\treturn this.setMembers(teamId, newMembers)\n\t}\n\n\tasync removeMembers(teamId: string, members: User[\"id\"][]): Promise<undefined> {\n\t\tconst { store } = this.client\n\t\tconst team = selectTeamById(teamId)(store.getState())\n\n\t\tif (!team) {\n\t\t\tthrow new Error(`Expected team with id ${teamId} to exist`)\n\t\t}\n\n\t\tconst newMembers = team.members.filter((member) => !members.includes(member))\n\n\t\treturn this.setMembers(teamId, newMembers)\n\t}\n\n\tasync refreshStore(organizationId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<Team>[]>({\n\t\t\tdescription: \"Fetch teams\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/teams/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeTeams(result))\n\t}\n}\n","import { BaseApiService } from \"./BaseApiService\"\nimport { setUsers } from \"../../store\"\nimport type { OvermapRootState, User } from \"../../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class UserService<TState extends OvermapRootState, TSDK extends BaseSDK<TState>> extends BaseApiService<\n\tTState,\n\tTSDK\n> {\n\tasync refreshStore(projectId: number, organizationId: number): Promise<void> {\n\t\tconst usersRecord: Record<number, User> = {}\n\n\t\tconst organizationUsers = await this.enqueueRequest<User[]>({\n\t\t\tdescription: \"Fetch organization users\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/organizations/${organizationId}/users/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const user of organizationUsers) {\n\t\t\tusersRecord[user.id] = user\n\t\t}\n\n\t\tconst projectUsers = await this.enqueueRequest<User[]>({\n\t\t\tdescription: \"Fetch project users\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/users/`,\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tfor (const user of projectUsers) {\n\t\t\tusersRecord[user.id] = user\n\t\t}\n\n\t\tthis.dispatch(setUsers(Object.values(usersRecord)))\n\t}\n}\n","import { HttpMethod } from \"../../enums\"\nimport type {\n\tBulkGeoImagePayload,\n\tCreated,\n\tGeoImage,\n\tGeoImagePayload,\n\tOffline,\n\tOvermapRootState,\n\tPointGeometry,\n\tStored,\n\tSubmitted,\n} from \"../../typings\"\nimport type { OptimisticModelResult, OptimisticMultipleModelResult, PresignedUrlsResponse } from \"../typings\"\nimport { hashFile, offline } from \"../../utils\"\nimport { FilePayload } from \"./BaseAttachmentService\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport {\n\taddGeoImage,\n\taddGeoImages,\n\tdeleteGeoImage,\n\tdeleteGeoImages,\n\tinitializeGeoImages,\n\tselectGeoImageById,\n\tsetGeoImage,\n\tsetGeoImages,\n\tupdateGeoImage,\n} from \"../../store\"\n\ninterface BulkCreateGeoImagesPayload {\n\tsubmitted_at: string\n\tproject: number\n\tgeo_images: {\n\t\t// requireds\n\t\toffline_id: string\n\t\tsha1: string\n\t\tfile_name: string\n\t\t// optionals\n\t\ttitle?: string\n\t\tdescription?: string\n\t\tgeo_marker?: PointGeometry\n\t\tcanvas_marker?: PointGeometry\n\n\t\tdirection?: number\n\t\toriginal_date?: string\n\t}[]\n\tfiles: FilePayload[]\n}\n\ninterface CreateGeoImageResult {\n\tgeo_image: Created<GeoImage>\n\tpresigned_urls: PresignedUrlsResponse\n}\n\ninterface BulkCreateMapImagesResult {\n\tgeo_images: Created<GeoImage>[]\n\tpresigned_urls: PresignedUrlsResponse\n}\n\nexport abstract class GeoImageService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tasync add(payload: GeoImagePayload): Promise<OptimisticModelResult<GeoImage>> {\n\t\tconst { store } = this.client\n\n\t\tconst { file, ...payloadWithoutFile } = payload\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\t\tconst projectId = payloadWithoutFile.project\n\n\t\tconst sha1 = await hashFile(file)\n\n\t\tconst filePayload: FilePayload = {\n\t\t\tsha1,\n\t\t\tfile_type: file.type,\n\t\t\textension: file.name.split(\".\").pop()!,\n\t\t\tsize: file.size,\n\t\t}\n\n\t\tconst offlineMapImage: Stored<GeoImage> = offline({\n\t\t\t...payloadWithoutFile,\n\t\t\tfile_name: file.name,\n\t\t\tfile_sha1: sha1,\n\t\t\tfile: URL.createObjectURL(file),\n\t\t\tsubmitted_at: submittedAt,\n\t\t\tcreated_by: createdBy,\n\t\t})\n\n\t\tthis.dispatch(addGeoImage(offlineMapImage))\n\n\t\tconst promise = this.enqueueRequest<CreateGeoImageResult>({\n\t\t\tdescription: \"Add geo image\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/geo-images/\",\n\t\t\tpayload: {\n\t\t\t\toffline_id: offlineMapImage.offline_id,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\ttitle: offlineMapImage.title,\n\t\t\t\tdescription: offlineMapImage.description,\n\t\t\t\tgeo_marker: offlineMapImage.geo_marker,\n\t\t\t\tcanvas_marker: offlineMapImage.canvas_marker,\n\t\t\t\tsha1: offlineMapImage.file_sha1,\n\t\t\t\tproject: offlineMapImage.project,\n\t\t\t\tfile_name: offlineMapImage.file_name,\n\t\t\t\tdirection: offlineMapImage.direction,\n\t\t\t\toriginal_date: offlineMapImage.original_date,\n\t\t\t\tfile: filePayload,\n\t\t\t},\n\t\t\tblocks: [projectId.toString()],\n\t\t\tblockers: [projectId.toString()],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(setGeoImage(result.geo_image))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteGeoImage(offlineMapImage.offline_id))\n\t\t\t})\n\n\t\treturn [offlineMapImage, promise.then((result) => result.geo_image)]\n\t}\n\n\tasync bulkAdd(\n\t\tpayloads: BulkGeoImagePayload[],\n\t\tprojectId: number,\n\t): Promise<OptimisticMultipleModelResult<GeoImage>> {\n\t\tconst { store } = this.client\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\n\t\tconst offlineGeoImages: Submitted<GeoImage>[] = []\n\t\tconst offlineIds: string[] = []\n\t\tconst geoImagePayloads: BulkCreateGeoImagesPayload[\"geo_images\"] = []\n\t\tconst filePayloadRecord: Record<string, FilePayload> = {}\n\n\t\tfor (const payloadAndFile of payloads) {\n\t\t\tconst { file, ...payload } = payloadAndFile\n\n\t\t\tconst sha1 = await hashFile(file)\n\t\t\tif (!(sha1 in filePayloadRecord)) {\n\t\t\t\tfilePayloadRecord[sha1] = {\n\t\t\t\t\tsha1,\n\t\t\t\t\tfile_type: file.type,\n\t\t\t\t\textension: file.name.split(\".\").pop()!,\n\t\t\t\t\tsize: file.size,\n\t\t\t\t}\n\t\t\t\tawait this.client.files.addCache(file, sha1)\n\t\t\t}\n\n\t\t\tconst offlineMapImage: Stored<GeoImage> = offline({\n\t\t\t\t...payload,\n\t\t\t\tfile_name: file.name,\n\t\t\t\tfile_sha1: sha1,\n\t\t\t\tfile: URL.createObjectURL(file),\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tcreated_by: createdBy,\n\t\t\t\tproject: projectId,\n\t\t\t})\n\t\t\tofflineGeoImages.push(offlineMapImage)\n\n\t\t\tofflineIds.push(offlineMapImage.offline_id)\n\n\t\t\tgeoImagePayloads.push({\n\t\t\t\toffline_id: offlineMapImage.offline_id,\n\t\t\t\tsha1: offlineMapImage.file_sha1,\n\t\t\t\tfile_name: offlineMapImage.file_name,\n\n\t\t\t\ttitle: offlineMapImage.title,\n\t\t\t\tdescription: offlineMapImage.description,\n\t\t\t\tgeo_marker: offlineMapImage.geo_marker,\n\t\t\t\tcanvas_marker: offlineMapImage.canvas_marker,\n\t\t\t\tdirection: offlineMapImage.direction,\n\t\t\t\toriginal_date: offlineMapImage.original_date,\n\t\t\t})\n\t\t}\n\n\t\tthis.dispatch(addGeoImages(offlineGeoImages))\n\n\t\tconst promise = this.enqueueRequest<BulkCreateMapImagesResult>({\n\t\t\tdescription: \"Bulk add geo images\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/geo-images/bulk/\",\n\t\t\tpayload: {\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\tproject: projectId,\n\t\t\t\tgeo_images: geoImagePayloads,\n\t\t\t\tfiles: Object.values(filePayloadRecord),\n\t\t\t} satisfies BulkCreateGeoImagesPayload,\n\t\t\tblocks: [projectId.toString()],\n\t\t\tblockers: offlineIds,\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.processPresignedUrls(result.presigned_urls)\n\t\t\t\tthis.dispatch(setGeoImages(result.geo_images))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteGeoImages(offlineIds))\n\t\t\t})\n\n\t\treturn [offlineGeoImages, promise.then((result) => result.geo_images)]\n\t}\n\n\tupdate(payload: Offline<Partial<Pick<GeoImagePayload, \"title\" | \"description\">>>): OptimisticModelResult<GeoImage> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst geoImageToUpdate = selectGeoImageById(payload.offline_id)(state)\n\n\t\tif (!geoImageToUpdate) {\n\t\t\tthrow new Error(`Map image with offline_id ${payload.offline_id} does not exist in the store`)\n\t\t}\n\n\t\tconst updatedGeoImage: Stored<GeoImage> = { ...geoImageToUpdate, ...payload }\n\n\t\tthis.dispatch(updateGeoImage(updatedGeoImage))\n\n\t\tconst promise = this.enqueueRequest<Created<GeoImage>>({\n\t\t\tdescription: \"Update geo image\",\n\t\t\tmethod: HttpMethod.PATCH,\n\t\t\turl: `/geo-images/${payload.offline_id}/`,\n\t\t\tpayload: payload,\n\t\t\tblocks: [payload.offline_id],\n\t\t\tblockers: [payload.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((result) => {\n\t\t\t\tthis.dispatch(setGeoImage(result))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(setGeoImage(geoImageToUpdate))\n\t\t\t})\n\n\t\treturn [updatedGeoImage, promise]\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tconst { store } = this.client\n\t\tconst state = store.getState()\n\n\t\tconst geoImageToDelete = selectGeoImageById(id)(state)\n\n\t\tif (!geoImageToDelete) {\n\t\t\tthrow new Error(`Map image with offline_id ${id} does not exist in the store`)\n\t\t}\n\n\t\tthis.dispatch(deleteGeoImage(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete geo image\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/geo-images/${id}/`,\n\t\t\tblocks: [id],\n\t\t\tblockers: [id],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(setGeoImage(geoImageToDelete))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst result = await this.enqueueRequest<Created<GeoImage>[]>({\n\t\t\tdescription: \"Get geo images\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: `/projects/${projectId}/geo-images/`,\n\t\t\tblocks: [projectId.toString()],\n\t\t\tblockers: [],\n\t\t})\n\n\t\tthis.dispatch(initializeGeoImages(result))\n\t}\n}\n","import type { Created, IssueAssociation, OvermapRootState, Payload, Stored } from \"../../typings\"\nimport type { OptimisticModelResult } from \"../typings\"\nimport type { BaseSDK } from \"../base\"\nimport { BaseUploadService } from \"./BaseUploadService\"\nimport { offline } from \"../../utils\"\nimport {\n\taddIssueAssociation,\n\tdeleteIssueAssociation,\n\tinitializeIssueAssociations,\n\tselectIssueAssociationById,\n\tupdateIssueAssociation,\n} from \"../../store\"\nimport { HttpMethod } from \"../../enums\"\n\nexport abstract class IssueAssociationService<\n\tTState extends OvermapRootState,\n\tTSDK extends BaseSDK<TState>,\n> extends BaseUploadService<TState, TSDK> {\n\tadd(payload: Payload<IssueAssociation>): OptimisticModelResult<IssueAssociation> {\n\t\tconst { store } = this.client\n\n\t\tconst submittedAt = new Date().toISOString()\n\t\tconst createdBy = store.getState().userReducer.currentUser?.id\n\n\t\tconst offlineIssueAssociation: Stored<IssueAssociation> = offline({\n\t\t\t...payload,\n\t\t\tsubmitted_at: submittedAt,\n\t\t\tcreated_by: createdBy,\n\t\t})\n\n\t\tthis.dispatch(addIssueAssociation(offlineIssueAssociation))\n\n\t\tconst promise = this.enqueueRequest<Created<IssueAssociation>>({\n\t\t\tdescription: \"Add issue association\",\n\t\t\tmethod: HttpMethod.POST,\n\t\t\turl: \"/issues/associations/\",\n\t\t\tpayload: {\n\t\t\t\toffline_id: offlineIssueAssociation.offline_id,\n\t\t\t\tsubmitted_at: submittedAt,\n\t\t\t\t...payload,\n\t\t\t},\n\t\t\tblockers: [\n\t\t\t\tpayload.associated_issue,\n\t\t\t\t...(payload.issue ? [payload.issue] : []),\n\t\t\t\t...(payload.asset ? [payload.asset] : []),\n\t\t\t],\n\t\t\tblocks: [offlineIssueAssociation.offline_id],\n\t\t})\n\n\t\tpromise\n\t\t\t.then((issueAssociation) => {\n\t\t\t\tthis.dispatch(updateIssueAssociation(issueAssociation))\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\tthis.dispatch(deleteIssueAssociation(offlineIssueAssociation.offline_id))\n\t\t\t})\n\n\t\treturn [offlineIssueAssociation, promise]\n\t}\n\n\tasync delete(id: string): Promise<void> {\n\t\tconst { store } = this.client\n\n\t\tconst issueAssociation = selectIssueAssociationById(id)(store.getState())\n\n\t\tif (!issueAssociation) {\n\t\t\tthrow new Error(`Issue association with id ${id} not found in store.`)\n\t\t}\n\n\t\tthis.dispatch(deleteIssueAssociation(id))\n\n\t\tconst promise = this.enqueueRequest<undefined>({\n\t\t\tdescription: \"Delete issue association\",\n\t\t\tmethod: HttpMethod.DELETE,\n\t\t\turl: `/issues/associations/${id}/`,\n\t\t\tblockers: [id],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tpromise.catch(() => {\n\t\t\tthis.dispatch(addIssueAssociation(issueAssociation))\n\t\t})\n\n\t\treturn promise\n\t}\n\n\tasync refreshStore(projectId: number): Promise<void> {\n\t\tconst issueAssociations = await this.enqueueRequest<Created<IssueAssociation>[]>({\n\t\t\tdescription: \"Fetch issue associations\",\n\t\t\tmethod: HttpMethod.GET,\n\t\t\turl: \"/issues/associations/\",\n\t\t\tqueryParams: { project_id: projectId.toString() },\n\t\t\tblockers: [],\n\t\t\tblocks: [],\n\t\t})\n\n\t\tthis.dispatch(initializeIssueAssociations(issueAssociations))\n\t}\n}\n","import type { RegistrationPayload } from \"./users\"\nimport type { OfflineModel } from \"./base\"\n\nexport type EmailVerificationPayload = undefined | RegistrationPayload | Omit<RegistrationPayload, \"username\" | \"email\">\n\nexport interface EmailVerificationReturn {\n\tusername?: string\n\tproject?: number\n}\n\nexport enum VerificationCodeType {\n\tUSER_REGISTRATION = 0,\n\tAPPLICATION_INVITE = 2,\n\tPROJECT_INVITE = 4,\n\tORGANIZATION_INVITE = 6,\n\tADD_EMAIL_DOMAIN = 8,\n\tRESET_PASSWORD = 10,\n}\n\nexport interface VerificationCode extends OfflineModel {\n\tverification_code: string\n\tverification_type: VerificationCodeType\n\torganization?: number\n\tproject?: number\n\tuser?: number\n}\n"],"names":["HttpMethod","AttachmentModel","IssuePriority","IssueStatus","IssueUpdateChange","ProjectAccessLevel","OrganizationAccessLevel","PaddleCheckoutEvent","LicenseLevel","LicenseStatus","request","_a","uuidv4","randomString","VERSION_REDUCER_KEY","migration","initialState","today","document","clientStore","offline","clientSDK","coordinator","payload","issueAttachmentReducer","assetAttachmentReducer","assetTypeAttachmentReducer","documentAttachmentReducer","projectAttachmentReducer","formRevisionAttachmentReducer","formSubmissionAttachmentReducer","geoImageReducer","file","organization","promise","VerificationCodeType"],"mappings":"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","x_google_ignoreList":[20]}
|