@cytario/web 2.1.4 → 2.1.5
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/README.md +20 -20
- package/app/.server/auth/README.md +8 -8
- package/app/.server/auth/authMiddleware.ts +9 -25
- package/app/.server/auth/exchangeAuthCode.ts +2 -6
- package/app/.server/auth/getS3Client.ts +3 -13
- package/app/.server/auth/getSessionCredentials.ts +6 -20
- package/app/.server/auth/getUserInfo.ts +2 -6
- package/app/.server/auth/keycloakAdmin/client.ts +2 -9
- package/app/.server/auth/keycloakAdmin/groups.ts +9 -26
- package/app/.server/auth/keycloakAdmin/users.ts +7 -23
- package/app/.server/auth/oauthState.ts +4 -13
- package/app/.server/auth/redirectIfAuthenticated.ts +1 -3
- package/app/.server/auth/refreshAuthTokens.ts +5 -19
- package/app/.server/auth/sessionMiddleware.ts +1 -4
- package/app/.server/auth/sessionStorage.ts +1 -4
- package/app/.server/auth/verifyIdToken.ts +1 -3
- package/app/.server/auth/wellKnownEndpoints.ts +1 -4
- package/app/.server/db/redis.ts +5 -1
- package/app/.server/logging.ts +1 -4
- package/app/.server/requestDurationMiddleware.ts +1 -4
- package/app/components/.client/ImageViewer/README.md +5 -5
- package/app/components/.client/ImageViewer/components/ChannelsController/ChannelsController.tsx +7 -9
- package/app/components/.client/ImageViewer/components/ChannelsController/ChannelsControllerBrightfieldItem.tsx +1 -2
- package/app/components/.client/ImageViewer/components/ChannelsController/ChannelsControllerItem.tsx +2 -5
- package/app/components/.client/ImageViewer/components/ChannelsController/ChannelsControllerItemList.tsx +7 -15
- package/app/components/.client/ImageViewer/components/ChannelsController/ColorPicker/ColorPicker.tsx +2 -9
- package/app/components/.client/ImageViewer/components/ChannelsController/ColorPicker/ColorSwatch.tsx +1 -4
- package/app/components/.client/ImageViewer/components/ChannelsController/DomainSlider.tsx +1 -3
- package/app/components/.client/ImageViewer/components/ChannelsController/Histogram.tsx +16 -18
- package/app/components/.client/ImageViewer/components/ChannelsController/HistogramChannel.tsx +2 -8
- package/app/components/.client/ImageViewer/components/ChannelsController/MinMaxSettings.tsx +6 -15
- package/app/components/.client/ImageViewer/components/FeatureBar/FeatureBarDragHandle.tsx +1 -5
- package/app/components/.client/ImageViewer/components/FeatureBar/FeatureBarToggle.tsx +1 -5
- package/app/components/.client/ImageViewer/components/FeatureBar/FeatureItem.tsx +1 -5
- package/app/components/.client/ImageViewer/components/FeatureBar/Presets.tsx +3 -11
- package/app/components/.client/ImageViewer/components/FeatureBar/useFeatureBar.tsx +16 -25
- package/app/components/.client/ImageViewer/components/Image/Channels/useChannelsLayer.ts +7 -18
- package/app/components/.client/ImageViewer/components/Image/ImageContainer.tsx +1 -1
- package/app/components/.client/ImageViewer/components/Image/ImagePanel.tsx +6 -26
- package/app/components/.client/ImageViewer/components/Image/ImagePreview.tsx +2 -9
- package/app/components/.client/ImageViewer/components/Image/Overlays/AdditivePolygonLayer.tsx +1 -5
- package/app/components/.client/ImageViewer/components/Image/Overlays/AdditiveScatterplotLayer.tsx +1 -5
- package/app/components/.client/ImageViewer/components/Image/Overlays/OverlaysLayer.tsx +6 -24
- package/app/components/.client/ImageViewer/components/Image/Overlays/markerUniforms.ts +2 -5
- package/app/components/.client/ImageViewer/components/Image/Overlays/useOverlaysLayer.tsx +7 -21
- package/app/components/.client/ImageViewer/components/Image/useInitializeChannels.ts +1 -7
- package/app/components/.client/ImageViewer/components/Image/useResizeObserver.ts +1 -1
- package/app/components/.client/ImageViewer/components/Magnifier.tsx +5 -13
- package/app/components/.client/ImageViewer/components/Measurements/ActiveViewStatePreview.tsx +3 -8
- package/app/components/.client/ImageViewer/components/Measurements/CursorTick.tsx +2 -7
- package/app/components/.client/ImageViewer/components/Measurements/Ruler.tsx +1 -8
- package/app/components/.client/ImageViewer/components/Measurements/SlideCarrier.tsx +3 -13
- package/app/components/.client/ImageViewer/components/Measurements/Tick.tsx +1 -1
- package/app/components/.client/ImageViewer/components/Measurements/calculateViewStateToFit.ts +1 -1
- package/app/components/.client/ImageViewer/components/Measurements/useMeasurements.ts +9 -28
- package/app/components/.client/ImageViewer/components/OverlaysController/AddOverlay.tsx +4 -13
- package/app/components/.client/ImageViewer/components/OverlaysController/OverlayPicker.modal.tsx +1 -6
- package/app/components/.client/ImageViewer/components/OverlaysController/OverlaysController.Item.tsx +24 -54
- package/app/components/.client/ImageViewer/components/OverlaysController/OverlaysController.tsx +1 -3
- package/app/components/.client/ImageViewer/components/SplitViewToggle.tsx +1 -3
- package/app/components/.client/ImageViewer/components/ViewerHeader.tsx +1 -3
- package/app/components/.client/ImageViewer/state/decoders/decodeJPEG2000.d.ts +9 -11
- package/app/components/.client/ImageViewer/state/decoders/decodeJPEG2000.js +11 -11
- package/app/components/.client/ImageViewer/state/decoders/decoder.worker.js +49 -49
- package/app/components/.client/ImageViewer/state/decoders/genericDecoder.ts +76 -81
- package/app/components/.client/ImageViewer/state/decoders/jp2k-decoder.ts +9 -9
- package/app/components/.client/ImageViewer/state/decoders/lzwDecoder.ts +9 -9
- package/app/components/.client/ImageViewer/state/loaders/loadBioformatsZarrWithCredentials.ts +10 -22
- package/app/components/.client/ImageViewer/state/store/ViewerStoreContext.tsx +4 -18
- package/app/components/.client/ImageViewer/state/store/createViewerStore.ts +110 -194
- package/app/components/.client/ImageViewer/state/store/getInitialChannelsState.ts +2 -6
- package/app/components/.client/ImageViewer/state/store/selectors.ts +9 -9
- package/app/components/.client/ImageViewer/state/store/types.ts +3 -12
- package/app/components/.client/ImageViewer/state/transport/CredentialedHTTPStore.ts +1 -5
- package/app/components/.client/ImageViewer/state/transport/SigV4TiffClient.ts +2 -9
- package/app/components/.client/ImageViewer/utils/getSelectionStats.ts +1 -4
- package/app/components/.client/ImageViewer/utils/handleImageViewerHover.ts +1 -1
- package/app/components/.client/ImageViewer/utils/mapChannelConfigsToState.ts +2 -4
- package/app/components/.client/ImageViewer/utils/useTilesLoading.ts +3 -3
- package/app/components/AppHeader.tsx +1 -4
- package/app/components/Breadcrumbs/Breadcrumbs.tsx +4 -13
- package/app/components/Breadcrumbs/getCrumbs.tsx +1 -1
- package/app/components/ClientOnly.tsx +1 -1
- package/app/components/Container.tsx +3 -15
- package/app/components/DataGrid/ConvertOverlay.modal.tsx +1 -6
- package/app/components/DataGrid/DataGrid.tsx +7 -27
- package/app/components/DataGrid/WktSvg.tsx +2 -4
- package/app/components/DataGrid/getParquetSchema.ts +1 -4
- package/app/components/DescriptionList.tsx +1 -3
- package/app/components/DirectoryView/ConnectionMenu.tsx +8 -22
- package/app/components/DirectoryView/DirectoryView.tsx +10 -46
- package/app/components/DirectoryView/DirectoryViewGrid.tsx +16 -49
- package/app/components/DirectoryView/DirectoryViewTableConnection.tsx +1 -4
- package/app/components/DirectoryView/DirectoryViewTableDirectory.tsx +2 -7
- package/app/components/DirectoryView/DirectoryViewTree.tsx +5 -21
- package/app/components/DirectoryView/FilterBar.tsx +9 -48
- package/app/components/DirectoryView/buildDirectoryTree.ts +6 -25
- package/app/components/DirectoryView/filterNodes.ts +4 -11
- package/app/components/DirectoryView/modals/Cyberduck.modal.tsx +6 -15
- package/app/components/DirectoryView/modals/FileInfo.modal.tsx +1 -5
- package/app/components/DirectoryView/useLayoutStore.ts +5 -25
- package/app/components/GlobalSearch/GlobalSearch.tsx +1 -4
- package/app/components/GlobalSearch/SearchBar.tsx +1 -7
- package/app/components/GlobalSearch/Suggestions.tsx +0 -1
- package/app/components/ImageViewer/state/formatRegistry.ts +5 -18
- package/app/components/LavaLoader.tsx +4 -11
- package/app/components/Layout/Footer.tsx +1 -4
- package/app/components/Pills/ScopePill.tsx +2 -8
- package/app/components/Table/ColumnFilterInput.tsx +5 -20
- package/app/components/Table/ColumnResizeHandle.tsx +1 -5
- package/app/components/Table/ColumnSortButton.tsx +1 -5
- package/app/components/Table/SelectionFooter.tsx +3 -5
- package/app/components/Table/Table.tsx +5 -21
- package/app/components/Table/TableBodyRow.tsx +19 -31
- package/app/components/Table/TableHeaderRow.tsx +7 -28
- package/app/components/Table/TableMenu.tsx +4 -20
- package/app/components/Table/state/createTableStore.ts +3 -9
- package/app/components/Table/state/useTableStore.ts +1 -3
- package/app/components/Table/types.ts +4 -10
- package/app/components/Table/useColumnFilters.ts +1 -4
- package/app/components/Table/useColumnVisibility.ts +4 -11
- package/app/components/Table/useColumnWidths.ts +1 -3
- package/app/components/Table/useTableSorting.ts +4 -12
- package/app/components/Tooltip/Tooltip.tsx +4 -17
- package/app/components/Tooltip/TooltipSpan.tsx +5 -28
- package/app/components/Tooltip/useCopyToClipboard.ts +1 -3
- package/app/components/Tooltip/useMiddleEllipsis.ts +2 -7
- package/app/components/Tooltip/useOverflowDetection.ts +2 -5
- package/app/components/UserMenu.tsx +2 -9
- package/app/entry.server.tsx +9 -19
- package/app/hooks/useSearchParam.ts +2 -4
- package/app/lib/bootstrapPluginsCore.ts +4 -9
- package/app/root.tsx +4 -15
- package/app/routes/admin/assertAdminScope.ts +1 -3
- package/app/routes/admin/assertGroupPathsInScope.ts +3 -11
- package/app/routes/admin/assertGroupsInScope.ts +3 -11
- package/app/routes/admin/assertUsersInScope.ts +2 -8
- package/app/routes/admin/bulkInvite/bulkInvite.action.ts +2 -13
- package/app/routes/admin/bulkInvite/bulkInvite.form.tsx +18 -35
- package/app/routes/admin/createGroup/createGroup.action.ts +3 -10
- package/app/routes/admin/createGroup/createGroup.form.tsx +2 -9
- package/app/routes/admin/createGroup/createGroup.modal.tsx +1 -5
- package/app/routes/admin/inviteUser/inviteUser.action.ts +1 -4
- package/app/routes/admin/inviteUser/inviteUser.form.tsx +2 -8
- package/app/routes/admin/inviteUser/inviteUser.loader.ts +1 -4
- package/app/routes/admin/inviteUser/inviteUser.modal.tsx +3 -16
- package/app/routes/admin/updateUser/updateUser.form.tsx +4 -15
- package/app/routes/admin/updateUser/updateUser.modal.tsx +5 -23
- package/app/routes/admin/updateUser/userDetail.action.ts +2 -10
- package/app/routes/admin/users/BulkActions.tsx +15 -38
- package/app/routes/admin/users/bulkUsers.action.ts +2 -9
- package/app/routes/admin/users/bulkUsers.schema.ts +1 -6
- package/app/routes/admin/users/users.route.tsx +14 -63
- package/app/routes/api/cyberduck-profile.$name.ts +6 -2
- package/app/routes/auth/callback.route.tsx +8 -33
- package/app/routes/auth/login.route.tsx +8 -11
- package/app/routes/auth/logout.route.tsx +4 -14
- package/app/routes/config.route.tsx +1 -5
- package/app/routes/connections/connection.form.tsx +5 -14
- package/app/routes/connections/connection.schema.ts +4 -16
- package/app/routes/connections/connections.loader.ts +11 -23
- package/app/routes/connections/connections.route.tsx +1 -5
- package/app/routes/connections/connections.server.ts +1 -3
- package/app/routes/connections/createConnection.action.ts +2 -8
- package/app/routes/connections/createConnection.modal.tsx +3 -13
- package/app/routes/connections/deleteConnection.action.ts +1 -4
- package/app/routes/connections/updateConnection.action.ts +2 -8
- package/app/routes/connections/updateConnection.modal.tsx +4 -14
- package/app/routes/home/home.route.tsx +8 -33
- package/app/routes/layouts/ModalOutlet.tsx +6 -18
- package/app/routes/objects/objects.loader.ts +5 -19
- package/app/routes/objects/objects.route.tsx +11 -30
- package/app/routes/presign.route.tsx +5 -18
- package/app/routes/recent.route.tsx +1 -4
- package/app/routes/search.route.tsx +4 -17
- package/app/routes.ts +1 -4
- package/app/tailwind.css +17 -12
- package/app/types/cornerstone-codecs.d.ts +25 -29
- package/app/utils/connectionsStore/selectors.ts +2 -6
- package/app/utils/connectionsStore/useConnectionsStore.ts +2 -6
- package/app/utils/db/convertCsvToParquet.ts +1 -3
- package/app/utils/db/createDatabase.ts +1 -3
- package/app/utils/db/createSingleton.ts +1 -1
- package/app/utils/db/getBlobFromObjectNode.ts +3 -9
- package/app/utils/db/getGeomQuery.ts +1 -1
- package/app/utils/db/getMarkerInfoWasm.ts +1 -3
- package/app/utils/db/getTileBoundingBox.ts +1 -4
- package/app/utils/db/sqlQueries.ts +1 -4
- package/app/utils/fileType.ts +80 -10
- package/app/utils/filterObjects.ts +2 -5
- package/app/utils/localFilesStore/useFileStore.ts +7 -7
- package/app/utils/recentlyViewed.server.ts +1 -4
- package/app/utils/resourceId.ts +3 -11
- package/app/utils/s3Provider.ts +3 -7
- package/app/utils/signedFetch.ts +4 -13
- package/bin-src/codegen.ts +4 -1
- package/package.json +5 -1
- package/prisma/seed.ts +1 -2
- package/public/favicon/site.webmanifest +1 -1
- package/server.js +1 -4
- package/server.js.map +1 -1
- package/vite-plugins/cytario-plugins.ts +2 -8
|
@@ -22,11 +22,7 @@ import { createMigrate } from "~/utils/persistMigration";
|
|
|
22
22
|
|
|
23
23
|
type PersistedViewerState = Pick<
|
|
24
24
|
ViewerStore,
|
|
25
|
-
| "
|
|
26
|
-
| "imagePanelIndex"
|
|
27
|
-
| "imagePanels"
|
|
28
|
-
| "layersStates"
|
|
29
|
-
| "viewStateActive"
|
|
25
|
+
"selectedChannelId" | "imagePanelIndex" | "imagePanels" | "layersStates" | "viewStateActive"
|
|
30
26
|
>;
|
|
31
27
|
|
|
32
28
|
const VIEWER_FALLBACK_STATE: PersistedViewerState = {
|
|
@@ -88,15 +84,11 @@ export const createViewerStore = (id: string) =>
|
|
|
88
84
|
state.error = error;
|
|
89
85
|
},
|
|
90
86
|
false,
|
|
91
|
-
"setError"
|
|
87
|
+
"setError",
|
|
92
88
|
),
|
|
93
89
|
|
|
94
90
|
setCursorPosition: (cursorPosition) =>
|
|
95
|
-
set(
|
|
96
|
-
(state) => ({ ...state, cursorPosition }),
|
|
97
|
-
false,
|
|
98
|
-
"setCursorPosition"
|
|
99
|
-
),
|
|
91
|
+
set((state) => ({ ...state, cursorPosition }), false, "setCursorPosition"),
|
|
100
92
|
|
|
101
93
|
setViewStatePreview: (viewStatePreview: ViewState) =>
|
|
102
94
|
set(
|
|
@@ -104,7 +96,7 @@ export const createViewerStore = (id: string) =>
|
|
|
104
96
|
state.viewStatePreview = viewStatePreview;
|
|
105
97
|
},
|
|
106
98
|
false,
|
|
107
|
-
"setViewStatePreview"
|
|
99
|
+
"setViewStatePreview",
|
|
108
100
|
),
|
|
109
101
|
|
|
110
102
|
setViewStateActive: (viewStateActive: ViewState) =>
|
|
@@ -115,7 +107,7 @@ export const createViewerStore = (id: string) =>
|
|
|
115
107
|
state.viewStateActive.maxZoom = 2;
|
|
116
108
|
},
|
|
117
109
|
false,
|
|
118
|
-
"setViewStateActive"
|
|
110
|
+
"setViewStateActive",
|
|
119
111
|
),
|
|
120
112
|
|
|
121
113
|
setIsViewerLoading: (isViewerLoading: boolean) =>
|
|
@@ -124,7 +116,7 @@ export const createViewerStore = (id: string) =>
|
|
|
124
116
|
state.isViewerLoading = isViewerLoading;
|
|
125
117
|
},
|
|
126
118
|
false,
|
|
127
|
-
"setIsViewerLoading"
|
|
119
|
+
"setIsViewerLoading",
|
|
128
120
|
),
|
|
129
121
|
|
|
130
122
|
setIsChannelsLoading: (imagePanelId: number, count: number) =>
|
|
@@ -137,7 +129,7 @@ export const createViewerStore = (id: string) =>
|
|
|
137
129
|
}
|
|
138
130
|
},
|
|
139
131
|
false,
|
|
140
|
-
"setIsChannelsLoading"
|
|
132
|
+
"setIsChannelsLoading",
|
|
141
133
|
),
|
|
142
134
|
|
|
143
135
|
setIsOverlaysLoading: (imagePanelId: number, count: number) =>
|
|
@@ -150,7 +142,7 @@ export const createViewerStore = (id: string) =>
|
|
|
150
142
|
}
|
|
151
143
|
},
|
|
152
144
|
false,
|
|
153
|
-
"setIsOverlaysLoading"
|
|
145
|
+
"setIsOverlaysLoading",
|
|
154
146
|
),
|
|
155
147
|
|
|
156
148
|
setMetadata: (metadata) =>
|
|
@@ -159,7 +151,7 @@ export const createViewerStore = (id: string) =>
|
|
|
159
151
|
state.metadata = metadata;
|
|
160
152
|
},
|
|
161
153
|
false,
|
|
162
|
-
"setMetadata"
|
|
154
|
+
"setMetadata",
|
|
163
155
|
),
|
|
164
156
|
|
|
165
157
|
setLoader: (loader) =>
|
|
@@ -168,7 +160,7 @@ export const createViewerStore = (id: string) =>
|
|
|
168
160
|
state.loader = loader;
|
|
169
161
|
},
|
|
170
162
|
false,
|
|
171
|
-
"setLoader"
|
|
163
|
+
"setLoader",
|
|
172
164
|
),
|
|
173
165
|
|
|
174
166
|
setSelectedChannelId: (selectedChannelId) =>
|
|
@@ -177,7 +169,7 @@ export const createViewerStore = (id: string) =>
|
|
|
177
169
|
state.selectedChannelId = selectedChannelId;
|
|
178
170
|
},
|
|
179
171
|
false,
|
|
180
|
-
"setSelectedChannelId"
|
|
172
|
+
"setSelectedChannelId",
|
|
181
173
|
),
|
|
182
174
|
|
|
183
175
|
setActiveImagePanelId: (imagePanelIndex) =>
|
|
@@ -186,7 +178,7 @@ export const createViewerStore = (id: string) =>
|
|
|
186
178
|
state.imagePanelIndex = imagePanelIndex;
|
|
187
179
|
},
|
|
188
180
|
false,
|
|
189
|
-
"setActiveImagePanelId"
|
|
181
|
+
"setActiveImagePanelId",
|
|
190
182
|
),
|
|
191
183
|
|
|
192
184
|
addImagePanel: () =>
|
|
@@ -197,13 +189,12 @@ export const createViewerStore = (id: string) =>
|
|
|
197
189
|
|
|
198
190
|
// If we don't have enough layersStates, duplicate the last one
|
|
199
191
|
while (state.layersStates.length < state.imagePanels.length) {
|
|
200
|
-
const lastLayersState =
|
|
201
|
-
state.layersStates[state.layersStates.length - 1];
|
|
192
|
+
const lastLayersState = state.layersStates[state.layersStates.length - 1];
|
|
202
193
|
state.layersStates.push({ ...lastLayersState });
|
|
203
194
|
}
|
|
204
195
|
},
|
|
205
196
|
false,
|
|
206
|
-
"addImagePanel"
|
|
197
|
+
"addImagePanel",
|
|
207
198
|
),
|
|
208
199
|
|
|
209
200
|
addChannelsState: async () => {
|
|
@@ -217,18 +208,17 @@ export const createViewerStore = (id: string) =>
|
|
|
217
208
|
setTimeout(() => {
|
|
218
209
|
reject(
|
|
219
210
|
new Error(
|
|
220
|
-
"Worker initialization timeout after 10 seconds. The decoder worker may not be loaded correctly."
|
|
221
|
-
)
|
|
211
|
+
"Worker initialization timeout after 10 seconds. The decoder worker may not be loaded correctly.",
|
|
212
|
+
),
|
|
222
213
|
);
|
|
223
214
|
}, 10000);
|
|
224
215
|
});
|
|
225
216
|
|
|
226
217
|
// Race between actual initialization and timeout
|
|
227
|
-
const { channelsState, channelIds, firstChannelKey } =
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
]);
|
|
218
|
+
const { channelsState, channelIds, firstChannelKey } = await Promise.race([
|
|
219
|
+
getInitialChannelsState(state.metadata, state.loader),
|
|
220
|
+
timeoutPromise,
|
|
221
|
+
]);
|
|
232
222
|
|
|
233
223
|
return set(
|
|
234
224
|
(state) => {
|
|
@@ -249,47 +239,36 @@ export const createViewerStore = (id: string) =>
|
|
|
249
239
|
];
|
|
250
240
|
},
|
|
251
241
|
false,
|
|
252
|
-
"addChannelsStateInitial"
|
|
242
|
+
"addChannelsStateInitial",
|
|
253
243
|
);
|
|
254
244
|
} catch (error) {
|
|
255
|
-
console.error(
|
|
256
|
-
"[createViewerStore] addChannelsState - FAILED:",
|
|
257
|
-
error
|
|
258
|
-
);
|
|
245
|
+
console.error("[createViewerStore] addChannelsState - FAILED:", error);
|
|
259
246
|
// Set error state so the UI can show an error message instead of hanging
|
|
260
247
|
set(
|
|
261
248
|
(state) => {
|
|
262
|
-
state.error =
|
|
263
|
-
error instanceof Error
|
|
264
|
-
? error
|
|
265
|
-
: new Error(String(error));
|
|
249
|
+
state.error = error instanceof Error ? error : new Error(String(error));
|
|
266
250
|
},
|
|
267
251
|
false,
|
|
268
|
-
"addChannelsStateError"
|
|
252
|
+
"addChannelsStateError",
|
|
269
253
|
);
|
|
270
254
|
return;
|
|
271
255
|
}
|
|
272
256
|
}
|
|
273
257
|
|
|
274
|
-
const activeImagePanelIndex =
|
|
275
|
-
state.imagePanels[state.imagePanelIndex];
|
|
258
|
+
const activeImagePanelIndex = state.imagePanels[state.imagePanelIndex];
|
|
276
259
|
|
|
277
260
|
return set(
|
|
278
261
|
(draft) => {
|
|
279
|
-
draft.imagePanels = draft.imagePanels.map(
|
|
280
|
-
(imagePanelIndex
|
|
281
|
-
|
|
282
|
-
return draft.layersStates.length;
|
|
283
|
-
}
|
|
284
|
-
return imagePanelIndex;
|
|
262
|
+
draft.imagePanels = draft.imagePanels.map((imagePanelIndex, index) => {
|
|
263
|
+
if (index === draft.imagePanelIndex) {
|
|
264
|
+
return draft.layersStates.length;
|
|
285
265
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
);
|
|
266
|
+
return imagePanelIndex;
|
|
267
|
+
});
|
|
268
|
+
draft.layersStates.push(castDraft(state.layersStates[activeImagePanelIndex]));
|
|
290
269
|
},
|
|
291
270
|
false,
|
|
292
|
-
"addChannelsStateDuplicate"
|
|
271
|
+
"addChannelsStateDuplicate",
|
|
293
272
|
);
|
|
294
273
|
},
|
|
295
274
|
|
|
@@ -297,14 +276,12 @@ export const createViewerStore = (id: string) =>
|
|
|
297
276
|
set(
|
|
298
277
|
(state) => {
|
|
299
278
|
state.imagePanels = state.imagePanels.map((imagePanelIndex) =>
|
|
300
|
-
Math.min(imagePanelIndex, state.layersStates.length - 2)
|
|
301
|
-
);
|
|
302
|
-
state.layersStates = state.layersStates.filter(
|
|
303
|
-
(_, index) => index !== i
|
|
279
|
+
Math.min(imagePanelIndex, state.layersStates.length - 2),
|
|
304
280
|
);
|
|
281
|
+
state.layersStates = state.layersStates.filter((_, index) => index !== i);
|
|
305
282
|
},
|
|
306
283
|
false,
|
|
307
|
-
"removeChannelsState"
|
|
284
|
+
"removeChannelsState",
|
|
308
285
|
),
|
|
309
286
|
|
|
310
287
|
setActiveChannelsStateIndex: (channelsStateIndex: number) =>
|
|
@@ -312,22 +289,19 @@ export const createViewerStore = (id: string) =>
|
|
|
312
289
|
(state) => {
|
|
313
290
|
// If we don't have enough layersStates, duplicate the last one
|
|
314
291
|
while (state.layersStates.length < channelsStateIndex + 1) {
|
|
315
|
-
const lastLayersState =
|
|
316
|
-
state.layersStates[state.layersStates.length - 1];
|
|
292
|
+
const lastLayersState = state.layersStates[state.layersStates.length - 1];
|
|
317
293
|
state.layersStates.push({ ...lastLayersState });
|
|
318
294
|
}
|
|
319
295
|
|
|
320
|
-
state.imagePanels = state.imagePanels.map(
|
|
321
|
-
(
|
|
322
|
-
|
|
323
|
-
return channelsStateIndex;
|
|
324
|
-
}
|
|
325
|
-
return imagePanel;
|
|
296
|
+
state.imagePanels = state.imagePanels.map((imagePanel, index) => {
|
|
297
|
+
if (index === state.imagePanelIndex) {
|
|
298
|
+
return channelsStateIndex;
|
|
326
299
|
}
|
|
327
|
-
|
|
300
|
+
return imagePanel;
|
|
301
|
+
});
|
|
328
302
|
},
|
|
329
303
|
false,
|
|
330
|
-
"setActiveChannelsStateIndex"
|
|
304
|
+
"setActiveChannelsStateIndex",
|
|
331
305
|
),
|
|
332
306
|
|
|
333
307
|
removeImagePanel: (imagePanelIndex) =>
|
|
@@ -335,20 +309,18 @@ export const createViewerStore = (id: string) =>
|
|
|
335
309
|
(state) => {
|
|
336
310
|
state.imagePanelIndex = imagePanelIndex - 1;
|
|
337
311
|
state.imagePanels = state.imagePanels.filter(
|
|
338
|
-
(_, index) => index !== imagePanelIndex
|
|
312
|
+
(_, index) => index !== imagePanelIndex,
|
|
339
313
|
);
|
|
340
314
|
},
|
|
341
315
|
false,
|
|
342
|
-
"removeImagePanel"
|
|
316
|
+
"removeImagePanel",
|
|
343
317
|
),
|
|
344
318
|
|
|
345
319
|
setContrastLimits: (contrastLimits) =>
|
|
346
320
|
set(
|
|
347
321
|
(state) => {
|
|
348
|
-
const activeChannelsStateIndex =
|
|
349
|
-
|
|
350
|
-
const layerState =
|
|
351
|
-
state.layersStates[activeChannelsStateIndex];
|
|
322
|
+
const activeChannelsStateIndex = state.imagePanels[state.imagePanelIndex];
|
|
323
|
+
const layerState = state.layersStates[activeChannelsStateIndex];
|
|
352
324
|
if (!layerState) return;
|
|
353
325
|
|
|
354
326
|
if (state.selectedChannelId === BRIGHTFIELD_GROUP_ID) {
|
|
@@ -360,24 +332,21 @@ export const createViewerStore = (id: string) =>
|
|
|
360
332
|
}
|
|
361
333
|
}
|
|
362
334
|
} else {
|
|
363
|
-
const key =
|
|
364
|
-
state.selectedChannelId as keyof ChannelsStateColumns;
|
|
335
|
+
const key = state.selectedChannelId as keyof ChannelsStateColumns;
|
|
365
336
|
if (layerState.channels[key]) {
|
|
366
337
|
layerState.channels[key].contrastLimits = contrastLimits;
|
|
367
338
|
}
|
|
368
339
|
}
|
|
369
340
|
},
|
|
370
341
|
false,
|
|
371
|
-
"setContrastLimits"
|
|
342
|
+
"setContrastLimits",
|
|
372
343
|
),
|
|
373
344
|
|
|
374
345
|
resetContrastLimits: () =>
|
|
375
346
|
set(
|
|
376
347
|
(state) => {
|
|
377
|
-
const activeChannelsStateIndex =
|
|
378
|
-
|
|
379
|
-
const layerState =
|
|
380
|
-
state.layersStates[activeChannelsStateIndex];
|
|
348
|
+
const activeChannelsStateIndex = state.imagePanels[state.imagePanelIndex];
|
|
349
|
+
const layerState = state.layersStates[activeChannelsStateIndex];
|
|
381
350
|
if (!layerState) return;
|
|
382
351
|
|
|
383
352
|
if (state.selectedChannelId === BRIGHTFIELD_GROUP_ID) {
|
|
@@ -386,22 +355,19 @@ export const createViewerStore = (id: string) =>
|
|
|
386
355
|
for (const key of [group.red, group.green, group.blue]) {
|
|
387
356
|
const channel = layerState.channels[key];
|
|
388
357
|
if (channel) {
|
|
389
|
-
channel.contrastLimits =
|
|
390
|
-
channel.contrastLimitsInitial as ByteDomain;
|
|
358
|
+
channel.contrastLimits = channel.contrastLimitsInitial as ByteDomain;
|
|
391
359
|
}
|
|
392
360
|
}
|
|
393
361
|
} else {
|
|
394
|
-
const key =
|
|
395
|
-
state.selectedChannelId as keyof ChannelsStateColumns;
|
|
362
|
+
const key = state.selectedChannelId as keyof ChannelsStateColumns;
|
|
396
363
|
const channel = layerState.channels[key];
|
|
397
364
|
if (channel) {
|
|
398
|
-
channel.contrastLimits =
|
|
399
|
-
channel.contrastLimitsInitial as ByteDomain;
|
|
365
|
+
channel.contrastLimits = channel.contrastLimitsInitial as ByteDomain;
|
|
400
366
|
}
|
|
401
367
|
}
|
|
402
368
|
},
|
|
403
369
|
false,
|
|
404
|
-
"resetContrastLimits"
|
|
370
|
+
"resetContrastLimits",
|
|
405
371
|
),
|
|
406
372
|
|
|
407
373
|
/**
|
|
@@ -409,18 +375,13 @@ export const createViewerStore = (id: string) =>
|
|
|
409
375
|
* If the channel is not initialized, it loads stats and initializes it before setting visibility.
|
|
410
376
|
* Handles BRIGHTFIELD_GROUP_ID by toggling all R/G/B channels together.
|
|
411
377
|
*/
|
|
412
|
-
setChannelVisibility: async (
|
|
413
|
-
key: keyof ChannelsState,
|
|
414
|
-
isVisible: boolean
|
|
415
|
-
) => {
|
|
378
|
+
setChannelVisibility: async (key: keyof ChannelsState, isVisible: boolean) => {
|
|
416
379
|
const state = get();
|
|
417
380
|
|
|
418
381
|
if (!state.loader || state.imagePanelIndex < 0) return;
|
|
419
382
|
|
|
420
|
-
const activeChannelsStateIndex =
|
|
421
|
-
|
|
422
|
-
const layerState =
|
|
423
|
-
state.layersStates[activeChannelsStateIndex];
|
|
383
|
+
const activeChannelsStateIndex = state.imagePanels[state.imagePanelIndex];
|
|
384
|
+
const layerState = state.layersStates[activeChannelsStateIndex];
|
|
424
385
|
|
|
425
386
|
// Brightfield group: toggle all 3 channels
|
|
426
387
|
if (key === BRIGHTFIELD_GROUP_ID) {
|
|
@@ -429,21 +390,17 @@ export const createViewerStore = (id: string) =>
|
|
|
429
390
|
const keys = [group.red, group.green, group.blue];
|
|
430
391
|
|
|
431
392
|
// Initialize any uninitialized channels in parallel
|
|
432
|
-
const uninitialized = keys.filter(
|
|
433
|
-
(k) => !layerState.channels[k]?.isInitialized
|
|
434
|
-
);
|
|
393
|
+
const uninitialized = keys.filter((k) => !layerState.channels[k]?.isInitialized);
|
|
435
394
|
|
|
436
395
|
if (uninitialized.length > 0) {
|
|
437
396
|
set(
|
|
438
397
|
(state) => {
|
|
439
398
|
for (const k of uninitialized) {
|
|
440
|
-
state.layersStates[activeChannelsStateIndex].channels[
|
|
441
|
-
k
|
|
442
|
-
].isLoading = true;
|
|
399
|
+
state.layersStates[activeChannelsStateIndex].channels[k].isLoading = true;
|
|
443
400
|
}
|
|
444
401
|
},
|
|
445
402
|
false,
|
|
446
|
-
"setBrightfieldVisibility/stats/request"
|
|
403
|
+
"setBrightfieldVisibility/stats/request",
|
|
447
404
|
);
|
|
448
405
|
|
|
449
406
|
try {
|
|
@@ -452,14 +409,13 @@ export const createViewerStore = (id: string) =>
|
|
|
452
409
|
getSelectionStats({
|
|
453
410
|
loader: state.loader!,
|
|
454
411
|
selection: layerState.channels[k].selection,
|
|
455
|
-
}).then((stats) => ({ key: k, ...stats }))
|
|
456
|
-
)
|
|
412
|
+
}).then((stats) => ({ key: k, ...stats })),
|
|
413
|
+
),
|
|
457
414
|
);
|
|
458
415
|
|
|
459
416
|
return set(
|
|
460
417
|
(state) => {
|
|
461
|
-
const ls =
|
|
462
|
-
state.layersStates[activeChannelsStateIndex];
|
|
418
|
+
const ls = state.layersStates[activeChannelsStateIndex];
|
|
463
419
|
for (const { key: k, domain, histogram } of results) {
|
|
464
420
|
const channel = ls.channels[k];
|
|
465
421
|
channel.isInitialized = true;
|
|
@@ -475,34 +431,32 @@ export const createViewerStore = (id: string) =>
|
|
|
475
431
|
}
|
|
476
432
|
},
|
|
477
433
|
false,
|
|
478
|
-
"setBrightfieldVisibility/stats/success"
|
|
434
|
+
"setBrightfieldVisibility/stats/success",
|
|
479
435
|
);
|
|
480
436
|
} catch {
|
|
481
437
|
return set(
|
|
482
438
|
(state) => {
|
|
483
|
-
const ls =
|
|
484
|
-
state.layersStates[activeChannelsStateIndex];
|
|
439
|
+
const ls = state.layersStates[activeChannelsStateIndex];
|
|
485
440
|
for (const k of uninitialized) {
|
|
486
441
|
ls.channels[k].isLoading = false;
|
|
487
442
|
ls.channels[k].isVisible = false;
|
|
488
443
|
}
|
|
489
444
|
},
|
|
490
445
|
false,
|
|
491
|
-
"setBrightfieldVisibility/stats/error"
|
|
446
|
+
"setBrightfieldVisibility/stats/error",
|
|
492
447
|
);
|
|
493
448
|
}
|
|
494
449
|
}
|
|
495
450
|
|
|
496
451
|
return set(
|
|
497
452
|
(state) => {
|
|
498
|
-
const ls =
|
|
499
|
-
state.layersStates[activeChannelsStateIndex];
|
|
453
|
+
const ls = state.layersStates[activeChannelsStateIndex];
|
|
500
454
|
for (const k of keys) {
|
|
501
455
|
ls.channels[k].isVisible = isVisible;
|
|
502
456
|
}
|
|
503
457
|
},
|
|
504
458
|
false,
|
|
505
|
-
"setBrightfieldVisibility"
|
|
459
|
+
"setBrightfieldVisibility",
|
|
506
460
|
);
|
|
507
461
|
}
|
|
508
462
|
|
|
@@ -512,27 +466,21 @@ export const createViewerStore = (id: string) =>
|
|
|
512
466
|
if (!activeChannelsStateConfig.isInitialized) {
|
|
513
467
|
set(
|
|
514
468
|
(state) => {
|
|
515
|
-
state.layersStates[activeChannelsStateIndex].channels[
|
|
516
|
-
key
|
|
517
|
-
].isLoading = true;
|
|
469
|
+
state.layersStates[activeChannelsStateIndex].channels[key].isLoading = true;
|
|
518
470
|
},
|
|
519
471
|
false,
|
|
520
|
-
"setChannelVisibility/stats/request"
|
|
472
|
+
"setChannelVisibility/stats/request",
|
|
521
473
|
);
|
|
522
474
|
|
|
523
475
|
try {
|
|
524
|
-
const { domain, contrastLimits, histogram } =
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
});
|
|
476
|
+
const { domain, contrastLimits, histogram } = await getSelectionStats({
|
|
477
|
+
loader: state.loader,
|
|
478
|
+
selection: activeChannelsStateConfig.selection,
|
|
479
|
+
});
|
|
529
480
|
|
|
530
481
|
return set(
|
|
531
482
|
(state) => {
|
|
532
|
-
const channel =
|
|
533
|
-
state.layersStates[activeChannelsStateIndex].channels[
|
|
534
|
-
key
|
|
535
|
-
];
|
|
483
|
+
const channel = state.layersStates[activeChannelsStateIndex].channels[key];
|
|
536
484
|
channel.isInitialized = true;
|
|
537
485
|
channel.isLoading = false;
|
|
538
486
|
channel.domain = castDraft(domain);
|
|
@@ -542,96 +490,76 @@ export const createViewerStore = (id: string) =>
|
|
|
542
490
|
channel.isVisible = isVisible;
|
|
543
491
|
},
|
|
544
492
|
false,
|
|
545
|
-
"setChannelVisibility/stats/success"
|
|
493
|
+
"setChannelVisibility/stats/success",
|
|
546
494
|
);
|
|
547
495
|
} catch {
|
|
548
496
|
return set(
|
|
549
497
|
(state) => {
|
|
550
|
-
const channel =
|
|
551
|
-
state.layersStates[activeChannelsStateIndex].channels[
|
|
552
|
-
key
|
|
553
|
-
];
|
|
498
|
+
const channel = state.layersStates[activeChannelsStateIndex].channels[key];
|
|
554
499
|
channel.isLoading = false;
|
|
555
500
|
channel.isVisible = false;
|
|
556
501
|
},
|
|
557
502
|
false,
|
|
558
|
-
"setChannelVisibility/stats/error"
|
|
503
|
+
"setChannelVisibility/stats/error",
|
|
559
504
|
);
|
|
560
505
|
}
|
|
561
506
|
}
|
|
562
507
|
|
|
563
508
|
set(
|
|
564
509
|
(state) => {
|
|
565
|
-
state.layersStates[activeChannelsStateIndex].channels[
|
|
566
|
-
key
|
|
567
|
-
].isVisible = isVisible;
|
|
510
|
+
state.layersStates[activeChannelsStateIndex].channels[key].isVisible = isVisible;
|
|
568
511
|
},
|
|
569
512
|
false,
|
|
570
|
-
"setChannelVisibility"
|
|
513
|
+
"setChannelVisibility",
|
|
571
514
|
);
|
|
572
515
|
},
|
|
573
516
|
|
|
574
|
-
setMarkerVisibility: (
|
|
575
|
-
fileName: string,
|
|
576
|
-
markerName: string,
|
|
577
|
-
isVisible: boolean
|
|
578
|
-
) =>
|
|
517
|
+
setMarkerVisibility: (fileName: string, markerName: string, isVisible: boolean) =>
|
|
579
518
|
set(
|
|
580
519
|
(state) => {
|
|
581
|
-
const activeImagePanelIndex =
|
|
582
|
-
|
|
583
|
-
const overlays =
|
|
584
|
-
state.layersStates[activeImagePanelIndex]?.overlays;
|
|
520
|
+
const activeImagePanelIndex = state.imagePanels[state.imagePanelIndex];
|
|
521
|
+
const overlays = state.layersStates[activeImagePanelIndex]?.overlays;
|
|
585
522
|
|
|
586
523
|
if (overlays?.[fileName]?.[markerName]) {
|
|
587
524
|
overlays[fileName][markerName].isVisible = isVisible;
|
|
588
525
|
}
|
|
589
526
|
},
|
|
590
527
|
false,
|
|
591
|
-
"setMarkerVisibility"
|
|
528
|
+
"setMarkerVisibility",
|
|
592
529
|
),
|
|
593
530
|
|
|
594
531
|
setChannelColor: (key: keyof ChannelsState, color: RGBA) =>
|
|
595
532
|
set(
|
|
596
533
|
(state) => {
|
|
597
|
-
const activeChannelsStateIndex =
|
|
598
|
-
|
|
599
|
-
const channel =
|
|
600
|
-
state.layersStates[activeChannelsStateIndex]?.channels[key];
|
|
534
|
+
const activeChannelsStateIndex = state.imagePanels[state.imagePanelIndex];
|
|
535
|
+
const channel = state.layersStates[activeChannelsStateIndex]?.channels[key];
|
|
601
536
|
|
|
602
537
|
if (channel) {
|
|
603
538
|
channel.color = color.slice(0, 3) as RGB;
|
|
604
539
|
}
|
|
605
540
|
},
|
|
606
541
|
false,
|
|
607
|
-
"setChannelColor"
|
|
542
|
+
"setChannelColor",
|
|
608
543
|
),
|
|
609
544
|
|
|
610
|
-
setMarkerColor: (
|
|
611
|
-
fileName: string,
|
|
612
|
-
markerName: string,
|
|
613
|
-
color: RGBA
|
|
614
|
-
) =>
|
|
545
|
+
setMarkerColor: (fileName: string, markerName: string, color: RGBA) =>
|
|
615
546
|
set(
|
|
616
547
|
(state) => {
|
|
617
|
-
const activeImagePanelIndex =
|
|
618
|
-
|
|
619
|
-
const overlays =
|
|
620
|
-
state.layersStates[activeImagePanelIndex]?.overlays;
|
|
548
|
+
const activeImagePanelIndex = state.imagePanels[state.imagePanelIndex];
|
|
549
|
+
const overlays = state.layersStates[activeImagePanelIndex]?.overlays;
|
|
621
550
|
|
|
622
551
|
if (overlays?.[fileName]?.[markerName]) {
|
|
623
552
|
overlays[fileName][markerName].color = color;
|
|
624
553
|
}
|
|
625
554
|
},
|
|
626
555
|
false,
|
|
627
|
-
"setMarkerColor"
|
|
556
|
+
"setMarkerColor",
|
|
628
557
|
),
|
|
629
558
|
|
|
630
559
|
addOverlaysState: (overlaysState: OverlaysState) =>
|
|
631
560
|
set(
|
|
632
561
|
(state) => {
|
|
633
|
-
const activeImagePanelIndex =
|
|
634
|
-
state.imagePanels[state.imagePanelIndex];
|
|
562
|
+
const activeImagePanelIndex = state.imagePanels[state.imagePanelIndex];
|
|
635
563
|
const layerState = state.layersStates[activeImagePanelIndex];
|
|
636
564
|
|
|
637
565
|
if (layerState) {
|
|
@@ -639,17 +567,13 @@ export const createViewerStore = (id: string) =>
|
|
|
639
567
|
}
|
|
640
568
|
},
|
|
641
569
|
false,
|
|
642
|
-
"addOverlaysState"
|
|
570
|
+
"addOverlaysState",
|
|
643
571
|
),
|
|
644
572
|
|
|
645
|
-
updateOverlaysState: (
|
|
646
|
-
overlayId: string,
|
|
647
|
-
overlayState: OverlayState
|
|
648
|
-
) =>
|
|
573
|
+
updateOverlaysState: (overlayId: string, overlayState: OverlayState) =>
|
|
649
574
|
set(
|
|
650
575
|
(state) => {
|
|
651
|
-
const activeImagePanelIndex =
|
|
652
|
-
state.imagePanels[state.imagePanelIndex];
|
|
576
|
+
const activeImagePanelIndex = state.imagePanels[state.imagePanelIndex];
|
|
653
577
|
const layerState = state.layersStates[activeImagePanelIndex];
|
|
654
578
|
|
|
655
579
|
if (layerState?.overlays[overlayId]) {
|
|
@@ -657,30 +581,27 @@ export const createViewerStore = (id: string) =>
|
|
|
657
581
|
}
|
|
658
582
|
},
|
|
659
583
|
false,
|
|
660
|
-
"updateOverlaysState"
|
|
584
|
+
"updateOverlaysState",
|
|
661
585
|
),
|
|
662
586
|
|
|
663
587
|
removeOverlaysState: (overlaysStateId: string) =>
|
|
664
588
|
set(
|
|
665
589
|
(state) => {
|
|
666
|
-
const activeImagePanelIndex =
|
|
667
|
-
|
|
668
|
-
const overlays =
|
|
669
|
-
state.layersStates[activeImagePanelIndex]?.overlays;
|
|
590
|
+
const activeImagePanelIndex = state.imagePanels[state.imagePanelIndex];
|
|
591
|
+
const overlays = state.layersStates[activeImagePanelIndex]?.overlays;
|
|
670
592
|
|
|
671
593
|
if (overlays) {
|
|
672
594
|
delete overlays[overlaysStateId];
|
|
673
595
|
}
|
|
674
596
|
},
|
|
675
597
|
false,
|
|
676
|
-
"removeOverlaysState"
|
|
598
|
+
"removeOverlaysState",
|
|
677
599
|
),
|
|
678
600
|
|
|
679
601
|
setOverlaysFillOpacity: (fillOpacity: number) =>
|
|
680
602
|
set(
|
|
681
603
|
(state) => {
|
|
682
|
-
const activeImagePanelIndex =
|
|
683
|
-
state.imagePanels[state.imagePanelIndex];
|
|
604
|
+
const activeImagePanelIndex = state.imagePanels[state.imagePanelIndex];
|
|
684
605
|
const layerState = state.layersStates[activeImagePanelIndex];
|
|
685
606
|
|
|
686
607
|
if (layerState) {
|
|
@@ -688,14 +609,13 @@ export const createViewerStore = (id: string) =>
|
|
|
688
609
|
}
|
|
689
610
|
},
|
|
690
611
|
false,
|
|
691
|
-
"setOverlaysFillOpacity"
|
|
612
|
+
"setOverlaysFillOpacity",
|
|
692
613
|
),
|
|
693
614
|
|
|
694
615
|
setChannelsOpacity: (channelsOpacity: number) =>
|
|
695
616
|
set(
|
|
696
617
|
(state) => {
|
|
697
|
-
const activeImagePanelIndex =
|
|
698
|
-
state.imagePanels[state.imagePanelIndex];
|
|
618
|
+
const activeImagePanelIndex = state.imagePanels[state.imagePanelIndex];
|
|
699
619
|
const layerState = state.layersStates[activeImagePanelIndex];
|
|
700
620
|
|
|
701
621
|
if (layerState) {
|
|
@@ -703,14 +623,13 @@ export const createViewerStore = (id: string) =>
|
|
|
703
623
|
}
|
|
704
624
|
},
|
|
705
625
|
false,
|
|
706
|
-
"setChannelsOpacity"
|
|
626
|
+
"setChannelsOpacity",
|
|
707
627
|
),
|
|
708
628
|
|
|
709
629
|
setShowCellOutline: (showCellOutline: boolean) =>
|
|
710
630
|
set(
|
|
711
631
|
(state) => {
|
|
712
|
-
const activeImagePanelIndex =
|
|
713
|
-
state.imagePanels[state.imagePanelIndex];
|
|
632
|
+
const activeImagePanelIndex = state.imagePanels[state.imagePanelIndex];
|
|
714
633
|
const layerState = state.layersStates[activeImagePanelIndex];
|
|
715
634
|
|
|
716
635
|
if (layerState) {
|
|
@@ -718,13 +637,13 @@ export const createViewerStore = (id: string) =>
|
|
|
718
637
|
}
|
|
719
638
|
},
|
|
720
639
|
false,
|
|
721
|
-
"setShowCellOutline"
|
|
640
|
+
"setShowCellOutline",
|
|
722
641
|
),
|
|
723
642
|
}),
|
|
724
643
|
{
|
|
725
644
|
name: "ViewerStore-" + id,
|
|
726
|
-
}
|
|
727
|
-
)
|
|
645
|
+
},
|
|
646
|
+
),
|
|
728
647
|
),
|
|
729
648
|
{
|
|
730
649
|
name: "ViewerStore-" + id,
|
|
@@ -766,12 +685,9 @@ export const createViewerStore = (id: string) =>
|
|
|
766
685
|
}),
|
|
767
686
|
onRehydrateStorage: () => (_state, error) => {
|
|
768
687
|
if (error) {
|
|
769
|
-
console.error(
|
|
770
|
-
`[ViewerStore-${id}] Rehydration failed:`,
|
|
771
|
-
error,
|
|
772
|
-
);
|
|
688
|
+
console.error(`[ViewerStore-${id}] Rehydration failed:`, error);
|
|
773
689
|
}
|
|
774
690
|
},
|
|
775
|
-
}
|
|
776
|
-
)
|
|
691
|
+
},
|
|
692
|
+
),
|
|
777
693
|
);
|