diff --git a/.changeset/little-apples-dream.md b/.changeset/little-apples-dream.md new file mode 100644 index 0000000..abc7adc --- /dev/null +++ b/.changeset/little-apples-dream.md @@ -0,0 +1,5 @@ +--- +"@feltmaps/js-sdk": minor +--- + +Add showLayerDataTable and hideLayerDataTable methods diff --git a/docs/Main/FeltController.md b/docs/Main/FeltController.md index 761e7a9..64eda44 100644 --- a/docs/Main/FeltController.md +++ b/docs/Main/FeltController.md @@ -1164,6 +1164,65 @@ will still be selected when clicked. *** +## showLayerDataTable() + +> **showLayerDataTable**(`params`?: \{ `layerId`: `string`; `sorting`: [`SortConfig`](../Shared/SortConfig.md); }): `Promise`\<`void`> + +Shows a data table view for the specified layer, optionally sorted by a given attribute. + +### Parameters + +| Parameter | Type | +| ----------------- | ----------------------------------------------------------------------------- | +| `params`? | \{ `layerId`: `string`; `sorting`: [`SortConfig`](../Shared/SortConfig.md); } | +| `params.layerId`? | `string` | +| `params.sorting`? | [`SortConfig`](../Shared/SortConfig.md) | + +### Returns + +`Promise`\<`void`> + +### Example + +```typescript +// Show data table with default sorting +await felt.showLayerDataTable({ + layerId: "layer-1", +}); + +// Show data table sorted by height in descending order +await felt.showLayerDataTable({ + layerId: "layer-1", + sorting: { + attribute: "height", + direction: "desc", + }, +}); + +// Show the data table pane with no table visible +await felt.showLayerDataTable(); +``` + +*** + +## hideLayerDataTable() + +> **hideLayerDataTable**(): `Promise`\<`void`> + +Hides the data table. + +### Returns + +`Promise`\<`void`> + +### Example + +```typescript +await felt.hideLayerDataTable(); +``` + +*** + ## getViewport() > **getViewport**(): `Promise`\<[`ViewportState`](../Viewport/ViewportState.md)> diff --git a/docs/Shared/README.md b/docs/Shared/README.md index 1a98f27..2c51775 100644 --- a/docs/Shared/README.md +++ b/docs/Shared/README.md @@ -10,10 +10,12 @@ These are generic types that are used across multiple modules. * [MultiPolygonGeometry](MultiPolygonGeometry.md) * [LineStringGeometry](LineStringGeometry.md) * [MultiLineStringGeometry](MultiLineStringGeometry.md) +* [SortConfig](SortConfig.md) * [LngLatTuple](LngLatTuple.md) * [Geometry](Geometry.md) * [FeltZoom](FeltZoom.md) * [FeltBoundary](FeltBoundary.md) +* [SortDirection](SortDirection.md) # Visibility diff --git a/docs/Shared/SortConfig.md b/docs/Shared/SortConfig.md new file mode 100644 index 0000000..532e837 --- /dev/null +++ b/docs/Shared/SortConfig.md @@ -0,0 +1,21 @@ +*** + +Configuration for sorting data by a specific attribute + +# Properties + +## attribute + +> **attribute**: `string` + +The attribute to sort by. What this represents depends on the context. +For instance, when sorting features in a data table, the attribute is +the column to sort by. + +*** + +## direction + +> **direction**: `"asc"` | `"desc"` = `SortDirectionSchema` + +The direction to sort in diff --git a/docs/Shared/SortDirection.md b/docs/Shared/SortDirection.md new file mode 100644 index 0000000..5c58459 --- /dev/null +++ b/docs/Shared/SortDirection.md @@ -0,0 +1,5 @@ +*** + +> **SortDirection**: `"asc"` | `"desc"` + +Specifies the direction to sort data in diff --git a/docs/UI/UiController.md b/docs/UI/UiController.md index 7553822..5670891 100644 --- a/docs/UI/UiController.md +++ b/docs/UI/UiController.md @@ -1,7 +1,9 @@ *** -The UI controller allows you to enable and disable UI controls on the -embedded map. +The UI controller allows you to control various aspects of the Felt UI in your embedded map. + +This includes enabling/disabling UI controls, managing on-map interactions, and controlling +the visibility of UI components like the data table. # Extended by @@ -50,3 +52,62 @@ will still be selected when clicked. ### Returns `void` + +*** + +## showLayerDataTable() + +> **showLayerDataTable**(`params`?: \{ `layerId`: `string`; `sorting`: [`SortConfig`](../Shared/SortConfig.md); }): `Promise`\<`void`> + +Shows a data table view for the specified layer, optionally sorted by a given attribute. + +### Parameters + +| Parameter | Type | +| ----------------- | ----------------------------------------------------------------------------- | +| `params`? | \{ `layerId`: `string`; `sorting`: [`SortConfig`](../Shared/SortConfig.md); } | +| `params.layerId`? | `string` | +| `params.sorting`? | [`SortConfig`](../Shared/SortConfig.md) | + +### Returns + +`Promise`\<`void`> + +### Example + +```typescript +// Show data table with default sorting +await felt.showLayerDataTable({ + layerId: "layer-1", +}); + +// Show data table sorted by height in descending order +await felt.showLayerDataTable({ + layerId: "layer-1", + sorting: { + attribute: "height", + direction: "desc", + }, +}); + +// Show the data table pane with no table visible +await felt.showLayerDataTable(); +``` + +*** + +## hideLayerDataTable() + +> **hideLayerDataTable**(): `Promise`\<`void`> + +Hides the data table. + +### Returns + +`Promise`\<`void`> + +### Example + +```typescript +await felt.hideLayerDataTable(); +``` diff --git a/etc/js-sdk.api.md b/etc/js-sdk.api.md index 15e48f6..97dfec0 100644 --- a/etc/js-sdk.api.md +++ b/etc/js-sdk.api.md @@ -4,112 +4,114 @@ ```ts -import { ao as AggregationConfig } from './types-NOlNQi4k.js'; -import { A as AggregationMethod } from './types-NOlNQi4k.js'; -import { Q as CircleElementCreate } from './types-NOlNQi4k.js'; -import { R as CircleElementRead } from './types-NOlNQi4k.js'; -import { U as CircleElementUpdate } from './types-NOlNQi4k.js'; -import { aF as CircleToolSettings } from './types-NOlNQi4k.js'; -import { C as ConfigurableToolType } from './types-NOlNQi4k.js'; -import { E as Element_2 } from './types-NOlNQi4k.js'; -import { d as ElementChangeCallbackParams } from './types-NOlNQi4k.js'; -import { f as ElementCreate } from './types-NOlNQi4k.js'; -import { b as ElementGroup } from './types-NOlNQi4k.js'; -import { e as ElementGroupChangeCallbackParams } from './types-NOlNQi4k.js'; -import { ar as ElementGroupNode } from './types-NOlNQi4k.js'; -import { as as ElementNode } from './types-NOlNQi4k.js'; -import { g as ElementUpdate } from './types-NOlNQi4k.js'; -import { z as EntityNode } from './types-NOlNQi4k.js'; -import { s as Feature } from './types-NOlNQi4k.js'; -import { at as FeatureNode } from './types-NOlNQi4k.js'; -import { B as FeatureSelection } from './types-NOlNQi4k.js'; -import { aw as FeltBoundary } from './types-NOlNQi4k.js'; -import { ax as FeltZoom } from './types-NOlNQi4k.js'; -import { al as FilterExpression } from './types-NOlNQi4k.js'; -import { am as FilterLogicGate } from './types-NOlNQi4k.js'; -import { F as Filters } from './types-NOlNQi4k.js'; -import { an as FilterTernary } from './types-NOlNQi4k.js'; -import { G as Geometry } from './types-NOlNQi4k.js'; -import { c as GetElementGroupsConstraint } from './types-NOlNQi4k.js'; -import { a as GetElementsConstraint } from './types-NOlNQi4k.js'; -import { x as GetLayerCalculationParams } from './types-NOlNQi4k.js'; -import { u as GetLayerCategoriesGroup } from './types-NOlNQi4k.js'; -import { t as GetLayerCategoriesParams } from './types-NOlNQi4k.js'; -import { k as GetLayerGroupsConstraint } from './types-NOlNQi4k.js'; -import { w as GetLayerHistogramBin } from './types-NOlNQi4k.js'; -import { v as GetLayerHistogramParams } from './types-NOlNQi4k.js'; -import { h as GetLayersConstraint } from './types-NOlNQi4k.js'; -import { r as GetRenderedFeaturesConstraint } from './types-NOlNQi4k.js'; -import { W as HighlighterElementCreate } from './types-NOlNQi4k.js'; -import { X as HighlighterElementRead } from './types-NOlNQi4k.js'; -import { Y as HighlighterElementUpdate } from './types-NOlNQi4k.js'; -import { aG as HighlighterToolSettings } from './types-NOlNQi4k.js'; -import { Z as ImageElementCreate } from './types-NOlNQi4k.js'; -import { _ as ImageElementRead } from './types-NOlNQi4k.js'; -import { $ as ImageElementUpdate } from './types-NOlNQi4k.js'; -import { I as InputToolSettings } from './types-NOlNQi4k.js'; -import { J } from './types-NOlNQi4k.js'; -import { ay as LatLng } from './types-NOlNQi4k.js'; -import { L as Layer } from './types-NOlNQi4k.js'; -import { i as LayerChangeCallbackParams } from './types-NOlNQi4k.js'; -import { q as LayerFilters } from './types-NOlNQi4k.js'; -import { j as LayerGroup } from './types-NOlNQi4k.js'; -import { l as LayerGroupChangeCallbackParams } from './types-NOlNQi4k.js'; -import { au as LayerGroupNode } from './types-NOlNQi4k.js'; -import { av as LayerNode } from './types-NOlNQi4k.js'; -import { aj as LayerProcessingStatus } from './types-NOlNQi4k.js'; -import { n as LegendItem } from './types-NOlNQi4k.js'; -import { p as LegendItemChangeCallbackParams } from './types-NOlNQi4k.js'; -import { m as LegendItemIdentifier } from './types-NOlNQi4k.js'; -import { o as LegendItemsConstraint } from './types-NOlNQi4k.js'; -import { az as LineStringGeometry } from './types-NOlNQi4k.js'; -import { aH as LineToolSettings } from './types-NOlNQi4k.js'; -import { a0 as LinkElementRead } from './types-NOlNQi4k.js'; -import { aA as LngLatTuple } from './types-NOlNQi4k.js'; -import { y as MapDetails } from './types-NOlNQi4k.js'; -import { M as MapInteractionEvent } from './types-NOlNQi4k.js'; -import { a1 as MarkerElementCreate } from './types-NOlNQi4k.js'; -import { a2 as MarkerElementRead } from './types-NOlNQi4k.js'; -import { a3 as MarkerElementUpdate } from './types-NOlNQi4k.js'; -import { aI as MarkerToolSettings } from './types-NOlNQi4k.js'; -import { ap as MultiAggregationConfig } from './types-NOlNQi4k.js'; -import { aB as MultiLineStringGeometry } from './types-NOlNQi4k.js'; -import { aC as MultiPolygonGeometry } from './types-NOlNQi4k.js'; -import { a4 as NoteElementCreate } from './types-NOlNQi4k.js'; -import { a5 as NoteElementRead } from './types-NOlNQi4k.js'; -import { a6 as NoteElementUpdate } from './types-NOlNQi4k.js'; -import { aJ as NoteToolSettings } from './types-NOlNQi4k.js'; -import { a7 as PathElementCreate } from './types-NOlNQi4k.js'; -import { a8 as PathElementRead } from './types-NOlNQi4k.js'; -import { a9 as PathElementUpdate } from './types-NOlNQi4k.js'; -import { aK as PinToolSettings } from './types-NOlNQi4k.js'; -import { aa as PlaceElementCreate } from './types-NOlNQi4k.js'; -import { ab as PlaceElementRead } from './types-NOlNQi4k.js'; -import { ac as PlaceElementUpdate } from './types-NOlNQi4k.js'; -import { aL as PlaceFrame } from './types-NOlNQi4k.js'; -import { aM as PlaceSymbol } from './types-NOlNQi4k.js'; -import { aD as PointGeometry } from './types-NOlNQi4k.js'; -import { ad as PolygonElementCreate } from './types-NOlNQi4k.js'; -import { ae as PolygonElementRead } from './types-NOlNQi4k.js'; -import { af as PolygonElementUpdate } from './types-NOlNQi4k.js'; -import { aE as PolygonGeometry } from './types-NOlNQi4k.js'; -import { aN as PolygonToolSettings } from './types-NOlNQi4k.js'; -import { ak as RasterValue } from './types-NOlNQi4k.js'; -import { aO as RouteToolSettings } from './types-NOlNQi4k.js'; -import { K as SetViewportCenterZoomParams } from './types-NOlNQi4k.js'; -import { S as SetVisibilityRequest } from './types-NOlNQi4k.js'; -import { ag as TextElementCreate } from './types-NOlNQi4k.js'; -import { ah as TextElementRead } from './types-NOlNQi4k.js'; -import { ai as TextElementUpdate } from './types-NOlNQi4k.js'; -import { aP as TextToolSettings } from './types-NOlNQi4k.js'; -import { H as ToolSettingsChangeEvent } from './types-NOlNQi4k.js'; -import { D as ToolSettingsMap } from './types-NOlNQi4k.js'; -import { T as ToolType } from './types-NOlNQi4k.js'; -import { aq as ValueConfiguration } from './types-NOlNQi4k.js'; -import { P as ViewportCenterZoom } from './types-NOlNQi4k.js'; -import { N as ViewportConstraints } from './types-NOlNQi4k.js'; -import { O as ViewportFitBoundsParams } from './types-NOlNQi4k.js'; -import { V as ViewportState } from './types-NOlNQi4k.js'; +import { ap as AggregationConfig } from './types-CZ8IFPkE.js'; +import { A as AggregationMethod } from './types-CZ8IFPkE.js'; +import { R as CircleElementCreate } from './types-CZ8IFPkE.js'; +import { U as CircleElementRead } from './types-CZ8IFPkE.js'; +import { W as CircleElementUpdate } from './types-CZ8IFPkE.js'; +import { aH as CircleToolSettings } from './types-CZ8IFPkE.js'; +import { C as ConfigurableToolType } from './types-CZ8IFPkE.js'; +import { E as Element_2 } from './types-CZ8IFPkE.js'; +import { d as ElementChangeCallbackParams } from './types-CZ8IFPkE.js'; +import { f as ElementCreate } from './types-CZ8IFPkE.js'; +import { b as ElementGroup } from './types-CZ8IFPkE.js'; +import { e as ElementGroupChangeCallbackParams } from './types-CZ8IFPkE.js'; +import { as as ElementGroupNode } from './types-CZ8IFPkE.js'; +import { at as ElementNode } from './types-CZ8IFPkE.js'; +import { g as ElementUpdate } from './types-CZ8IFPkE.js'; +import { z as EntityNode } from './types-CZ8IFPkE.js'; +import { s as Feature } from './types-CZ8IFPkE.js'; +import { au as FeatureNode } from './types-CZ8IFPkE.js'; +import { B as FeatureSelection } from './types-CZ8IFPkE.js'; +import { ax as FeltBoundary } from './types-CZ8IFPkE.js'; +import { ay as FeltZoom } from './types-CZ8IFPkE.js'; +import { am as FilterExpression } from './types-CZ8IFPkE.js'; +import { an as FilterLogicGate } from './types-CZ8IFPkE.js'; +import { F as Filters } from './types-CZ8IFPkE.js'; +import { ao as FilterTernary } from './types-CZ8IFPkE.js'; +import { G as Geometry } from './types-CZ8IFPkE.js'; +import { c as GetElementGroupsConstraint } from './types-CZ8IFPkE.js'; +import { a as GetElementsConstraint } from './types-CZ8IFPkE.js'; +import { x as GetLayerCalculationParams } from './types-CZ8IFPkE.js'; +import { u as GetLayerCategoriesGroup } from './types-CZ8IFPkE.js'; +import { t as GetLayerCategoriesParams } from './types-CZ8IFPkE.js'; +import { k as GetLayerGroupsConstraint } from './types-CZ8IFPkE.js'; +import { w as GetLayerHistogramBin } from './types-CZ8IFPkE.js'; +import { v as GetLayerHistogramParams } from './types-CZ8IFPkE.js'; +import { h as GetLayersConstraint } from './types-CZ8IFPkE.js'; +import { r as GetRenderedFeaturesConstraint } from './types-CZ8IFPkE.js'; +import { X as HighlighterElementCreate } from './types-CZ8IFPkE.js'; +import { Y as HighlighterElementRead } from './types-CZ8IFPkE.js'; +import { Z as HighlighterElementUpdate } from './types-CZ8IFPkE.js'; +import { aI as HighlighterToolSettings } from './types-CZ8IFPkE.js'; +import { _ as ImageElementCreate } from './types-CZ8IFPkE.js'; +import { $ as ImageElementRead } from './types-CZ8IFPkE.js'; +import { a0 as ImageElementUpdate } from './types-CZ8IFPkE.js'; +import { I as InputToolSettings } from './types-CZ8IFPkE.js'; +import { J } from './types-CZ8IFPkE.js'; +import { az as LatLng } from './types-CZ8IFPkE.js'; +import { L as Layer } from './types-CZ8IFPkE.js'; +import { i as LayerChangeCallbackParams } from './types-CZ8IFPkE.js'; +import { q as LayerFilters } from './types-CZ8IFPkE.js'; +import { j as LayerGroup } from './types-CZ8IFPkE.js'; +import { l as LayerGroupChangeCallbackParams } from './types-CZ8IFPkE.js'; +import { av as LayerGroupNode } from './types-CZ8IFPkE.js'; +import { aw as LayerNode } from './types-CZ8IFPkE.js'; +import { ak as LayerProcessingStatus } from './types-CZ8IFPkE.js'; +import { n as LegendItem } from './types-CZ8IFPkE.js'; +import { p as LegendItemChangeCallbackParams } from './types-CZ8IFPkE.js'; +import { m as LegendItemIdentifier } from './types-CZ8IFPkE.js'; +import { o as LegendItemsConstraint } from './types-CZ8IFPkE.js'; +import { aA as LineStringGeometry } from './types-CZ8IFPkE.js'; +import { aJ as LineToolSettings } from './types-CZ8IFPkE.js'; +import { a1 as LinkElementRead } from './types-CZ8IFPkE.js'; +import { aB as LngLatTuple } from './types-CZ8IFPkE.js'; +import { y as MapDetails } from './types-CZ8IFPkE.js'; +import { M as MapInteractionEvent } from './types-CZ8IFPkE.js'; +import { a2 as MarkerElementCreate } from './types-CZ8IFPkE.js'; +import { a3 as MarkerElementRead } from './types-CZ8IFPkE.js'; +import { a4 as MarkerElementUpdate } from './types-CZ8IFPkE.js'; +import { aK as MarkerToolSettings } from './types-CZ8IFPkE.js'; +import { aq as MultiAggregationConfig } from './types-CZ8IFPkE.js'; +import { aC as MultiLineStringGeometry } from './types-CZ8IFPkE.js'; +import { aD as MultiPolygonGeometry } from './types-CZ8IFPkE.js'; +import { a5 as NoteElementCreate } from './types-CZ8IFPkE.js'; +import { a6 as NoteElementRead } from './types-CZ8IFPkE.js'; +import { a7 as NoteElementUpdate } from './types-CZ8IFPkE.js'; +import { aL as NoteToolSettings } from './types-CZ8IFPkE.js'; +import { a8 as PathElementCreate } from './types-CZ8IFPkE.js'; +import { a9 as PathElementRead } from './types-CZ8IFPkE.js'; +import { aa as PathElementUpdate } from './types-CZ8IFPkE.js'; +import { aM as PinToolSettings } from './types-CZ8IFPkE.js'; +import { ab as PlaceElementCreate } from './types-CZ8IFPkE.js'; +import { ac as PlaceElementRead } from './types-CZ8IFPkE.js'; +import { ad as PlaceElementUpdate } from './types-CZ8IFPkE.js'; +import { aN as PlaceFrame } from './types-CZ8IFPkE.js'; +import { aO as PlaceSymbol } from './types-CZ8IFPkE.js'; +import { aE as PointGeometry } from './types-CZ8IFPkE.js'; +import { ae as PolygonElementCreate } from './types-CZ8IFPkE.js'; +import { af as PolygonElementRead } from './types-CZ8IFPkE.js'; +import { ag as PolygonElementUpdate } from './types-CZ8IFPkE.js'; +import { aF as PolygonGeometry } from './types-CZ8IFPkE.js'; +import { aP as PolygonToolSettings } from './types-CZ8IFPkE.js'; +import { al as RasterValue } from './types-CZ8IFPkE.js'; +import { aQ as RouteToolSettings } from './types-CZ8IFPkE.js'; +import { N as SetViewportCenterZoomParams } from './types-CZ8IFPkE.js'; +import { S as SetVisibilityRequest } from './types-CZ8IFPkE.js'; +import { K as SortConfig } from './types-CZ8IFPkE.js'; +import { aG as SortDirection } from './types-CZ8IFPkE.js'; +import { ah as TextElementCreate } from './types-CZ8IFPkE.js'; +import { ai as TextElementRead } from './types-CZ8IFPkE.js'; +import { aj as TextElementUpdate } from './types-CZ8IFPkE.js'; +import { aR as TextToolSettings } from './types-CZ8IFPkE.js'; +import { H as ToolSettingsChangeEvent } from './types-CZ8IFPkE.js'; +import { D as ToolSettingsMap } from './types-CZ8IFPkE.js'; +import { T as ToolType } from './types-CZ8IFPkE.js'; +import { ar as ValueConfiguration } from './types-CZ8IFPkE.js'; +import { Q as ViewportCenterZoom } from './types-CZ8IFPkE.js'; +import { O as ViewportConstraints } from './types-CZ8IFPkE.js'; +import { P as ViewportFitBoundsParams } from './types-CZ8IFPkE.js'; +import { V as ViewportState } from './types-CZ8IFPkE.js'; import { z } from 'zod'; export { AggregationConfig } @@ -537,6 +539,10 @@ export { SetViewportCenterZoomParams } export { SetVisibilityRequest } +export { SortConfig } + +export { SortDirection } + export { TextElementCreate } export { TextElementRead } @@ -567,7 +573,12 @@ export { ToolType } // @public export interface UiController { + hideLayerDataTable(): Promise; setOnMapInteractionsUi(options: OnMapInteractionsOptions): void; + showLayerDataTable(params?: { + layerId: string; + sorting?: SortConfig; + }): Promise; updateUiControls(controls: UiControlsOptions): void; } diff --git a/src/modules/shared/index.ts b/src/modules/shared/index.ts index aaa0b74..4d7b664 100644 --- a/src/modules/shared/index.ts +++ b/src/modules/shared/index.ts @@ -15,4 +15,6 @@ export type { PointGeometry, PolygonGeometry, SetVisibilityRequest, + SortConfig, + SortDirection, } from "./types"; diff --git a/src/modules/shared/types.ts b/src/modules/shared/types.ts index c4b55b2..a600114 100644 --- a/src/modules/shared/types.ts +++ b/src/modules/shared/types.ts @@ -151,3 +151,33 @@ export const SetVisibilityRequestSchema = z.object({ show: z.array(z.string()).optional(), hide: z.array(z.string()).optional(), }); + +/** + * Specifies the direction to sort data in + * + * @group Types + */ +export type SortDirection = z.infer; +/** @ignore */ +const SortDirectionSchema = z.enum(["asc", "desc"]); + +/** + * Configuration for sorting data by a specific attribute + * + * @group Types + */ +export interface SortConfig extends zInfer {} +/** @ignore */ +export const SortConfigSchema = z.object({ + /** + * The attribute to sort by. What this represents depends on the context. + * For instance, when sorting features in a data table, the attribute is + * the column to sort by. + */ + attribute: z.string(), + + /** + * The direction to sort in + */ + direction: SortDirectionSchema, +}); diff --git a/src/modules/ui/controller.ts b/src/modules/ui/controller.ts index ffe6c79..af14557 100644 --- a/src/modules/ui/controller.ts +++ b/src/modules/ui/controller.ts @@ -1,4 +1,5 @@ import { method } from "~/lib/interface"; +import type { SortConfig } from "~/modules/shared/types"; import type { UiControlsOptions, UiOnMapInteractionsOptions } from "./types"; /** @@ -7,11 +8,16 @@ import type { UiControlsOptions, UiOnMapInteractionsOptions } from "./types"; export const uiController = (feltWindow: Window): UiController => ({ updateUiControls: method(feltWindow, "updateUiControls"), setOnMapInteractionsUi: method(feltWindow, "setOnMapInteractionsUi"), + + showLayerDataTable: method(feltWindow, "showLayerDataTable"), + hideLayerDataTable: method(feltWindow, "hideLayerDataTable"), }); /** - * The UI controller allows you to enable and disable UI controls on the - * embedded map. + * The UI controller allows you to control various aspects of the Felt UI in your embedded map. + * + * This includes enabling/disabling UI controls, managing on-map interactions, and controlling + * the visibility of UI components like the data table. * * @group Controller * @public @@ -36,4 +42,42 @@ export interface UiController { * will still be selected when clicked. */ setOnMapInteractionsUi(options: UiOnMapInteractionsOptions): void; + + /** + * Shows a data table view for the specified layer, optionally sorted by a given attribute. + * + * @example + * ```typescript + * // Show data table with default sorting + * await felt.showLayerDataTable({ + * layerId: "layer-1", + * }); + * + * // Show data table sorted by height in descending order + * await felt.showLayerDataTable({ + * layerId: "layer-1", + * sorting: { + * attribute: "height", + * direction: "desc", + * }, + * }); + * + * // Show the data table pane with no table visible + * await felt.showLayerDataTable(); + * ``` + */ + showLayerDataTable(params?: { + layerId: string; + sorting?: SortConfig; + }): Promise; + + /** + * Hides the data table. + * + * @example + * ```typescript + * await felt.hideLayerDataTable(); + * ``` + */ + hideLayerDataTable(): Promise; } diff --git a/src/modules/ui/schema.ts b/src/modules/ui/schema.ts index ea55f9b..08b0618 100644 --- a/src/modules/ui/schema.ts +++ b/src/modules/ui/schema.ts @@ -1,6 +1,8 @@ +import { z } from "zod"; import type { ModuleSchema } from "~/lib/ModuleSchema"; import { type Method, methodMessage } from "~/lib/builders"; import type { zInfer } from "~/lib/utils"; +import { SortConfigSchema } from "../shared/types"; import { UiControlsOptionsSchema, UiOnMapInteractionsOptionsSchema, @@ -16,8 +18,29 @@ const OnMapInteractionsMessage = methodMessage( UiOnMapInteractionsOptionsSchema, ); +const ShowLayerDataTableMessage = methodMessage( + "showLayerDataTable", + z + .object({ + layerId: z.string(), + sorting: SortConfigSchema.optional(), + }) + .optional(), +); + +const HideLayerDataTableMessage = methodMessage( + "hideLayerDataTable", + z.undefined(), +); + export const uiSchema = { - methods: [UiControlsMessage, OnMapInteractionsMessage], + methods: [ + UiControlsMessage, + OnMapInteractionsMessage, + + ShowLayerDataTableMessage, + HideLayerDataTableMessage, + ], listeners: null, } satisfies ModuleSchema; @@ -28,6 +51,9 @@ export type UiSchema = { zInfer, void >; + + showLayerDataTable: Method, void>; + hideLayerDataTable: Method, void>; }; listeners: {}; };