@panoboard/core 1.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/dist/cache/cache.d.ts +11 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +42 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/client.d.ts +9 -0
- package/dist/cache/client.d.ts.map +1 -0
- package/dist/cache/client.js +63 -0
- package/dist/cache/client.js.map +1 -0
- package/dist/cache/index.d.ts +4 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +17 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/keys.d.ts +2 -0
- package/dist/cache/keys.d.ts.map +1 -0
- package/dist/cache/keys.js +26 -0
- package/dist/cache/keys.js.map +1 -0
- package/dist/components/DashboardCard.d.ts +15 -0
- package/dist/components/DashboardCard.d.ts.map +1 -0
- package/dist/components/DashboardCard.js +80 -0
- package/dist/components/DashboardCard.js.map +1 -0
- package/dist/components/DashboardShell.d.ts +11 -0
- package/dist/components/DashboardShell.d.ts.map +1 -0
- package/dist/components/DashboardShell.js +115 -0
- package/dist/components/DashboardShell.js.map +1 -0
- package/dist/components/EmptyState.d.ts +6 -0
- package/dist/components/EmptyState.d.ts.map +1 -0
- package/dist/components/EmptyState.js +29 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/ErrorPage.d.ts +14 -0
- package/dist/components/ErrorPage.d.ts.map +1 -0
- package/dist/components/ErrorPage.js +132 -0
- package/dist/components/ErrorPage.js.map +1 -0
- package/dist/components/FilterBar.d.ts +8 -0
- package/dist/components/FilterBar.d.ts.map +1 -0
- package/dist/components/FilterBar.js +70 -0
- package/dist/components/FilterBar.js.map +1 -0
- package/dist/components/PanelGrid.d.ts +9 -0
- package/dist/components/PanelGrid.d.ts.map +1 -0
- package/dist/components/PanelGrid.js +26 -0
- package/dist/components/PanelGrid.js.map +1 -0
- package/dist/components/PanelWrapper.d.ts +8 -0
- package/dist/components/PanelWrapper.d.ts.map +1 -0
- package/dist/components/PanelWrapper.js +154 -0
- package/dist/components/PanelWrapper.js.map +1 -0
- package/dist/components/filters/BooleanFilter.d.ts +8 -0
- package/dist/components/filters/BooleanFilter.d.ts.map +1 -0
- package/dist/components/filters/BooleanFilter.js +36 -0
- package/dist/components/filters/BooleanFilter.js.map +1 -0
- package/dist/components/filters/CalendarGrid.d.ts +8 -0
- package/dist/components/filters/CalendarGrid.d.ts.map +1 -0
- package/dist/components/filters/CalendarGrid.js +159 -0
- package/dist/components/filters/CalendarGrid.js.map +1 -0
- package/dist/components/filters/DateRangeFilter.d.ts +10 -0
- package/dist/components/filters/DateRangeFilter.d.ts.map +1 -0
- package/dist/components/filters/DateRangeFilter.js +80 -0
- package/dist/components/filters/DateRangeFilter.js.map +1 -0
- package/dist/components/filters/FilterChips.d.ts +8 -0
- package/dist/components/filters/FilterChips.d.ts.map +1 -0
- package/dist/components/filters/FilterChips.js +94 -0
- package/dist/components/filters/FilterChips.js.map +1 -0
- package/dist/components/filters/MultiSelectFilter.d.ts +17 -0
- package/dist/components/filters/MultiSelectFilter.d.ts.map +1 -0
- package/dist/components/filters/MultiSelectFilter.js +80 -0
- package/dist/components/filters/MultiSelectFilter.js.map +1 -0
- package/dist/components/filters/NumberFilter.d.ts +10 -0
- package/dist/components/filters/NumberFilter.d.ts.map +1 -0
- package/dist/components/filters/NumberFilter.js +47 -0
- package/dist/components/filters/NumberFilter.js.map +1 -0
- package/dist/components/filters/SelectFilter.d.ts +16 -0
- package/dist/components/filters/SelectFilter.d.ts.map +1 -0
- package/dist/components/filters/SelectFilter.js +71 -0
- package/dist/components/filters/SelectFilter.js.map +1 -0
- package/dist/components/filters/TextFilter.d.ts +8 -0
- package/dist/components/filters/TextFilter.d.ts.map +1 -0
- package/dist/components/filters/TextFilter.js +57 -0
- package/dist/components/filters/TextFilter.js.map +1 -0
- package/dist/components/filters/useDropdown.d.ts +7 -0
- package/dist/components/filters/useDropdown.d.ts.map +1 -0
- package/dist/components/filters/useDropdown.js +41 -0
- package/dist/components/filters/useDropdown.js.map +1 -0
- package/dist/components/filters/useFilterUpdate.d.ts +2 -0
- package/dist/components/filters/useFilterUpdate.d.ts.map +1 -0
- package/dist/components/filters/useFilterUpdate.js +30 -0
- package/dist/components/filters/useFilterUpdate.js.map +1 -0
- package/dist/components/index.d.ts +59 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +75 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/panels/AreaChart.d.ts +7 -0
- package/dist/components/panels/AreaChart.d.ts.map +1 -0
- package/dist/components/panels/AreaChart.js +88 -0
- package/dist/components/panels/AreaChart.js.map +1 -0
- package/dist/components/panels/BarChart.d.ts +7 -0
- package/dist/components/panels/BarChart.d.ts.map +1 -0
- package/dist/components/panels/BarChart.js +99 -0
- package/dist/components/panels/BarChart.js.map +1 -0
- package/dist/components/panels/BoxPlotChart.d.ts +7 -0
- package/dist/components/panels/BoxPlotChart.d.ts.map +1 -0
- package/dist/components/panels/BoxPlotChart.js +41 -0
- package/dist/components/panels/BoxPlotChart.js.map +1 -0
- package/dist/components/panels/BulletChart.d.ts +7 -0
- package/dist/components/panels/BulletChart.d.ts.map +1 -0
- package/dist/components/panels/BulletChart.js +46 -0
- package/dist/components/panels/BulletChart.js.map +1 -0
- package/dist/components/panels/BumpChart.d.ts +7 -0
- package/dist/components/panels/BumpChart.d.ts.map +1 -0
- package/dist/components/panels/BumpChart.js +38 -0
- package/dist/components/panels/BumpChart.js.map +1 -0
- package/dist/components/panels/CalendarHeatmap.d.ts +7 -0
- package/dist/components/panels/CalendarHeatmap.d.ts.map +1 -0
- package/dist/components/panels/CalendarHeatmap.js +41 -0
- package/dist/components/panels/CalendarHeatmap.js.map +1 -0
- package/dist/components/panels/ChartTooltip.d.ts +48 -0
- package/dist/components/panels/ChartTooltip.d.ts.map +1 -0
- package/dist/components/panels/ChartTooltip.js +129 -0
- package/dist/components/panels/ChartTooltip.js.map +1 -0
- package/dist/components/panels/DonutChart.d.ts +7 -0
- package/dist/components/panels/DonutChart.d.ts.map +1 -0
- package/dist/components/panels/DonutChart.js +40 -0
- package/dist/components/panels/DonutChart.js.map +1 -0
- package/dist/components/panels/FunnelChart.d.ts +7 -0
- package/dist/components/panels/FunnelChart.d.ts.map +1 -0
- package/dist/components/panels/FunnelChart.js +32 -0
- package/dist/components/panels/FunnelChart.js.map +1 -0
- package/dist/components/panels/HeatmapChart.d.ts +7 -0
- package/dist/components/panels/HeatmapChart.d.ts.map +1 -0
- package/dist/components/panels/HeatmapChart.js +41 -0
- package/dist/components/panels/HeatmapChart.js.map +1 -0
- package/dist/components/panels/IframePanel.d.ts +6 -0
- package/dist/components/panels/IframePanel.d.ts.map +1 -0
- package/dist/components/panels/IframePanel.js +5 -0
- package/dist/components/panels/IframePanel.js.map +1 -0
- package/dist/components/panels/ImagePanel.d.ts +7 -0
- package/dist/components/panels/ImagePanel.d.ts.map +1 -0
- package/dist/components/panels/ImagePanel.js +9 -0
- package/dist/components/panels/ImagePanel.js.map +1 -0
- package/dist/components/panels/LineChart.d.ts +7 -0
- package/dist/components/panels/LineChart.d.ts.map +1 -0
- package/dist/components/panels/LineChart.js +87 -0
- package/dist/components/panels/LineChart.js.map +1 -0
- package/dist/components/panels/ListPanel.d.ts +7 -0
- package/dist/components/panels/ListPanel.d.ts.map +1 -0
- package/dist/components/panels/ListPanel.js +24 -0
- package/dist/components/panels/ListPanel.js.map +1 -0
- package/dist/components/panels/MarkdownPanel.d.ts +7 -0
- package/dist/components/panels/MarkdownPanel.d.ts.map +1 -0
- package/dist/components/panels/MarkdownPanel.js +39 -0
- package/dist/components/panels/MarkdownPanel.js.map +1 -0
- package/dist/components/panels/MetricPanel.d.ts +7 -0
- package/dist/components/panels/MetricPanel.d.ts.map +1 -0
- package/dist/components/panels/MetricPanel.js +23 -0
- package/dist/components/panels/MetricPanel.js.map +1 -0
- package/dist/components/panels/PanelEmpty.d.ts +2 -0
- package/dist/components/panels/PanelEmpty.d.ts.map +1 -0
- package/dist/components/panels/PanelEmpty.js +27 -0
- package/dist/components/panels/PanelEmpty.js.map +1 -0
- package/dist/components/panels/PanelError.d.ts +7 -0
- package/dist/components/panels/PanelError.d.ts.map +1 -0
- package/dist/components/panels/PanelError.js +21 -0
- package/dist/components/panels/PanelError.js.map +1 -0
- package/dist/components/panels/PanelSkeleton.d.ts +6 -0
- package/dist/components/panels/PanelSkeleton.d.ts.map +1 -0
- package/dist/components/panels/PanelSkeleton.js +24 -0
- package/dist/components/panels/PanelSkeleton.js.map +1 -0
- package/dist/components/panels/PieChart.d.ts +7 -0
- package/dist/components/panels/PieChart.d.ts.map +1 -0
- package/dist/components/panels/PieChart.js +40 -0
- package/dist/components/panels/PieChart.js.map +1 -0
- package/dist/components/panels/RadarChart.d.ts +7 -0
- package/dist/components/panels/RadarChart.d.ts.map +1 -0
- package/dist/components/panels/RadarChart.js +50 -0
- package/dist/components/panels/RadarChart.js.map +1 -0
- package/dist/components/panels/RadialBarChart.d.ts +7 -0
- package/dist/components/panels/RadialBarChart.d.ts.map +1 -0
- package/dist/components/panels/RadialBarChart.js +49 -0
- package/dist/components/panels/RadialBarChart.js.map +1 -0
- package/dist/components/panels/SankeyChart.d.ts +7 -0
- package/dist/components/panels/SankeyChart.d.ts.map +1 -0
- package/dist/components/panels/SankeyChart.js +39 -0
- package/dist/components/panels/SankeyChart.js.map +1 -0
- package/dist/components/panels/ScatterChart.d.ts +7 -0
- package/dist/components/panels/ScatterChart.d.ts.map +1 -0
- package/dist/components/panels/ScatterChart.js +54 -0
- package/dist/components/panels/ScatterChart.js.map +1 -0
- package/dist/components/panels/StatPanel.d.ts +8 -0
- package/dist/components/panels/StatPanel.d.ts.map +1 -0
- package/dist/components/panels/StatPanel.js +40 -0
- package/dist/components/panels/StatPanel.js.map +1 -0
- package/dist/components/panels/StreamChart.d.ts +7 -0
- package/dist/components/panels/StreamChart.d.ts.map +1 -0
- package/dist/components/panels/StreamChart.js +54 -0
- package/dist/components/panels/StreamChart.js.map +1 -0
- package/dist/components/panels/SunburstChart.d.ts +7 -0
- package/dist/components/panels/SunburstChart.d.ts.map +1 -0
- package/dist/components/panels/SunburstChart.js +60 -0
- package/dist/components/panels/SunburstChart.js.map +1 -0
- package/dist/components/panels/TablePanel.d.ts +7 -0
- package/dist/components/panels/TablePanel.d.ts.map +1 -0
- package/dist/components/panels/TablePanel.js +79 -0
- package/dist/components/panels/TablePanel.js.map +1 -0
- package/dist/components/panels/TreemapChart.d.ts +7 -0
- package/dist/components/panels/TreemapChart.d.ts.map +1 -0
- package/dist/components/panels/TreemapChart.js +59 -0
- package/dist/components/panels/TreemapChart.js.map +1 -0
- package/dist/components/panels/VideoPanel.d.ts +15 -0
- package/dist/components/panels/VideoPanel.d.ts.map +1 -0
- package/dist/components/panels/VideoPanel.js +25 -0
- package/dist/components/panels/VideoPanel.js.map +1 -0
- package/dist/components/panels/WaffleChart.d.ts +7 -0
- package/dist/components/panels/WaffleChart.d.ts.map +1 -0
- package/dist/components/panels/WaffleChart.js +46 -0
- package/dist/components/panels/WaffleChart.js.map +1 -0
- package/dist/components/panels/index.d.ts +3 -0
- package/dist/components/panels/index.d.ts.map +1 -0
- package/dist/components/panels/index.js +60 -0
- package/dist/components/panels/index.js.map +1 -0
- package/dist/components/panels/nivo-theme.d.ts +95 -0
- package/dist/components/panels/nivo-theme.d.ts.map +1 -0
- package/dist/components/panels/nivo-theme.js +140 -0
- package/dist/components/panels/nivo-theme.js.map +1 -0
- package/dist/components/panels/semantic-colors.d.ts +7 -0
- package/dist/components/panels/semantic-colors.d.ts.map +1 -0
- package/dist/components/panels/semantic-colors.js +100 -0
- package/dist/components/panels/semantic-colors.js.map +1 -0
- package/dist/components/ui/Button.d.ts +9 -0
- package/dist/components/ui/Button.d.ts.map +1 -0
- package/dist/components/ui/Button.js +40 -0
- package/dist/components/ui/Button.js.map +1 -0
- package/dist/components/ui/Tabs.d.ts +11 -0
- package/dist/components/ui/Tabs.d.ts.map +1 -0
- package/dist/components/ui/Tabs.js +28 -0
- package/dist/components/ui/Tabs.js.map +1 -0
- package/dist/connectors/bigquery.d.ts +26 -0
- package/dist/connectors/bigquery.d.ts.map +1 -0
- package/dist/connectors/bigquery.js +113 -0
- package/dist/connectors/bigquery.js.map +1 -0
- package/dist/connectors/index.d.ts +17 -0
- package/dist/connectors/index.d.ts.map +1 -0
- package/dist/connectors/index.js +23 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/params.d.ts +15 -0
- package/dist/connectors/params.d.ts.map +1 -0
- package/dist/connectors/params.js +46 -0
- package/dist/connectors/params.js.map +1 -0
- package/dist/connectors/postgres.d.ts +29 -0
- package/dist/connectors/postgres.d.ts.map +1 -0
- package/dist/connectors/postgres.js +130 -0
- package/dist/connectors/postgres.js.map +1 -0
- package/dist/connectors/redshift-data.d.ts +25 -0
- package/dist/connectors/redshift-data.d.ts.map +1 -0
- package/dist/connectors/redshift-data.js +237 -0
- package/dist/connectors/redshift-data.js.map +1 -0
- package/dist/connectors/redshift.d.ts +29 -0
- package/dist/connectors/redshift.d.ts.map +1 -0
- package/dist/connectors/redshift.js +138 -0
- package/dist/connectors/redshift.js.map +1 -0
- package/dist/connectors/registry.d.ts +7 -0
- package/dist/connectors/registry.d.ts.map +1 -0
- package/dist/connectors/registry.js +30 -0
- package/dist/connectors/registry.js.map +1 -0
- package/dist/connectors/snowflake.d.ts +37 -0
- package/dist/connectors/snowflake.d.ts.map +1 -0
- package/dist/connectors/snowflake.js +181 -0
- package/dist/connectors/snowflake.js.map +1 -0
- package/dist/connectors/types.d.ts +41 -0
- package/dist/connectors/types.d.ts.map +1 -0
- package/dist/connectors/types.js +15 -0
- package/dist/connectors/types.js.map +1 -0
- package/dist/connectors/url-parsers.d.ts +13 -0
- package/dist/connectors/url-parsers.d.ts.map +1 -0
- package/dist/connectors/url-parsers.js +95 -0
- package/dist/connectors/url-parsers.js.map +1 -0
- package/dist/connectors/url.d.ts +36 -0
- package/dist/connectors/url.d.ts.map +1 -0
- package/dist/connectors/url.js +139 -0
- package/dist/connectors/url.js.map +1 -0
- package/dist/filters/cascade.d.ts +13 -0
- package/dist/filters/cascade.d.ts.map +1 -0
- package/dist/filters/cascade.js +32 -0
- package/dist/filters/cascade.js.map +1 -0
- package/dist/filters/daterange.d.ts +8 -0
- package/dist/filters/daterange.d.ts.map +1 -0
- package/dist/filters/daterange.js +119 -0
- package/dist/filters/daterange.js.map +1 -0
- package/dist/filters/index.d.ts +7 -0
- package/dist/filters/index.d.ts.map +1 -0
- package/dist/filters/index.js +18 -0
- package/dist/filters/index.js.map +1 -0
- package/dist/filters/resolver.d.ts +3 -0
- package/dist/filters/resolver.d.ts.map +1 -0
- package/dist/filters/resolver.js +122 -0
- package/dist/filters/resolver.js.map +1 -0
- package/dist/filters/validation.d.ts +17 -0
- package/dist/filters/validation.d.ts.map +1 -0
- package/dist/filters/validation.js +84 -0
- package/dist/filters/validation.js.map +1 -0
- package/dist/formats.d.ts +4 -0
- package/dist/formats.d.ts.map +1 -0
- package/dist/formats.js +127 -0
- package/dist/formats.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/auth-provider.d.ts +22 -0
- package/dist/interfaces/auth-provider.d.ts.map +1 -0
- package/dist/interfaces/auth-provider.js +15 -0
- package/dist/interfaces/auth-provider.js.map +1 -0
- package/dist/interfaces/dashboard-store.d.ts +17 -0
- package/dist/interfaces/dashboard-store.d.ts.map +1 -0
- package/dist/interfaces/dashboard-store.js +15 -0
- package/dist/interfaces/dashboard-store.js.map +1 -0
- package/dist/interfaces/datasource-store.d.ts +6 -0
- package/dist/interfaces/datasource-store.d.ts.map +1 -0
- package/dist/interfaces/datasource-store.js +15 -0
- package/dist/interfaces/datasource-store.js.map +1 -0
- package/dist/interfaces/index.d.ts +4 -0
- package/dist/interfaces/index.d.ts.map +1 -0
- package/dist/interfaces/index.js +15 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/locale/context.d.ts +6 -0
- package/dist/locale/context.d.ts.map +1 -0
- package/dist/locale/context.js +23 -0
- package/dist/locale/context.js.map +1 -0
- package/dist/locale/index.d.ts +2 -0
- package/dist/locale/index.d.ts.map +1 -0
- package/dist/locale/index.js +15 -0
- package/dist/locale/index.js.map +1 -0
- package/dist/query/array-expansion.d.ts +5 -0
- package/dist/query/array-expansion.d.ts.map +1 -0
- package/dist/query/array-expansion.js +39 -0
- package/dist/query/array-expansion.js.map +1 -0
- package/dist/query/index.d.ts +8 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +20 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/pipeline.d.ts +27 -0
- package/dist/query/pipeline.d.ts.map +1 -0
- package/dist/query/pipeline.js +49 -0
- package/dist/query/pipeline.js.map +1 -0
- package/dist/query/strategy/http.d.ts +7 -0
- package/dist/query/strategy/http.d.ts.map +1 -0
- package/dist/query/strategy/http.js +26 -0
- package/dist/query/strategy/http.js.map +1 -0
- package/dist/query/strategy/index.d.ts +4 -0
- package/dist/query/strategy/index.d.ts.map +1 -0
- package/dist/query/strategy/index.js +32 -0
- package/dist/query/strategy/index.js.map +1 -0
- package/dist/query/strategy/sql.d.ts +7 -0
- package/dist/query/strategy/sql.d.ts.map +1 -0
- package/dist/query/strategy/sql.js +40 -0
- package/dist/query/strategy/sql.js.map +1 -0
- package/dist/query/strategy/types.d.ts +6 -0
- package/dist/query/strategy/types.d.ts.map +1 -0
- package/dist/query/strategy/types.js +15 -0
- package/dist/query/strategy/types.js.map +1 -0
- package/dist/query/template.d.ts +7 -0
- package/dist/query/template.d.ts.map +1 -0
- package/dist/query/template.js +36 -0
- package/dist/query/template.js.map +1 -0
- package/dist/schemas/config.d.ts +74 -0
- package/dist/schemas/config.d.ts.map +1 -0
- package/dist/schemas/config.js +129 -0
- package/dist/schemas/config.js.map +1 -0
- package/dist/schemas/dashboard.d.ts +716 -0
- package/dist/schemas/dashboard.d.ts.map +1 -0
- package/dist/schemas/dashboard.js +314 -0
- package/dist/schemas/dashboard.js.map +1 -0
- package/dist/schemas/datasource.d.ts +252 -0
- package/dist/schemas/datasource.d.ts.map +1 -0
- package/dist/schemas/datasource.js +186 -0
- package/dist/schemas/datasource.js.map +1 -0
- package/dist/schemas/index.d.ts +5 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +18 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/theme.d.ts +36 -0
- package/dist/schemas/theme.d.ts.map +1 -0
- package/dist/schemas/theme.js +48 -0
- package/dist/schemas/theme.js.map +1 -0
- package/dist/startup/index.d.ts +3 -0
- package/dist/startup/index.d.ts.map +1 -0
- package/dist/startup/index.js +15 -0
- package/dist/startup/index.js.map +1 -0
- package/dist/startup/sql-lint.d.ts +13 -0
- package/dist/startup/sql-lint.d.ts.map +1 -0
- package/dist/startup/sql-lint.js +86 -0
- package/dist/startup/sql-lint.js.map +1 -0
- package/dist/theme/builtin.d.ts +5 -0
- package/dist/theme/builtin.d.ts.map +1 -0
- package/dist/theme/builtin.js +102 -0
- package/dist/theme/builtin.js.map +1 -0
- package/dist/theme/context.d.ts +7 -0
- package/dist/theme/context.d.ts.map +1 -0
- package/dist/theme/context.js +26 -0
- package/dist/theme/context.js.map +1 -0
- package/dist/theme/index.d.ts +3 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +16 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/loader-export.d.ts +2 -0
- package/dist/theme/loader-export.d.ts.map +1 -0
- package/dist/theme/loader-export.js +15 -0
- package/dist/theme/loader-export.js.map +1 -0
- package/dist/theme/loader.d.ts +11 -0
- package/dist/theme/loader.d.ts.map +1 -0
- package/dist/theme/loader.js +60 -0
- package/dist/theme/loader.js.map +1 -0
- package/package.json +148 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 2026 Mataki Labs LLC
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Business Source License 1.1 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// https://github.com/panoboard/panoboard/blob/main/LICENSE
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
import { useState } from "react";
|
|
16
|
+
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
17
|
+
import { useTheme } from "../../theme/context";
|
|
18
|
+
function toISO(year, month, day) {
|
|
19
|
+
return `${year}-${String(month + 1).padStart(2, "0")}-${String(day).padStart(2, "0")}`;
|
|
20
|
+
}
|
|
21
|
+
function parseISO(iso) {
|
|
22
|
+
if (!iso)
|
|
23
|
+
return null;
|
|
24
|
+
const m = iso.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
25
|
+
if (!m)
|
|
26
|
+
return null;
|
|
27
|
+
return {
|
|
28
|
+
year: parseInt(m[1]),
|
|
29
|
+
month: parseInt(m[2]) - 1,
|
|
30
|
+
day: parseInt(m[3]),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const MONTH_NAMES = [
|
|
34
|
+
"January",
|
|
35
|
+
"February",
|
|
36
|
+
"March",
|
|
37
|
+
"April",
|
|
38
|
+
"May",
|
|
39
|
+
"June",
|
|
40
|
+
"July",
|
|
41
|
+
"August",
|
|
42
|
+
"September",
|
|
43
|
+
"October",
|
|
44
|
+
"November",
|
|
45
|
+
"December",
|
|
46
|
+
];
|
|
47
|
+
const DAY_NAMES = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
48
|
+
export function CalendarGrid({ onRangeSelect, startDate, endDate, }) {
|
|
49
|
+
const theme = useTheme();
|
|
50
|
+
const today = new Date();
|
|
51
|
+
const [viewYear, setViewYear] = useState(() => {
|
|
52
|
+
if (startDate) {
|
|
53
|
+
const p = parseISO(startDate);
|
|
54
|
+
if (p)
|
|
55
|
+
return p.year;
|
|
56
|
+
}
|
|
57
|
+
return today.getFullYear();
|
|
58
|
+
});
|
|
59
|
+
const [viewMonth, setViewMonth] = useState(() => {
|
|
60
|
+
if (startDate) {
|
|
61
|
+
const p = parseISO(startDate);
|
|
62
|
+
if (p)
|
|
63
|
+
return p.month;
|
|
64
|
+
}
|
|
65
|
+
return today.getMonth();
|
|
66
|
+
});
|
|
67
|
+
// Selection state: first click sets pending start, second click completes range
|
|
68
|
+
const [pendingStart, setPendingStart] = useState(startDate ?? null);
|
|
69
|
+
const [pendingEnd, setPendingEnd] = useState(endDate ?? null);
|
|
70
|
+
const [awaitingEnd, setAwaitingEnd] = useState(false);
|
|
71
|
+
function prevMonth() {
|
|
72
|
+
if (viewMonth === 0) {
|
|
73
|
+
setViewYear((y) => y - 1);
|
|
74
|
+
setViewMonth(11);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
setViewMonth((m) => m - 1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function nextMonth() {
|
|
81
|
+
if (viewMonth === 11) {
|
|
82
|
+
setViewYear((y) => y + 1);
|
|
83
|
+
setViewMonth(0);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
setViewMonth((m) => m + 1);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function handleDayClick(iso) {
|
|
90
|
+
if (!awaitingEnd) {
|
|
91
|
+
// First click: set start, clear end, wait for second click
|
|
92
|
+
setPendingStart(iso);
|
|
93
|
+
setPendingEnd(null);
|
|
94
|
+
setAwaitingEnd(true);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
// Second click: set end and fire callback
|
|
98
|
+
const start = pendingStart;
|
|
99
|
+
const end = iso;
|
|
100
|
+
if (end < start) {
|
|
101
|
+
// Clicked before start: swap
|
|
102
|
+
setPendingStart(end);
|
|
103
|
+
setPendingEnd(start);
|
|
104
|
+
setAwaitingEnd(false);
|
|
105
|
+
onRangeSelect(end, start);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
setPendingEnd(end);
|
|
109
|
+
setAwaitingEnd(false);
|
|
110
|
+
onRangeSelect(start, end);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Build the grid for the current month view
|
|
115
|
+
const firstDayOfMonth = new Date(viewYear, viewMonth, 1).getDay(); // 0=Sun
|
|
116
|
+
const daysInMonth = new Date(viewYear, viewMonth + 1, 0).getDate();
|
|
117
|
+
// Cells: leading empty + days
|
|
118
|
+
const cells = [];
|
|
119
|
+
for (let i = 0; i < firstDayOfMonth; i++)
|
|
120
|
+
cells.push(null);
|
|
121
|
+
for (let d = 1; d <= daysInMonth; d++) {
|
|
122
|
+
cells.push({ day: d, iso: toISO(viewYear, viewMonth, d) });
|
|
123
|
+
}
|
|
124
|
+
const todayISO = toISO(today.getFullYear(), today.getMonth(), today.getDate());
|
|
125
|
+
function classifyDay(iso) {
|
|
126
|
+
const s = pendingStart;
|
|
127
|
+
const e = pendingEnd;
|
|
128
|
+
if (s && iso === s)
|
|
129
|
+
return "start";
|
|
130
|
+
if (e && iso === e)
|
|
131
|
+
return "end";
|
|
132
|
+
if (s && e && iso > s && iso < e)
|
|
133
|
+
return "in-range";
|
|
134
|
+
if (iso === todayISO)
|
|
135
|
+
return "today";
|
|
136
|
+
return "default";
|
|
137
|
+
}
|
|
138
|
+
return (_jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between mb-3", children: [_jsx("button", { type: "button", onClick: prevMonth, className: `p-1 rounded hover:opacity-70 transition ${theme.typography.muted}`, "aria-label": "Previous month", children: _jsx(ChevronLeft, { className: "w-4 h-4" }) }), _jsxs("span", { className: `text-sm font-semibold ${theme.filters.text}`, children: [MONTH_NAMES[viewMonth], " ", viewYear] }), _jsx("button", { type: "button", onClick: nextMonth, className: `p-1 rounded hover:opacity-70 transition ${theme.typography.muted}`, "aria-label": "Next month", children: _jsx(ChevronRight, { className: "w-4 h-4" }) })] }), _jsx("div", { className: "grid grid-cols-7 mb-1", children: DAY_NAMES.map((d) => (_jsx("div", { className: `text-center text-xs font-medium ${theme.typography.muted} py-1`, children: d }, d))) }), _jsx("div", { className: "grid grid-cols-7 gap-y-0.5", children: cells.map((cell, idx) => {
|
|
139
|
+
if (!cell) {
|
|
140
|
+
return _jsx("div", {}, `empty-${idx}`);
|
|
141
|
+
}
|
|
142
|
+
const kind = classifyDay(cell.iso);
|
|
143
|
+
let cellClass = `text-center text-sm py-1 rounded-lg cursor-pointer transition select-none `;
|
|
144
|
+
if (kind === "start" || kind === "end") {
|
|
145
|
+
cellClass += `${theme.typography.link} bg-current/20 font-semibold`;
|
|
146
|
+
}
|
|
147
|
+
else if (kind === "in-range") {
|
|
148
|
+
cellClass += `${theme.filters.text} bg-current/10`;
|
|
149
|
+
}
|
|
150
|
+
else if (kind === "today") {
|
|
151
|
+
cellClass += `${theme.typography.link} font-semibold`;
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
cellClass += `${theme.filters.text} hover:opacity-70`;
|
|
155
|
+
}
|
|
156
|
+
return (_jsx("button", { type: "button", onClick: () => handleDayClick(cell.iso), className: cellClass, "aria-label": cell.iso, children: cell.day }, cell.iso));
|
|
157
|
+
}) })] }));
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=CalendarGrid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CalendarGrid.js","sourceRoot":"","sources":["../../../src/components/filters/CalendarGrid.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface DateRangeFilterProps {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
defaultValue?: string;
|
|
5
|
+
presets?: string[];
|
|
6
|
+
allowCustom?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function DateRangeFilter({ id, label, defaultValue, presets, allowCustom, }: DateRangeFilterProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=DateRangeFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateRangeFilter.d.ts","sourceRoot":"","sources":["../../../src/components/filters/DateRangeFilter.tsx"],"names":[],"mappings":"AAsBA,UAAU,oBAAoB;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAgCD,wBAAgB,eAAe,CAAC,EAC9B,EAAE,EACF,KAAK,EACL,YAAY,EACZ,OAAO,EACP,WAAkB,GACnB,EAAE,oBAAoB,2CAkHtB"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 2026 Mataki Labs LLC
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Business Source License 1.1 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// https://github.com/panoboard/panoboard/blob/main/LICENSE
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
import { useState } from "react";
|
|
16
|
+
import { useSearchParams } from "react-router";
|
|
17
|
+
import { Calendar, ChevronDown } from "lucide-react";
|
|
18
|
+
import { useFilterUpdate } from "./useFilterUpdate";
|
|
19
|
+
import { useDropdown } from "./useDropdown";
|
|
20
|
+
import { useTheme } from "../../theme/context";
|
|
21
|
+
import { CalendarGrid } from "./CalendarGrid";
|
|
22
|
+
const ALL_PRESETS = [
|
|
23
|
+
{ value: "today", label: "Today" },
|
|
24
|
+
{ value: "yesterday", label: "Yesterday" },
|
|
25
|
+
{ value: "last_7d", label: "Last 7 days" },
|
|
26
|
+
{ value: "last_14d", label: "Last 14 days" },
|
|
27
|
+
{ value: "last_30d", label: "Last 30 days" },
|
|
28
|
+
{ value: "last_60d", label: "Last 60 days" },
|
|
29
|
+
{ value: "last_90d", label: "Last 90 days" },
|
|
30
|
+
{ value: "last_180d", label: "Last 180 days" },
|
|
31
|
+
{ value: "last_365d", label: "Last 365 days" },
|
|
32
|
+
{ value: "this_week", label: "This week" },
|
|
33
|
+
{ value: "this_month", label: "This month" },
|
|
34
|
+
{ value: "this_quarter", label: "This quarter" },
|
|
35
|
+
{ value: "this_year", label: "Year to date" },
|
|
36
|
+
{ value: "last_week", label: "Last week" },
|
|
37
|
+
{ value: "last_month", label: "Last month" },
|
|
38
|
+
{ value: "last_quarter", label: "Last quarter" },
|
|
39
|
+
{ value: "last_year", label: "Last year" },
|
|
40
|
+
];
|
|
41
|
+
function presetLabel(value) {
|
|
42
|
+
const found = ALL_PRESETS.find((p) => p.value === value);
|
|
43
|
+
if (found)
|
|
44
|
+
return found.label;
|
|
45
|
+
if (value.includes(",")) {
|
|
46
|
+
const [start, end] = value.split(",");
|
|
47
|
+
return `${start} — ${end}`;
|
|
48
|
+
}
|
|
49
|
+
return value.replace(/_/g, " ");
|
|
50
|
+
}
|
|
51
|
+
export function DateRangeFilter({ id, label, defaultValue, presets, allowCustom = true, }) {
|
|
52
|
+
const { open, toggle, close, ref } = useDropdown();
|
|
53
|
+
const updateFilter = useFilterUpdate();
|
|
54
|
+
const [searchParams] = useSearchParams();
|
|
55
|
+
const theme = useTheme();
|
|
56
|
+
const currentValue = searchParams.get(id) ?? defaultValue ?? "last_30d";
|
|
57
|
+
const [customStart, setCustomStart] = useState("");
|
|
58
|
+
const [customEnd, setCustomEnd] = useState("");
|
|
59
|
+
// If presets allowlist is provided, filter to only those; otherwise show all
|
|
60
|
+
const visiblePresets = presets
|
|
61
|
+
? ALL_PRESETS.filter((p) => presets.includes(p.value))
|
|
62
|
+
: ALL_PRESETS;
|
|
63
|
+
function selectPreset(preset) {
|
|
64
|
+
updateFilter(id, preset === defaultValue ? null : preset);
|
|
65
|
+
close();
|
|
66
|
+
}
|
|
67
|
+
function applyCustomRange() {
|
|
68
|
+
if (customStart && customEnd) {
|
|
69
|
+
updateFilter(id, `${customStart},${customEnd}`);
|
|
70
|
+
close();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return (_jsxs("div", { ref: ref, className: "relative", children: [_jsxs("button", { type: "button", onClick: toggle, className: `${theme.filters.background} border ${theme.filters.border} rounded-lg px-3 py-2 flex items-center gap-2 text-sm hover:opacity-90 transition cursor-default`, children: [_jsx(Calendar, { className: `w-4 h-4 ${theme.typography.link}` }), _jsx("span", { className: theme.typography.label, children: label }), _jsx("span", { className: theme.filters.text, children: presetLabel(currentValue) }), _jsx(ChevronDown, { className: `w-3.5 h-3.5 ${theme.typography.muted}` })] }), open && (_jsxs("div", { className: `absolute top-full left-0 mt-2 w-80 ${theme.surfaces.panel} border ${theme.filters.border} rounded-xl shadow-xl z-50 p-4`, children: [_jsx("div", { className: "grid grid-cols-2 gap-2", children: visiblePresets.map((preset) => (_jsx("button", { type: "button", onClick: () => selectPreset(preset.value), className: `px-3 py-2 rounded-lg text-sm text-left transition ${currentValue === preset.value
|
|
74
|
+
? `${theme.typography.link} bg-current/10`
|
|
75
|
+
: `${theme.filters.text} hover:opacity-80`}`, children: preset.label }, preset.value))) }), allowCustom && (_jsxs(_Fragment, { children: [_jsx("div", { className: `border-t ${theme.filters.border} my-3` }), _jsxs("div", { children: [_jsx("div", { className: `text-xs font-semibold ${theme.typography.muted} tracking-wider mb-2`, children: "CUSTOM RANGE" }), _jsx(CalendarGrid, { startDate: customStart || undefined, endDate: customEnd || undefined, onRangeSelect: (start, end) => {
|
|
76
|
+
setCustomStart(start);
|
|
77
|
+
setCustomEnd(end);
|
|
78
|
+
} }), customStart && customEnd && (_jsxs("div", { className: `text-xs ${theme.typography.muted} mt-2 text-center`, children: [customStart, " \u2014 ", customEnd] }))] }), _jsxs("div", { className: "flex justify-end gap-2 mt-3", children: [_jsx("button", { type: "button", onClick: close, className: `${theme.typography.muted} text-sm px-3 py-1.5 hover:opacity-80 transition`, children: "Cancel" }), _jsx("button", { type: "button", onClick: applyCustomRange, className: "bg-indigo-500 hover:bg-indigo-600 text-white text-sm rounded-lg px-4 py-1.5 transition", children: "Apply" })] })] }))] }))] }));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=DateRangeFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateRangeFilter.js","sourceRoot":"","sources":["../../../src/components/filters/DateRangeFilter.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Filter } from "../../schemas/dashboard";
|
|
2
|
+
interface FilterChipsProps {
|
|
3
|
+
filters: Filter[];
|
|
4
|
+
filterState: Record<string, unknown>;
|
|
5
|
+
}
|
|
6
|
+
export declare function FilterChips({ filters, filterState }: FilterChipsProps): import("react/jsx-runtime").JSX.Element | null;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=FilterChips.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterChips.d.ts","sourceRoot":"","sources":["../../../src/components/filters/FilterChips.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,UAAU,gBAAgB;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AA0BD,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,gBAAgB,kDAsFrE"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 2026 Mataki Labs LLC
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Business Source License 1.1 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// https://github.com/panoboard/panoboard/blob/main/LICENSE
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
import { useSearchParams } from "react-router";
|
|
16
|
+
import { X } from "lucide-react";
|
|
17
|
+
import { useTheme } from "../../theme/context";
|
|
18
|
+
/** Returns a display label for a filter value. */
|
|
19
|
+
function formatChipValue(filter, rawValue) {
|
|
20
|
+
// For select filters, try to resolve the option label
|
|
21
|
+
if (filter.type === "select" && filter.options) {
|
|
22
|
+
const option = filter.options.find((o) => o.value === rawValue);
|
|
23
|
+
if (option)
|
|
24
|
+
return option.label;
|
|
25
|
+
}
|
|
26
|
+
return rawValue;
|
|
27
|
+
}
|
|
28
|
+
/** Returns the param keys owned by a filter (daterange expands to multiple). */
|
|
29
|
+
function filterParamKeys(filter) {
|
|
30
|
+
if (filter.type === "daterange") {
|
|
31
|
+
const outputs = filter.outputs ?? {};
|
|
32
|
+
const keys = [filter.id];
|
|
33
|
+
if (outputs.start)
|
|
34
|
+
keys.push(outputs.start);
|
|
35
|
+
if (outputs.end)
|
|
36
|
+
keys.push(outputs.end);
|
|
37
|
+
if (outputs.prior_start)
|
|
38
|
+
keys.push(outputs.prior_start);
|
|
39
|
+
if (outputs.prior_end)
|
|
40
|
+
keys.push(outputs.prior_end);
|
|
41
|
+
return keys;
|
|
42
|
+
}
|
|
43
|
+
return [filter.id];
|
|
44
|
+
}
|
|
45
|
+
export function FilterChips({ filters, filterState }) {
|
|
46
|
+
const theme = useTheme();
|
|
47
|
+
const [, setSearchParams] = useSearchParams();
|
|
48
|
+
// Build chip list from visible, active filters
|
|
49
|
+
const chips = [];
|
|
50
|
+
for (const filter of filters) {
|
|
51
|
+
if ("hidden" in filter && filter.hidden)
|
|
52
|
+
continue;
|
|
53
|
+
const rawValue = filterState[filter.id];
|
|
54
|
+
if (rawValue === undefined || rawValue === null || rawValue === "")
|
|
55
|
+
continue;
|
|
56
|
+
const label = filter.label ?? filter.id;
|
|
57
|
+
const strValue = String(rawValue);
|
|
58
|
+
chips.push({
|
|
59
|
+
filterId: filter.id,
|
|
60
|
+
label,
|
|
61
|
+
value: strValue,
|
|
62
|
+
displayValue: formatChipValue(filter, strValue),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (chips.length === 0)
|
|
66
|
+
return null;
|
|
67
|
+
function removeChip(filterId) {
|
|
68
|
+
const filter = filters.find((f) => f.id === filterId);
|
|
69
|
+
if (!filter)
|
|
70
|
+
return;
|
|
71
|
+
setSearchParams((prev) => {
|
|
72
|
+
const next = new URLSearchParams(prev);
|
|
73
|
+
for (const key of filterParamKeys(filter)) {
|
|
74
|
+
next.delete(key);
|
|
75
|
+
}
|
|
76
|
+
return next;
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function clearAll() {
|
|
80
|
+
setSearchParams((prev) => {
|
|
81
|
+
const next = new URLSearchParams(prev);
|
|
82
|
+
for (const filter of filters) {
|
|
83
|
+
if ("hidden" in filter && filter.hidden)
|
|
84
|
+
continue;
|
|
85
|
+
for (const key of filterParamKeys(filter)) {
|
|
86
|
+
next.delete(key);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return next;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return (_jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-4", children: [chips.map((chip) => (_jsxs("span", { className: `inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium ${theme.filters.background} ${theme.filters.text} border ${theme.filters.border}`, children: [_jsxs("span", { className: theme.typography.muted, children: [chip.label, ":"] }), _jsx("span", { children: chip.displayValue }), _jsx("button", { type: "button", "aria-label": `Remove ${chip.label} filter`, onClick: () => removeChip(chip.filterId), className: `${theme.typography.muted} hover:opacity-80 transition-opacity ml-0.5`, children: _jsx(X, { className: "w-3 h-3" }) })] }, chip.filterId))), _jsx("button", { type: "button", onClick: clearAll, className: `text-xs font-medium ${theme.typography.muted} hover:opacity-80 transition-opacity underline underline-offset-2`, children: "Clear All" })] }));
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=FilterChips.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterChips.js","sourceRoot":"","sources":["../../../src/components/filters/FilterChips.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface MultiSelectFilterProps {
|
|
2
|
+
slug: string;
|
|
3
|
+
filter: {
|
|
4
|
+
id: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
options?: {
|
|
7
|
+
value: string;
|
|
8
|
+
label: string;
|
|
9
|
+
}[];
|
|
10
|
+
options_query?: unknown;
|
|
11
|
+
depends_on?: string;
|
|
12
|
+
};
|
|
13
|
+
value: string[];
|
|
14
|
+
}
|
|
15
|
+
export declare function MultiSelectFilter({ slug, filter, value, }: MultiSelectFilterProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=MultiSelectFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiSelectFilter.d.ts","sourceRoot":"","sources":["../../../src/components/filters/MultiSelectFilter.tsx"],"names":[],"mappings":"AAoBA,UAAU,sBAAsB;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,MAAM,EACN,KAAK,GACN,EAAE,sBAAsB,2CAsJxB"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 2026 Mataki Labs LLC
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Business Source License 1.1 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// https://github.com/panoboard/panoboard/blob/main/LICENSE
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
import { useState, useEffect } from "react";
|
|
16
|
+
import { useSearchParams, useNavigate, useParams } from "react-router";
|
|
17
|
+
import { ChevronDown, Search } from "lucide-react";
|
|
18
|
+
import { useDropdown } from "./useDropdown";
|
|
19
|
+
import { useTheme } from "../../theme/context";
|
|
20
|
+
export function MultiSelectFilter({ slug, filter, value, }) {
|
|
21
|
+
const { open, toggle, close, ref } = useDropdown();
|
|
22
|
+
const navigate = useNavigate();
|
|
23
|
+
const [searchParams] = useSearchParams();
|
|
24
|
+
const params = useParams();
|
|
25
|
+
const theme = useTheme();
|
|
26
|
+
const effectiveSlug = slug || params.slug || "";
|
|
27
|
+
const [selected, setSelected] = useState(value);
|
|
28
|
+
const [options, setOptions] = useState(filter.options ?? []);
|
|
29
|
+
const [search, setSearch] = useState("");
|
|
30
|
+
// Fetch dynamic options (re-fetch when parent filter value changes for cascading)
|
|
31
|
+
const dependsOnValue = filter.depends_on
|
|
32
|
+
? searchParams.get(filter.depends_on)
|
|
33
|
+
: undefined;
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (!filter.options_query || !effectiveSlug)
|
|
36
|
+
return;
|
|
37
|
+
const url = new URL(`/api/filters/${effectiveSlug}/${filter.id}`, window.location.origin);
|
|
38
|
+
if (filter.depends_on && dependsOnValue) {
|
|
39
|
+
url.searchParams.set(filter.depends_on, dependsOnValue);
|
|
40
|
+
}
|
|
41
|
+
let cancelled = false;
|
|
42
|
+
fetch(url.toString())
|
|
43
|
+
.then((r) => r.json())
|
|
44
|
+
.then((d) => {
|
|
45
|
+
if (!cancelled)
|
|
46
|
+
setOptions(d.options ?? []);
|
|
47
|
+
})
|
|
48
|
+
.catch(() => {
|
|
49
|
+
if (!cancelled)
|
|
50
|
+
setOptions([]);
|
|
51
|
+
});
|
|
52
|
+
return () => {
|
|
53
|
+
cancelled = true;
|
|
54
|
+
};
|
|
55
|
+
}, [
|
|
56
|
+
effectiveSlug,
|
|
57
|
+
filter.id,
|
|
58
|
+
filter.options_query,
|
|
59
|
+
filter.depends_on,
|
|
60
|
+
dependsOnValue,
|
|
61
|
+
]);
|
|
62
|
+
const filtered = options.filter((o) => o.label?.toLowerCase().includes(search.toLowerCase()) ||
|
|
63
|
+
o.value?.toLowerCase().includes(search.toLowerCase()));
|
|
64
|
+
const toggleOption = (val) => {
|
|
65
|
+
setSelected((prev) => prev.includes(val) ? prev.filter((v) => v !== val) : [...prev, val]);
|
|
66
|
+
};
|
|
67
|
+
const apply = () => {
|
|
68
|
+
const nextParams = new URLSearchParams(searchParams);
|
|
69
|
+
if (selected.length === 0) {
|
|
70
|
+
nextParams.delete(filter.id);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
nextParams.set(filter.id, selected.join(","));
|
|
74
|
+
}
|
|
75
|
+
navigate(`?${nextParams.toString()}`, { replace: true });
|
|
76
|
+
close();
|
|
77
|
+
};
|
|
78
|
+
return (_jsxs("div", { ref: ref, className: "relative", children: [_jsxs("button", { type: "button", onClick: toggle, className: `flex items-center gap-2 ${theme.filters.background} border ${theme.filters.border} rounded-lg px-3 py-2 text-sm ${theme.filters.text} hover:opacity-90 transition cursor-default`, children: [_jsx("span", { className: "text-amber-400", children: "\u2630" }), _jsxs("span", { children: [filter.label ?? filter.id, ":", " ", selected.length > 0 ? `${selected.length} selected` : "None"] }), _jsx(ChevronDown, { className: `w-4 h-4 ${theme.typography.muted}` })] }), open && (_jsxs("div", { className: `absolute top-full mt-1 left-0 w-72 ${theme.surfaces.panel} border ${theme.filters.border} rounded-xl shadow-xl z-50 p-3`, children: [_jsxs("div", { className: "relative mb-2", children: [_jsx(Search, { className: `absolute left-2 top-2 w-4 h-4 ${theme.typography.muted}` }), _jsx("input", { type: "text", placeholder: "Search...", value: search, onChange: (e) => setSearch(e.target.value), className: `w-full ${theme.filters.background} rounded-lg pl-8 pr-3 py-1.5 text-sm ${theme.filters.text} border ${theme.filters.border}` })] }), _jsxs("div", { className: "max-h-48 overflow-y-auto space-y-1", children: [filtered.map((opt) => (_jsxs("label", { className: `flex items-center gap-2 py-1 px-1 rounded hover:opacity-80 cursor-pointer text-sm ${theme.filters.text}`, children: [_jsx("input", { type: "checkbox", checked: selected.includes(opt.value), onChange: () => toggleOption(opt.value), className: `rounded ${theme.filters.border} ${theme.filters.background} text-indigo-500` }), opt.label || opt.value] }, opt.value))), filtered.length === 0 && (_jsx("div", { className: `px-1 py-2 text-sm ${theme.typography.muted}`, children: "No results" }))] }), _jsxs("div", { className: `flex justify-between items-center mt-3 pt-2 border-t ${theme.surfaces.panelBorder}`, children: [_jsx("button", { type: "button", onClick: () => setSelected([]), className: `${theme.typography.muted} text-xs uppercase tracking-wide`, children: "Clear All" }), _jsx("button", { type: "button", onClick: apply, className: "bg-indigo-500 text-white rounded-lg px-4 py-1.5 text-sm", children: "Update" })] })] }))] }));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=MultiSelectFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiSelectFilter.js","sourceRoot":"","sources":["../../../src/components/filters/MultiSelectFilter.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface NumberFilterProps {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
min?: number;
|
|
5
|
+
max?: number;
|
|
6
|
+
defaultValue?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare function NumberFilter({ id, label, min, max, defaultValue, }: NumberFilterProps): import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=NumberFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NumberFilter.d.ts","sourceRoot":"","sources":["../../../src/components/filters/NumberFilter.tsx"],"names":[],"mappings":"AAoBA,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,EAC3B,EAAE,EACF,KAAK,EACL,GAAG,EACH,GAAG,EACH,YAAY,GACb,EAAE,iBAAiB,2CAkDnB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 2026 Mataki Labs LLC
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Business Source License 1.1 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// https://github.com/panoboard/panoboard/blob/main/LICENSE
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
import { useState, useEffect } from "react";
|
|
16
|
+
import { useSearchParams } from "react-router";
|
|
17
|
+
import { Hash } from "lucide-react";
|
|
18
|
+
import { useFilterUpdate } from "./useFilterUpdate";
|
|
19
|
+
import { useTheme } from "../../theme/context";
|
|
20
|
+
export function NumberFilter({ id, label, min, max, defaultValue, }) {
|
|
21
|
+
const updateFilter = useFilterUpdate();
|
|
22
|
+
const [searchParams] = useSearchParams();
|
|
23
|
+
const theme = useTheme();
|
|
24
|
+
const currentValue = searchParams.get(id) ?? (defaultValue != null ? String(defaultValue) : "");
|
|
25
|
+
const [value, setValue] = useState(currentValue);
|
|
26
|
+
// Sync from URL changes
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
setValue(searchParams.get(id) ??
|
|
29
|
+
(defaultValue != null ? String(defaultValue) : ""));
|
|
30
|
+
}, [searchParams, id, defaultValue]);
|
|
31
|
+
function commit() {
|
|
32
|
+
const trimmed = value.trim();
|
|
33
|
+
if (trimmed === "") {
|
|
34
|
+
updateFilter(id, null);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
updateFilter(id, trimmed);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function handleKeyDown(e) {
|
|
41
|
+
if (e.key === "Enter") {
|
|
42
|
+
commit();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return (_jsxs("div", { className: "relative", children: [_jsx(Hash, { className: `absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 ${theme.typography.muted}` }), _jsx("input", { type: "number", value: value, onChange: (e) => setValue(e.target.value), onBlur: commit, onKeyDown: handleKeyDown, min: min, max: max, placeholder: label, className: `${theme.filters.background} border ${theme.filters.border} rounded-lg pl-9 pr-3 py-2 text-sm ${theme.filters.text} ${theme.filters.placeholder} w-36`, "aria-label": label })] }));
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=NumberFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NumberFilter.js","sourceRoot":"","sources":["../../../src/components/filters/NumberFilter.tsx"],"names":[],"mappings":";AAAA,iCAAiC;AACjC,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,+DAA+D;AAC/D,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAU/C,MAAM,UAAU,YAAY,CAAC,EAC3B,EAAE,EACF,KAAK,EACL,GAAG,EACH,GAAG,EACH,YAAY,GACM;IAClB,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,MAAM,CAAC,YAAY,CAAC,GAAG,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,YAAY,GAChB,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7E,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEjD,wBAAwB;IACxB,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CACN,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,CAAC,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CACrD,CAAC;IACJ,CAAC,EAAE,CAAC,YAAY,EAAE,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;IAErC,SAAS,MAAM;QACb,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;YACnB,YAAY,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,SAAS,aAAa,CAAC,CAAsB;QAC3C,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YACtB,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,UAAU,aACvB,KAAC,IAAI,IACH,SAAS,EAAE,oDAAoD,KAAK,CAAC,UAAU,CAAC,KAAK,EAAE,GACvF,EACF,gBACE,IAAI,EAAC,QAAQ,EACb,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACzC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,aAAa,EACxB,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,WAAW,EAAE,KAAK,EAClB,SAAS,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,WAAW,KAAK,CAAC,OAAO,CAAC,MAAM,sCAAsC,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,OAAO,gBACrJ,KAAK,GACjB,IACE,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
interface SelectOption {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
}
|
|
5
|
+
interface SelectFilterProps {
|
|
6
|
+
id: string;
|
|
7
|
+
label: string;
|
|
8
|
+
defaultValue?: string;
|
|
9
|
+
includeAll?: boolean;
|
|
10
|
+
options?: SelectOption[];
|
|
11
|
+
optionsQuery?: boolean;
|
|
12
|
+
iconColor?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function SelectFilter({ id, label, defaultValue, includeAll, options: staticOptions, optionsQuery, iconColor, }: SelectFilterProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=SelectFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectFilter.d.ts","sourceRoot":"","sources":["../../../src/components/filters/SelectFilter.tsx"],"names":[],"mappings":"AAqBA,UAAU,YAAY;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,iBAAiB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,EAC3B,EAAE,EACF,KAAK,EACL,YAAY,EACZ,UAAU,EACV,OAAO,EAAE,aAAa,EACtB,YAAY,EACZ,SAA8B,GAC/B,EAAE,iBAAiB,2CAoHnB"}
|