@overmap-ai/core 1.0.71-project-file-improvements.4 → 1.0.71-workspace-settings.1

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