@comapeo/core-react 6.3.0 → 6.4.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.
@@ -1,3 +1,4 @@
1
+ import type { Preset } from '@comapeo/schema' with { 'resolution-mode': 'import' };
1
2
  import type { WriteableDocumentType } from '../lib/types.js';
2
3
  /**
3
4
  * Retrieve a single document from the database based on the document's document ID.
@@ -545,3 +546,37 @@ export declare function useDeleteDocument<D extends WriteableDocumentType>({ doc
545
546
  reset: () => void;
546
547
  status: "pending" | "success" | "idle";
547
548
  };
549
+ /**
550
+ * Retrieve presets for category selection, ordered by project settings.
551
+ *
552
+ * Returns presets in the order defined by `projectSettings.defaultPresets` for the
553
+ * specified data type. Falls back to alphabetical order (by preset name) if no defaults are configured.
554
+ *
555
+ * @param opts.projectId Project public ID
556
+ * @param opts.dataType Type of data being created ('observation' or 'track')
557
+ * @param opts.lang Language to translate presets into
558
+ *
559
+ * @example
560
+ * ```tsx
561
+ * function ObservationCategoryChooser() {
562
+ * const presets = usePresetsSelection({
563
+ * projectId: '...',
564
+ * dataType: 'observation',
565
+ * })
566
+ * }
567
+ * ```
568
+ *
569
+ * ```tsx
570
+ * function TrackCategoryChooser() {
571
+ * const presets = usePresetsSelection({
572
+ * projectId: '...',
573
+ * dataType: 'track',
574
+ * })
575
+ * }
576
+ * ```
577
+ */
578
+ export declare function usePresetsSelection({ projectId, dataType, lang, }: {
579
+ projectId: string;
580
+ dataType: 'observation' | 'track';
581
+ lang?: string;
582
+ }): Array<Preset>;
@@ -6,7 +6,10 @@ exports.useManyDocs = useManyDocs;
6
6
  exports.useCreateDocument = useCreateDocument;
7
7
  exports.useUpdateDocument = useUpdateDocument;
8
8
  exports.useDeleteDocument = useDeleteDocument;
9
+ exports.usePresetsSelection = usePresetsSelection;
9
10
  const react_query_1 = require("@tanstack/react-query");
11
+ const react_1 = require("react");
12
+ const presets_js_1 = require("../lib/presets.js");
10
13
  const documents_js_1 = require("../lib/react-query/documents.js");
11
14
  const projects_js_1 = require("./projects.js");
12
15
  /**
@@ -191,3 +194,50 @@ function useDeleteDocument({ docType, projectId, }) {
191
194
  ? { error, mutate, mutateAsync, reset, status }
192
195
  : { error: null, mutate, mutateAsync, reset, status };
193
196
  }
197
+ const dataTypeToGeometry = {
198
+ observation: 'point',
199
+ track: 'line',
200
+ };
201
+ /**
202
+ * Retrieve presets for category selection, ordered by project settings.
203
+ *
204
+ * Returns presets in the order defined by `projectSettings.defaultPresets` for the
205
+ * specified data type. Falls back to alphabetical order (by preset name) if no defaults are configured.
206
+ *
207
+ * @param opts.projectId Project public ID
208
+ * @param opts.dataType Type of data being created ('observation' or 'track')
209
+ * @param opts.lang Language to translate presets into
210
+ *
211
+ * @example
212
+ * ```tsx
213
+ * function ObservationCategoryChooser() {
214
+ * const presets = usePresetsSelection({
215
+ * projectId: '...',
216
+ * dataType: 'observation',
217
+ * })
218
+ * }
219
+ * ```
220
+ *
221
+ * ```tsx
222
+ * function TrackCategoryChooser() {
223
+ * const presets = usePresetsSelection({
224
+ * projectId: '...',
225
+ * dataType: 'track',
226
+ * })
227
+ * }
228
+ * ```
229
+ */
230
+ function usePresetsSelection({ projectId, dataType, lang, }) {
231
+ const { data: projectSettings } = (0, projects_js_1.useProjectSettings)({ projectId });
232
+ const { data: presets } = useManyDocs({
233
+ projectId,
234
+ docType: 'preset',
235
+ lang,
236
+ });
237
+ const presetsSelection = (0, react_1.useMemo)(() => {
238
+ const geometry = dataTypeToGeometry[dataType];
239
+ const defaults = projectSettings.defaultPresets?.[geometry];
240
+ return (0, presets_js_1.getPresetsSelection)(presets, defaults);
241
+ }, [presets, projectSettings.defaultPresets, dataType]);
242
+ return presetsSelection;
243
+ }
@@ -221,6 +221,8 @@ export declare function useAttachmentUrl({ projectId, blobId, }: {
221
221
  * })
