@overmap-ai/core 1.0.71-project-file-improvements.4 → 1.0.71-workspace-settings.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.
@@ -1127,9 +1127,8 @@ var __publicField = (obj, key, value) => {
1127
1127
  );
1128
1128
  const selectStagesOfAssetType = restructureCreateSelectorWithArgs(
1129
1129
  toolkit.createSelector([selectAssetStages, (_state, assetTypeId) => assetTypeId], (stages, assetTypeId) => {
1130
- return fallbackToEmptyArray(
1131
- stages.filter((stage) => stage.asset_type === assetTypeId).sort((a, b) => a.priority - b.priority)
1132
- );
1130
+ const stagesOfAssetType = stages.filter((stage) => stage.asset_type === assetTypeId);
1131
+ return fallbackToEmptyArray(stagesOfAssetType.sort((a, b) => a.priority - b.priority));
1133
1132
  })
1134
1133
  );
1135
1134
  const selectAssetStagesByIds = restructureCreateSelectorWithArgs(
@@ -1846,36 +1845,86 @@ var __publicField = (obj, key, value) => {
1846
1845
  const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
1847
1846
  const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
1848
1847
  const outboxReducer = outboxSlice.reducer;
1849
- const projectFileAdapter = createModelAdapter((file) => file.offline_id);
1850
- const initialState$j = projectFileAdapter.getInitialState({});
1848
+ const initialState$j = {
1849
+ projectFiles: {},
1850
+ activeProjectFileId: null,
1851
+ isImportingProjectFile: false
1852
+ };
1851
1853
  const projectFileSlice = toolkit.createSlice({
1852
1854
  name: "projectFiles",
1853
1855
  initialState: initialState$j,
1854
1856
  extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1855
1857
  reducers: {
1856
- initializeProjectFiles: projectFileAdapter.initialize,
1857
- addProjectFile: projectFileAdapter.addOne,
1858
- addProjectFiles: projectFileAdapter.addMany,
1859
- setProjectFile: projectFileAdapter.setOne,
1860
- setProjectFiles: projectFileAdapter.setMany,
1861
- updateProjectFile: projectFileAdapter.updateOne,
1862
- updateProjectFiles: projectFileAdapter.updateMany,
1863
- deleteProjectFile: projectFileAdapter.deleteOne,
1864
- deleteProjectFiles: projectFileAdapter.deleteMany
1858
+ addOrReplaceProjectFiles: (state, action) => {
1859
+ for (let fileObj of action.payload) {
1860
+ let file = fileObj.file;
1861
+ if (file.includes("+")) {
1862
+ console.warn("Attempting to apply fix for image URL with '+' character:", file);
1863
+ const parts = file.split("/");
1864
+ if (parts.length < 2) {
1865
+ throw new Error("Invalid URL: " + file);
1866
+ }
1867
+ const lastPart = encodeURIComponent(parts[parts.length - 1]);
1868
+ file = parts.slice(0, -1).join("/") + "/" + lastPart;
1869
+ console.warn("Fixed URL:", file);
1870
+ fileObj = { ...fileObj, file };
1871
+ }
1872
+ state.projectFiles[fileObj.offline_id] = fileObj;
1873
+ }
1874
+ },
1875
+ addOrReplaceProjectFile: (state, action) => {
1876
+ if (!action.payload.project) {
1877
+ throw new Error("ProjectFile has no project. A project must be set before storing.");
1878
+ }
1879
+ state.projectFiles[action.payload.offline_id] = action.payload;
1880
+ },
1881
+ setIsImportingProjectFile: (state, action) => {
1882
+ state.isImportingProjectFile = action.payload;
1883
+ },
1884
+ saveActiveProjectFileBounds: (state, action) => {
1885
+ const activeProjectFileId = state.activeProjectFileId;
1886
+ if (!activeProjectFileId) {
1887
+ throw new Error("Tried to save bounds for active project file, but no active project file was set.");
1888
+ }
1889
+ if (!state.projectFiles[activeProjectFileId]) {
1890
+ throw new Error(
1891
+ `Tried to save bounds for active project file, but project file with ID ${activeProjectFileId}
1892
+ doesn't exist.`
1893
+ );
1894
+ }
1895
+ state.projectFiles[activeProjectFileId].bounds = action.payload;
1896
+ },
1897
+ // TODO: Move to MapContext. Should not be persisted.
1898
+ setActiveProjectFileId: (state, action) => {
1899
+ state.activeProjectFileId = action.payload;
1900
+ },
1901
+ removeProjectFile: (state, action) => {
1902
+ delete state.projectFiles[action.payload];
1903
+ },
1904
+ removeProjectFilesOfProject: (state, action) => {
1905
+ const filesToDelete = Object.values(state.projectFiles).filter((file) => file.project === action.payload);
1906
+ for (const file of filesToDelete) {
1907
+ delete state.projectFiles[file.offline_id];
1908
+ }
1909
+ },
1910
+ resetProjectFileObjectUrls: (state, ..._args) => {
1911
+ for (const key in state.projectFiles) {
1912
+ delete state.projectFiles[key].objectURL;
1913
+ }
1914
+ }
1865
1915
  }
1866
1916
  });
1867
1917
  const {
1868
- initializeProjectFiles,
1869
- addProjectFile,
1870
- addProjectFiles,
1871
- setProjectFile,
1872
- setProjectFiles,
1873
- updateProjectFile,
1874
- updateProjectFiles,
1875
- deleteProjectFile,
1876
- deleteProjectFiles
1918
+ addOrReplaceProjectFiles,
1919
+ addOrReplaceProjectFile,
1920
+ setIsImportingProjectFile,
1921
+ setActiveProjectFileId,
1922
+ saveActiveProjectFileBounds,
1923
+ removeProjectFile,
1924
+ removeProjectFilesOfProject,
1925
+ resetProjectFileObjectUrls
1877
1926
  } = projectFileSlice.actions;
1878
- const selectProjectFileMapping = (state) => state.projectFileReducer.instances;
1927
+ const selectProjectFileMapping = (state) => state.projectFileReducer.projectFiles;
1879
1928
  const selectProjectFiles = toolkit.createSelector(
1880
1929
  [selectProjectFileMapping, selectActiveProjectId],
1881
1930
  (mapping, activeProjectId) => {
@@ -1884,8 +1933,10 @@ var __publicField = (obj, key, value) => {
1884
1933
  );
1885
1934
  }
1886
1935
  );
1936
+ const selectActiveProjectFileId = (state) => state.projectFileReducer.activeProjectFileId;
1937
+ const selectIsImportingProjectFile = (state) => state.projectFileReducer.isImportingProjectFile;
1887
1938
  const selectProjectFileById = (id) => (state) => {
1888
- return state.projectFileReducer.instances[id];
1939
+ return state.projectFileReducer.projectFiles[id];
1889
1940
  };
1890
1941
  const projectFileReducer = projectFileSlice.reducer;
1891
1942
  const projectAttachmentAdapter = createModelAdapter((attachment) => attachment.offline_id);
@@ -5047,98 +5098,93 @@ var __publicField = (obj, key, value) => {
5047
5098
  this.dispatch(initializeProjectAccesses(result));
5048
5099
  }
5049
5100
  }
5050
- class ProjectFileService extends BaseUploadService {
5051
- async add(payload) {
5052
- var _a2;
5053
- const { store } = this.client;
5054
- const createdBy = (_a2 = store.getState().userReducer.currentUser) == null ? void 0 : _a2.id;
5055
- const { file, ...payloadWithoutFile } = payload;
5056
- const sha1 = await hashFile(file);
5057
- const filePayload = {
5058
- sha1,
5059
- file_type: file.type,
5060
- extension: file.name.split(".").pop(),
5061
- size: file.size
5062
- };
5063
- const offlineProjectFile = offline({
5064
- ...payloadWithoutFile,
5065
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5066
- created_by: createdBy,
5067
- file_name: file.name,
5068
- file_sha1: sha1,
5069
- file: URL.createObjectURL(file)
5070
- });
5071
- this.dispatch(addProjectFile(offlineProjectFile));
5101
+ class ProjectFileService extends BaseApiService {
5102
+ async saveExisting(file) {
5103
+ if (!file.offline_id) {
5104
+ throw new Error(
5105
+ "You can only use this method to save existing project files. The one provided has no offline_id."
5106
+ );
5107
+ }
5108
+ const editableData = { ...file };
5109
+ delete editableData.file;
5072
5110
  const promise = this.enqueueRequest({
5073
- description: "Add project file",
5074
- method: HttpMethod.POST,
5075
- url: `/projects/${payload.project}/files/`,
5076
- payload: {
5077
- offline_id: offlineProjectFile.offline_id,
5078
- submitted_at: offlineProjectFile.submitted_at,
5079
- z_index: offlineProjectFile.z_index,
5080
- canvas_bounds: offlineProjectFile.canvas_bounds,
5081
- bounds: offlineProjectFile.bounds,
5082
- file_name: offlineProjectFile.file_name,
5083
- file_sha1: offlineProjectFile.file_sha1,
5084
- file: offlineProjectFile.file,
5085
- file_payload: filePayload
5086
- },
5087
- blockers: [],
5088
- blocks: [offlineProjectFile.offline_id]
5111
+ method: HttpMethod.PATCH,
5112
+ url: `/projects/files/${file.offline_id}/`,
5113
+ payload: editableData,
5114
+ blockers: [file.offline_id],
5115
+ blocks: [file.offline_id]
5089
5116
  });
5090
- promise.then((result) => {
5091
- this.processPresignedUrls(result.presigned_urls);
5092
- this.dispatch(updateProjectFile(result.project_file));
5093
- }).catch(() => {
5094
- this.dispatch(deleteProjectFile(offlineProjectFile.offline_id));
5117
+ void promise.then((result) => {
5118
+ this.dispatch(addOrReplaceProjectFile(result));
5095
5119
  });
5096
- return [offlineProjectFile, promise.then((result) => result.project_file)];
5120
+ return promise;
5097
5121
  }
5098
- update(payload) {
5122
+ // TODO: This needs to be seperated into a update and create method
5123
+ saveActive() {
5099
5124
  const { store } = this.client;
5100
- const projectFile = selectProjectFileById(payload.offline_id)(store.getState());
5101
- if (!projectFile) {
5102
- throw new Error(`Project file with id ${payload.offline_id} not found`);
5125
+ const state = store.getState();
5126
+ const activeProjectFileId = state.projectFileReducer.activeProjectFileId;
5127
+ const activeProjectId = state.projectReducer.activeProjectId;
5128
+ if (!activeProjectFileId) {
5129
+ throw new Error("No active project file");
5130
+ }
5131
+ if (!activeProjectId) {
5132
+ throw new Error("No active project");
5133
+ }
5134
+ const activeProjectFile = state.projectFileReducer.projectFiles[activeProjectFileId];
5135
+ if (!activeProjectFile) {
5136
+ throw new Error("No active project file");
5137
+ }
5138
+ if (!activeProjectFile.bounds && !activeProjectFile.canvas_bounds) {
5139
+ throw new Error("Project file must either have bounds or canvas_bounds set");
5140
+ }
5141
+ let requestDetails;
5142
+ const existing = typeof activeProjectFile.file === "string" && !activeProjectFile.file.startsWith("blob:");
5143
+ if (existing) {
5144
+ const editableData = { ...activeProjectFile };
5145
+ delete editableData.file;
5146
+ requestDetails = {
5147
+ method: HttpMethod.PATCH,
5148
+ url: `/projects/files/${activeProjectFileId}/`,
5149
+ payload: editableData,
5150
+ blockers: [activeProjectFileId],
5151
+ blocks: [activeProjectFileId]
5152
+ };
5153
+ } else {
5154
+ requestDetails = new Promise((resolve, reject) => {
5155
+ this.client.files.uploadFileToS3(activeProjectFile.file_sha1).then(([fileProps]) => {
5156
+ resolve({
5157
+ method: HttpMethod.POST,
5158
+ url: `/projects/${activeProjectId}/files/`,
5159
+ payload: {
5160
+ ...activeProjectFile,
5161
+ ...fileProps
5162
+ },
5163
+ blockers: [activeProjectFileId],
5164
+ blocks: [activeProjectFileId]
5165
+ });
5166
+ }).catch(reject);
5167
+ });
5103
5168
  }
5104
- const updatedProjectFile = {
5105
- ...projectFile,
5106
- ...payload
5107
- };
5108
- this.dispatch(updateProjectFile(updatedProjectFile));
5109
- const promise = this.enqueueRequest({
5110
- description: "Update project file",
5111
- method: HttpMethod.PATCH,
5112
- url: `/projects/files/${payload.offline_id}/`,
5113
- payload,
5114
- blockers: [payload.offline_id],
5115
- blocks: [payload.offline_id]
5169
+ const promise = Promise.resolve(requestDetails).then((requestDetails2) => {
5170
+ return this.enqueueRequest(requestDetails2);
5116
5171
  });
5117
- promise.then((result) => {
5118
- this.dispatch(updateProjectFile(result));
5119
- }).catch(() => {
5120
- this.dispatch(updateProjectFile(projectFile));
5172
+ void promise.then((result) => {
5173
+ this.dispatch(addOrReplaceProjectFile(result));
5121
5174
  });
5122
- return [updatedProjectFile, promise];
5175
+ this.dispatch(saveActiveProjectFileBounds);
5176
+ this.dispatch(setActiveProjectFileId(null));
5177
+ this.dispatch(setIsImportingProjectFile(false));
5178
+ return [activeProjectFile, promise];
5123
5179
  }
5124
- delete(id) {
5125
- const { store } = this.client;
5126
- const projectFileToDelete = selectProjectFileById(id)(store.getState());
5127
- if (!projectFileToDelete) {
5128
- throw new Error(`Project file with id ${id} not found`);
5129
- }
5130
- this.dispatch(deleteProjectFile(id));
5131
- const promise = this.enqueueRequest({
5132
- description: "Delete project file",
5180
+ delete(projectFileId) {
5181
+ this.dispatch(removeProjectFile(projectFileId));
5182
+ return this.enqueueRequest({
5133
5183
  method: HttpMethod.DELETE,
5134
- url: `/projects/files/${id}/`,
5135
- blockers: [id],
5184
+ url: `/projects/files/${projectFileId}`,
5185
+ blockers: [projectFileId],
5136
5186
  blocks: []
5137
5187
  });
5138
- promise.catch(() => {
5139
- this.dispatch(updateProjectFile(projectFileToDelete));
5140
- });
5141
- return promise;
5142
5188
  }
5143
5189
  async refreshStore(projectId) {
5144
5190
  const result = await this.enqueueRequest({
@@ -5148,7 +5194,8 @@ var __publicField = (obj, key, value) => {
5148
5194
  blockers: [],
5149
5195
  blocks: []
5150
5196
  });
5151
- this.dispatch(initializeProjectFiles(result));
5197
+ this.dispatch(addOrReplaceProjectFiles([]));
5198
+ this.dispatch(addOrReplaceProjectFiles(result));
5152
5199
  }
5153
5200
  }
5154
5201
  class ProjectAttachmentService extends BaseAttachmentService {
@@ -5225,8 +5272,8 @@ var __publicField = (obj, key, value) => {
5225
5272
  if (!project) {
5226
5273
  throw new Error("Expected project to exist");
5227
5274
  }
5228
- const projectFiles = selectProjectFiles(state).filter((file) => file.project === projectId);
5229
- this.dispatch(deleteProjectFiles(projectFiles.map(({ offline_id }) => offline_id)));
5275
+ const filesToDelete = selectProjectFiles(state).filter((file) => file.project === projectId);
5276
+ this.dispatch(removeProjectFilesOfProject(project.id));
5230
5277
  const attachmentsOfProject = selectAttachmentsOfProject(project.id)(state);
5231
5278
  this.dispatch(deleteProjectAttachments(attachmentsOfProject.map(({ offline_id }) => offline_id)));
5232
5279
  const projectAccesses = selectProjectAccesses(state);
@@ -5249,7 +5296,7 @@ var __publicField = (obj, key, value) => {
5249
5296
  } catch (e) {
5250
5297
  this.dispatch(setProjects(Object.values(projects)));
5251
5298
  this.dispatch(initializeProjectAccesses(Object.values(projectAccesses)));
5252
- this.dispatch(initializeProjectFiles(projectFiles));
5299
+ this.dispatch(addOrReplaceProjectFiles(filesToDelete));
5253
5300
  this.dispatch(setProjectAttachments(attachmentsOfProject));
5254
5301
  this.dispatch({ type: "rehydrated/setRehydrated", payload: true });
5255
5302
  if (license) {
@@ -7381,11 +7428,11 @@ var __publicField = (obj, key, value) => {
7381
7428
  exports2.addIssueUpdates = addIssueUpdates;
7382
7429
  exports2.addIssues = addIssues;
7383
7430
  exports2.addLicenses = addLicenses;
7431
+ exports2.addOrReplaceProjectFile = addOrReplaceProjectFile;
7432
+ exports2.addOrReplaceProjectFiles = addOrReplaceProjectFiles;
7384
7433
  exports2.addOrReplaceProjects = addOrReplaceProjects;
7385
7434
  exports2.addProjectAttachment = addProjectAttachment;
7386
7435
  exports2.addProjectAttachments = addProjectAttachments;
7387
- exports2.addProjectFile = addProjectFile;
7388
- exports2.addProjectFiles = addProjectFiles;
7389
7436
  exports2.addTeam = addTeam;
7390
7437
  exports2.addUsers = addUsers;
7391
7438
  exports2.addWorkspace = addWorkspace;
@@ -7463,8 +7510,6 @@ var __publicField = (obj, key, value) => {
7463
7510
  exports2.deleteProjectAccesses = deleteProjectAccesses;
7464
7511
  exports2.deleteProjectAttachment = deleteProjectAttachment;
7465
7512
  exports2.deleteProjectAttachments = deleteProjectAttachments;
7466
- exports2.deleteProjectFile = deleteProjectFile;
7467
- exports2.deleteProjectFiles = deleteProjectFiles;
7468
7513
  exports2.deleteTeam = deleteTeam;
7469
7514
  exports2.deleteWorkspace = deleteWorkspace;
7470
7515
  exports2.dequeue = dequeue;
@@ -7533,7 +7578,6 @@ var __publicField = (obj, key, value) => {
7533
7578
  exports2.initializeOrganizationAccesses = initializeOrganizationAccesses;
7534
7579
  exports2.initializeProjectAccesses = initializeProjectAccesses;
7535
7580
  exports2.initializeProjectAttachments = initializeProjectAttachments;
7536
- exports2.initializeProjectFiles = initializeProjectFiles;
7537
7581
  exports2.initializeTeams = initializeTeams;
7538
7582
  exports2.initializeWorkspaces = initializeWorkspaces;
7539
7583
  exports2.isToday = isToday;
@@ -7586,13 +7630,18 @@ var __publicField = (obj, key, value) => {
7586
7630
  exports2.rehydratedSlice = rehydratedSlice;
7587
7631
  exports2.removeDocuments = removeDocuments;
7588
7632
  exports2.removeIssueType = removeIssueType;
7633
+ exports2.removeProjectFile = removeProjectFile;
7634
+ exports2.removeProjectFilesOfProject = removeProjectFilesOfProject;
7589
7635
  exports2.removeUser = removeUser;
7636
+ exports2.resetProjectFileObjectUrls = resetProjectFileObjectUrls;
7590
7637
  exports2.resetStore = resetStore;
7591
7638
  exports2.restructureCreateSelectorWithArgs = restructureCreateSelectorWithArgs;
7639
+ exports2.saveActiveProjectFileBounds = saveActiveProjectFileBounds;
7592
7640
  exports2.selectAccessToken = selectAccessToken;
7593
7641
  exports2.selectActiveOrganizationAccess = selectActiveOrganizationAccess;
7594
7642
  exports2.selectActiveProject = selectActiveProject;
7595
7643
  exports2.selectActiveProjectAccess = selectActiveProjectAccess;
7644
+ exports2.selectActiveProjectFileId = selectActiveProjectFileId;
7596
7645
  exports2.selectActiveProjectId = selectActiveProjectId;
7597
7646
  exports2.selectActiveStatusLicenses = selectActiveStatusLicenses;
7598
7647
  exports2.selectAllDocumentAttachments = selectAllDocumentAttachments;
@@ -7684,6 +7733,7 @@ var __publicField = (obj, key, value) => {
7684
7733
  exports2.selectGeoImageMapping = selectGeoImageMapping;
7685
7734
  exports2.selectGeoImages = selectGeoImages;
7686
7735
  exports2.selectGeoImagesOfProject = selectGeoImagesOfProject;
7736
+ exports2.selectIsImportingProjectFile = selectIsImportingProjectFile;
7687
7737
  exports2.selectIsLoggedIn = selectIsLoggedIn;
7688
7738
  exports2.selectIssueAssociationById = selectIssueAssociationById;
7689
7739
  exports2.selectIssueAssociationMapping = selectIssueAssociationMapping;
@@ -7766,6 +7816,7 @@ var __publicField = (obj, key, value) => {
7766
7816
  exports2.selectWorkspaceById = selectWorkspaceById;
7767
7817
  exports2.selectWorkspaceMapping = selectWorkspaceMapping;
7768
7818
  exports2.selectWorkspaces = selectWorkspaces;
7819
+ exports2.setActiveProjectFileId = setActiveProjectFileId;
7769
7820
  exports2.setActiveProjectId = setActiveProjectId;
7770
7821
  exports2.setAsset = setAsset;
7771
7822
  exports2.setAssetAttachment = setAssetAttachment;
@@ -7792,6 +7843,7 @@ var __publicField = (obj, key, value) => {
7792
7843
  exports2.setFormSubmissions = setFormSubmissions;
7793
7844
  exports2.setGeoImage = setGeoImage;
7794
7845
  exports2.setGeoImages = setGeoImages;
7846
+ exports2.setIsImportingProjectFile = setIsImportingProjectFile;
7795
7847
  exports2.setIssueAssociation = setIssueAssociation;
7796
7848
  exports2.setIssueAssociations = setIssueAssociations;
7797
7849
  exports2.setIssueAttachment = setIssueAttachment;
@@ -7805,8 +7857,6 @@ var __publicField = (obj, key, value) => {
7805
7857
  exports2.setProfilePicture = setProfilePicture;
7806
7858
  exports2.setProjectAttachment = setProjectAttachment;
7807
7859
  exports2.setProjectAttachments = setProjectAttachments;
7808
- exports2.setProjectFile = setProjectFile;
7809
- exports2.setProjectFiles = setProjectFiles;
7810
7860
  exports2.setProjects = setProjects;
7811
7861
  exports2.setRehydrated = setRehydrated;
7812
7862
  exports2.setTeam = setTeam;
@@ -7861,8 +7911,6 @@ var __publicField = (obj, key, value) => {
7861
7911
  exports2.updateProjectAccess = updateProjectAccess;
7862
7912
  exports2.updateProjectAttachment = updateProjectAttachment;
7863
7913
  exports2.updateProjectAttachments = updateProjectAttachments;
7864
- exports2.updateProjectFile = updateProjectFile;
7865
- exports2.updateProjectFiles = updateProjectFiles;
7866
7914
  exports2.updateTeam = updateTeam;
7867
7915
  exports2.updateWorkspace = updateWorkspace;
7868
7916
  exports2.userReducer = userReducer;