@overmap-ai/core 1.0.45 → 1.0.46-project-attachments.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 +504 -75
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +504 -75
- package/dist/overmap-core.umd.cjs.map +1 -1
- package/dist/sdk/sdk.d.ts +2 -1
- package/dist/sdk/services/AttachmentService.d.ts +6 -1
- package/dist/sdk/services/DocumentService.d.ts +10 -0
- package/dist/sdk/services/index.d.ts +2 -1
- package/dist/sdk/typings.d.ts +1 -1
- package/dist/store/slices/categorySlice.d.ts +1 -0
- package/dist/store/slices/documentSlice.d.ts +66 -0
- package/dist/store/slices/index.d.ts +1 -0
- package/dist/store/slices/issueSlice.d.ts +1 -0
- package/dist/store/slices/projectFileSlice.d.ts +1 -0
- package/dist/store/slices/projectSlice.d.ts +34 -2
- package/dist/store/slices/workspaceSlice.d.ts +1 -0
- package/dist/store/store.d.ts +4 -1
- package/dist/typings/models/attachments.d.ts +4 -0
- package/dist/typings/models/documents.d.ts +11 -0
- package/dist/typings/models/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/overmap-core.js
CHANGED
|
@@ -632,15 +632,15 @@ const wrapMigration = (migrator) => (state) => {
|
|
|
632
632
|
};
|
|
633
633
|
const migrations = [initialVersioning, signOut, signOut, createOutboxState];
|
|
634
634
|
const manifest = Object.fromEntries(migrations.map((migration2, i) => [i, wrapMigration(migration2)]));
|
|
635
|
-
const initialState$
|
|
635
|
+
const initialState$n = {
|
|
636
636
|
accessToken: "",
|
|
637
637
|
refreshToken: "",
|
|
638
638
|
isLoggedIn: false
|
|
639
639
|
};
|
|
640
640
|
const authSlice = createSlice({
|
|
641
641
|
name: "auth",
|
|
642
|
-
initialState: initialState$
|
|
643
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
642
|
+
initialState: initialState$n,
|
|
643
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
|
|
644
644
|
reducers: {
|
|
645
645
|
setTokens: (state, action) => {
|
|
646
646
|
state.accessToken = action.payload.accessToken;
|
|
@@ -1371,7 +1371,7 @@ const getLocalRelativeDateString = memoize((date, min, max) => {
|
|
|
1371
1371
|
return getLocalDateString(date);
|
|
1372
1372
|
return relative.format(days, "days");
|
|
1373
1373
|
});
|
|
1374
|
-
const initialState$
|
|
1374
|
+
const initialState$m = {
|
|
1375
1375
|
categories: {},
|
|
1376
1376
|
usedCategoryColors: [],
|
|
1377
1377
|
categoryVisibility: {
|
|
@@ -1381,8 +1381,8 @@ const initialState$l = {
|
|
|
1381
1381
|
};
|
|
1382
1382
|
const categorySlice = createSlice({
|
|
1383
1383
|
name: "categories",
|
|
1384
|
-
initialState: initialState$
|
|
1385
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1384
|
+
initialState: initialState$m,
|
|
1385
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
|
|
1386
1386
|
reducers: {
|
|
1387
1387
|
setCategories: (state, action) => {
|
|
1388
1388
|
if (!Array.isArray(action.payload))
|
|
@@ -1550,14 +1550,14 @@ function removeAttachments(state, action) {
|
|
|
1550
1550
|
delete state.attachments[attachmentId];
|
|
1551
1551
|
}
|
|
1552
1552
|
}
|
|
1553
|
-
const initialState$
|
|
1553
|
+
const initialState$l = {
|
|
1554
1554
|
components: {},
|
|
1555
1555
|
attachments: {}
|
|
1556
1556
|
};
|
|
1557
1557
|
const componentSlice = createSlice({
|
|
1558
1558
|
name: "components",
|
|
1559
|
-
initialState: initialState$
|
|
1560
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1559
|
+
initialState: initialState$l,
|
|
1560
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
|
|
1561
1561
|
reducers: {
|
|
1562
1562
|
addComponent: (state, action) => {
|
|
1563
1563
|
state.components[action.payload.offline_id] = action.payload;
|
|
@@ -1711,13 +1711,13 @@ const {
|
|
|
1711
1711
|
removeAllComponentsOfType
|
|
1712
1712
|
} = componentSlice.actions;
|
|
1713
1713
|
const componentReducer = componentSlice.reducer;
|
|
1714
|
-
const initialState$
|
|
1714
|
+
const initialState$k = {
|
|
1715
1715
|
completionsByComponentId: {}
|
|
1716
1716
|
};
|
|
1717
1717
|
const componentStageCompletionSlice = createSlice({
|
|
1718
1718
|
name: "componentStageCompletions",
|
|
1719
|
-
initialState: initialState$
|
|
1720
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1719
|
+
initialState: initialState$k,
|
|
1720
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
|
|
1721
1721
|
reducers: {
|
|
1722
1722
|
addStageCompletion: (state, action) => {
|
|
1723
1723
|
let stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component];
|
|
@@ -1768,13 +1768,13 @@ const selectCompletedStageIdsForComponent = (component) => (state) => {
|
|
|
1768
1768
|
return Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {});
|
|
1769
1769
|
};
|
|
1770
1770
|
const componentStageCompletionReducer = componentStageCompletionSlice.reducer;
|
|
1771
|
-
const initialState$
|
|
1771
|
+
const initialState$j = {
|
|
1772
1772
|
stages: {}
|
|
1773
1773
|
};
|
|
1774
1774
|
const componentStageSlice = createSlice({
|
|
1775
1775
|
name: "componentStages",
|
|
1776
|
-
initialState: initialState$
|
|
1777
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1776
|
+
initialState: initialState$j,
|
|
1777
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
|
|
1778
1778
|
reducers: {
|
|
1779
1779
|
addStages: (state, action) => {
|
|
1780
1780
|
Object.assign(state.stages, toOfflineIdRecord(action.payload));
|
|
@@ -1865,15 +1865,15 @@ const selectStageFormIdsFromStageIds = restructureCreateSelectorWithArgs(
|
|
|
1865
1865
|
);
|
|
1866
1866
|
const { addStages, updateStages, removeStages, linkStageToForm, unlinkStageToForm } = componentStageSlice.actions;
|
|
1867
1867
|
const componentStageReducer = componentStageSlice.reducer;
|
|
1868
|
-
const initialState$
|
|
1868
|
+
const initialState$i = {
|
|
1869
1869
|
componentTypes: {},
|
|
1870
1870
|
hiddenComponentTypeIds: {},
|
|
1871
1871
|
attachments: {}
|
|
1872
1872
|
};
|
|
1873
1873
|
const componentTypeSlice = createSlice({
|
|
1874
1874
|
name: "componentTypes",
|
|
1875
|
-
initialState: initialState$
|
|
1876
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1875
|
+
initialState: initialState$i,
|
|
1876
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
|
|
1877
1877
|
reducers: {
|
|
1878
1878
|
addComponentType: (state, action) => {
|
|
1879
1879
|
state.componentTypes[action.payload.offline_id] = action.payload;
|
|
@@ -1981,13 +1981,13 @@ const {
|
|
|
1981
1981
|
deleteComponentType
|
|
1982
1982
|
} = componentTypeSlice.actions;
|
|
1983
1983
|
const componentTypeReducer = componentTypeSlice.reducer;
|
|
1984
|
-
const initialState$
|
|
1984
|
+
const initialState$h = {
|
|
1985
1985
|
workspaces: {},
|
|
1986
1986
|
activeWorkspaceId: null
|
|
1987
1987
|
};
|
|
1988
1988
|
const workspaceSlice = createSlice({
|
|
1989
1989
|
name: "workspace",
|
|
1990
|
-
initialState: initialState$
|
|
1990
|
+
initialState: initialState$h,
|
|
1991
1991
|
// The `reducers` field lets us define reducers and generate associated actions
|
|
1992
1992
|
reducers: {
|
|
1993
1993
|
setWorkspaces: (state, action) => {
|
|
@@ -2044,7 +2044,7 @@ const selectPermittedWorkspaceIds = createSelector(
|
|
|
2044
2044
|
);
|
|
2045
2045
|
const workspaceReducer = workspaceSlice.reducer;
|
|
2046
2046
|
const maxRecentIssues = 10;
|
|
2047
|
-
const initialState$
|
|
2047
|
+
const initialState$g = {
|
|
2048
2048
|
issues: {},
|
|
2049
2049
|
attachments: {},
|
|
2050
2050
|
comments: {},
|
|
@@ -2055,9 +2055,9 @@ const initialState$f = {
|
|
|
2055
2055
|
};
|
|
2056
2056
|
const issueSlice = createSlice({
|
|
2057
2057
|
name: "issues",
|
|
2058
|
-
initialState: initialState$
|
|
2058
|
+
initialState: initialState$g,
|
|
2059
2059
|
extraReducers: (builder) => builder.addCase("RESET", (state) => {
|
|
2060
|
-
Object.assign(state, initialState$
|
|
2060
|
+
Object.assign(state, initialState$g);
|
|
2061
2061
|
}),
|
|
2062
2062
|
reducers: {
|
|
2063
2063
|
setIssues: (state, action) => {
|
|
@@ -2068,7 +2068,6 @@ const issueSlice = createSlice({
|
|
|
2068
2068
|
state.issues[issue.offline_id] = issue;
|
|
2069
2069
|
});
|
|
2070
2070
|
},
|
|
2071
|
-
// TODO: Reusable function
|
|
2072
2071
|
setIssueAttachments: setAttachments,
|
|
2073
2072
|
setActiveIssueId: (state, action) => {
|
|
2074
2073
|
state.activeIssueId = action.payload;
|
|
@@ -2079,7 +2078,6 @@ const issueSlice = createSlice({
|
|
|
2079
2078
|
}
|
|
2080
2079
|
state.issues[action.payload.offline_id] = action.payload;
|
|
2081
2080
|
},
|
|
2082
|
-
// TODO: Reusable function
|
|
2083
2081
|
addIssueAttachment: addAttachment,
|
|
2084
2082
|
addIssueAttachments: addAttachments,
|
|
2085
2083
|
updateIssue: (state, action) => {
|
|
@@ -2092,7 +2090,6 @@ const issueSlice = createSlice({
|
|
|
2092
2090
|
throw new Error(`Tried to update issue with ID that doesn't exist: ${action.payload.offline_id}`);
|
|
2093
2091
|
}
|
|
2094
2092
|
},
|
|
2095
|
-
// TODO: Reusable function
|
|
2096
2093
|
updateIssueAttachment: updateAttachment,
|
|
2097
2094
|
removeIssue: (state, action) => {
|
|
2098
2095
|
if (action.payload in state.issues) {
|
|
@@ -2381,15 +2378,15 @@ const selectRecentIssuesAsSearchResults = createSelector(
|
|
|
2381
2378
|
}
|
|
2382
2379
|
);
|
|
2383
2380
|
const issueReducer = issueSlice.reducer;
|
|
2384
|
-
const initialState$
|
|
2381
|
+
const initialState$f = {
|
|
2385
2382
|
s3Urls: {}
|
|
2386
2383
|
};
|
|
2387
2384
|
const msPerHour = 1e3 * 60 * 60;
|
|
2388
2385
|
const msPerWeek = msPerHour * 24 * 7;
|
|
2389
2386
|
const fileSlice = createSlice({
|
|
2390
2387
|
name: "file",
|
|
2391
|
-
initialState: initialState$
|
|
2392
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2388
|
+
initialState: initialState$f,
|
|
2389
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
|
|
2393
2390
|
reducers: {
|
|
2394
2391
|
setUploadUrl: (state, action) => {
|
|
2395
2392
|
const { url, fields, sha1 } = action.payload;
|
|
@@ -2416,7 +2413,7 @@ const selectUploadUrl = (sha1) => (state) => {
|
|
|
2416
2413
|
return url;
|
|
2417
2414
|
};
|
|
2418
2415
|
const fileReducer = fileSlice.reducer;
|
|
2419
|
-
const initialState$
|
|
2416
|
+
const initialState$e = {
|
|
2420
2417
|
// TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed
|
|
2421
2418
|
mapStyle: MapStyle.SATELLITE,
|
|
2422
2419
|
showTooltips: false,
|
|
@@ -2424,8 +2421,8 @@ const initialState$d = {
|
|
|
2424
2421
|
};
|
|
2425
2422
|
const mapSlice = createSlice({
|
|
2426
2423
|
name: "map",
|
|
2427
|
-
initialState: initialState$
|
|
2428
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2424
|
+
initialState: initialState$e,
|
|
2425
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
|
|
2429
2426
|
reducers: {
|
|
2430
2427
|
setMapStyle: (state, action) => {
|
|
2431
2428
|
state.mapStyle = action.payload;
|
|
@@ -2484,7 +2481,7 @@ var LicenseStatus = /* @__PURE__ */ ((LicenseStatus2) => {
|
|
|
2484
2481
|
LicenseStatus2[LicenseStatus2["PAST_DUE"] = 8] = "PAST_DUE";
|
|
2485
2482
|
return LicenseStatus2;
|
|
2486
2483
|
})(LicenseStatus || {});
|
|
2487
|
-
const initialState$
|
|
2484
|
+
const initialState$d = {
|
|
2488
2485
|
users: {},
|
|
2489
2486
|
currentUser: {
|
|
2490
2487
|
id: 0,
|
|
@@ -2495,8 +2492,8 @@ const initialState$c = {
|
|
|
2495
2492
|
};
|
|
2496
2493
|
const userSlice = createSlice({
|
|
2497
2494
|
name: "users",
|
|
2498
|
-
initialState: initialState$
|
|
2499
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2495
|
+
initialState: initialState$d,
|
|
2496
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
|
|
2500
2497
|
reducers: {
|
|
2501
2498
|
setUsers: (state, action) => {
|
|
2502
2499
|
const usersMapping = {};
|
|
@@ -2558,13 +2555,13 @@ const selectUser = (userId) => (state) => {
|
|
|
2558
2555
|
const selectUsersAsMapping = (state) => state.userReducer.users;
|
|
2559
2556
|
const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
|
|
2560
2557
|
const userReducer = userSlice.reducer;
|
|
2561
|
-
const initialState$
|
|
2558
|
+
const initialState$c = {
|
|
2562
2559
|
organizationAccesses: {}
|
|
2563
2560
|
};
|
|
2564
2561
|
const organizationAccessSlice = createSlice({
|
|
2565
2562
|
name: "organizationAccess",
|
|
2566
|
-
initialState: initialState$
|
|
2567
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2563
|
+
initialState: initialState$c,
|
|
2564
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
|
|
2568
2565
|
reducers: {
|
|
2569
2566
|
setOrganizationAccesses: (state, action) => {
|
|
2570
2567
|
if (!Array.isArray(action.payload))
|
|
@@ -2627,13 +2624,13 @@ const selectOrganizationAccessUserMapping = (state) => {
|
|
|
2627
2624
|
return organizationAccesses;
|
|
2628
2625
|
};
|
|
2629
2626
|
const organizationAccessReducer = organizationAccessSlice.reducer;
|
|
2630
|
-
const initialState$
|
|
2627
|
+
const initialState$b = {
|
|
2631
2628
|
licenses: {}
|
|
2632
2629
|
};
|
|
2633
2630
|
const licenseSlice = createSlice({
|
|
2634
2631
|
name: "license",
|
|
2635
|
-
initialState: initialState$
|
|
2636
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2632
|
+
initialState: initialState$b,
|
|
2633
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
|
|
2637
2634
|
reducers: {
|
|
2638
2635
|
setLicenses: (state, action) => {
|
|
2639
2636
|
if (!Array.isArray(action.payload))
|
|
@@ -2678,13 +2675,13 @@ const selectLicensesForProjectsMapping = createSelector(
|
|
|
2678
2675
|
(licenses) => Object.values(licenses).filter((license) => license.project).reduce((accum, license) => ({ ...accum, [license.project]: license }), {})
|
|
2679
2676
|
);
|
|
2680
2677
|
const licenseReducer = licenseSlice.reducer;
|
|
2681
|
-
const initialState$
|
|
2678
|
+
const initialState$a = {
|
|
2682
2679
|
projectAccesses: {}
|
|
2683
2680
|
};
|
|
2684
2681
|
const projectAccessSlice = createSlice({
|
|
2685
2682
|
name: "projectAccess",
|
|
2686
|
-
initialState: initialState$
|
|
2687
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2683
|
+
initialState: initialState$a,
|
|
2684
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
|
|
2688
2685
|
reducers: {
|
|
2689
2686
|
setProjectAccesses: (state, action) => {
|
|
2690
2687
|
if (!Array.isArray(action.payload))
|
|
@@ -2752,16 +2749,17 @@ const selectProjectAccessUserMapping = (state) => {
|
|
|
2752
2749
|
return projectAccesses;
|
|
2753
2750
|
};
|
|
2754
2751
|
const projectAccessReducer = projectAccessSlice.reducer;
|
|
2755
|
-
const initialState$
|
|
2752
|
+
const initialState$9 = {
|
|
2756
2753
|
projects: {},
|
|
2757
2754
|
activeProjectId: null,
|
|
2758
2755
|
recentProjectIds: [],
|
|
2759
2756
|
recentSearchableQueries: [],
|
|
2760
|
-
createProjectType: ProjectType.PERSONAL
|
|
2757
|
+
createProjectType: ProjectType.PERSONAL,
|
|
2758
|
+
attachments: {}
|
|
2761
2759
|
};
|
|
2762
2760
|
const projectSlice = createSlice({
|
|
2763
2761
|
name: "projects",
|
|
2764
|
-
initialState: initialState$
|
|
2762
|
+
initialState: initialState$9,
|
|
2765
2763
|
reducers: {
|
|
2766
2764
|
setProjects: (state, action) => {
|
|
2767
2765
|
const projectsMap = {};
|
|
@@ -2828,7 +2826,14 @@ const projectSlice = createSlice({
|
|
|
2828
2826
|
} else {
|
|
2829
2827
|
throw new Error("Update form submissions count: no active project");
|
|
2830
2828
|
}
|
|
2831
|
-
}
|
|
2829
|
+
},
|
|
2830
|
+
// Attachment related
|
|
2831
|
+
setProjectAttachments: setAttachments,
|
|
2832
|
+
addProjectAttachment: addAttachment,
|
|
2833
|
+
addProjectAttachments: addAttachments,
|
|
2834
|
+
updateProjectAttachment: updateAttachment,
|
|
2835
|
+
removeProjectAttachment: removeAttachment,
|
|
2836
|
+
removeProjectAttachments: removeAttachments
|
|
2832
2837
|
}
|
|
2833
2838
|
});
|
|
2834
2839
|
const {
|
|
@@ -2840,7 +2845,14 @@ const {
|
|
|
2840
2845
|
deleteProject,
|
|
2841
2846
|
acceptProjectInvite,
|
|
2842
2847
|
addActiveProjectIssuesCount,
|
|
2843
|
-
addActiveProjectFormSubmissionsCount
|
|
2848
|
+
addActiveProjectFormSubmissionsCount,
|
|
2849
|
+
// Attachment related
|
|
2850
|
+
setProjectAttachments,
|
|
2851
|
+
addProjectAttachment,
|
|
2852
|
+
addProjectAttachments,
|
|
2853
|
+
updateProjectAttachment,
|
|
2854
|
+
removeProjectAttachment,
|
|
2855
|
+
removeProjectAttachments
|
|
2844
2856
|
} = projectSlice.actions;
|
|
2845
2857
|
const selectProjects = (state) => state.projectReducer.projects;
|
|
2846
2858
|
const selectActiveProjectId = (state) => state.projectReducer.activeProjectId;
|
|
@@ -2904,14 +2916,44 @@ const selectSortedProjectUsers = createSelector(
|
|
|
2904
2916
|
});
|
|
2905
2917
|
}
|
|
2906
2918
|
);
|
|
2907
|
-
const
|
|
2919
|
+
const selectProjectAttachmentMapping = (state) => state.projectReducer.attachments;
|
|
2920
|
+
const selectAllProjectAttachments = createSelector(
|
|
2921
|
+
[selectProjectAttachmentMapping],
|
|
2922
|
+
(mapping) => Object.values(mapping)
|
|
2923
|
+
);
|
|
2924
|
+
const selectAttachmentsOfProject = restructureCreateSelectorWithArgs(
|
|
2925
|
+
createSelector(
|
|
2926
|
+
[selectAllProjectAttachments, (_state, projectId) => projectId],
|
|
2927
|
+
(attachments, projectId) => {
|
|
2928
|
+
return attachments.filter(({ project }) => projectId === project);
|
|
2929
|
+
}
|
|
2930
|
+
)
|
|
2931
|
+
);
|
|
2932
|
+
const selectAttachmentsOfProjectByType = restructureCreateSelectorWithArgs(
|
|
2933
|
+
createSelector(
|
|
2934
|
+
[selectAllProjectAttachments, (_state, projectId) => projectId],
|
|
2935
|
+
(attachments, projectId) => {
|
|
2936
|
+
const attachmentsOfProject = attachments.filter(({ project }) => projectId === project);
|
|
2937
|
+
const fileAttachments = attachmentsOfProject.filter(
|
|
2938
|
+
// this null check here is necessary, there are cases where file_type is null or undefined
|
|
2939
|
+
({ file_type }) => !file_type || !file_type.startsWith("image/")
|
|
2940
|
+
);
|
|
2941
|
+
const imageAttachments = attachmentsOfProject.filter(
|
|
2942
|
+
// this null check here is necessary, there are cases where file_type is null or undefined
|
|
2943
|
+
({ file_type }) => file_type && file_type.startsWith("image/")
|
|
2944
|
+
);
|
|
2945
|
+
return { fileAttachments, imageAttachments };
|
|
2946
|
+
}
|
|
2947
|
+
)
|
|
2948
|
+
);
|
|
2949
|
+
const initialState$8 = {
|
|
2908
2950
|
organizations: {},
|
|
2909
2951
|
activeOrganizationId: null
|
|
2910
2952
|
};
|
|
2911
2953
|
const organizationSlice = createSlice({
|
|
2912
2954
|
name: "organizations",
|
|
2913
|
-
initialState: initialState$
|
|
2914
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2955
|
+
initialState: initialState$8,
|
|
2956
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
|
|
2915
2957
|
reducers: {
|
|
2916
2958
|
setOrganizations: (state, action) => {
|
|
2917
2959
|
for (const org of action.payload) {
|
|
@@ -3030,14 +3072,14 @@ const createOfflineAction = (request2, baseUrl) => {
|
|
|
3030
3072
|
}
|
|
3031
3073
|
};
|
|
3032
3074
|
};
|
|
3033
|
-
const initialState$
|
|
3075
|
+
const initialState$7 = {
|
|
3034
3076
|
deletedRequests: [],
|
|
3035
3077
|
latestRetryTime: 0
|
|
3036
3078
|
};
|
|
3037
3079
|
const outboxSlice = createSlice({
|
|
3038
3080
|
name: "outbox",
|
|
3039
|
-
initialState: initialState$
|
|
3040
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3081
|
+
initialState: initialState$7,
|
|
3082
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
|
|
3041
3083
|
reducers: {
|
|
3042
3084
|
// enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
|
|
3043
3085
|
// Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
|
|
@@ -3069,7 +3111,7 @@ const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
|
|
|
3069
3111
|
const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
|
|
3070
3112
|
const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
|
|
3071
3113
|
const outboxReducer = outboxSlice.reducer;
|
|
3072
|
-
const initialState$
|
|
3114
|
+
const initialState$6 = {
|
|
3073
3115
|
projectFiles: {},
|
|
3074
3116
|
activeProjectFileId: null,
|
|
3075
3117
|
isImportingProjectFile: false,
|
|
@@ -3077,8 +3119,8 @@ const initialState$5 = {
|
|
|
3077
3119
|
};
|
|
3078
3120
|
const projectFileSlice = createSlice({
|
|
3079
3121
|
name: "projectFiles",
|
|
3080
|
-
initialState: initialState$
|
|
3081
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3122
|
+
initialState: initialState$6,
|
|
3123
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
|
|
3082
3124
|
reducers: {
|
|
3083
3125
|
addOrReplaceProjectFiles: (state, action) => {
|
|
3084
3126
|
for (let fileObj of action.payload) {
|
|
@@ -3179,12 +3221,12 @@ const selectProjectFiles = createSelector(
|
|
|
3179
3221
|
const selectActiveProjectFileId = (state) => state.projectFileReducer.activeProjectFileId;
|
|
3180
3222
|
const selectIsImportingProjectFile = (state) => state.projectFileReducer.isImportingProjectFile;
|
|
3181
3223
|
const projectFileReducer = projectFileSlice.reducer;
|
|
3182
|
-
const initialState$
|
|
3224
|
+
const initialState$5 = {
|
|
3183
3225
|
isRehydrated: false
|
|
3184
3226
|
};
|
|
3185
3227
|
const rehydratedSlice = createSlice({
|
|
3186
3228
|
name: "rehydrated",
|
|
3187
|
-
initialState: initialState$
|
|
3229
|
+
initialState: initialState$5,
|
|
3188
3230
|
// The `reducers` field lets us define reducers and generate associated actions
|
|
3189
3231
|
reducers: {
|
|
3190
3232
|
setRehydrated: (state, action) => {
|
|
@@ -3194,7 +3236,7 @@ const rehydratedSlice = createSlice({
|
|
|
3194
3236
|
});
|
|
3195
3237
|
const selectRehydrated = (state) => state.rehydratedReducer.isRehydrated;
|
|
3196
3238
|
const rehydratedReducer = rehydratedSlice.reducer;
|
|
3197
|
-
const initialState$
|
|
3239
|
+
const initialState$4 = {
|
|
3198
3240
|
useIssueTemplate: false,
|
|
3199
3241
|
placementMode: false,
|
|
3200
3242
|
enableClustering: true,
|
|
@@ -3211,8 +3253,8 @@ const initialState$3 = {
|
|
|
3211
3253
|
};
|
|
3212
3254
|
const settingSlice = createSlice({
|
|
3213
3255
|
name: "settings",
|
|
3214
|
-
initialState: initialState$
|
|
3215
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3256
|
+
initialState: initialState$4,
|
|
3257
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
|
|
3216
3258
|
reducers: {
|
|
3217
3259
|
setEnableDuplicateIssues: (state, action) => {
|
|
3218
3260
|
state.useIssueTemplate = action.payload;
|
|
@@ -3285,7 +3327,7 @@ function considerCachingRevision(revision, formId2, preferPending = false) {
|
|
|
3285
3327
|
function getLatestRevisionFromCache(formId2) {
|
|
3286
3328
|
return LATEST_REVISION_CACHE[formId2];
|
|
3287
3329
|
}
|
|
3288
|
-
const initialState$
|
|
3330
|
+
const initialState$3 = {
|
|
3289
3331
|
userForms: {},
|
|
3290
3332
|
revisions: {},
|
|
3291
3333
|
submissions: {},
|
|
@@ -3294,8 +3336,8 @@ const initialState$2 = {
|
|
|
3294
3336
|
};
|
|
3295
3337
|
const userFormSlice = createSlice({
|
|
3296
3338
|
name: "userForms",
|
|
3297
|
-
initialState: initialState$
|
|
3298
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3339
|
+
initialState: initialState$3,
|
|
3340
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
|
|
3299
3341
|
reducers: {
|
|
3300
3342
|
setUserForms: (state, action) => {
|
|
3301
3343
|
state.userForms = {};
|
|
@@ -3599,12 +3641,12 @@ const selectNumberOfGeneralUserForms = createSelector([selectUserFormMapping], (
|
|
|
3599
3641
|
return Object.values(userForms).filter((form) => !form.component_type).length;
|
|
3600
3642
|
});
|
|
3601
3643
|
const userFormReducer = userFormSlice.reducer;
|
|
3602
|
-
const initialState$
|
|
3644
|
+
const initialState$2 = {
|
|
3603
3645
|
emailDomains: {}
|
|
3604
3646
|
};
|
|
3605
3647
|
const emailDomainsSlice = createSlice({
|
|
3606
3648
|
name: "emailDomains",
|
|
3607
|
-
initialState: initialState$
|
|
3649
|
+
initialState: initialState$2,
|
|
3608
3650
|
reducers: {
|
|
3609
3651
|
setEmailDomains: (state, action) => {
|
|
3610
3652
|
const emailDomains = {};
|
|
@@ -3631,6 +3673,166 @@ const selectSortedEmailDomains = (state) => Object.values(state.emailDomainsRedu
|
|
|
3631
3673
|
(ed1, ed2) => ed1.domain.localeCompare(ed2.domain)
|
|
3632
3674
|
);
|
|
3633
3675
|
const emailDomainsReducer = emailDomainsSlice.reducer;
|
|
3676
|
+
const initialState$1 = {
|
|
3677
|
+
documents: {}
|
|
3678
|
+
};
|
|
3679
|
+
const documentSlice = createSlice({
|
|
3680
|
+
name: "documents",
|
|
3681
|
+
initialState: initialState$1,
|
|
3682
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => {
|
|
3683
|
+
Object.assign(state, initialState$1);
|
|
3684
|
+
}),
|
|
3685
|
+
reducers: {
|
|
3686
|
+
setDocuments: (state, action) => {
|
|
3687
|
+
if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
|
|
3688
|
+
throw new Error("Tried to use setIssues reducer with duplicate ID's");
|
|
3689
|
+
}
|
|
3690
|
+
for (const document2 of action.payload) {
|
|
3691
|
+
state.documents[document2.offline_id] = document2;
|
|
3692
|
+
}
|
|
3693
|
+
},
|
|
3694
|
+
addDocuments: (state, action) => {
|
|
3695
|
+
for (const document2 of action.payload) {
|
|
3696
|
+
if (document2.offline_id in state.documents) {
|
|
3697
|
+
throw new Error(
|
|
3698
|
+
`attempting to add a document with offline_id ${document2.offline_id} which already exists in state.documents.`
|
|
3699
|
+
);
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
for (const document2 of action.payload) {
|
|
3703
|
+
if (document2.parent_document && !!state.documents[document2.parent_document]) {
|
|
3704
|
+
const parentDocument = state.documents[document2.parent_document];
|
|
3705
|
+
state.documents[document2.parent_document] = {
|
|
3706
|
+
...parentDocument,
|
|
3707
|
+
children_documents: [...parentDocument.children_documents, document2.offline_id]
|
|
3708
|
+
};
|
|
3709
|
+
}
|
|
3710
|
+
state.documents[document2.offline_id] = document2;
|
|
3711
|
+
}
|
|
3712
|
+
},
|
|
3713
|
+
updateDocuments: (state, action) => {
|
|
3714
|
+
for (const document2 of action.payload) {
|
|
3715
|
+
if (!(document2.offline_id in state.documents)) {
|
|
3716
|
+
throw new Error(
|
|
3717
|
+
`attempting to update a document with offline_id ${document2.offline_id} which doesn't exists in state.documents.`
|
|
3718
|
+
);
|
|
3719
|
+
}
|
|
3720
|
+
}
|
|
3721
|
+
for (const document2 of action.payload) {
|
|
3722
|
+
state.documents[document2.offline_id] = {
|
|
3723
|
+
...state.documents[document2.offline_id],
|
|
3724
|
+
...document2
|
|
3725
|
+
};
|
|
3726
|
+
}
|
|
3727
|
+
},
|
|
3728
|
+
moveDocument: (state, action) => {
|
|
3729
|
+
const { documentId, targetDocumentId, position } = action.payload;
|
|
3730
|
+
if (!(documentId in state.documents)) {
|
|
3731
|
+
throw new Error(
|
|
3732
|
+
`attempting to move a document with offline_id ${documentId} which doesn't exist in state.documents`
|
|
3733
|
+
);
|
|
3734
|
+
}
|
|
3735
|
+
const document2 = state.documents[documentId];
|
|
3736
|
+
if (document2.parent_document && state.documents[document2.parent_document]) {
|
|
3737
|
+
const { children_documents } = state.documents[document2.parent_document];
|
|
3738
|
+
state.documents[document2.parent_document].children_documents.splice(
|
|
3739
|
+
children_documents.indexOf(document2.offline_id),
|
|
3740
|
+
1
|
|
3741
|
+
);
|
|
3742
|
+
}
|
|
3743
|
+
if (targetDocumentId) {
|
|
3744
|
+
const targetDocument = state.documents[targetDocumentId];
|
|
3745
|
+
const newParentDocument = (targetDocument == null ? void 0 : targetDocument.parent_document) ? state.documents[targetDocument.parent_document] : null;
|
|
3746
|
+
switch (position) {
|
|
3747
|
+
case "left":
|
|
3748
|
+
if (!newParentDocument) {
|
|
3749
|
+
throw new Error(
|
|
3750
|
+
"attempting to move a document to the left of a document with no parent_document"
|
|
3751
|
+
);
|
|
3752
|
+
}
|
|
3753
|
+
state.documents[targetDocument.parent_document].children_documents.splice(
|
|
3754
|
+
newParentDocument.children_documents.indexOf(targetDocument.offline_id),
|
|
3755
|
+
0,
|
|
3756
|
+
document2.offline_id
|
|
3757
|
+
);
|
|
3758
|
+
state.documents[documentId].parent_document = newParentDocument.offline_id;
|
|
3759
|
+
break;
|
|
3760
|
+
case "right":
|
|
3761
|
+
if (!newParentDocument) {
|
|
3762
|
+
throw new Error(
|
|
3763
|
+
"attempting to move a document to the left of a document with no parent_document"
|
|
3764
|
+
);
|
|
3765
|
+
}
|
|
3766
|
+
state.documents[targetDocument.parent_document].children_documents.splice(
|
|
3767
|
+
newParentDocument.children_documents.indexOf(targetDocument.offline_id) + 1,
|
|
3768
|
+
0,
|
|
3769
|
+
document2.offline_id
|
|
3770
|
+
);
|
|
3771
|
+
state.documents[documentId].parent_document = newParentDocument.offline_id;
|
|
3772
|
+
break;
|
|
3773
|
+
case "left-child":
|
|
3774
|
+
if (!targetDocument) {
|
|
3775
|
+
throw new Error(
|
|
3776
|
+
"attempting to move a document to the left-child of a document that doesn't exist"
|
|
3777
|
+
);
|
|
3778
|
+
}
|
|
3779
|
+
state.documents[targetDocumentId].children_documents.unshift(document2.offline_id);
|
|
3780
|
+
state.documents[documentId].parent_document = targetDocument.offline_id;
|
|
3781
|
+
break;
|
|
3782
|
+
case "right-child":
|
|
3783
|
+
if (!targetDocument) {
|
|
3784
|
+
throw new Error(
|
|
3785
|
+
"attempting to move a document to the left-child of a document that doesn't exist"
|
|
3786
|
+
);
|
|
3787
|
+
}
|
|
3788
|
+
state.documents[targetDocumentId].children_documents.push(document2.offline_id);
|
|
3789
|
+
state.documents[documentId].parent_document = targetDocument.offline_id;
|
|
3790
|
+
}
|
|
3791
|
+
} else {
|
|
3792
|
+
state.documents[documentId].parent_document = null;
|
|
3793
|
+
}
|
|
3794
|
+
},
|
|
3795
|
+
removeDocuments: (state, action) => {
|
|
3796
|
+
for (const documentId of action.payload) {
|
|
3797
|
+
if (!(documentId in state.documents)) {
|
|
3798
|
+
throw new Error(
|
|
3799
|
+
`attempting to delete a document with offline_id ${documentId} which doesn't exists in state.documents.`
|
|
3800
|
+
);
|
|
3801
|
+
}
|
|
3802
|
+
}
|
|
3803
|
+
for (const documentId of action.payload) {
|
|
3804
|
+
const document2 = state.documents[documentId];
|
|
3805
|
+
if (document2.parent_document && !!state.documents[document2.parent_document]) {
|
|
3806
|
+
const parentDocument = state.documents[document2.parent_document];
|
|
3807
|
+
state.documents[document2.parent_document] = {
|
|
3808
|
+
...parentDocument,
|
|
3809
|
+
children_documents: parentDocument.children_documents.filter(
|
|
3810
|
+
(offline_id) => offline_id !== document2.offline_id
|
|
3811
|
+
)
|
|
3812
|
+
};
|
|
3813
|
+
}
|
|
3814
|
+
delete state.documents[documentId];
|
|
3815
|
+
}
|
|
3816
|
+
}
|
|
3817
|
+
}
|
|
3818
|
+
});
|
|
3819
|
+
const { setDocuments, addDocuments, updateDocuments, moveDocument, removeDocuments } = documentSlice.actions;
|
|
3820
|
+
const selectDocumentsMapping = (state) => state.documentsReducer.documents;
|
|
3821
|
+
const selectDocuments = createSelector(
|
|
3822
|
+
[selectDocumentsMapping],
|
|
3823
|
+
(mapping) => Object.values(mapping)
|
|
3824
|
+
);
|
|
3825
|
+
const selectDocument = restructureCreateSelectorWithArgs(
|
|
3826
|
+
createSelector(
|
|
3827
|
+
[selectDocumentsMapping, (_state, documentId) => documentId],
|
|
3828
|
+
(mapping, documentId) => mapping[documentId]
|
|
3829
|
+
)
|
|
3830
|
+
);
|
|
3831
|
+
const selectRootDocuments = createSelector(
|
|
3832
|
+
[selectDocuments],
|
|
3833
|
+
(documents) => documents.filter((document2) => !document2.parent_document)
|
|
3834
|
+
);
|
|
3835
|
+
const documentsReducer = documentSlice.reducer;
|
|
3634
3836
|
const initialState = {
|
|
3635
3837
|
version: 0
|
|
3636
3838
|
};
|
|
@@ -3677,7 +3879,8 @@ const overmapReducers = {
|
|
|
3677
3879
|
userReducer,
|
|
3678
3880
|
workspaceReducer,
|
|
3679
3881
|
emailDomainsReducer,
|
|
3680
|
-
licenseReducer
|
|
3882
|
+
licenseReducer,
|
|
3883
|
+
documentsReducer
|
|
3681
3884
|
};
|
|
3682
3885
|
const overmapReducer = combineReducers(overmapReducers);
|
|
3683
3886
|
const resetStore = "RESET";
|
|
@@ -4208,10 +4411,12 @@ class AttachmentService extends BaseApiService {
|
|
|
4208
4411
|
blocks: [],
|
|
4209
4412
|
blockers: []
|
|
4210
4413
|
});
|
|
4414
|
+
const state = this.client.store.getState();
|
|
4211
4415
|
const allAttachments = {
|
|
4212
|
-
issue_attachments: Object.values(
|
|
4213
|
-
component_attachments: Object.values(
|
|
4214
|
-
component_type_attachments: Object.values(
|
|
4416
|
+
issue_attachments: Object.values(state.issueReducer.attachments),
|
|
4417
|
+
component_attachments: Object.values(state.componentReducer.attachments),
|
|
4418
|
+
component_type_attachments: Object.values(state.componentTypeReducer.attachments),
|
|
4419
|
+
project_attachments: Object.values(state.projectReducer.attachments)
|
|
4215
4420
|
};
|
|
4216
4421
|
return [allAttachments, promise];
|
|
4217
4422
|
}
|
|
@@ -4318,6 +4523,40 @@ class AttachmentService extends BaseApiService {
|
|
|
4318
4523
|
});
|
|
4319
4524
|
return [offlineAttachment, promise];
|
|
4320
4525
|
}
|
|
4526
|
+
async addProjectAttachment(attachmentPayload) {
|
|
4527
|
+
const { description: description2, project, file_sha1, offline_id } = attachmentPayload;
|
|
4528
|
+
if (!attachmentPayload.file.objectURL) {
|
|
4529
|
+
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4530
|
+
}
|
|
4531
|
+
const offlineAttachment = {
|
|
4532
|
+
...attachmentPayload,
|
|
4533
|
+
file: attachmentPayload.file.objectURL,
|
|
4534
|
+
file_name: attachmentPayload.file.name,
|
|
4535
|
+
file_type: attachmentPayload.file.type
|
|
4536
|
+
};
|
|
4537
|
+
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4538
|
+
this.client.store.dispatch(addProjectAttachment(offlineAttachment));
|
|
4539
|
+
const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
|
|
4540
|
+
const promise = this.enqueueRequest({
|
|
4541
|
+
description: "Create attachment",
|
|
4542
|
+
method: HttpMethod.POST,
|
|
4543
|
+
url: `/components/types/${project}/attach/`,
|
|
4544
|
+
blocks: [offline_id, project.toString()],
|
|
4545
|
+
blockers: [file_sha1],
|
|
4546
|
+
payload: {
|
|
4547
|
+
offline_id,
|
|
4548
|
+
project,
|
|
4549
|
+
description: description2 ?? "",
|
|
4550
|
+
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4551
|
+
...fileProps
|
|
4552
|
+
}
|
|
4553
|
+
});
|
|
4554
|
+
promise.catch((error2) => {
|
|
4555
|
+
this.client.store.dispatch(removeProjectAttachment(offlineAttachment.offline_id));
|
|
4556
|
+
throw error2;
|
|
4557
|
+
});
|
|
4558
|
+
return [offlineAttachment, promise];
|
|
4559
|
+
}
|
|
4321
4560
|
/** the outer Promise is needed to await the hashing of each file, which is required before offline use. If wanting to
|
|
4322
4561
|
* attach promise handlers to the request to add the attachment in the backend, apply it on the promise returned from the
|
|
4323
4562
|
* OptimisticModelResult. */
|
|
@@ -4378,6 +4617,25 @@ class AttachmentService extends BaseApiService {
|
|
|
4378
4617
|
return photoAttachmentPromise(file);
|
|
4379
4618
|
});
|
|
4380
4619
|
}
|
|
4620
|
+
attachFilesToProjectType(filesToSubmit, projectId) {
|
|
4621
|
+
return filesToSubmit.map((file) => {
|
|
4622
|
+
if (!(file instanceof File)) {
|
|
4623
|
+
throw new Error("Expected a File instance.");
|
|
4624
|
+
}
|
|
4625
|
+
const photoAttachmentPromise = async (file2) => {
|
|
4626
|
+
const hash = await hashFile(file2);
|
|
4627
|
+
const attachment = offline({
|
|
4628
|
+
file: file2,
|
|
4629
|
+
file_name: file2.name,
|
|
4630
|
+
file_type: file2.type,
|
|
4631
|
+
project: projectId,
|
|
4632
|
+
file_sha1: hash
|
|
4633
|
+
});
|
|
4634
|
+
return this.addProjectAttachment(attachment);
|
|
4635
|
+
};
|
|
4636
|
+
return photoAttachmentPromise(file);
|
|
4637
|
+
});
|
|
4638
|
+
}
|
|
4381
4639
|
async replaceIssueAttachmentFile(attachmentId, newFile) {
|
|
4382
4640
|
const { store } = this.client;
|
|
4383
4641
|
const attachment = store.getState().issueReducer.attachments[attachmentId];
|
|
@@ -4605,6 +4863,22 @@ class AttachmentService extends BaseApiService {
|
|
|
4605
4863
|
blocks: [componentTypeAttachmentId]
|
|
4606
4864
|
});
|
|
4607
4865
|
}
|
|
4866
|
+
deleteProjectAttachment(projectAttachmentId) {
|
|
4867
|
+
const { store } = this.client;
|
|
4868
|
+
const attachment = selectProjectAttachmentMapping(store.getState())[projectAttachmentId];
|
|
4869
|
+
if (!attachment) {
|
|
4870
|
+
throw new Error(`Attachment ${projectAttachmentId} not found`);
|
|
4871
|
+
}
|
|
4872
|
+
store.dispatch(removeProjectAttachment(projectAttachmentId));
|
|
4873
|
+
void this.client.files.removeCache(attachment.file_sha1);
|
|
4874
|
+
return this.enqueueRequest({
|
|
4875
|
+
description: "Delete attachment",
|
|
4876
|
+
method: HttpMethod.DELETE,
|
|
4877
|
+
url: `/attachments/projects/${projectAttachmentId}/`,
|
|
4878
|
+
blockers: [projectAttachmentId],
|
|
4879
|
+
blocks: [projectAttachmentId]
|
|
4880
|
+
});
|
|
4881
|
+
}
|
|
4608
4882
|
}
|
|
4609
4883
|
const EXPIRING_SOON_THRESHOLD = 1800;
|
|
4610
4884
|
function parseTokens(response) {
|
|
@@ -5717,11 +5991,13 @@ class MainService extends BaseApiService {
|
|
|
5717
5991
|
if (currentProjectId) {
|
|
5718
5992
|
const [_offlineAttachments, promise] = this.client.attachments.fetchAll(currentProjectId);
|
|
5719
5993
|
void promise.then((result) => {
|
|
5720
|
-
const { issue_attachments, component_type_attachments, component_attachments } = result;
|
|
5994
|
+
const { issue_attachments, component_type_attachments, component_attachments, project_attachments } = result;
|
|
5721
5995
|
store.dispatch(setIssueAttachments(issue_attachments));
|
|
5722
5996
|
store.dispatch(setComponentAttachments(component_attachments));
|
|
5723
5997
|
store.dispatch(setComponentTypeAttachments(component_type_attachments));
|
|
5998
|
+
store.dispatch(setProjectAttachments(project_attachments));
|
|
5724
5999
|
});
|
|
6000
|
+
void this.client.documents.refreshStore();
|
|
5725
6001
|
}
|
|
5726
6002
|
store.dispatch(setIsFetchingInitialData(false));
|
|
5727
6003
|
if (overwrite) {
|
|
@@ -5960,12 +6236,13 @@ class ProjectService extends BaseApiService {
|
|
|
5960
6236
|
}
|
|
5961
6237
|
const filesToDelete = selectProjectFiles(state).filter((file) => file.project === projectId);
|
|
5962
6238
|
store.dispatch(removeProjectFilesOfProject(project.id));
|
|
6239
|
+
const attachmentsOfProject = selectAttachmentsOfProject(project.id)(state);
|
|
6240
|
+
store.dispatch(removeProjectAttachments(attachmentsOfProject.map(({ offline_id }) => offline_id)));
|
|
5963
6241
|
const projectAccesses = selectProjectAccesses(state);
|
|
5964
6242
|
store.dispatch(removeProjectAccessesOfProject(project.id));
|
|
5965
6243
|
store.dispatch({ type: "rehydrated/setRehydrated", payload: false });
|
|
5966
6244
|
store.dispatch(deleteProject(project));
|
|
5967
|
-
const
|
|
5968
|
-
const license = licenseSelector(state);
|
|
6245
|
+
const license = selectLicenseForProject(project.id)(state);
|
|
5969
6246
|
if (license) {
|
|
5970
6247
|
store.dispatch(updateLicense({ ...license, project: null }));
|
|
5971
6248
|
}
|
|
@@ -5982,6 +6259,7 @@ class ProjectService extends BaseApiService {
|
|
|
5982
6259
|
store.dispatch(setProjects(Object.values(projects)));
|
|
5983
6260
|
store.dispatch(setProjectAccesses(Object.values(projectAccesses)));
|
|
5984
6261
|
store.dispatch(addOrReplaceProjectFiles(filesToDelete));
|
|
6262
|
+
store.dispatch(setProjectAttachments(attachmentsOfProject));
|
|
5985
6263
|
store.dispatch(setActiveProjectId(activeProjectId));
|
|
5986
6264
|
store.dispatch({ type: "rehydrated/setRehydrated", payload: true });
|
|
5987
6265
|
if (license) {
|
|
@@ -7009,6 +7287,134 @@ class LicenseService extends BaseApiService {
|
|
|
7009
7287
|
});
|
|
7010
7288
|
}
|
|
7011
7289
|
}
|
|
7290
|
+
class DocumentService extends BaseApiService {
|
|
7291
|
+
add(document2) {
|
|
7292
|
+
const offlineDocument = offline(document2);
|
|
7293
|
+
const { store } = this.client;
|
|
7294
|
+
const activeProjectId = store.getState().projectReducer.activeProjectId;
|
|
7295
|
+
store.dispatch(addDocuments([offlineDocument]));
|
|
7296
|
+
const promise = this.enqueueRequest({
|
|
7297
|
+
description: "Create Document",
|
|
7298
|
+
method: HttpMethod.POST,
|
|
7299
|
+
url: `/projects/${activeProjectId}/create-document/`,
|
|
7300
|
+
payload: { ...offlineDocument },
|
|
7301
|
+
// if adding as a child of another document, need that document to exist first
|
|
7302
|
+
blockers: offlineDocument.parent_document ? [offlineDocument.parent_document] : [],
|
|
7303
|
+
blocks: [offlineDocument.offline_id]
|
|
7304
|
+
});
|
|
7305
|
+
promise.catch(() => {
|
|
7306
|
+
store.dispatch(removeDocuments([offlineDocument.offline_id]));
|
|
7307
|
+
});
|
|
7308
|
+
return [offlineDocument, promise];
|
|
7309
|
+
}
|
|
7310
|
+
update(document2) {
|
|
7311
|
+
const { store } = this.client;
|
|
7312
|
+
const documentToBeUpdated = store.getState().documentsReducer.documents[document2.offline_id];
|
|
7313
|
+
if (!documentToBeUpdated) {
|
|
7314
|
+
throw new Error(
|
|
7315
|
+
`attempting to update a document with offline_id ${document2.offline_id} that does not exist in store.documents`
|
|
7316
|
+
);
|
|
7317
|
+
}
|
|
7318
|
+
store.dispatch(updateDocuments([documentToBeUpdated]));
|
|
7319
|
+
const promise = this.enqueueRequest({
|
|
7320
|
+
description: "Delete Document",
|
|
7321
|
+
method: HttpMethod.DELETE,
|
|
7322
|
+
url: `/documents/${document2.offline_id}`,
|
|
7323
|
+
blockers: [document2.offline_id],
|
|
7324
|
+
blocks: [document2.offline_id]
|
|
7325
|
+
});
|
|
7326
|
+
promise.catch(() => {
|
|
7327
|
+
setDocuments([documentToBeUpdated]);
|
|
7328
|
+
});
|
|
7329
|
+
const fullDocument = store.getState().documentsReducer.documents[document2.offline_id];
|
|
7330
|
+
return [fullDocument, promise];
|
|
7331
|
+
}
|
|
7332
|
+
move(documentId, targetDocumentId, position) {
|
|
7333
|
+
const { store } = this.client;
|
|
7334
|
+
const documentsMapping = selectDocumentsMapping(store.getState());
|
|
7335
|
+
const documentsToRevertIfMoveFails = [];
|
|
7336
|
+
const documentBeingMoved = documentsMapping[documentId];
|
|
7337
|
+
if (!documentBeingMoved) {
|
|
7338
|
+
throw new Error(
|
|
7339
|
+
`attempting to move a document with offline_id ${documentId} that does not exist in store.documents`
|
|
7340
|
+
);
|
|
7341
|
+
}
|
|
7342
|
+
documentsToRevertIfMoveFails.push(documentBeingMoved);
|
|
7343
|
+
if (documentBeingMoved.parent_document) {
|
|
7344
|
+
documentsToRevertIfMoveFails.push(documentsMapping[documentBeingMoved.parent_document]);
|
|
7345
|
+
}
|
|
7346
|
+
if (targetDocumentId) {
|
|
7347
|
+
const targetDocument = documentsMapping[targetDocumentId];
|
|
7348
|
+
if (!targetDocument) {
|
|
7349
|
+
throw new Error(
|
|
7350
|
+
`attempting to move a document to target with offline_id ${targetDocumentId} that does not exist in store.documents`
|
|
7351
|
+
);
|
|
7352
|
+
}
|
|
7353
|
+
documentsToRevertIfMoveFails.push(targetDocument);
|
|
7354
|
+
if (targetDocument.parent_document) {
|
|
7355
|
+
documentsToRevertIfMoveFails.push(documentsMapping[targetDocument.parent_document]);
|
|
7356
|
+
}
|
|
7357
|
+
}
|
|
7358
|
+
store.dispatch(moveDocument({ documentId, targetDocumentId, position }));
|
|
7359
|
+
const promise = this.enqueueRequest({
|
|
7360
|
+
description: "Delete Document",
|
|
7361
|
+
method: HttpMethod.PATCH,
|
|
7362
|
+
url: `/documents/${documentId}/move/`,
|
|
7363
|
+
queryParams: {
|
|
7364
|
+
target: targetDocumentId ?? void 0,
|
|
7365
|
+
position
|
|
7366
|
+
},
|
|
7367
|
+
blockers: [documentId],
|
|
7368
|
+
blocks: []
|
|
7369
|
+
});
|
|
7370
|
+
promise.then((result) => {
|
|
7371
|
+
setDocuments(result);
|
|
7372
|
+
}).catch(() => {
|
|
7373
|
+
setDocuments(documentsToRevertIfMoveFails);
|
|
7374
|
+
});
|
|
7375
|
+
return promise;
|
|
7376
|
+
}
|
|
7377
|
+
delete(documentId) {
|
|
7378
|
+
const { store } = this.client;
|
|
7379
|
+
const documentsMapping = selectDocumentsMapping(store.getState());
|
|
7380
|
+
const documentToBeDeleted = documentsMapping[documentId];
|
|
7381
|
+
if (!documentToBeDeleted) {
|
|
7382
|
+
throw new Error(
|
|
7383
|
+
`attempting to delete a document with offline_id ${documentId} that does not exist in store.documents`
|
|
7384
|
+
);
|
|
7385
|
+
}
|
|
7386
|
+
const parentDocument = documentToBeDeleted.parent_document ? documentsMapping[documentToBeDeleted.parent_document] : void 0;
|
|
7387
|
+
store.dispatch(removeDocuments([documentId]));
|
|
7388
|
+
const promise = this.enqueueRequest({
|
|
7389
|
+
description: "Delete Document",
|
|
7390
|
+
method: HttpMethod.DELETE,
|
|
7391
|
+
url: `/documents/${documentId}`,
|
|
7392
|
+
blockers: [documentId],
|
|
7393
|
+
blocks: []
|
|
7394
|
+
});
|
|
7395
|
+
promise.then((documentsToUpdate) => {
|
|
7396
|
+
store.dispatch(updateDocuments(documentsToUpdate));
|
|
7397
|
+
}).catch(() => {
|
|
7398
|
+
store.dispatch(setDocuments([documentToBeDeleted]));
|
|
7399
|
+
if (parentDocument) {
|
|
7400
|
+
store.dispatch(setDocuments([parentDocument]));
|
|
7401
|
+
}
|
|
7402
|
+
});
|
|
7403
|
+
return promise;
|
|
7404
|
+
}
|
|
7405
|
+
async refreshStore() {
|
|
7406
|
+
const { store } = this.client;
|
|
7407
|
+
const activeProjectId = store.getState().projectReducer.activeProjectId;
|
|
7408
|
+
const result = await this.enqueueRequest({
|
|
7409
|
+
description: "Get project documents",
|
|
7410
|
+
method: HttpMethod.GET,
|
|
7411
|
+
url: `/documents/projects/${activeProjectId}`,
|
|
7412
|
+
blockers: [],
|
|
7413
|
+
blocks: []
|
|
7414
|
+
});
|
|
7415
|
+
store.dispatch(setDocuments(result));
|
|
7416
|
+
}
|
|
7417
|
+
}
|
|
7012
7418
|
class OvermapSDK {
|
|
7013
7419
|
constructor(apiUrl, store) {
|
|
7014
7420
|
__publicField(this, "API_URL");
|
|
@@ -7035,6 +7441,7 @@ class OvermapSDK {
|
|
|
7035
7441
|
__publicField(this, "emailVerification", new EmailVerificationService(this));
|
|
7036
7442
|
__publicField(this, "emailDomains", new EmailDomainsService(this));
|
|
7037
7443
|
__publicField(this, "licenses", new LicenseService(this));
|
|
7444
|
+
__publicField(this, "documents", new DocumentService(this));
|
|
7038
7445
|
this.API_URL = apiUrl;
|
|
7039
7446
|
this.store = store;
|
|
7040
7447
|
}
|
|
@@ -15025,6 +15432,7 @@ export {
|
|
|
15025
15432
|
DEFAULT_ISSUE_STATUS,
|
|
15026
15433
|
DateField,
|
|
15027
15434
|
DateInput,
|
|
15435
|
+
DocumentService,
|
|
15028
15436
|
EmailDomainsService,
|
|
15029
15437
|
EmailVerificationService,
|
|
15030
15438
|
FEATHER_ICON_SIZE,
|
|
@@ -15109,6 +15517,7 @@ export {
|
|
|
15109
15517
|
addComponentTypeAttachment,
|
|
15110
15518
|
addComponentTypeAttachments,
|
|
15111
15519
|
addComponentsInBatches,
|
|
15520
|
+
addDocuments,
|
|
15112
15521
|
addEmailDomain,
|
|
15113
15522
|
addFavouriteProjectId,
|
|
15114
15523
|
addIssue,
|
|
@@ -15121,6 +15530,8 @@ export {
|
|
|
15121
15530
|
addOrReplaceProjectFiles,
|
|
15122
15531
|
addOrReplaceProjects,
|
|
15123
15532
|
addOrReplaceWorkspaces,
|
|
15533
|
+
addProjectAttachment,
|
|
15534
|
+
addProjectAttachments,
|
|
15124
15535
|
addStageCompletion,
|
|
15125
15536
|
addStageCompletions,
|
|
15126
15537
|
addStages,
|
|
@@ -15172,6 +15583,8 @@ export {
|
|
|
15172
15583
|
deserialize,
|
|
15173
15584
|
deserializeField,
|
|
15174
15585
|
discard,
|
|
15586
|
+
documentSlice,
|
|
15587
|
+
documentsReducer,
|
|
15175
15588
|
downloadFile,
|
|
15176
15589
|
downloadInMemoryFile,
|
|
15177
15590
|
emailDomainsReducer,
|
|
@@ -15227,6 +15640,7 @@ export {
|
|
|
15227
15640
|
markerCoordinatesToText,
|
|
15228
15641
|
markerToCoordinates,
|
|
15229
15642
|
memoize,
|
|
15643
|
+
moveDocument,
|
|
15230
15644
|
offline,
|
|
15231
15645
|
offsetPositionByMeters,
|
|
15232
15646
|
onlyUniqueHashes,
|
|
@@ -15262,6 +15676,7 @@ export {
|
|
|
15262
15676
|
removeComponentAttachments,
|
|
15263
15677
|
removeComponentTypeAttachment,
|
|
15264
15678
|
removeComponentTypeAttachments,
|
|
15679
|
+
removeDocuments,
|
|
15265
15680
|
removeEmailDomain,
|
|
15266
15681
|
removeFavouriteProjectId,
|
|
15267
15682
|
removeIssue,
|
|
@@ -15270,6 +15685,8 @@ export {
|
|
|
15270
15685
|
removeOrganizationAccess,
|
|
15271
15686
|
removeProjectAccess,
|
|
15272
15687
|
removeProjectAccessesOfProject,
|
|
15688
|
+
removeProjectAttachment,
|
|
15689
|
+
removeProjectAttachments,
|
|
15273
15690
|
removeProjectFile,
|
|
15274
15691
|
removeProjectFilesOfProject,
|
|
15275
15692
|
removeRecentIssue,
|
|
@@ -15303,6 +15720,7 @@ export {
|
|
|
15303
15720
|
selectAllAttachments,
|
|
15304
15721
|
selectAllComponentAttachments,
|
|
15305
15722
|
selectAllComponentTypeAttachments,
|
|
15723
|
+
selectAllProjectAttachments,
|
|
15306
15724
|
selectAppearance,
|
|
15307
15725
|
selectAttachmentsOfComponent,
|
|
15308
15726
|
selectAttachmentsOfComponentByType,
|
|
@@ -15310,6 +15728,8 @@ export {
|
|
|
15310
15728
|
selectAttachmentsOfComponentTypeByType,
|
|
15311
15729
|
selectAttachmentsOfIssue,
|
|
15312
15730
|
selectAttachmentsOfIssueByType,
|
|
15731
|
+
selectAttachmentsOfProject,
|
|
15732
|
+
selectAttachmentsOfProjectByType,
|
|
15313
15733
|
selectCategories,
|
|
15314
15734
|
selectCategoriesOfWorkspace,
|
|
15315
15735
|
selectCategory,
|
|
@@ -15337,6 +15757,9 @@ export {
|
|
|
15337
15757
|
selectCreateProjectType,
|
|
15338
15758
|
selectCurrentUser,
|
|
15339
15759
|
selectDeletedRequests,
|
|
15760
|
+
selectDocument,
|
|
15761
|
+
selectDocuments,
|
|
15762
|
+
selectDocumentsMapping,
|
|
15340
15763
|
selectEmailDomainsAsMapping,
|
|
15341
15764
|
selectEnableClustering,
|
|
15342
15765
|
selectEnableDuplicateIssues,
|
|
@@ -15390,6 +15813,7 @@ export {
|
|
|
15390
15813
|
selectProjectAccessForUser,
|
|
15391
15814
|
selectProjectAccessUserMapping,
|
|
15392
15815
|
selectProjectAccesses,
|
|
15816
|
+
selectProjectAttachmentMapping,
|
|
15393
15817
|
selectProjectFileVisibility,
|
|
15394
15818
|
selectProjectFiles,
|
|
15395
15819
|
selectProjectUsersAsMapping,
|
|
@@ -15402,6 +15826,7 @@ export {
|
|
|
15402
15826
|
selectRehydrated,
|
|
15403
15827
|
selectRevisionAttachments,
|
|
15404
15828
|
selectRevisionsForForm,
|
|
15829
|
+
selectRootDocuments,
|
|
15405
15830
|
selectShowTooltips,
|
|
15406
15831
|
selectSortedEmailDomains,
|
|
15407
15832
|
selectSortedOrganizationLicenses,
|
|
@@ -15443,6 +15868,7 @@ export {
|
|
|
15443
15868
|
setComponents,
|
|
15444
15869
|
setCreateProjectType,
|
|
15445
15870
|
setCurrentUser,
|
|
15871
|
+
setDocuments,
|
|
15446
15872
|
setEmailDomains,
|
|
15447
15873
|
setEnableClustering,
|
|
15448
15874
|
setEnableDuplicateIssues,
|
|
@@ -15460,6 +15886,7 @@ export {
|
|
|
15460
15886
|
setOrganizations,
|
|
15461
15887
|
setProfilePicture,
|
|
15462
15888
|
setProjectAccesses,
|
|
15889
|
+
setProjectAttachments,
|
|
15463
15890
|
setProjectFileVisible,
|
|
15464
15891
|
setProjects,
|
|
15465
15892
|
setSectionExpanded,
|
|
@@ -15493,6 +15920,7 @@ export {
|
|
|
15493
15920
|
updateComponent,
|
|
15494
15921
|
updateComponentAttachment,
|
|
15495
15922
|
updateComponentTypeAttachment,
|
|
15923
|
+
updateDocuments,
|
|
15496
15924
|
updateIssue,
|
|
15497
15925
|
updateIssueAttachment,
|
|
15498
15926
|
updateLicense,
|
|
@@ -15500,6 +15928,7 @@ export {
|
|
|
15500
15928
|
updateOrCreateUserFormSubmission,
|
|
15501
15929
|
updateOrganizationAccess,
|
|
15502
15930
|
updateProjectAccess,
|
|
15931
|
+
updateProjectAttachment,
|
|
15503
15932
|
updateStages,
|
|
15504
15933
|
useAppDispatch,
|
|
15505
15934
|
useAppSelector,
|