222
222
  * }
223
223
  * ```
224
+ *
225
+ * @deprecated Use `createdBy` field from document read hooks.
224
226
  */
225
227
  export declare function useDocumentCreatedBy({ projectId, originalVersionId, }: {
226
228
  projectId: string;
@@ -279,6 +279,8 @@ function useMediaServerOrigin({ projectApi }) {
279
279
  * })
280
280
  * }
281
281
  * ```
282
+ *
283
+ * @deprecated Use `createdBy` field from document read hooks.
282
284
  */
283
285
  function useDocumentCreatedBy({ projectId, originalVersionId, }) {
284
286
  const { data: projectApi } = useSingleProject({ projectId });
@@ -1,6 +1,6 @@
1
1
  export { ClientApiContext, ClientApiProvider } from './contexts/ClientApi.js';
2
2
  export { useClientApi, useIsArchiveDevice, useOwnDeviceInfo, useSetIsArchiveDevice, useSetOwnDeviceInfo, } from './hooks/client.js';
3
- export { useCreateDocument, useDeleteDocument, useManyDocs, useSingleDocByDocId, useSingleDocByVersionId, useUpdateDocument, } from './hooks/documents.js';
3
+ export { useCreateDocument, useDeleteDocument, useManyDocs, usePresetsSelection, useSingleDocByDocId, useSingleDocByVersionId, useUpdateDocument, } from './hooks/documents.js';
4
4
  export { useAcceptInvite, useManyInvites, useRejectInvite, useRequestCancelInvite, useSendInvite, useSetUpInvitesListeners, useSingleInvite, } from './hooks/invites.js';
5
5
  export { useMapStyleUrl } from './hooks/maps.js';
6
6
  export { useAddServerPeer, useAttachmentUrl, useConnectSyncServers, useCreateBlob, useCreateProject, useDataSyncProgress, useDisconnectSyncServers, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectSettings, useRemoveServerPeer, useSetAutostopDataSyncTimeout, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, useChangeMemberRole, useExportGeoJSON, useExportZipFile, } from './hooks/projects.js';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useExportZipFile = exports.useExportGeoJSON = exports.useChangeMemberRole = exports.useUpdateProjectSettings = exports.useSyncState = exports.useStopSync = exports.useStartSync = exports.useSingleProject = exports.useSingleMember = exports.useSetAutostopDataSyncTimeout = exports.useRemoveServerPeer = exports.useProjectSettings = exports.useOwnRoleInProject = exports.useManyProjects = exports.useManyMembers = exports.useLeaveProject = exports.useImportProjectConfig = exports.useIconUrl = exports.useDocumentCreatedBy = exports.useDisconnectSyncServers = exports.useDataSyncProgress = exports.useCreateProject = exports.useCreateBlob = exports.useConnectSyncServers = exports.useAttachmentUrl = exports.useAddServerPeer = exports.useMapStyleUrl = exports.useSingleInvite = exports.useSetUpInvitesListeners = exports.useSendInvite = exports.useRequestCancelInvite = exports.useRejectInvite = exports.useManyInvites = exports.useAcceptInvite = exports.useUpdateDocument = exports.useSingleDocByVersionId = exports.useSingleDocByDocId = exports.useManyDocs = exports.useDeleteDocument = exports.useCreateDocument = exports.useSetOwnDeviceInfo = exports.useSetIsArchiveDevice = exports.useOwnDeviceInfo = exports.useIsArchiveDevice = exports.useClientApi = exports.ClientApiProvider = exports.ClientApiContext = void 0;
3
+ exports.useExportZipFile = exports.useExportGeoJSON = exports.useChangeMemberRole = exports.useUpdateProjectSettings = exports.useSyncState = exports.useStopSync = exports.useStartSync = exports.useSingleProject = exports.useSingleMember = exports.useSetAutostopDataSyncTimeout = exports.useRemoveServerPeer = exports.useProjectSettings = exports.useOwnRoleInProject = exports.useManyProjects = exports.useManyMembers = exports.useLeaveProject = exports.useImportProjectConfig = exports.useIconUrl = exports.useDocumentCreatedBy = exports.useDisconnectSyncServers = exports.useDataSyncProgress = exports.useCreateProject = exports.useCreateBlob = exports.useConnectSyncServers = exports.useAttachmentUrl = exports.useAddServerPeer = exports.useMapStyleUrl = exports.useSingleInvite = exports.useSetUpInvitesListeners = exports.useSendInvite = exports.useRequestCancelInvite = exports.useRejectInvite = exports.useManyInvites = exports.useAcceptInvite = exports.useUpdateDocument = exports.useSingleDocByVersionId = exports.useSingleDocByDocId = exports.usePresetsSelection = exports.useManyDocs = exports.useDeleteDocument = exports.useCreateDocument = exports.useSetOwnDeviceInfo = exports.useSetIsArchiveDevice = exports.useOwnDeviceInfo = exports.useIsArchiveDevice = exports.useClientApi = exports.ClientApiProvider = exports.ClientApiContext = void 0;
4
4
  var ClientApi_js_1 = require("./contexts/ClientApi.js");
5
5
  Object.defineProperty(exports, "ClientApiContext", { enumerable: true, get: function () { return ClientApi_js_1.ClientApiContext; } });
6
6
  Object.defineProperty(exports, "ClientApiProvider", { enumerable: true, get: function () { return ClientApi_js_1.ClientApiProvider; } });
@@ -14,6 +14,7 @@ var documents_js_1 = require("./hooks/documents.js");
14
14
  Object.defineProperty(exports, "useCreateDocument", { enumerable: true, get: function () { return documents_js_1.useCreateDocument; } });
15
15
  Object.defineProperty(exports, "useDeleteDocument", { enumerable: true, get: function () { return documents_js_1.useDeleteDocument; } });
16
16
  Object.defineProperty(exports, "useManyDocs", { enumerable: true, get: function () { return documents_js_1.useManyDocs; } });
17
+ Object.defineProperty(exports, "usePresetsSelection", { enumerable: true, get: function () { return documents_js_1.usePresetsSelection; } });
17
18
  Object.defineProperty(exports, "useSingleDocByDocId", { enumerable: true, get: function () { return documents_js_1.useSingleDocByDocId; } });
18
19
  Object.defineProperty(exports, "useSingleDocByVersionId", { enumerable: true, get: function () { return documents_js_1.useSingleDocByVersionId; } });
19
20
  Object.defineProperty(exports, "useUpdateDocument", { enumerable: true, get: function () { return documents_js_1.useUpdateDocument; } });
@@ -0,0 +1,2 @@
1
+ import type { Preset } from '@comapeo/schema' with { 'resolution-mode': 'import' };
2
+ export declare function getPresetsSelection(presets: Array<Preset>, orderedPresetIds?: Array<string>): Array<Preset>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPresetsSelection = getPresetsSelection;
4
+ /**
5
+ * Internal helper to sort presets alphabetically by name (case-insensitive).
6
+ */
7
+ function sortByName(presets) {
8
+ return [...presets].sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
9
+ }
10
+ function getPresetsSelection(presets, orderedPresetIds = []) {
11
+ if (orderedPresetIds.length === 0) {
12
+ return sortByName(presets);
13
+ }
14
+ const presetsSelection = [];
15
+ for (const presetId of orderedPresetIds) {
16
+ const preset = presets.find((p) => p.docId === presetId);
17
+ if (preset) {
18
+ presetsSelection.push(preset);
19
+ }
20
+ }
21
+ if (presetsSelection.length === 0) {
22
+ return sortByName(presets);
23
+ }
24
+ return presetsSelection;
25
+ }
@@ -1,3 +1,4 @@
1
+ import type { Preset } from '@comapeo/schema' with { 'resolution-mode': 'import' };
1
2
  import type { WriteableDocumentType } from '../lib/types.js';
2
3
  /**
3
4
  * Retrieve a single document from the database based on the document's document ID.
@@ -545,3 +546,37 @@ export declare function useDeleteDocument<D extends WriteableDocumentType>({ doc
545
546
  reset: () => void;
546
547
  status: "pending" | "success" | "idle";
547
548
  };
549
+ /**
550
+ * Retrieve presets for category selection, ordered by project settings.
551
+ *
552
+ * Returns presets in the order defined by `projectSettings.defaultPresets` for the
553
+ * specified data type. Falls back to alphabetical order (by preset name) if no defaults are configured.
554
+ *
555
+ * @param opts.projectId Project public ID
556
+ * @param opts.dataType Type of data being created ('observation' or 'track')
557
+ * @param opts.lang Language to translate presets into
558
+ *
559
+ * @example
560
+ * ```tsx
561
+ * function ObservationCategoryChooser() {
562
+ * const presets = usePresetsSelection({
563
+ * projectId: '...',
564
+ * dataType: 'observation',
565
+ * })
566
+ * }
567
+ * ```
568
+ *
569
+ * ```tsx
570
+ * function TrackCategoryChooser() {
571
+ * const presets = usePresetsSelection({
572
+ * projectId: '...',
573
+ * dataType: 'track',
574
+ * })
575
+ * }
576
+ * ```
577
+ */
578
+ export declare function usePresetsSelection({ projectId, dataType, lang, }: {
579
+ projectId: string;
580
+ dataType: 'observation' | 'track';
581
+ lang?: string;
582
+ }): Array<Preset>;
@@ -1,6 +1,8 @@
1
1
  import { useMutation, useQueryClient, useSuspenseQuery, } from '@tanstack/react-query';
2
+ import { useMemo } from 'react';
3
+ import { getPresetsSelection } from '../lib/presets.js';
2
4
  import { createDocumentMutationOptions, deleteDocumentMutationOptions, documentByDocumentIdQueryOptions, documentByVersionIdQueryOptions, documentsQueryOptions, updateDocumentMutationOptions, } from '../lib/react-query/documents.js';
3
- import { useSingleProject } from './projects.js';
5
+ import { useProjectSettings, useSingleProject } from './projects.js';
4
6
  /**
5
7
  * Retrieve a single document from the database based on the document's document ID.
6
8
  *
@@ -183,3 +185,50 @@ export function useDeleteDocument({ docType, projectId, }) {
183
185
  ? { error, mutate, mutateAsync, reset, status }
184
186
  : { error: null, mutate, mutateAsync, reset, status };
185
187
  }
188
+ const dataTypeToGeometry = {
189
+ observation: 'point',
190
+ track: 'line',
191
+ };
192
+ /**
193
+ * Retrieve presets for category selection, ordered by project settings.
194
+ *
195
+ * Returns presets in the order defined by `projectSettings.defaultPresets` for the
196
+ * specified data type. Falls back to alphabetical order (by preset name) if no defaults are configured.
197
+ *
198
+ * @param opts.projectId Project public ID
199
+ * @param opts.dataType Type of data being created ('observation' or 'track')
200
+ * @param opts.lang Language to translate presets into
201
+ *
202
+ * @example
203
+ * ```tsx
204
+ * function ObservationCategoryChooser() {
205
+ * const presets = usePresetsSelection({
206
+ * projectId: '...',
207
+ * dataType: 'observation',
208
+ * })
209
+ * }
210
+ * ```
211
+ *
212
+ * ```tsx
213
+ * function TrackCategoryChooser() {
214
+ * const presets = usePresetsSelection({
215
+ * projectId: '...',
216
+ * dataType: 'track',
217
+ * })
218
+ * }
219
+ * ```
220
+ */
221
+ export function usePresetsSelection({ projectId, dataType, lang, }) {
222
+ const { data: projectSettings } = useProjectSettings({ projectId });
223
+ const { data: presets } = useManyDocs({
224
+ projectId,
225
+ docType: 'preset',
226
+ lang,
227
+ });
228
+ const presetsSelection = useMemo(() => {
229
+ const geometry = dataTypeToGeometry[dataType];
230
+ const defaults = projectSettings.defaultPresets?.[geometry];
231
+ return getPresetsSelection(presets, defaults);
232
+ }, [presets, projectSettings.defaultPresets, dataType]);
233
+ return presetsSelection;
234
+ }
@@ -221,6 +221,8 @@ export declare function useAttachmentUrl({ projectId, blobId, }: {
221
221
  * })
222
222
  * }
223
223
  * ```
224
+ *
225
+ * @deprecated Use `createdBy` field from document read hooks.
224
226
  */
225
227
  export declare function useDocumentCreatedBy({ projectId, originalVersionId, }: {
226
228
  projectId: string;
@@ -251,6 +251,8 @@ function useMediaServerOrigin({ projectApi }) {
251
251
  * })
252
252
  * }
253
253
  * ```
254
+ *
255
+ * @deprecated Use `createdBy` field from document read hooks.
254
256
  */
255
257
  export function useDocumentCreatedBy({ projectId, originalVersionId, }) {
256
258
  const { data: projectApi } = useSingleProject({ projectId });
@@ -1,6 +1,6 @@
1
1
  export { ClientApiContext, ClientApiProvider } from './contexts/ClientApi.js';
2
2
  export { useClientApi, useIsArchiveDevice, useOwnDeviceInfo, useSetIsArchiveDevice, useSetOwnDeviceInfo, } from './hooks/client.js';
3
- export { useCreateDocument, useDeleteDocument, useManyDocs, useSingleDocByDocId, useSingleDocByVersionId, useUpdateDocument, } from './hooks/documents.js';
3
+ export { useCreateDocument, useDeleteDocument, useManyDocs, usePresetsSelection, useSingleDocByDocId, useSingleDocByVersionId, useUpdateDocument, } from './hooks/documents.js';
4
4
  export { useAcceptInvite, useManyInvites, useRejectInvite, useRequestCancelInvite, useSendInvite, useSetUpInvitesListeners, useSingleInvite, } from './hooks/invites.js';
5
5
  export { useMapStyleUrl } from './hooks/maps.js';
6
6
  export { useAddServerPeer, useAttachmentUrl, useConnectSyncServers, useCreateBlob, useCreateProject, useDataSyncProgress, useDisconnectSyncServers, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectSettings, useRemoveServerPeer, useSetAutostopDataSyncTimeout, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, useChangeMemberRole, useExportGeoJSON, useExportZipFile, } from './hooks/projects.js';
package/dist/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export { ClientApiContext, ClientApiProvider } from './contexts/ClientApi.js';
2
2
  export { useClientApi, useIsArchiveDevice, useOwnDeviceInfo, useSetIsArchiveDevice, useSetOwnDeviceInfo, } from './hooks/client.js';
3
- export { useCreateDocument, useDeleteDocument, useManyDocs, useSingleDocByDocId, useSingleDocByVersionId, useUpdateDocument, } from './hooks/documents.js';
3
+ export { useCreateDocument, useDeleteDocument, useManyDocs, usePresetsSelection, useSingleDocByDocId, useSingleDocByVersionId, useUpdateDocument, } from './hooks/documents.js';
4
4
  export { useAcceptInvite, useManyInvites, useRejectInvite, useRequestCancelInvite, useSendInvite, useSetUpInvitesListeners, useSingleInvite, } from './hooks/invites.js';
5
5
  export { useMapStyleUrl } from './hooks/maps.js';
6
6
  export { useAddServerPeer, useAttachmentUrl, useConnectSyncServers, useCreateBlob, useCreateProject, useDataSyncProgress, useDisconnectSyncServers, useDocumentCreatedBy, useIconUrl, useImportProjectConfig, useLeaveProject, useManyMembers, useManyProjects, useOwnRoleInProject, useProjectSettings, useRemoveServerPeer, useSetAutostopDataSyncTimeout, useSingleMember, useSingleProject, useStartSync, useStopSync, useSyncState, useUpdateProjectSettings, useChangeMemberRole, useExportGeoJSON, useExportZipFile, } from './hooks/projects.js';
@@ -0,0 +1,2 @@
1
+ import type { Preset } from '@comapeo/schema' with { 'resolution-mode': 'import' };
2
+ export declare function getPresetsSelection(presets: Array<Preset>, orderedPresetIds?: Array<string>): Array<Preset>;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Internal helper to sort presets alphabetically by name (case-insensitive).
3
+ */
4
+ function sortByName(presets) {
5
+ return [...presets].sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
6
+ }
7
+ export function getPresetsSelection(presets, orderedPresetIds = []) {
8
+ if (orderedPresetIds.length === 0) {
9
+ return sortByName(presets);
10
+ }
11
+ const presetsSelection = [];
12
+ for (const presetId of orderedPresetIds) {
13
+ const preset = presets.find((p) => p.docId === presetId);
14
+ if (preset) {
15
+ presetsSelection.push(preset);
16
+ }
17
+ }
18
+ if (presetsSelection.length === 0) {
19
+ return sortByName(presets);
20
+ }
21
+ return presetsSelection;
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comapeo/core-react",
3
- "version": "6.3.0",
3
+ "version": "6.4.0",
4
4
  "description": "React wrapper for working with @comapeo/core",
5
5
  "repository": {
6
6
  "type": "git",
@@ -71,6 +71,8 @@
71
71
  "@eslint/js": "9.35.0",
72
72
  "@ianvs/prettier-plugin-sort-imports": "4.7.0",
73
73
  "@mapeo/crypto": "1.0.0-alpha.10",
74
+ "@mapeo/default-config": "5.0.0",
75
+ "@mapeo/mock-data": "5.0.0",
74
76
  "@tanstack/eslint-plugin-query": "5.89.0",
75
77
  "@tanstack/react-query": "5.89.0",
76
78
  "@testing-library/dom": "10.4.1",