@perses-dev/components 0.53.1 → 0.54.0-beta.1
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/ContentWithLegend/ContentWithLegend.js +1 -1
- package/dist/ContentWithLegend/ContentWithLegend.js.map +1 -1
- package/dist/ContentWithLegend/model/content-with-legend-model.d.ts +1 -1
- package/dist/ContentWithLegend/model/content-with-legend-model.d.ts.map +1 -1
- package/dist/ContentWithLegend/model/content-with-legend-model.js +1 -1
- package/dist/ContentWithLegend/model/content-with-legend-model.js.map +1 -1
- package/dist/FormEditor/FormActions.d.ts +1 -1
- package/dist/FormEditor/FormActions.d.ts.map +1 -1
- package/dist/FormEditor/FormActions.js.map +1 -1
- package/dist/FormatControls/FormatControls.d.ts +1 -1
- package/dist/FormatControls/FormatControls.d.ts.map +1 -1
- package/dist/FormatControls/FormatControls.js +1 -1
- package/dist/FormatControls/FormatControls.js.map +1 -1
- package/dist/FormatControls/UnitSelector.d.ts +1 -1
- package/dist/FormatControls/UnitSelector.d.ts.map +1 -1
- package/dist/FormatControls/UnitSelector.js +1 -1
- package/dist/FormatControls/UnitSelector.js.map +1 -1
- package/dist/Legend/Legend.js +1 -1
- package/dist/Legend/Legend.js.map +1 -1
- package/dist/Legend/legend-model.d.ts +1 -1
- package/dist/Legend/legend-model.d.ts.map +1 -1
- package/dist/Legend/legend-model.js.map +1 -1
- package/dist/LinksEditor/LinksEditor.d.ts +1 -1
- package/dist/LinksEditor/LinksEditor.js.map +1 -1
- package/dist/RefreshIntervalPicker/RefreshIntervalPicker.d.ts +1 -1
- package/dist/RefreshIntervalPicker/RefreshIntervalPicker.js.map +1 -1
- package/dist/Table/Table.d.ts +1 -1
- package/dist/Table/Table.d.ts.map +1 -1
- package/dist/Table/Table.js +26 -6
- package/dist/Table/Table.js.map +1 -1
- package/dist/Table/TableToolbar.d.ts +34 -0
- package/dist/Table/TableToolbar.d.ts.map +1 -0
- package/dist/Table/TableToolbar.js +127 -0
- package/dist/Table/TableToolbar.js.map +1 -0
- package/dist/Table/VirtualizedTable.d.ts +3 -1
- package/dist/Table/VirtualizedTable.d.ts.map +1 -1
- package/dist/Table/VirtualizedTable.js +128 -117
- package/dist/Table/VirtualizedTable.js.map +1 -1
- package/dist/Table/VirtualizedTableContainer.d.ts.map +1 -1
- package/dist/Table/VirtualizedTableContainer.js +5 -1
- package/dist/Table/VirtualizedTableContainer.js.map +1 -1
- package/dist/Table/hooks/useFuzzySearch.d.ts +12 -0
- package/dist/Table/hooks/useFuzzySearch.d.ts.map +1 -0
- package/dist/Table/hooks/useFuzzySearch.js +43 -0
- package/dist/Table/hooks/useFuzzySearch.js.map +1 -0
- package/dist/Table/model/table-model.d.ts +38 -4
- package/dist/Table/model/table-model.d.ts.map +1 -1
- package/dist/Table/model/table-model.js.map +1 -1
- package/dist/ThresholdsEditor/ThresholdInput.d.ts +1 -1
- package/dist/ThresholdsEditor/ThresholdInput.d.ts.map +1 -1
- package/dist/ThresholdsEditor/ThresholdInput.js.map +1 -1
- package/dist/ThresholdsEditor/ThresholdsEditor.d.ts +1 -1
- package/dist/ThresholdsEditor/ThresholdsEditor.d.ts.map +1 -1
- package/dist/ThresholdsEditor/ThresholdsEditor.js.map +1 -1
- package/dist/TimeRangeSelector/DateTimeRangePicker.d.ts +2 -3
- package/dist/TimeRangeSelector/DateTimeRangePicker.d.ts.map +1 -1
- package/dist/TimeRangeSelector/DateTimeRangePicker.js +2 -0
- package/dist/TimeRangeSelector/DateTimeRangePicker.js.map +1 -1
- package/dist/TimeRangeSelector/TimeRangeSelector.d.ts +1 -1
- package/dist/TimeRangeSelector/TimeRangeSelector.js +1 -1
- package/dist/TimeRangeSelector/TimeRangeSelector.js.map +1 -1
- package/dist/TimeRangeSelector/utils.d.ts +1 -1
- package/dist/TimeRangeSelector/utils.js +1 -1
- package/dist/TimeRangeSelector/utils.js.map +1 -1
- package/dist/TimeSeriesTooltip/TimeChartTooltip.d.ts +2 -2
- package/dist/TimeSeriesTooltip/TimeChartTooltip.d.ts.map +1 -1
- package/dist/TimeSeriesTooltip/TimeChartTooltip.js.map +1 -1
- package/dist/TimeSeriesTooltip/nearby-series.d.ts +2 -2
- package/dist/TimeSeriesTooltip/nearby-series.d.ts.map +1 -1
- package/dist/TimeSeriesTooltip/nearby-series.js +1 -2
- package/dist/TimeSeriesTooltip/nearby-series.js.map +1 -1
- package/dist/TransformsEditor/TransformEditor.d.ts +1 -1
- package/dist/TransformsEditor/TransformEditor.d.ts.map +1 -1
- package/dist/TransformsEditor/TransformEditor.js.map +1 -1
- package/dist/TransformsEditor/TransformEditorContainer.d.ts.map +1 -1
- package/dist/TransformsEditor/TransformEditorContainer.js +1 -1
- package/dist/TransformsEditor/TransformEditorContainer.js.map +1 -1
- package/dist/TransformsEditor/TransformsEditor.d.ts +1 -1
- package/dist/TransformsEditor/TransformsEditor.d.ts.map +1 -1
- package/dist/TransformsEditor/TransformsEditor.js.map +1 -1
- package/dist/ValueMappingEditor/ValueMappingEditor.js.map +1 -1
- package/dist/ValueMappingEditor/ValueMappingsEditor.d.ts.map +1 -1
- package/dist/ValueMappingEditor/ValueMappingsEditor.js.map +1 -1
- package/dist/cjs/ContentWithLegend/ContentWithLegend.js +2 -2
- package/dist/cjs/ContentWithLegend/model/content-with-legend-model.js +2 -2
- package/dist/cjs/FormatControls/FormatControls.js +4 -4
- package/dist/cjs/FormatControls/UnitSelector.js +3 -3
- package/dist/cjs/Legend/Legend.js +2 -2
- package/dist/cjs/Table/Table.js +24 -4
- package/dist/cjs/Table/TableToolbar.js +140 -0
- package/dist/cjs/Table/VirtualizedTable.js +126 -115
- package/dist/cjs/Table/VirtualizedTableContainer.js +5 -1
- package/dist/cjs/Table/hooks/useFuzzySearch.js +48 -0
- package/dist/cjs/TimeRangeSelector/DateTimeRangePicker.js +2 -0
- package/dist/cjs/TimeRangeSelector/TimeRangeSelector.js +3 -3
- package/dist/cjs/TimeRangeSelector/utils.js +2 -2
- package/dist/cjs/TimeSeriesTooltip/nearby-series.js +2 -3
- package/dist/cjs/TransformsEditor/TransformEditorContainer.js +2 -2
- package/dist/cjs/model/action.js +43 -0
- package/dist/cjs/model/bits.js +113 -0
- package/dist/cjs/model/bytes.js +115 -0
- package/dist/cjs/model/constants.js +23 -0
- package/dist/cjs/model/currency.js +126 -0
- package/dist/cjs/model/date.js +297 -0
- package/dist/cjs/model/decimal.js +72 -0
- package/dist/cjs/model/formatterCache.js +120 -0
- package/dist/cjs/model/index.js +16 -0
- package/dist/cjs/model/legend.js +101 -0
- package/dist/cjs/model/percent.js +82 -0
- package/dist/cjs/model/temperature.js +72 -0
- package/dist/cjs/model/thresholds.js +16 -0
- package/dist/cjs/model/throughput.js +161 -0
- package/dist/cjs/model/time.js +178 -0
- package/dist/cjs/model/timeOption.js +2 -2
- package/dist/cjs/model/transforms.js +29 -0
- package/dist/cjs/model/types.js +16 -0
- package/dist/cjs/model/units.js +186 -0
- package/dist/cjs/model/utils.js +48 -0
- package/dist/cjs/theme/theme.js +44 -29
- package/dist/cjs/theme/typography.js +8 -7
- package/dist/cjs/utils/axis.js +5 -5
- package/dist/cjs/utils/index.js +1 -0
- package/dist/cjs/utils/request-interpolation.js +49 -0
- package/dist/model/action.d.ts +4 -0
- package/dist/model/action.d.ts.map +1 -0
- package/dist/model/action.js +27 -0
- package/dist/model/action.js.map +1 -0
- package/dist/model/bits.d.ts +12 -0
- package/dist/model/bits.d.ts.map +1 -0
- package/dist/model/bits.js +89 -0
- package/dist/model/bits.js.map +1 -0
- package/dist/model/bytes.d.ts +12 -0
- package/dist/model/bytes.d.ts.map +1 -0
- package/dist/model/bytes.js +91 -0
- package/dist/model/bytes.js.map +1 -0
- package/dist/model/constants.d.ts +2 -0
- package/dist/model/constants.d.ts.map +1 -0
- package/dist/model/constants.js +15 -0
- package/dist/model/constants.js.map +1 -0
- package/dist/model/currency.d.ts +11 -0
- package/dist/model/currency.d.ts.map +1 -0
- package/dist/model/currency.js +107 -0
- package/dist/model/currency.js.map +1 -0
- package/dist/model/date.d.ts +28 -0
- package/dist/model/date.d.ts.map +1 -0
- package/dist/model/date.js +278 -0
- package/dist/model/date.js.map +1 -0
- package/dist/model/decimal.d.ts +12 -0
- package/dist/model/decimal.d.ts.map +1 -0
- package/dist/model/decimal.js +53 -0
- package/dist/model/decimal.js.map +1 -0
- package/dist/model/formatterCache.d.ts +11 -0
- package/dist/model/formatterCache.d.ts.map +1 -0
- package/dist/model/formatterCache.js +104 -0
- package/dist/model/formatterCache.js.map +1 -0
- package/dist/model/graph.d.ts +1 -1
- package/dist/model/graph.js.map +1 -1
- package/dist/model/index.d.ts +16 -0
- package/dist/model/index.d.ts.map +1 -1
- package/dist/model/index.js +16 -0
- package/dist/model/index.js.map +1 -1
- package/dist/model/legend.d.ts +19 -0
- package/dist/model/legend.d.ts.map +1 -0
- package/dist/model/legend.js +61 -0
- package/dist/model/legend.js.map +1 -0
- package/dist/model/percent.d.ts +11 -0
- package/dist/model/percent.d.ts.map +1 -0
- package/dist/model/percent.js +63 -0
- package/dist/model/percent.js.map +1 -0
- package/dist/model/temperature.d.ts +11 -0
- package/dist/model/temperature.d.ts.map +1 -0
- package/dist/model/temperature.js +53 -0
- package/dist/model/temperature.js.map +1 -0
- package/dist/model/theme.d.ts +1 -1
- package/dist/model/theme.d.ts.map +1 -1
- package/dist/model/theme.js.map +1 -1
- package/dist/model/thresholds.d.ts +16 -0
- package/dist/model/thresholds.d.ts.map +1 -0
- package/dist/model/thresholds.js +15 -0
- package/dist/model/thresholds.js.map +1 -0
- package/dist/model/throughput.d.ts +12 -0
- package/dist/model/throughput.d.ts.map +1 -0
- package/dist/model/throughput.js +142 -0
- package/dist/model/throughput.js.map +1 -0
- package/dist/model/time.d.ts +23 -0
- package/dist/model/time.d.ts.map +1 -0
- package/dist/model/time.js +158 -0
- package/dist/model/time.js.map +1 -0
- package/dist/model/timeOption.d.ts +1 -1
- package/dist/model/timeOption.js +1 -1
- package/dist/model/timeOption.js.map +1 -1
- package/dist/model/transforms.d.ts +43 -0
- package/dist/model/transforms.d.ts.map +1 -0
- package/dist/model/transforms.js +22 -0
- package/dist/model/transforms.js.map +1 -0
- package/dist/model/types.d.ts +56 -0
- package/dist/model/types.d.ts.map +1 -0
- package/dist/model/types.js +15 -0
- package/dist/model/types.js.map +1 -0
- package/dist/model/units.d.ts +105 -0
- package/dist/model/units.d.ts.map +1 -0
- package/dist/model/units.js +132 -0
- package/dist/model/units.js.map +1 -0
- package/dist/model/utils.d.ts +4 -0
- package/dist/model/utils.d.ts.map +1 -0
- package/dist/model/utils.js +32 -0
- package/dist/model/utils.js.map +1 -0
- package/dist/theme/theme.d.ts +3 -1
- package/dist/theme/theme.d.ts.map +1 -1
- package/dist/theme/theme.js +46 -29
- package/dist/theme/theme.js.map +1 -1
- package/dist/theme/typography.d.ts +6 -4
- package/dist/theme/typography.d.ts.map +1 -1
- package/dist/theme/typography.js +8 -7
- package/dist/theme/typography.js.map +1 -1
- package/dist/utils/axis.d.ts +1 -1
- package/dist/utils/axis.d.ts.map +1 -1
- package/dist/utils/axis.js +1 -1
- package/dist/utils/axis.js.map +1 -1
- package/dist/utils/chart-actions.d.ts +1 -1
- package/dist/utils/chart-actions.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/request-interpolation.d.ts +6 -0
- package/dist/utils/request-interpolation.d.ts.map +1 -0
- package/dist/utils/request-interpolation.js +33 -0
- package/dist/utils/request-interpolation.js.map +1 -0
- package/dist/utils/variable-interpolation.d.ts +1 -1
- package/dist/utils/variable-interpolation.js.map +1 -1
- package/package.json +6 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/TimeRangeSelector/DateTimeRangePicker.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useState } from 'react';\nimport { Box, Stack, Typography, Button } from '@mui/material';\nimport { DateTimeField, LocalizationProvider, StaticDateTimePicker } from '@mui/x-date-pickers';\nimport { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFnsV3';\nimport { AbsoluteTimeRange } from '@perses-dev/core';\nimport { TZDate } from '@date-fns/tz';\nimport { ErrorBoundary } from '../ErrorBoundary';\nimport { ErrorAlert } from '../ErrorAlert';\nimport { DATE_TIME_FORMAT, validateDateRange } from './utils';\n\ninterface AbsoluteTimeFormProps {\n initialTimeRange: AbsoluteTimeRange;\n onChange: (timeRange: AbsoluteTimeRange) => void;\n onCancel: () => void;\n timeZone: string;\n}\n\n/**\n * Start and End datetime picker, allowing use to select a specific time range selecting two absolute dates and times.\n * TODO: Use directly the MUI X ``DateTimePicker`` for datetime selection which is better. https://next.mui.com/x/react-date-pickers/date-time-picker/\n * Use ``DateTimeRangePicker`` directly would be cool but paid https://next.mui.com/x/react-date-pickers/date-time-range-picker/\n * @param initialTimeRange initial time range to pre-select.\n * @param onChange event received when start and end has been selected (click on apply)\n * @param onCancel event received when user click on cancel\n * @constructor\n */\nexport const DateTimeRangePicker = ({\n initialTimeRange,\n onChange,\n onCancel,\n timeZone,\n}: AbsoluteTimeFormProps): ReactElement => {\n const stdTimeZone = ['local', 'browser'].includes(timeZone.toLowerCase())\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : timeZone;\n const [timeRange, setTimeRange] = useState<AbsoluteTimeRange>(initialTimeRange);\n\n const [showStartCalendar, setShowStartCalendar] = useState<boolean>(true);\n\n const changeTimeRange = (newTime: Date, segment: keyof AbsoluteTimeRange): void => {\n setTimeRange((prevTimeRange) => {\n return {\n ...prevTimeRange,\n [segment]: newTime,\n };\n });\n };\n\n const onChangeStartTime = (newStartTime: Date): void => {\n changeTimeRange(newStartTime, 'start');\n };\n\n const onChangeEndTime = (newEndTime: Date): void => {\n changeTimeRange(newEndTime, 'end');\n };\n\n const updateDateRange = (): { start: Date; end: Date } | undefined => {\n const newDates = {\n start: timeRange.start,\n end: timeRange.end,\n };\n const isValidDateRange = validateDateRange(newDates.start, newDates.end);\n if (isValidDateRange) {\n return newDates;\n }\n };\n\n const onApply = (): void => {\n const newDates = updateDateRange();\n if (newDates) {\n onChange(newDates);\n }\n };\n\n return (\n <LocalizationProvider dateAdapter={AdapterDateFns}>\n <Stack\n spacing={2}\n sx={(theme) => ({\n padding: theme.spacing(1, 0, 2),\n })}\n >\n {showStartCalendar && (\n <Box\n sx={(theme) => ({\n // TODO: create separate reusable calendar component\n '.MuiPickersLayout-contentWrapper': {\n backgroundColor: theme.palette.background.default,\n },\n })}\n >\n <Typography variant=\"h3\" padding={1} paddingLeft={2}>\n Select Start Time\n </Typography>\n <StaticDateTimePicker\n timezone={stdTimeZone}\n displayStaticWrapperAs=\"desktop\"\n openTo=\"day\"\n disableHighlightToday={true}\n value={new TZDate(timeRange.start, stdTimeZone)}\n onChange={(newValue) => {\n if (newValue === null) return;\n onChangeStartTime(newValue);\n }}\n onAccept={() => {\n setShowStartCalendar(false);\n }}\n />\n </Box>\n )}\n {!showStartCalendar && (\n <Box\n sx={(theme) => ({\n '.MuiPickersLayout-contentWrapper': {\n backgroundColor: theme.palette.background.default,\n },\n })}\n >\n <Typography variant=\"h3\" padding={1} paddingLeft={2}>\n Select End Time\n </Typography>\n <StaticDateTimePicker\n timezone={stdTimeZone}\n displayStaticWrapperAs=\"desktop\"\n openTo=\"day\"\n disableHighlightToday={true}\n value={new TZDate(timeRange.end, stdTimeZone)}\n minDateTime={new TZDate(timeRange.start, stdTimeZone)}\n onChange={(newValue) => {\n if (newValue === null) return;\n onChangeEndTime(newValue);\n }}\n onAccept={(newValue) => {\n if (newValue === null) return;\n setShowStartCalendar(true);\n onChangeEndTime(newValue);\n }}\n />\n </Box>\n )}\n <Stack direction=\"row\" alignItems=\"center\" gap={1} pl={1} pr={1}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <DateTimeField\n timezone={stdTimeZone}\n label=\"Start Time\"\n value={new TZDate(timeRange.start, stdTimeZone)}\n onChange={(event: Date | null) => {\n if (event) {\n onChangeStartTime(event);\n }\n }}\n onBlur={() => updateDateRange()}\n format={DATE_TIME_FORMAT}\n />\n </ErrorBoundary>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <DateTimeField\n timezone={stdTimeZone}\n label=\"End Time\"\n value={new TZDate(timeRange.end, stdTimeZone)}\n onChange={(event: Date | null) => {\n if (event) {\n onChangeEndTime(event);\n }\n }}\n onBlur={() => updateDateRange()}\n format={DATE_TIME_FORMAT}\n />\n </ErrorBoundary>\n </Stack>\n <Stack direction=\"row\" sx={{ padding: (theme) => theme.spacing(0, 1) }} gap={1}>\n <Button variant=\"contained\" onClick={() => onApply()} fullWidth>\n Apply\n </Button>\n <Button variant=\"outlined\" onClick={() => onCancel()} fullWidth>\n Cancel\n </Button>\n </Stack>\n </Stack>\n </LocalizationProvider>\n );\n};\n"],"names":["useState","Box","Stack","Typography","Button","DateTimeField","LocalizationProvider","StaticDateTimePicker","AdapterDateFns","TZDate","ErrorBoundary","ErrorAlert","DATE_TIME_FORMAT","validateDateRange","DateTimeRangePicker","initialTimeRange","onChange","onCancel","timeZone","stdTimeZone","includes","toLowerCase","Intl","DateTimeFormat","resolvedOptions","timeRange","setTimeRange","showStartCalendar","setShowStartCalendar","changeTimeRange","newTime","segment","prevTimeRange","onChangeStartTime","newStartTime","onChangeEndTime","newEndTime","updateDateRange","newDates","start","end","isValidDateRange","onApply","dateAdapter","spacing","sx","theme","padding","backgroundColor","palette","background","default","variant","paddingLeft","timezone","displayStaticWrapperAs","openTo","disableHighlightToday","value","newValue","onAccept","minDateTime","direction","alignItems","gap","pl","pr","FallbackComponent","label","event","onBlur","format","onClick","fullWidth"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/TimeRangeSelector/DateTimeRangePicker.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ReactElement, useState } from 'react';\nimport { Box, Stack, Typography, Button } from '@mui/material';\nimport { DateTimeField, LocalizationProvider, StaticDateTimePicker } from '@mui/x-date-pickers';\nimport { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFnsV3';\nimport { AbsoluteTimeRange } from '@perses-dev/spec';\nimport { TZDate } from '@date-fns/tz';\nimport { ErrorBoundary } from '../ErrorBoundary';\nimport { ErrorAlert } from '../ErrorAlert';\nimport { DATE_TIME_FORMAT, validateDateRange } from './utils';\n\nexport interface AbsoluteTimeFormProps {\n initialTimeRange: AbsoluteTimeRange;\n onChange: (timeRange: AbsoluteTimeRange) => void;\n onCancel: () => void;\n timeZone: string;\n}\n\n/**\n * Start and End datetime picker, allowing use to select a specific time range selecting two absolute dates and times.\n * TODO: Use directly the MUI X ``DateTimePicker`` for datetime selection which is better. https://next.mui.com/x/react-date-pickers/date-time-picker/\n * Use ``DateTimeRangePicker`` directly would be cool but paid https://next.mui.com/x/react-date-pickers/date-time-range-picker/\n * @param initialTimeRange initial time range to pre-select.\n * @param onChange event received when start and end has been selected (click on apply)\n * @param onCancel event received when user click on cancel\n * @constructor\n */\nexport const DateTimeRangePicker = ({\n initialTimeRange,\n onChange,\n onCancel,\n timeZone,\n}: AbsoluteTimeFormProps): ReactElement => {\n const stdTimeZone = ['local', 'browser'].includes(timeZone.toLowerCase())\n ? Intl.DateTimeFormat().resolvedOptions().timeZone\n : timeZone;\n const [timeRange, setTimeRange] = useState<AbsoluteTimeRange>(initialTimeRange);\n const [showStartCalendar, setShowStartCalendar] = useState<boolean>(true);\n\n const changeTimeRange = (newTime: Date, segment: keyof AbsoluteTimeRange): void => {\n setTimeRange((prevTimeRange) => {\n return {\n ...prevTimeRange,\n [segment]: newTime,\n };\n });\n };\n\n const onChangeStartTime = (newStartTime: Date): void => {\n changeTimeRange(newStartTime, 'start');\n };\n\n const onChangeEndTime = (newEndTime: Date): void => {\n changeTimeRange(newEndTime, 'end');\n };\n\n const updateDateRange = (): { start: Date; end: Date } | undefined => {\n const newDates = {\n start: timeRange.start,\n end: timeRange.end,\n };\n const isValidDateRange = validateDateRange(newDates.start, newDates.end);\n if (isValidDateRange) {\n return newDates;\n }\n };\n\n const onApply = (): void => {\n const newDates = updateDateRange();\n if (newDates) {\n onChange(newDates);\n }\n };\n\n return (\n <LocalizationProvider dateAdapter={AdapterDateFns}>\n <Stack\n spacing={2}\n sx={(theme) => ({\n padding: theme.spacing(1, 0, 2),\n })}\n >\n {showStartCalendar && (\n <Box\n sx={(theme) => ({\n // TODO: create separate reusable calendar component\n '.MuiPickersLayout-contentWrapper': {\n backgroundColor: theme.palette.background.default,\n },\n })}\n >\n <Typography variant=\"h3\" padding={1} paddingLeft={2}>\n Select Start Time\n </Typography>\n <StaticDateTimePicker\n timezone={stdTimeZone}\n displayStaticWrapperAs=\"desktop\"\n openTo=\"day\"\n disableHighlightToday={true}\n value={new TZDate(timeRange.start, stdTimeZone)}\n onChange={(newValue) => {\n if (newValue === null) return;\n onChangeStartTime(newValue);\n }}\n onAccept={() => {\n setShowStartCalendar(false);\n }}\n />\n </Box>\n )}\n {!showStartCalendar && (\n <Box\n sx={(theme) => ({\n '.MuiPickersLayout-contentWrapper': {\n backgroundColor: theme.palette.background.default,\n },\n })}\n >\n <Typography variant=\"h3\" padding={1} paddingLeft={2}>\n Select End Time\n </Typography>\n <StaticDateTimePicker\n timezone={stdTimeZone}\n displayStaticWrapperAs=\"desktop\"\n openTo=\"day\"\n disableHighlightToday={true}\n value={new TZDate(timeRange.end, stdTimeZone)}\n minDateTime={new TZDate(timeRange.start, stdTimeZone)}\n onChange={(newValue) => {\n if (newValue === null) return;\n onChangeEndTime(newValue);\n }}\n onAccept={(newValue) => {\n if (newValue === null) return;\n setShowStartCalendar(true);\n onChangeEndTime(newValue);\n }}\n />\n </Box>\n )}\n <Stack direction=\"row\" alignItems=\"center\" gap={1} pl={1} pr={1}>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <DateTimeField\n data-testid=\"start_time_input\"\n timezone={stdTimeZone}\n label=\"Start Time\"\n value={new TZDate(timeRange.start, stdTimeZone)}\n onChange={(event: Date | null) => {\n if (event) {\n onChangeStartTime(event);\n }\n }}\n onBlur={() => updateDateRange()}\n format={DATE_TIME_FORMAT}\n />\n </ErrorBoundary>\n <ErrorBoundary FallbackComponent={ErrorAlert}>\n <DateTimeField\n data-testid=\"end_time_input\"\n timezone={stdTimeZone}\n label=\"End Time\"\n value={new TZDate(timeRange.end, stdTimeZone)}\n onChange={(event: Date | null) => {\n if (event) {\n onChangeEndTime(event);\n }\n }}\n onBlur={() => updateDateRange()}\n format={DATE_TIME_FORMAT}\n />\n </ErrorBoundary>\n </Stack>\n <Stack direction=\"row\" sx={{ padding: (theme) => theme.spacing(0, 1) }} gap={1}>\n <Button variant=\"contained\" onClick={() => onApply()} fullWidth>\n Apply\n </Button>\n <Button variant=\"outlined\" onClick={() => onCancel()} fullWidth>\n Cancel\n </Button>\n </Stack>\n </Stack>\n </LocalizationProvider>\n );\n};\n"],"names":["useState","Box","Stack","Typography","Button","DateTimeField","LocalizationProvider","StaticDateTimePicker","AdapterDateFns","TZDate","ErrorBoundary","ErrorAlert","DATE_TIME_FORMAT","validateDateRange","DateTimeRangePicker","initialTimeRange","onChange","onCancel","timeZone","stdTimeZone","includes","toLowerCase","Intl","DateTimeFormat","resolvedOptions","timeRange","setTimeRange","showStartCalendar","setShowStartCalendar","changeTimeRange","newTime","segment","prevTimeRange","onChangeStartTime","newStartTime","onChangeEndTime","newEndTime","updateDateRange","newDates","start","end","isValidDateRange","onApply","dateAdapter","spacing","sx","theme","padding","backgroundColor","palette","background","default","variant","paddingLeft","timezone","displayStaticWrapperAs","openTo","disableHighlightToday","value","newValue","onAccept","minDateTime","direction","alignItems","gap","pl","pr","FallbackComponent","data-testid","label","event","onBlur","format","onClick","fullWidth"],"mappings":"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"}
|
|
@@ -14,7 +14,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
14
14
|
import { Box, MenuItem, Popover, Select, IconButton, TextField } from '@mui/material';
|
|
15
15
|
import Calendar from 'mdi-material-ui/Calendar';
|
|
16
16
|
import EarthIcon from 'mdi-material-ui/Earth';
|
|
17
|
-
import { isRelativeTimeRange, toAbsoluteTimeRange } from '@perses-dev/
|
|
17
|
+
import { isRelativeTimeRange, toAbsoluteTimeRange } from '@perses-dev/spec';
|
|
18
18
|
import { useMemo, useRef, useState } from 'react';
|
|
19
19
|
import { useTimeZone } from '../context';
|
|
20
20
|
import { getTimeZoneOptions } from '../model/timeZoneOption';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/TimeRangeSelector/TimeRangeSelector.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, MenuItem, Popover, Select, IconButton, TextField } from '@mui/material';\nimport Calendar from 'mdi-material-ui/Calendar';\nimport EarthIcon from 'mdi-material-ui/Earth';\nimport { TimeRangeValue, isRelativeTimeRange, AbsoluteTimeRange, toAbsoluteTimeRange } from '@perses-dev/core';\nimport { ReactElement, useMemo, useRef, useState } from 'react';\nimport { useTimeZone } from '../context';\nimport { TimeZoneOption, getTimeZoneOptions } from '../model/timeZoneOption';\nimport { TimeOption } from '../model';\nimport { SettingsAutocomplete, SettingsAutocompleteOption } from '../SettingsAutocomplete';\nimport { DateTimeRangePicker } from './DateTimeRangePicker';\nimport { buildCustomTimeOption, formatTimeRange } from './utils';\n\ninterface TimeRangeSelectorProps {\n /**\n * The current value of the time range.\n */\n value: TimeRangeValue;\n /**\n * The list of time options to display in the dropdown.\n * The component will automatically add the last two options as a zoom out x2 and a custom absolute time range.\n */\n timeOptions: TimeOption[];\n /**\n * The callback to call when the time range changes.\n */\n onChange: (value: TimeRangeValue) => void;\n /**\n * Custom line height for the select component.\n */\n height?: string;\n /**\n * Whether to show the custom time range option.\n * Defaults to true.\n */\n showCustomTimeRange?: boolean;\n /** Optional explicit timezone and change handler to enable changing tz from the selector */\n timeZone?: string;\n timeZoneOptions?: TimeZoneOption[];\n onTimeZoneChange?: (timeZone: TimeZoneOption) => void;\n}\n\n/**\n * Date & time selection component to customize what data renders on dashboard.\n * This includes relative shortcuts and the ability to pick absolute start and end times.\n * @param props\n * @constructor\n */\nexport function TimeRangeSelector({\n value,\n timeOptions,\n onChange,\n height,\n showCustomTimeRange = true,\n timeZone: timeZoneProp,\n timeZoneOptions,\n onTimeZoneChange,\n}: TimeRangeSelectorProps): ReactElement {\n const { timeZone: ctxTimeZone } = useTimeZone();\n const timeZone = timeZoneProp ?? ctxTimeZone;\n\n const anchorEl = useRef();\n const [showCustomDateSelector, setShowCustomDateSelector] = useState(false);\n\n const convertedTimeRange = useMemo(() => {\n return isRelativeTimeRange(value) ? toAbsoluteTimeRange(value) : value;\n }, [value]);\n\n const lastOption = useMemo(\n () => buildCustomTimeOption(isRelativeTimeRange(value) ? undefined : value, timeZone),\n [value, timeZone]\n );\n\n const [open, setOpen] = useState(false);\n const tzOptions = timeZoneOptions ?? getTimeZoneOptions();\n const [tzAnchorEl, setTzAnchorEl] = useState<HTMLElement | null>(null);\n const tzOpen = Boolean(tzAnchorEl);\n const tzLabel = tzOptions.find((o) => o.value === timeZone)?.display ?? timeZone;\n const tzAutocompleteOptions = tzOptions.map((o) => ({ id: o.value, label: o.display }));\n let tzAutocompleteValue: SettingsAutocompleteOption | undefined = undefined;\n {\n const current = tzOptions.find((o) => o.value === timeZone);\n if (current) tzAutocompleteValue = { id: current.value, label: current.display };\n }\n\n return (\n <>\n <Popover\n anchorEl={tzAnchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n open={tzOpen}\n onClose={() => setTzAnchorEl(null)}\n sx={(theme) => ({ padding: theme.spacing(1) })}\n >\n <Box\n sx={{ p: 1, minWidth: 260 }}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n <SettingsAutocomplete\n options={tzAutocompleteOptions}\n value={tzAutocompleteValue}\n onChange={(_e, option) => {\n if (option) {\n const selected = tzOptions.find((o) => o.value === option.id);\n if (selected) onTimeZoneChange?.(selected);\n }\n setTzAnchorEl(null);\n }}\n disableClearable\n renderInput={(params) => <TextField {...params} placeholder=\"Search timezones\" size=\"small\" />}\n />\n </Box>\n </Popover>\n <Popover\n anchorEl={anchorEl.current}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n open={showCustomDateSelector}\n onClose={() => setShowCustomDateSelector(false)}\n sx={(theme) => ({ padding: theme.spacing(2) })}\n >\n <DateTimeRangePicker\n initialTimeRange={convertedTimeRange}\n onChange={(value: AbsoluteTimeRange) => {\n onChange(value);\n setShowCustomDateSelector(false);\n setOpen(false);\n }}\n onCancel={() => setShowCustomDateSelector(false)}\n timeZone={timeZone}\n />\n </Popover>\n <Box ref={anchorEl}>\n <Select\n open={open}\n value={formatTimeRange(value, timeZone)}\n onClick={() => setOpen(!open)}\n IconComponent={Calendar}\n inputProps={{ 'aria-label': `Select time range. Currently set to ${value}` }}\n sx={{\n '.MuiSelect-icon': { marginTop: '1px', transform: 'none' },\n '.MuiSelect-select.MuiSelect-outlined.MuiInputBase-input': { paddingRight: '36px' },\n '.MuiSelect-select': height ? { lineHeight: height, paddingY: 0 } : {},\n }}\n >\n <MenuItem\n disableRipple\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n sx={{ cursor: 'default', '&:hover': { backgroundColor: 'transparent' }, py: 0.5, px: 1 }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', width: '100%', justifyContent: 'space-between' }}>\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>\n <Box sx={{ typography: 'subtitle1' }}>Time Range</Box>\n <Box sx={{ color: 'text.secondary', typography: 'caption', mt: 0.25 }}>Timezone: {tzLabel}</Box>\n </Box>\n <Box sx={{ display: 'flex', alignItems: 'center', pr: 1, ml: 1.5 }}>\n <IconButton\n size=\"small\"\n aria-label=\"Select timezone\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setTzAnchorEl(e.currentTarget);\n }}\n >\n <EarthIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n </Box>\n </MenuItem>\n {timeOptions.map((item, idx) => (\n <MenuItem\n key={idx}\n value={formatTimeRange(item.value, timeZone)}\n onClick={() => {\n onChange(item.value);\n }}\n >\n {item.display}\n </MenuItem>\n ))}\n {showCustomTimeRange && (\n <MenuItem\n value={formatTimeRange(lastOption.value, timeZone)}\n onClick={() => setShowCustomDateSelector(true)}\n >\n {lastOption.display}\n </MenuItem>\n )}\n </Select>\n </Box>\n </>\n );\n}\n"],"names":["Box","MenuItem","Popover","Select","IconButton","TextField","Calendar","EarthIcon","isRelativeTimeRange","toAbsoluteTimeRange","useMemo","useRef","useState","useTimeZone","getTimeZoneOptions","SettingsAutocomplete","DateTimeRangePicker","buildCustomTimeOption","formatTimeRange","TimeRangeSelector","value","timeOptions","onChange","height","showCustomTimeRange","timeZone","timeZoneProp","timeZoneOptions","onTimeZoneChange","ctxTimeZone","anchorEl","showCustomDateSelector","setShowCustomDateSelector","convertedTimeRange","lastOption","undefined","open","setOpen","tzOptions","tzAnchorEl","setTzAnchorEl","tzOpen","Boolean","tzLabel","find","o","display","tzAutocompleteOptions","map","id","label","tzAutocompleteValue","current","anchorOrigin","vertical","horizontal","transformOrigin","onClose","sx","theme","padding","spacing","p","minWidth","onClick","e","stopPropagation","options","_e","option","selected","disableClearable","renderInput","params","placeholder","size","initialTimeRange","onCancel","ref","IconComponent","inputProps","marginTop","transform","paddingRight","lineHeight","paddingY","disableRipple","preventDefault","cursor","backgroundColor","py","px","alignItems","width","justifyContent","flexDirection","typography","color","mt","pr","ml","aria-label","currentTarget","fontSize","item","idx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/TimeRangeSelector/TimeRangeSelector.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Box, MenuItem, Popover, Select, IconButton, TextField } from '@mui/material';\nimport Calendar from 'mdi-material-ui/Calendar';\nimport EarthIcon from 'mdi-material-ui/Earth';\nimport { TimeRangeValue, isRelativeTimeRange, AbsoluteTimeRange, toAbsoluteTimeRange } from '@perses-dev/spec';\nimport { ReactElement, useMemo, useRef, useState } from 'react';\nimport { useTimeZone } from '../context';\nimport { TimeZoneOption, getTimeZoneOptions } from '../model/timeZoneOption';\nimport { TimeOption } from '../model';\nimport { SettingsAutocomplete, SettingsAutocompleteOption } from '../SettingsAutocomplete';\nimport { DateTimeRangePicker } from './DateTimeRangePicker';\nimport { buildCustomTimeOption, formatTimeRange } from './utils';\n\ninterface TimeRangeSelectorProps {\n /**\n * The current value of the time range.\n */\n value: TimeRangeValue;\n /**\n * The list of time options to display in the dropdown.\n * The component will automatically add the last two options as a zoom out x2 and a custom absolute time range.\n */\n timeOptions: TimeOption[];\n /**\n * The callback to call when the time range changes.\n */\n onChange: (value: TimeRangeValue) => void;\n /**\n * Custom line height for the select component.\n */\n height?: string;\n /**\n * Whether to show the custom time range option.\n * Defaults to true.\n */\n showCustomTimeRange?: boolean;\n /** Optional explicit timezone and change handler to enable changing tz from the selector */\n timeZone?: string;\n timeZoneOptions?: TimeZoneOption[];\n onTimeZoneChange?: (timeZone: TimeZoneOption) => void;\n}\n\n/**\n * Date & time selection component to customize what data renders on dashboard.\n * This includes relative shortcuts and the ability to pick absolute start and end times.\n * @param props\n * @constructor\n */\nexport function TimeRangeSelector({\n value,\n timeOptions,\n onChange,\n height,\n showCustomTimeRange = true,\n timeZone: timeZoneProp,\n timeZoneOptions,\n onTimeZoneChange,\n}: TimeRangeSelectorProps): ReactElement {\n const { timeZone: ctxTimeZone } = useTimeZone();\n const timeZone = timeZoneProp ?? ctxTimeZone;\n\n const anchorEl = useRef();\n const [showCustomDateSelector, setShowCustomDateSelector] = useState(false);\n\n const convertedTimeRange = useMemo(() => {\n return isRelativeTimeRange(value) ? toAbsoluteTimeRange(value) : value;\n }, [value]);\n\n const lastOption = useMemo(\n () => buildCustomTimeOption(isRelativeTimeRange(value) ? undefined : value, timeZone),\n [value, timeZone]\n );\n\n const [open, setOpen] = useState(false);\n const tzOptions = timeZoneOptions ?? getTimeZoneOptions();\n const [tzAnchorEl, setTzAnchorEl] = useState<HTMLElement | null>(null);\n const tzOpen = Boolean(tzAnchorEl);\n const tzLabel = tzOptions.find((o) => o.value === timeZone)?.display ?? timeZone;\n const tzAutocompleteOptions = tzOptions.map((o) => ({ id: o.value, label: o.display }));\n let tzAutocompleteValue: SettingsAutocompleteOption | undefined = undefined;\n {\n const current = tzOptions.find((o) => o.value === timeZone);\n if (current) tzAutocompleteValue = { id: current.value, label: current.display };\n }\n\n return (\n <>\n <Popover\n anchorEl={tzAnchorEl}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}\n transformOrigin={{ vertical: 'top', horizontal: 'right' }}\n open={tzOpen}\n onClose={() => setTzAnchorEl(null)}\n sx={(theme) => ({ padding: theme.spacing(1) })}\n >\n <Box\n sx={{ p: 1, minWidth: 260 }}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n <SettingsAutocomplete\n options={tzAutocompleteOptions}\n value={tzAutocompleteValue}\n onChange={(_e, option) => {\n if (option) {\n const selected = tzOptions.find((o) => o.value === option.id);\n if (selected) onTimeZoneChange?.(selected);\n }\n setTzAnchorEl(null);\n }}\n disableClearable\n renderInput={(params) => <TextField {...params} placeholder=\"Search timezones\" size=\"small\" />}\n />\n </Box>\n </Popover>\n <Popover\n anchorEl={anchorEl.current}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}\n open={showCustomDateSelector}\n onClose={() => setShowCustomDateSelector(false)}\n sx={(theme) => ({ padding: theme.spacing(2) })}\n >\n <DateTimeRangePicker\n initialTimeRange={convertedTimeRange}\n onChange={(value: AbsoluteTimeRange) => {\n onChange(value);\n setShowCustomDateSelector(false);\n setOpen(false);\n }}\n onCancel={() => setShowCustomDateSelector(false)}\n timeZone={timeZone}\n />\n </Popover>\n <Box ref={anchorEl}>\n <Select\n open={open}\n value={formatTimeRange(value, timeZone)}\n onClick={() => setOpen(!open)}\n IconComponent={Calendar}\n inputProps={{ 'aria-label': `Select time range. Currently set to ${value}` }}\n sx={{\n '.MuiSelect-icon': { marginTop: '1px', transform: 'none' },\n '.MuiSelect-select.MuiSelect-outlined.MuiInputBase-input': { paddingRight: '36px' },\n '.MuiSelect-select': height ? { lineHeight: height, paddingY: 0 } : {},\n }}\n >\n <MenuItem\n disableRipple\n onClick={(e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n sx={{ cursor: 'default', '&:hover': { backgroundColor: 'transparent' }, py: 0.5, px: 1 }}\n >\n <Box sx={{ display: 'flex', alignItems: 'center', width: '100%', justifyContent: 'space-between' }}>\n <Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>\n <Box sx={{ typography: 'subtitle1' }}>Time Range</Box>\n <Box sx={{ color: 'text.secondary', typography: 'caption', mt: 0.25 }}>Timezone: {tzLabel}</Box>\n </Box>\n <Box sx={{ display: 'flex', alignItems: 'center', pr: 1, ml: 1.5 }}>\n <IconButton\n size=\"small\"\n aria-label=\"Select timezone\"\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n setTzAnchorEl(e.currentTarget);\n }}\n >\n <EarthIcon fontSize=\"small\" />\n </IconButton>\n </Box>\n </Box>\n </MenuItem>\n {timeOptions.map((item, idx) => (\n <MenuItem\n key={idx}\n value={formatTimeRange(item.value, timeZone)}\n onClick={() => {\n onChange(item.value);\n }}\n >\n {item.display}\n </MenuItem>\n ))}\n {showCustomTimeRange && (\n <MenuItem\n value={formatTimeRange(lastOption.value, timeZone)}\n onClick={() => setShowCustomDateSelector(true)}\n >\n {lastOption.display}\n </MenuItem>\n )}\n </Select>\n </Box>\n </>\n );\n}\n"],"names":["Box","MenuItem","Popover","Select","IconButton","TextField","Calendar","EarthIcon","isRelativeTimeRange","toAbsoluteTimeRange","useMemo","useRef","useState","useTimeZone","getTimeZoneOptions","SettingsAutocomplete","DateTimeRangePicker","buildCustomTimeOption","formatTimeRange","TimeRangeSelector","value","timeOptions","onChange","height","showCustomTimeRange","timeZone","timeZoneProp","timeZoneOptions","onTimeZoneChange","ctxTimeZone","anchorEl","showCustomDateSelector","setShowCustomDateSelector","convertedTimeRange","lastOption","undefined","open","setOpen","tzOptions","tzAnchorEl","setTzAnchorEl","tzOpen","Boolean","tzLabel","find","o","display","tzAutocompleteOptions","map","id","label","tzAutocompleteValue","current","anchorOrigin","vertical","horizontal","transformOrigin","onClose","sx","theme","padding","spacing","p","minWidth","onClick","e","stopPropagation","options","_e","option","selected","disableClearable","renderInput","params","placeholder","size","initialTimeRange","onCancel","ref","IconComponent","inputProps","marginTop","transform","paddingRight","lineHeight","paddingY","disableRipple","preventDefault","cursor","backgroundColor","py","px","alignItems","width","justifyContent","flexDirection","typography","color","mt","pr","ml","aria-label","currentTarget","fontSize","item","idx"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbsoluteTimeRange, TimeRangeValue } from '@perses-dev/
|
|
1
|
+
import { AbsoluteTimeRange, TimeRangeValue } from '@perses-dev/spec';
|
|
2
2
|
export declare const DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
|
3
3
|
export interface CustomTimeOption {
|
|
4
4
|
value: TimeRangeValue | undefined;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { isBefore, isValid } from 'date-fns';
|
|
14
|
-
import { isRelativeTimeRange } from '@perses-dev/
|
|
14
|
+
import { isRelativeTimeRange } from '@perses-dev/spec';
|
|
15
15
|
import { formatWithTimeZone } from '../utils';
|
|
16
16
|
export const DATE_TIME_FORMAT = 'yyyy-MM-dd HH:mm:ss';
|
|
17
17
|
export function buildCustomTimeOption(value, timeZone) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/TimeRangeSelector/utils.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { isBefore, isValid } from 'date-fns';\nimport { AbsoluteTimeRange, isRelativeTimeRange, TimeRangeValue } from '@perses-dev/
|
|
1
|
+
{"version":3,"sources":["../../src/TimeRangeSelector/utils.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { isBefore, isValid } from 'date-fns';\nimport { AbsoluteTimeRange, isRelativeTimeRange, TimeRangeValue } from '@perses-dev/spec';\nimport { formatWithTimeZone } from '../utils';\n\nexport const DATE_TIME_FORMAT = 'yyyy-MM-dd HH:mm:ss';\n\nexport interface CustomTimeOption {\n value: TimeRangeValue | undefined;\n display: string;\n}\n\nexport function buildCustomTimeOption(value: AbsoluteTimeRange | undefined, timeZone: string): CustomTimeOption {\n return { value, display: formatTimeRange(value, timeZone) };\n}\n\n/**\n * Date validation and check if end is after start\n */\nexport function validateDateRange(startDate: Date, endDate: Date): boolean {\n // TODO: display error as helperText\n if (!isValid(startDate) || !isValid(endDate)) {\n console.error('Invalid Date');\n return false;\n }\n if (!isBefore(startDate, endDate)) {\n console.error('End Time is before Start Time');\n return false;\n }\n return true;\n}\n\n/**\n * Format start and end time based on provided date format\n * @param timeRange absolute time range with a start and end datetime\n * @param dateFormat date format string\n * @param timeZone\n */\nexport function formatAbsoluteRange(timeRange: AbsoluteTimeRange, dateFormat: string, timeZone?: string): string {\n const formattedStart = formatWithTimeZone(timeRange.start, dateFormat, timeZone);\n const formattedEnd = formatWithTimeZone(timeRange.end, dateFormat, timeZone);\n return `${formattedStart} - ${formattedEnd}`;\n}\n\n/**\n * Format the time range for display purpose only (e.g. in the selector)\n * @param value\n * @param timeZone\n */\nexport function formatTimeRange(value: TimeRangeValue | undefined, timeZone: string): string {\n if (!value) {\n return 'Custom Time Range';\n }\n return !isRelativeTimeRange(value) ? formatAbsoluteRange(value, DATE_TIME_FORMAT, timeZone) : value.pastDuration;\n}\n"],"names":["isBefore","isValid","isRelativeTimeRange","formatWithTimeZone","DATE_TIME_FORMAT","buildCustomTimeOption","value","timeZone","display","formatTimeRange","validateDateRange","startDate","endDate","console","error","formatAbsoluteRange","timeRange","dateFormat","formattedStart","start","formattedEnd","end","pastDuration"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,QAAQ,EAAEC,OAAO,QAAQ,WAAW;AAC7C,SAA4BC,mBAAmB,QAAwB,mBAAmB;AAC1F,SAASC,kBAAkB,QAAQ,WAAW;AAE9C,OAAO,MAAMC,mBAAmB,sBAAsB;AAOtD,OAAO,SAASC,sBAAsBC,KAAoC,EAAEC,QAAgB;IAC1F,OAAO;QAAED;QAAOE,SAASC,gBAAgBH,OAAOC;IAAU;AAC5D;AAEA;;CAEC,GACD,OAAO,SAASG,kBAAkBC,SAAe,EAAEC,OAAa;IAC9D,oCAAoC;IACpC,IAAI,CAACX,QAAQU,cAAc,CAACV,QAAQW,UAAU;QAC5CC,QAAQC,KAAK,CAAC;QACd,OAAO;IACT;IACA,IAAI,CAACd,SAASW,WAAWC,UAAU;QACjCC,QAAQC,KAAK,CAAC;QACd,OAAO;IACT;IACA,OAAO;AACT;AAEA;;;;;CAKC,GACD,OAAO,SAASC,oBAAoBC,SAA4B,EAAEC,UAAkB,EAAEV,QAAiB;IACrG,MAAMW,iBAAiBf,mBAAmBa,UAAUG,KAAK,EAAEF,YAAYV;IACvE,MAAMa,eAAejB,mBAAmBa,UAAUK,GAAG,EAAEJ,YAAYV;IACnE,OAAO,GAAGW,eAAe,GAAG,EAAEE,cAAc;AAC9C;AAEA;;;;CAIC,GACD,OAAO,SAASX,gBAAgBH,KAAiC,EAAEC,QAAgB;IACjF,IAAI,CAACD,OAAO;QACV,OAAO;IACT;IACA,OAAO,CAACJ,oBAAoBI,SAASS,oBAAoBT,OAAOF,kBAAkBG,YAAYD,MAAMgB,YAAY;AAClH"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MutableRefObject } from 'react';
|
|
2
2
|
import { ECharts as EChartsInstance } from 'echarts/core';
|
|
3
|
-
import {
|
|
4
|
-
import { TimeChartSeriesMapping } from '../model';
|
|
3
|
+
import { TimeSeries } from '@perses-dev/spec';
|
|
4
|
+
import { FormatOptions, TimeChartSeriesMapping } from '../model';
|
|
5
5
|
import { CursorCoordinates } from './tooltip-model';
|
|
6
6
|
export interface TimeChartTooltipProps {
|
|
7
7
|
chartRef: MutableRefObject<EChartsInstance | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeChartTooltip.d.ts","sourceRoot":"","sources":["../../src/TimeSeriesTooltip/TimeChartTooltip.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAQ,gBAAgB,EAAoB,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"TimeChartTooltip.d.ts","sourceRoot":"","sources":["../../src/TimeSeriesTooltip/TimeChartTooltip.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAQ,gBAAgB,EAAoB,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAoB,MAAM,iBAAiB,CAAC;AAMtE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,gBAAgB,CAAC,eAAe,GAAG,SAAS,CAAC,CAAC;IACxD,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,aAAa,EAAE,sBAAsB,CAAC;IACtC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB;;OAEG;IACH,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,6DA0E3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/TimeSeriesTooltip/TimeChartTooltip.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { memo, MutableRefObject, useRef, useState } from 'react';\nimport { Box, Portal, Stack } from '@mui/material';\nimport { ECharts as EChartsInstance } from 'echarts/core';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/TimeSeriesTooltip/TimeChartTooltip.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { memo, MutableRefObject, useRef, useState } from 'react';\nimport { Box, Portal, Stack } from '@mui/material';\nimport { ECharts as EChartsInstance } from 'echarts/core';\nimport { TimeSeries } from '@perses-dev/spec';\nimport useResizeObserver from 'use-resize-observer';\nimport { FormatOptions, TimeChartSeriesMapping } from '../model';\nimport { CursorCoordinates, useMousePosition } from './tooltip-model';\nimport { assembleTransform, getTooltipStyles } from './utils';\nimport { getNearbySeriesData } from './nearby-series';\nimport { TooltipHeader } from './TooltipHeader';\nimport { TooltipContent } from './TooltipContent';\n\nexport interface TimeChartTooltipProps {\n chartRef: MutableRefObject<EChartsInstance | undefined>;\n data: TimeSeries[];\n seriesMapping: TimeChartSeriesMapping;\n enablePinning?: boolean;\n pinnedPos: CursorCoordinates | null;\n /**\n * The id of the container that will have the chart tooltip appended to it.\n * By default, the chart tooltip is attached to document.body.\n */\n containerId?: string;\n onUnpinClick?: () => void;\n format?: FormatOptions;\n /**\n * Map of series ID to format options for per-series formatting (used with multiple Y axes)\n */\n seriesFormatMap?: Map<string, FormatOptions>;\n wrapLabels?: boolean;\n}\n\nexport const TimeChartTooltip = memo(function TimeChartTooltip({\n containerId,\n chartRef,\n data,\n seriesMapping,\n enablePinning = true,\n wrapLabels,\n format,\n seriesFormatMap,\n onUnpinClick,\n pinnedPos,\n}: TimeChartTooltipProps) {\n const [showAllSeries, setShowAllSeries] = useState(false);\n const transform = useRef<string | undefined>();\n\n const mousePos = useMousePosition();\n const { height, width, ref: tooltipRef } = useResizeObserver();\n\n const isTooltipPinned = pinnedPos !== null && enablePinning;\n\n if (mousePos === null || mousePos.target === null || data === null) return null;\n\n // Ensure user is hovering over a chart before checking for nearby series.\n if (pinnedPos === null && (mousePos.target as HTMLElement).tagName !== 'CANVAS') return null;\n\n const chart = chartRef.current;\n\n const containerElement = containerId ? document.querySelector(containerId) : undefined;\n // if tooltip is attached to a container, set max height to the height of the container so tooltip does not get cut off\n const maxHeight = containerElement ? containerElement.getBoundingClientRect().height : undefined;\n\n transform.current = assembleTransform(mousePos, pinnedPos, height ?? 0, width ?? 0, containerElement);\n\n // Get series nearby the cursor and pass into tooltip content children.\n const nearbySeries = getNearbySeriesData({\n mousePos,\n data,\n seriesMapping,\n pinnedPos,\n chart,\n format,\n seriesFormatMap,\n showAllSeries,\n });\n if (nearbySeries.length === 0) {\n return null;\n }\n\n const totalSeries = data.length;\n\n return (\n <Portal container={containerElement}>\n <Box\n ref={tooltipRef}\n sx={(theme) => getTooltipStyles(theme, pinnedPos, maxHeight)}\n style={{\n transform: transform.current,\n }}\n >\n <Stack spacing={0.5}>\n <TooltipHeader\n nearbySeries={nearbySeries}\n totalSeries={totalSeries}\n enablePinning={enablePinning}\n isTooltipPinned={isTooltipPinned}\n showAllSeries={showAllSeries}\n onShowAllClick={(checked) => setShowAllSeries(checked)}\n onUnpinClick={onUnpinClick}\n />\n <TooltipContent series={nearbySeries} wrapLabels={wrapLabels} />\n </Stack>\n </Box>\n </Portal>\n );\n});\n"],"names":["memo","useRef","useState","Box","Portal","Stack","useResizeObserver","useMousePosition","assembleTransform","getTooltipStyles","getNearbySeriesData","TooltipHeader","TooltipContent","TimeChartTooltip","containerId","chartRef","data","seriesMapping","enablePinning","wrapLabels","format","seriesFormatMap","onUnpinClick","pinnedPos","showAllSeries","setShowAllSeries","transform","mousePos","height","width","ref","tooltipRef","isTooltipPinned","target","tagName","chart","current","containerElement","document","querySelector","undefined","maxHeight","getBoundingClientRect","nearbySeries","length","totalSeries","container","sx","theme","style","spacing","onShowAllClick","checked","series"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,IAAI,EAAoBC,MAAM,EAAEC,QAAQ,QAAQ,QAAQ;AACjE,SAASC,GAAG,EAAEC,MAAM,EAAEC,KAAK,QAAQ,gBAAgB;AAGnD,OAAOC,uBAAuB,sBAAsB;AAEpD,SAA4BC,gBAAgB,QAAQ,kBAAkB;AACtE,SAASC,iBAAiB,EAAEC,gBAAgB,QAAQ,UAAU;AAC9D,SAASC,mBAAmB,QAAQ,kBAAkB;AACtD,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,cAAc,QAAQ,mBAAmB;AAsBlD,OAAO,MAAMC,iCAAmBb,KAAK,SAASa,iBAAiB,EAC7DC,WAAW,EACXC,QAAQ,EACRC,IAAI,EACJC,aAAa,EACbC,gBAAgB,IAAI,EACpBC,UAAU,EACVC,MAAM,EACNC,eAAe,EACfC,YAAY,EACZC,SAAS,EACa;IACtB,MAAM,CAACC,eAAeC,iBAAiB,GAAGvB,SAAS;IACnD,MAAMwB,YAAYzB;IAElB,MAAM0B,WAAWpB;IACjB,MAAM,EAAEqB,MAAM,EAAEC,KAAK,EAAEC,KAAKC,UAAU,EAAE,GAAGzB;IAE3C,MAAM0B,kBAAkBT,cAAc,QAAQL;IAE9C,IAAIS,aAAa,QAAQA,SAASM,MAAM,KAAK,QAAQjB,SAAS,MAAM,OAAO;IAE3E,0EAA0E;IAC1E,IAAIO,cAAc,QAAQ,AAACI,SAASM,MAAM,CAAiBC,OAAO,KAAK,UAAU,OAAO;IAExF,MAAMC,QAAQpB,SAASqB,OAAO;IAE9B,MAAMC,mBAAmBvB,cAAcwB,SAASC,aAAa,CAACzB,eAAe0B;IAC7E,uHAAuH;IACvH,MAAMC,YAAYJ,mBAAmBA,iBAAiBK,qBAAqB,GAAGd,MAAM,GAAGY;IAEvFd,UAAUU,OAAO,GAAG5B,kBAAkBmB,UAAUJ,WAAWK,UAAU,GAAGC,SAAS,GAAGQ;IAEpF,uEAAuE;IACvE,MAAMM,eAAejC,oBAAoB;QACvCiB;QACAX;QACAC;QACAM;QACAY;QACAf;QACAC;QACAG;IACF;IACA,IAAImB,aAAaC,MAAM,KAAK,GAAG;QAC7B,OAAO;IACT;IAEA,MAAMC,cAAc7B,KAAK4B,MAAM;IAE/B,qBACE,KAACxC;QAAO0C,WAAWT;kBACjB,cAAA,KAAClC;YACC2B,KAAKC;YACLgB,IAAI,CAACC,QAAUvC,iBAAiBuC,OAAOzB,WAAWkB;YAClDQ,OAAO;gBACLvB,WAAWA,UAAUU,OAAO;YAC9B;sBAEA,cAAA,MAAC/B;gBAAM6C,SAAS;;kCACd,KAACvC;wBACCgC,cAAcA;wBACdE,aAAaA;wBACb3B,eAAeA;wBACfc,iBAAiBA;wBACjBR,eAAeA;wBACf2B,gBAAgB,CAACC,UAAY3B,iBAAiB2B;wBAC9C9B,cAAcA;;kCAEhB,KAACV;wBAAeyC,QAAQV;wBAAcxB,YAAYA;;;;;;AAK5D,GAAG"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ECharts as EChartsInstance } from 'echarts/core';
|
|
2
|
-
import {
|
|
3
|
-
import { EChartsDataFormat, TimeChartSeriesMapping } from '../model';
|
|
2
|
+
import { TimeSeries } from '@perses-dev/spec';
|
|
3
|
+
import { EChartsDataFormat, TimeChartSeriesMapping, FormatOptions } from '../model';
|
|
4
4
|
import { CursorCoordinates, CursorData } from './tooltip-model';
|
|
5
5
|
export declare const INCREASE_NEARBY_SERIES_MULTIPLIER = 5.5;
|
|
6
6
|
export declare const DYNAMIC_NEARBY_SERIES_MULTIPLIER = 30;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nearby-series.d.ts","sourceRoot":"","sources":["../../src/TimeSeriesTooltip/nearby-series.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,
|
|
1
|
+
{"version":3,"file":"nearby-series.d.ts","sourceRoot":"","sources":["../../src/TimeSeriesTooltip/nearby-series.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACpE,OAAO,EACL,iBAAiB,EAEjB,sBAAsB,EAEtB,aAAa,EAEd,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAsB,MAAM,iBAAiB,CAAC;AAGpF,eAAO,MAAM,iCAAiC,MAAM,CAAC;AACrD,eAAO,MAAM,gCAAgC,KAAK,CAAC;AACnD,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,iBAAiB,GAAG,gBAAgB,EAAE,CAAC;AAEnD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,UAAU,EAAE,EAClB,aAAa,EAAE,sBAAsB,EACrC,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,eAAe,EACtB,MAAM,CAAC,EAAE,aAAa,EACtB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,EAE5C,YAAY,CAAC,EAAE,MAAM,GACpB,iBAAiB,CAiLnB;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,iBAAiB,EACvB,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,aAAa,GACrB,iBAAiB,CAmGnB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,aAAa,EACb,KAAK,EACL,MAAM,EACN,eAAe,EACf,aAAqB,GACtB,EAAE;IACD,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC/B,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACpC,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,aAAa,EAAE,sBAAsB,CAAC;IACtC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7C,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GAAG,iBAAiB,CAmEpB;AAKD,wBAAgB,uBAAuB,CAAC,EACtC,YAAY,EACZ,SAAS,EACT,UAAU,GACX,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAKV;AAKD,wBAAgB,UAAU,CAAC,EACzB,SAAS,EACT,WAAW,EACX,aAAqB,GACtB,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GAAG,MAAM,CAcT"}
|
|
@@ -10,8 +10,7 @@
|
|
|
10
10
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
|
-
import { formatValue } from '
|
|
14
|
-
import { OPTIMIZED_MODE_SERIES_LIMIT } from '../model';
|
|
13
|
+
import { OPTIMIZED_MODE_SERIES_LIMIT, formatValue } from '../model';
|
|
15
14
|
import { batchDispatchNearbySeriesActions, getPointInGrid, getClosestTimestamp } from '../utils';
|
|
16
15
|
import { EMPTY_TOOLTIP_DATA } from './tooltip-model';
|
|
17
16
|
// increase multipliers to show more series in tooltip
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/TimeSeriesTooltip/nearby-series.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ECharts as EChartsInstance } from 'echarts/core';\nimport { LineSeriesOption } from 'echarts/charts';\nimport { formatValue, TimeSeriesValueTuple, FormatOptions, TimeSeries } from '@perses-dev/core';\nimport { EChartsDataFormat, OPTIMIZED_MODE_SERIES_LIMIT, TimeChartSeriesMapping, DatapointInfo } from '../model';\nimport { batchDispatchNearbySeriesActions, getPointInGrid, getClosestTimestamp } from '../utils';\nimport { CursorCoordinates, CursorData, EMPTY_TOOLTIP_DATA } from './tooltip-model';\n\n// increase multipliers to show more series in tooltip\nexport const INCREASE_NEARBY_SERIES_MULTIPLIER = 5.5; // adjusts how many series show in tooltip (higher == more series shown)\nexport const DYNAMIC_NEARBY_SERIES_MULTIPLIER = 30; // used for adjustment after series number divisor\nexport const SHOW_FEWER_SERIES_LIMIT = 5;\n\nexport interface NearbySeriesInfo {\n seriesIdx: number | null;\n datumIdx: number | null;\n seriesName: string;\n date: number;\n markerColor: string;\n x: number;\n y: number;\n formattedY: string;\n isClosestToCursor: boolean;\n}\n\nexport type NearbySeriesArray = NearbySeriesInfo[];\n\n/**\n * Returns formatted series data for the points that are close to the user's cursor.\n * Adjust xBuffer and yBuffer to increase or decrease number of series shown.\n */\nexport function checkforNearbyTimeSeries(\n data: TimeSeries[],\n seriesMapping: TimeChartSeriesMapping,\n pointInGrid: number[],\n yBuffer: number,\n chart: EChartsInstance,\n format?: FormatOptions,\n seriesFormatMap?: Map<string, FormatOptions>,\n // in the case of multi-axis, we need the cursor Y position in pixel space\n cursorPixelY?: number\n): NearbySeriesArray {\n const currentNearbySeriesData: NearbySeriesArray = [];\n const cursorX: number | null = pointInGrid[0] ?? null;\n const cursorY: number | null = pointInGrid[1] ?? null;\n\n if (cursorX === null || cursorY === null) return currentNearbySeriesData;\n\n if (chart.dispatchAction === undefined) return currentNearbySeriesData;\n\n if (!Array.isArray(data)) return currentNearbySeriesData;\n const nearbySeriesIndexes: number[] = [];\n const emphasizedSeriesIndexes: number[] = [];\n const nonEmphasizedSeriesIndexes: number[] = [];\n const emphasizedDatapoints: DatapointInfo[] = [];\n const duplicateDatapoints: DatapointInfo[] = [];\n\n const totalSeries = data.length;\n\n const yValueCounts: Map<number, number> = new Map();\n\n // Only need to loop through first dataset source since getCommonTimeScale ensures xAxis timestamps are consistent\n const firstTimeSeriesValues = data[0]?.values;\n const closestTimestamp = getClosestTimestamp(firstTimeSeriesValues, cursorX);\n\n if (closestTimestamp === null) {\n return EMPTY_TOOLTIP_DATA;\n }\n\n // For multi-axis support: convert yBuffer to pixel space for consistent comparison\n // This allows us to compare series on different Y axes fairly\n let yBufferPixels: number | null = null;\n if (cursorPixelY !== undefined) {\n // Convert a point at cursorY and cursorY + yBuffer to pixels to get the buffer in pixel space\n const cursorPoint = chart.convertToPixel('grid', [0, cursorY]);\n const bufferPoint = chart.convertToPixel('grid', [0, cursorY + yBuffer]);\n if (cursorPoint && bufferPoint && cursorPoint[1] !== undefined && bufferPoint[1] !== undefined) {\n yBufferPixels = Math.abs(bufferPoint[1] - cursorPoint[1]);\n }\n }\n\n // find the timestamp with data that is closest to cursorX\n for (let seriesIdx = 0; seriesIdx < totalSeries; seriesIdx++) {\n const currentSeries = seriesMapping[seriesIdx];\n if (!currentSeries) break;\n\n const currentDataset = totalSeries > 0 ? data[seriesIdx] : null;\n if (!currentDataset) break;\n\n const currentDatasetValues: TimeSeriesValueTuple[] = currentDataset.values;\n if (currentDatasetValues === undefined || !Array.isArray(currentDatasetValues)) break;\n const lineSeries = currentSeries as LineSeriesOption;\n const currentSeriesName = lineSeries.name ? lineSeries.name.toString() : '';\n const seriesId = lineSeries.id ? lineSeries.id.toString() : '';\n const markerColor = lineSeries.color ?? '#000';\n\n // Get the format for this series (from seriesFormatMap or fallback to default format)\n const seriesFormat = seriesFormatMap?.get(seriesId) ?? format;\n\n if (Array.isArray(data)) {\n for (let datumIdx = 0; datumIdx < currentDatasetValues.length; datumIdx++) {\n const nearbyTimeSeries = currentDatasetValues[datumIdx];\n if (nearbyTimeSeries === undefined || !Array.isArray(nearbyTimeSeries)) break;\n\n const xValue = nearbyTimeSeries[0];\n const yValue = nearbyTimeSeries[1];\n // TODO: ensure null values not displayed in tooltip\n if (yValue !== undefined && yValue !== null) {\n if (closestTimestamp === xValue) {\n // Check if this series is nearby the cursor\n let isNearby = false;\n\n // For multi-axis: compare in pixel space\n if (cursorPixelY !== undefined && yBufferPixels !== null) {\n const dataPointPixel = chart.convertToPixel({ seriesIndex: seriesIdx }, [datumIdx, yValue]);\n if (dataPointPixel && dataPointPixel[1] !== undefined) {\n const pixelDistance = Math.abs(cursorPixelY - dataPointPixel[1]);\n isNearby = pixelDistance <= yBufferPixels;\n } else {\n // Fallback to data-space comparison for primary axis\n isNearby = cursorY <= yValue + yBuffer && cursorY >= yValue - yBuffer;\n }\n } else {\n // Fallback to original data-space comparison\n isNearby = cursorY <= yValue + yBuffer && cursorY >= yValue - yBuffer;\n }\n\n if (isNearby) {\n // show fewer bold series in tooltip when many total series\n const minPercentRange = totalSeries > SHOW_FEWER_SERIES_LIMIT ? 2 : 5;\n const percentRangeToCheck = Math.max(minPercentRange, 100 / totalSeries);\n\n // For isClosestToCursor, also use pixel space for multi-axis\n let isClosestToCursor = false;\n if (cursorPixelY !== undefined) {\n const dataPointPixel = chart.convertToPixel({ seriesIndex: seriesIdx }, [datumIdx, yValue]);\n if (dataPointPixel && dataPointPixel[1] !== undefined) {\n const pixelDistance = Math.abs(cursorPixelY - dataPointPixel[1]);\n // Use percentage of buffer for \"closest\" determination\n const tightBufferPixels = (yBufferPixels ?? 50) * (percentRangeToCheck / 100);\n isClosestToCursor = pixelDistance <= Math.max(tightBufferPixels, 5);\n } else {\n isClosestToCursor = isWithinPercentageRange({\n valueToCheck: cursorY,\n baseValue: yValue,\n percentage: percentRangeToCheck,\n });\n }\n } else {\n isClosestToCursor = isWithinPercentageRange({\n valueToCheck: cursorY,\n baseValue: yValue,\n percentage: percentRangeToCheck,\n });\n }\n\n if (isClosestToCursor) {\n // shows as bold in tooltip, customize 'emphasis' options in getTimeSeries util\n emphasizedSeriesIndexes.push(seriesIdx);\n\n // Used to determine which datapoint to apply select styles to.\n // Accounts for cases where lines may be rendered directly on top of eachother.\n const duplicateValuesCount = yValueCounts.get(yValue) ?? 0;\n yValueCounts.set(yValue, duplicateValuesCount + 1);\n if (duplicateValuesCount > 0) {\n duplicateDatapoints.push({\n seriesIndex: seriesIdx,\n dataIndex: datumIdx,\n seriesName: currentSeriesName,\n yValue: yValue,\n });\n }\n\n // keep track of all bold datapoints in tooltip so that 'select' state only applied to topmost\n emphasizedDatapoints.push({\n seriesIndex: seriesIdx,\n dataIndex: datumIdx,\n seriesName: currentSeriesName,\n yValue: yValue,\n });\n } else {\n nonEmphasizedSeriesIndexes.push(seriesIdx);\n // ensure series far away from cursor are not highlighted\n chart.dispatchAction({\n type: 'downplay',\n seriesIndex: seriesIdx,\n });\n }\n const formattedY = formatValue(yValue, seriesFormat);\n currentNearbySeriesData.push({\n seriesIdx: seriesIdx,\n datumIdx: datumIdx,\n seriesName: currentSeriesName,\n date: closestTimestamp,\n x: xValue,\n y: yValue,\n formattedY: formattedY,\n markerColor: markerColor.toString(),\n isClosestToCursor,\n });\n nearbySeriesIndexes.push(seriesIdx);\n }\n }\n }\n }\n }\n }\n\n batchDispatchNearbySeriesActions(\n chart,\n nearbySeriesIndexes,\n emphasizedSeriesIndexes,\n nonEmphasizedSeriesIndexes,\n emphasizedDatapoints,\n duplicateDatapoints\n );\n\n return currentNearbySeriesData;\n}\n\n/**\n * [DEPRECATED] Returns formatted series data for the points that are close to the user's cursor\n * Adjust yBuffer to increase or decrease number of series shown\n */\nexport function legacyCheckforNearbySeries(\n data: EChartsDataFormat,\n pointInGrid: number[],\n yBuffer: number,\n chart?: EChartsInstance,\n format?: FormatOptions\n): NearbySeriesArray {\n const currentNearbySeriesData: NearbySeriesArray = [];\n const cursorX: number | null = pointInGrid[0] ?? null;\n const cursorY: number | null = pointInGrid[1] ?? null;\n\n if (cursorX === null || cursorY === null) {\n return currentNearbySeriesData;\n }\n\n const nearbySeriesIndexes: number[] = [];\n const emphasizedSeriesIndexes: number[] = [];\n const nonEmphasizedSeriesIndexes: number[] = [];\n const totalSeries = data.timeSeries.length;\n if (Array.isArray(data.xAxis) && Array.isArray(data.timeSeries)) {\n for (let seriesIdx = 0; seriesIdx < totalSeries; seriesIdx++) {\n const currentSeries = data.timeSeries[seriesIdx];\n if (currentSeries === undefined) break;\n if (currentNearbySeriesData.length >= OPTIMIZED_MODE_SERIES_LIMIT) break;\n\n const currentSeriesName = currentSeries.name ? currentSeries.name.toString() : '';\n const markerColor = currentSeries.color ?? '#000';\n if (Array.isArray(currentSeries.data)) {\n for (let datumIdx = 0; datumIdx < currentSeries.data.length; datumIdx++) {\n const xValue = data.xAxis[datumIdx] ?? 0;\n const yValue = currentSeries.data[datumIdx];\n // ensure null values not displayed in tooltip\n if (yValue !== undefined && yValue !== null && cursorX === datumIdx) {\n if (yValue !== '-' && cursorY <= yValue + yBuffer && cursorY >= yValue - yBuffer) {\n // show fewer bold series in tooltip when many total series\n const minPercentRange = totalSeries > SHOW_FEWER_SERIES_LIMIT ? 2 : 5;\n const percentRangeToCheck = Math.max(minPercentRange, 100 / totalSeries);\n const isClosestToCursor = isWithinPercentageRange({\n valueToCheck: cursorY,\n baseValue: yValue,\n percentage: percentRangeToCheck,\n });\n if (isClosestToCursor) {\n emphasizedSeriesIndexes.push(seriesIdx);\n } else {\n nonEmphasizedSeriesIndexes.push(seriesIdx);\n // ensure series not close to cursor are not highlighted\n if (chart?.dispatchAction !== undefined) {\n chart.dispatchAction({\n type: 'downplay',\n seriesIndex: seriesIdx,\n });\n }\n }\n\n // determine whether to convert timestamp to ms, see: https://stackoverflow.com/a/23982005/17575201\n const xValueMilliSeconds = xValue > 99999999999 ? xValue : xValue * 1000;\n const formattedY = formatValue(yValue, format);\n currentNearbySeriesData.push({\n seriesIdx: seriesIdx,\n datumIdx: datumIdx,\n seriesName: currentSeriesName,\n date: xValueMilliSeconds,\n x: xValue,\n y: yValue,\n formattedY: formattedY,\n markerColor: markerColor.toString(),\n isClosestToCursor,\n });\n nearbySeriesIndexes.push(seriesIdx);\n }\n }\n }\n }\n }\n }\n if (chart?.dispatchAction !== undefined) {\n // Clears emphasis state of all lines that are not emphasized.\n // Emphasized is a subset of just the nearby series that are closest to cursor.\n chart.dispatchAction({\n type: 'downplay',\n seriesIndex: nonEmphasizedSeriesIndexes,\n });\n\n // https://echarts.apache.org/en/api.html#action.highlight\n if (emphasizedSeriesIndexes.length > 0) {\n // Fadeout opacity of all series not closest to cursor.\n chart.dispatchAction({\n type: 'highlight',\n seriesIndex: emphasizedSeriesIndexes,\n notBlur: false, // ensure blur IS triggered, this is default but setting so it is explicit\n escapeConnect: true, // shared crosshair should not emphasize series on adjacent charts\n });\n } else {\n // When no emphasized series with bold text, notBlur allows opacity fadeout to not trigger.\n chart.dispatchAction({\n type: 'highlight',\n seriesIndex: nearbySeriesIndexes,\n notBlur: true, // do not trigger blur state when cursor is not immediately close to any series\n escapeConnect: true, // shared crosshair should not emphasize series on adjacent charts\n });\n }\n }\n\n return currentNearbySeriesData;\n}\n\n/**\n * Uses mouse position to determine whether user is hovering over a chart canvas\n * If yes, convert from pixel values to logical cartesian coordinates and return all nearby series\n */\nexport function getNearbySeriesData({\n mousePos,\n pinnedPos,\n data,\n seriesMapping,\n chart,\n format,\n seriesFormatMap,\n showAllSeries = false,\n}: {\n mousePos: CursorData['coords'];\n pinnedPos: CursorCoordinates | null;\n data: TimeSeries[];\n seriesMapping: TimeChartSeriesMapping;\n chart?: EChartsInstance;\n format?: FormatOptions;\n seriesFormatMap?: Map<string, FormatOptions>;\n showAllSeries?: boolean;\n}): NearbySeriesArray {\n if (chart === undefined || mousePos === null) return EMPTY_TOOLTIP_DATA;\n\n // prevents multiple tooltips showing from adjacent charts unless tooltip is pinned\n let cursorTargetMatchesChart = false;\n if (mousePos.target !== null) {\n const currentParent = (<HTMLElement>mousePos.target).parentElement;\n if (currentParent !== null) {\n const currentGrandparent = currentParent.parentElement;\n if (currentGrandparent !== null) {\n const chartDom = chart.getDom();\n if (chartDom === currentGrandparent) {\n cursorTargetMatchesChart = true;\n }\n }\n }\n }\n\n // allows moving cursor inside tooltip without it fading away\n if (pinnedPos !== null) {\n mousePos = pinnedPos;\n cursorTargetMatchesChart = true;\n }\n\n if (cursorTargetMatchesChart === false || data === null || chart['_model'] === undefined) return EMPTY_TOOLTIP_DATA;\n\n // mousemove position undefined when not hovering over chart canvas\n if (mousePos.plotCanvas.x === undefined || mousePos.plotCanvas.y === undefined) return EMPTY_TOOLTIP_DATA;\n\n const cursorPixelY = mousePos.plotCanvas.y;\n const pointInGrid = getPointInGrid(mousePos.plotCanvas.x, cursorPixelY, chart);\n if (pointInGrid !== null) {\n const chartModel = chart['_model'];\n const yAxisScale = chartModel.getComponent('yAxis').axis.scale;\n const isLogScale = yAxisScale.type === 'log';\n let yInterval = yAxisScale._interval;\n // For logarithmic scales, convert the log interval to actual data range\n if (isLogScale && yAxisScale.base) {\n const logBase = yAxisScale.base;\n const extent = yAxisScale._extent;\n // Calculate actual data range from log extent\n // extent is in log space (e.g., [0, 2] for 10^0 to 10^2)\n const actualMin = logBase ** extent[0];\n const actualMax = logBase ** extent[1];\n // Use a fraction of the actual range as the interval\n yInterval = (actualMax - actualMin) / 100;\n }\n const totalSeries = data.length;\n const yBuffer = getYBuffer({ yInterval, totalSeries, showAllSeries });\n\n // Detect if chart has multiple Y-axes by checking if any series uses yAxisIndex > 0\n const hasMultipleYAxes = seriesMapping.some((series) => series.yAxisIndex !== undefined && series.yAxisIndex > 0);\n\n return checkforNearbyTimeSeries(\n data,\n seriesMapping,\n pointInGrid,\n yBuffer,\n chart,\n format,\n seriesFormatMap,\n hasMultipleYAxes ? cursorPixelY : undefined\n );\n }\n\n // no nearby series found\n return EMPTY_TOOLTIP_DATA;\n}\n\n/*\n * Check if two numbers are within a specified percentage range\n */\nexport function isWithinPercentageRange({\n valueToCheck,\n baseValue,\n percentage,\n}: {\n valueToCheck: number;\n baseValue: number;\n percentage: number;\n}): boolean {\n const range = (percentage / 100) * baseValue;\n const lowerBound = baseValue - range;\n const upperBound = baseValue + range;\n return valueToCheck >= lowerBound && valueToCheck <= upperBound;\n}\n\n/*\n * Get range to check within for nearby series to show in tooltip.\n */\nexport function getYBuffer({\n yInterval,\n totalSeries,\n showAllSeries = false,\n}: {\n yInterval: number;\n totalSeries: number;\n showAllSeries?: boolean;\n}): number {\n if (showAllSeries) {\n return yInterval * 10; // roughly correlates with grid so entire canvas is searched\n }\n // never let nearby series range be less than roughly the size of a single tick\n const yBufferMin = yInterval * 0.3;\n\n // tooltip trigger area gets smaller with more series\n if (totalSeries > SHOW_FEWER_SERIES_LIMIT) {\n const adjustedBuffer = (yInterval * DYNAMIC_NEARBY_SERIES_MULTIPLIER) / totalSeries;\n return Math.max(yBufferMin, adjustedBuffer);\n }\n // increase multiplier to expand nearby series range\n return Math.max(yBufferMin, yInterval * INCREASE_NEARBY_SERIES_MULTIPLIER);\n}\n"],"names":["formatValue","OPTIMIZED_MODE_SERIES_LIMIT","batchDispatchNearbySeriesActions","getPointInGrid","getClosestTimestamp","EMPTY_TOOLTIP_DATA","INCREASE_NEARBY_SERIES_MULTIPLIER","DYNAMIC_NEARBY_SERIES_MULTIPLIER","SHOW_FEWER_SERIES_LIMIT","checkforNearbyTimeSeries","data","seriesMapping","pointInGrid","yBuffer","chart","format","seriesFormatMap","cursorPixelY","currentNearbySeriesData","cursorX","cursorY","dispatchAction","undefined","Array","isArray","nearbySeriesIndexes","emphasizedSeriesIndexes","nonEmphasizedSeriesIndexes","emphasizedDatapoints","duplicateDatapoints","totalSeries","length","yValueCounts","Map","firstTimeSeriesValues","values","closestTimestamp","yBufferPixels","cursorPoint","convertToPixel","bufferPoint","Math","abs","seriesIdx","currentSeries","currentDataset","currentDatasetValues","lineSeries","currentSeriesName","name","toString","seriesId","id","markerColor","color","seriesFormat","get","datumIdx","nearbyTimeSeries","xValue","yValue","isNearby","dataPointPixel","seriesIndex","pixelDistance","minPercentRange","percentRangeToCheck","max","isClosestToCursor","tightBufferPixels","isWithinPercentageRange","valueToCheck","baseValue","percentage","push","duplicateValuesCount","set","dataIndex","seriesName","type","formattedY","date","x","y","legacyCheckforNearbySeries","timeSeries","xAxis","xValueMilliSeconds","notBlur","escapeConnect","getNearbySeriesData","mousePos","pinnedPos","showAllSeries","cursorTargetMatchesChart","target","currentParent","parentElement","currentGrandparent","chartDom","getDom","plotCanvas","chartModel","yAxisScale","getComponent","axis","scale","isLogScale","yInterval","_interval","base","logBase","extent","_extent","actualMin","actualMax","getYBuffer","hasMultipleYAxes","some","series","yAxisIndex","range","lowerBound","upperBound","yBufferMin","adjustedBuffer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/TimeSeriesTooltip/nearby-series.ts"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { ECharts as EChartsInstance } from 'echarts/core';\nimport { LineSeriesOption } from 'echarts/charts';\nimport { TimeSeries, TimeSeriesValueTuple } from '@perses-dev/spec';\nimport {\n EChartsDataFormat,\n OPTIMIZED_MODE_SERIES_LIMIT,\n TimeChartSeriesMapping,\n DatapointInfo,\n FormatOptions,\n formatValue,\n} from '../model';\nimport { batchDispatchNearbySeriesActions, getPointInGrid, getClosestTimestamp } from '../utils';\nimport { CursorCoordinates, CursorData, EMPTY_TOOLTIP_DATA } from './tooltip-model';\n\n// increase multipliers to show more series in tooltip\nexport const INCREASE_NEARBY_SERIES_MULTIPLIER = 5.5; // adjusts how many series show in tooltip (higher == more series shown)\nexport const DYNAMIC_NEARBY_SERIES_MULTIPLIER = 30; // used for adjustment after series number divisor\nexport const SHOW_FEWER_SERIES_LIMIT = 5;\n\nexport interface NearbySeriesInfo {\n seriesIdx: number | null;\n datumIdx: number | null;\n seriesName: string;\n date: number;\n markerColor: string;\n x: number;\n y: number;\n formattedY: string;\n isClosestToCursor: boolean;\n}\n\nexport type NearbySeriesArray = NearbySeriesInfo[];\n\n/**\n * Returns formatted series data for the points that are close to the user's cursor.\n * Adjust xBuffer and yBuffer to increase or decrease number of series shown.\n */\nexport function checkforNearbyTimeSeries(\n data: TimeSeries[],\n seriesMapping: TimeChartSeriesMapping,\n pointInGrid: number[],\n yBuffer: number,\n chart: EChartsInstance,\n format?: FormatOptions,\n seriesFormatMap?: Map<string, FormatOptions>,\n // in the case of multi-axis, we need the cursor Y position in pixel space\n cursorPixelY?: number\n): NearbySeriesArray {\n const currentNearbySeriesData: NearbySeriesArray = [];\n const cursorX: number | null = pointInGrid[0] ?? null;\n const cursorY: number | null = pointInGrid[1] ?? null;\n\n if (cursorX === null || cursorY === null) return currentNearbySeriesData;\n\n if (chart.dispatchAction === undefined) return currentNearbySeriesData;\n\n if (!Array.isArray(data)) return currentNearbySeriesData;\n const nearbySeriesIndexes: number[] = [];\n const emphasizedSeriesIndexes: number[] = [];\n const nonEmphasizedSeriesIndexes: number[] = [];\n const emphasizedDatapoints: DatapointInfo[] = [];\n const duplicateDatapoints: DatapointInfo[] = [];\n\n const totalSeries = data.length;\n\n const yValueCounts: Map<number, number> = new Map();\n\n // Only need to loop through first dataset source since getCommonTimeScale ensures xAxis timestamps are consistent\n const firstTimeSeriesValues = data[0]?.values;\n const closestTimestamp = getClosestTimestamp(firstTimeSeriesValues, cursorX);\n\n if (closestTimestamp === null) {\n return EMPTY_TOOLTIP_DATA;\n }\n\n // For multi-axis support: convert yBuffer to pixel space for consistent comparison\n // This allows us to compare series on different Y axes fairly\n let yBufferPixels: number | null = null;\n if (cursorPixelY !== undefined) {\n // Convert a point at cursorY and cursorY + yBuffer to pixels to get the buffer in pixel space\n const cursorPoint = chart.convertToPixel('grid', [0, cursorY]);\n const bufferPoint = chart.convertToPixel('grid', [0, cursorY + yBuffer]);\n if (cursorPoint && bufferPoint && cursorPoint[1] !== undefined && bufferPoint[1] !== undefined) {\n yBufferPixels = Math.abs(bufferPoint[1] - cursorPoint[1]);\n }\n }\n\n // find the timestamp with data that is closest to cursorX\n for (let seriesIdx = 0; seriesIdx < totalSeries; seriesIdx++) {\n const currentSeries = seriesMapping[seriesIdx];\n if (!currentSeries) break;\n\n const currentDataset = totalSeries > 0 ? data[seriesIdx] : null;\n if (!currentDataset) break;\n\n const currentDatasetValues: TimeSeriesValueTuple[] = currentDataset.values;\n if (currentDatasetValues === undefined || !Array.isArray(currentDatasetValues)) break;\n const lineSeries = currentSeries as LineSeriesOption;\n const currentSeriesName = lineSeries.name ? lineSeries.name.toString() : '';\n const seriesId = lineSeries.id ? lineSeries.id.toString() : '';\n const markerColor = lineSeries.color ?? '#000';\n\n // Get the format for this series (from seriesFormatMap or fallback to default format)\n const seriesFormat = seriesFormatMap?.get(seriesId) ?? format;\n\n if (Array.isArray(data)) {\n for (let datumIdx = 0; datumIdx < currentDatasetValues.length; datumIdx++) {\n const nearbyTimeSeries = currentDatasetValues[datumIdx];\n if (nearbyTimeSeries === undefined || !Array.isArray(nearbyTimeSeries)) break;\n\n const xValue = nearbyTimeSeries[0];\n const yValue = nearbyTimeSeries[1];\n // TODO: ensure null values not displayed in tooltip\n if (yValue !== undefined && yValue !== null) {\n if (closestTimestamp === xValue) {\n // Check if this series is nearby the cursor\n let isNearby = false;\n\n // For multi-axis: compare in pixel space\n if (cursorPixelY !== undefined && yBufferPixels !== null) {\n const dataPointPixel = chart.convertToPixel({ seriesIndex: seriesIdx }, [datumIdx, yValue]);\n if (dataPointPixel && dataPointPixel[1] !== undefined) {\n const pixelDistance = Math.abs(cursorPixelY - dataPointPixel[1]);\n isNearby = pixelDistance <= yBufferPixels;\n } else {\n // Fallback to data-space comparison for primary axis\n isNearby = cursorY <= yValue + yBuffer && cursorY >= yValue - yBuffer;\n }\n } else {\n // Fallback to original data-space comparison\n isNearby = cursorY <= yValue + yBuffer && cursorY >= yValue - yBuffer;\n }\n\n if (isNearby) {\n // show fewer bold series in tooltip when many total series\n const minPercentRange = totalSeries > SHOW_FEWER_SERIES_LIMIT ? 2 : 5;\n const percentRangeToCheck = Math.max(minPercentRange, 100 / totalSeries);\n\n // For isClosestToCursor, also use pixel space for multi-axis\n let isClosestToCursor = false;\n if (cursorPixelY !== undefined) {\n const dataPointPixel = chart.convertToPixel({ seriesIndex: seriesIdx }, [datumIdx, yValue]);\n if (dataPointPixel && dataPointPixel[1] !== undefined) {\n const pixelDistance = Math.abs(cursorPixelY - dataPointPixel[1]);\n // Use percentage of buffer for \"closest\" determination\n const tightBufferPixels = (yBufferPixels ?? 50) * (percentRangeToCheck / 100);\n isClosestToCursor = pixelDistance <= Math.max(tightBufferPixels, 5);\n } else {\n isClosestToCursor = isWithinPercentageRange({\n valueToCheck: cursorY,\n baseValue: yValue,\n percentage: percentRangeToCheck,\n });\n }\n } else {\n isClosestToCursor = isWithinPercentageRange({\n valueToCheck: cursorY,\n baseValue: yValue,\n percentage: percentRangeToCheck,\n });\n }\n\n if (isClosestToCursor) {\n // shows as bold in tooltip, customize 'emphasis' options in getTimeSeries util\n emphasizedSeriesIndexes.push(seriesIdx);\n\n // Used to determine which datapoint to apply select styles to.\n // Accounts for cases where lines may be rendered directly on top of eachother.\n const duplicateValuesCount = yValueCounts.get(yValue) ?? 0;\n yValueCounts.set(yValue, duplicateValuesCount + 1);\n if (duplicateValuesCount > 0) {\n duplicateDatapoints.push({\n seriesIndex: seriesIdx,\n dataIndex: datumIdx,\n seriesName: currentSeriesName,\n yValue: yValue,\n });\n }\n\n // keep track of all bold datapoints in tooltip so that 'select' state only applied to topmost\n emphasizedDatapoints.push({\n seriesIndex: seriesIdx,\n dataIndex: datumIdx,\n seriesName: currentSeriesName,\n yValue: yValue,\n });\n } else {\n nonEmphasizedSeriesIndexes.push(seriesIdx);\n // ensure series far away from cursor are not highlighted\n chart.dispatchAction({\n type: 'downplay',\n seriesIndex: seriesIdx,\n });\n }\n const formattedY = formatValue(yValue, seriesFormat);\n currentNearbySeriesData.push({\n seriesIdx: seriesIdx,\n datumIdx: datumIdx,\n seriesName: currentSeriesName,\n date: closestTimestamp,\n x: xValue,\n y: yValue,\n formattedY: formattedY,\n markerColor: markerColor.toString(),\n isClosestToCursor,\n });\n nearbySeriesIndexes.push(seriesIdx);\n }\n }\n }\n }\n }\n }\n\n batchDispatchNearbySeriesActions(\n chart,\n nearbySeriesIndexes,\n emphasizedSeriesIndexes,\n nonEmphasizedSeriesIndexes,\n emphasizedDatapoints,\n duplicateDatapoints\n );\n\n return currentNearbySeriesData;\n}\n\n/**\n * [DEPRECATED] Returns formatted series data for the points that are close to the user's cursor\n * Adjust yBuffer to increase or decrease number of series shown\n */\nexport function legacyCheckforNearbySeries(\n data: EChartsDataFormat,\n pointInGrid: number[],\n yBuffer: number,\n chart?: EChartsInstance,\n format?: FormatOptions\n): NearbySeriesArray {\n const currentNearbySeriesData: NearbySeriesArray = [];\n const cursorX: number | null = pointInGrid[0] ?? null;\n const cursorY: number | null = pointInGrid[1] ?? null;\n\n if (cursorX === null || cursorY === null) {\n return currentNearbySeriesData;\n }\n\n const nearbySeriesIndexes: number[] = [];\n const emphasizedSeriesIndexes: number[] = [];\n const nonEmphasizedSeriesIndexes: number[] = [];\n const totalSeries = data.timeSeries.length;\n if (Array.isArray(data.xAxis) && Array.isArray(data.timeSeries)) {\n for (let seriesIdx = 0; seriesIdx < totalSeries; seriesIdx++) {\n const currentSeries = data.timeSeries[seriesIdx];\n if (currentSeries === undefined) break;\n if (currentNearbySeriesData.length >= OPTIMIZED_MODE_SERIES_LIMIT) break;\n\n const currentSeriesName = currentSeries.name ? currentSeries.name.toString() : '';\n const markerColor = currentSeries.color ?? '#000';\n if (Array.isArray(currentSeries.data)) {\n for (let datumIdx = 0; datumIdx < currentSeries.data.length; datumIdx++) {\n const xValue = data.xAxis[datumIdx] ?? 0;\n const yValue = currentSeries.data[datumIdx];\n // ensure null values not displayed in tooltip\n if (yValue !== undefined && yValue !== null && cursorX === datumIdx) {\n if (yValue !== '-' && cursorY <= yValue + yBuffer && cursorY >= yValue - yBuffer) {\n // show fewer bold series in tooltip when many total series\n const minPercentRange = totalSeries > SHOW_FEWER_SERIES_LIMIT ? 2 : 5;\n const percentRangeToCheck = Math.max(minPercentRange, 100 / totalSeries);\n const isClosestToCursor = isWithinPercentageRange({\n valueToCheck: cursorY,\n baseValue: yValue,\n percentage: percentRangeToCheck,\n });\n if (isClosestToCursor) {\n emphasizedSeriesIndexes.push(seriesIdx);\n } else {\n nonEmphasizedSeriesIndexes.push(seriesIdx);\n // ensure series not close to cursor are not highlighted\n if (chart?.dispatchAction !== undefined) {\n chart.dispatchAction({\n type: 'downplay',\n seriesIndex: seriesIdx,\n });\n }\n }\n\n // determine whether to convert timestamp to ms, see: https://stackoverflow.com/a/23982005/17575201\n const xValueMilliSeconds = xValue > 99999999999 ? xValue : xValue * 1000;\n const formattedY = formatValue(yValue, format);\n currentNearbySeriesData.push({\n seriesIdx: seriesIdx,\n datumIdx: datumIdx,\n seriesName: currentSeriesName,\n date: xValueMilliSeconds,\n x: xValue,\n y: yValue,\n formattedY: formattedY,\n markerColor: markerColor.toString(),\n isClosestToCursor,\n });\n nearbySeriesIndexes.push(seriesIdx);\n }\n }\n }\n }\n }\n }\n if (chart?.dispatchAction !== undefined) {\n // Clears emphasis state of all lines that are not emphasized.\n // Emphasized is a subset of just the nearby series that are closest to cursor.\n chart.dispatchAction({\n type: 'downplay',\n seriesIndex: nonEmphasizedSeriesIndexes,\n });\n\n // https://echarts.apache.org/en/api.html#action.highlight\n if (emphasizedSeriesIndexes.length > 0) {\n // Fadeout opacity of all series not closest to cursor.\n chart.dispatchAction({\n type: 'highlight',\n seriesIndex: emphasizedSeriesIndexes,\n notBlur: false, // ensure blur IS triggered, this is default but setting so it is explicit\n escapeConnect: true, // shared crosshair should not emphasize series on adjacent charts\n });\n } else {\n // When no emphasized series with bold text, notBlur allows opacity fadeout to not trigger.\n chart.dispatchAction({\n type: 'highlight',\n seriesIndex: nearbySeriesIndexes,\n notBlur: true, // do not trigger blur state when cursor is not immediately close to any series\n escapeConnect: true, // shared crosshair should not emphasize series on adjacent charts\n });\n }\n }\n\n return currentNearbySeriesData;\n}\n\n/**\n * Uses mouse position to determine whether user is hovering over a chart canvas\n * If yes, convert from pixel values to logical cartesian coordinates and return all nearby series\n */\nexport function getNearbySeriesData({\n mousePos,\n pinnedPos,\n data,\n seriesMapping,\n chart,\n format,\n seriesFormatMap,\n showAllSeries = false,\n}: {\n mousePos: CursorData['coords'];\n pinnedPos: CursorCoordinates | null;\n data: TimeSeries[];\n seriesMapping: TimeChartSeriesMapping;\n chart?: EChartsInstance;\n format?: FormatOptions;\n seriesFormatMap?: Map<string, FormatOptions>;\n showAllSeries?: boolean;\n}): NearbySeriesArray {\n if (chart === undefined || mousePos === null) return EMPTY_TOOLTIP_DATA;\n\n // prevents multiple tooltips showing from adjacent charts unless tooltip is pinned\n let cursorTargetMatchesChart = false;\n if (mousePos.target !== null) {\n const currentParent = (<HTMLElement>mousePos.target).parentElement;\n if (currentParent !== null) {\n const currentGrandparent = currentParent.parentElement;\n if (currentGrandparent !== null) {\n const chartDom = chart.getDom();\n if (chartDom === currentGrandparent) {\n cursorTargetMatchesChart = true;\n }\n }\n }\n }\n\n // allows moving cursor inside tooltip without it fading away\n if (pinnedPos !== null) {\n mousePos = pinnedPos;\n cursorTargetMatchesChart = true;\n }\n\n if (cursorTargetMatchesChart === false || data === null || chart['_model'] === undefined) return EMPTY_TOOLTIP_DATA;\n\n // mousemove position undefined when not hovering over chart canvas\n if (mousePos.plotCanvas.x === undefined || mousePos.plotCanvas.y === undefined) return EMPTY_TOOLTIP_DATA;\n\n const cursorPixelY = mousePos.plotCanvas.y;\n const pointInGrid = getPointInGrid(mousePos.plotCanvas.x, cursorPixelY, chart);\n if (pointInGrid !== null) {\n const chartModel = chart['_model'];\n const yAxisScale = chartModel.getComponent('yAxis').axis.scale;\n const isLogScale = yAxisScale.type === 'log';\n let yInterval = yAxisScale._interval;\n // For logarithmic scales, convert the log interval to actual data range\n if (isLogScale && yAxisScale.base) {\n const logBase = yAxisScale.base;\n const extent = yAxisScale._extent;\n // Calculate actual data range from log extent\n // extent is in log space (e.g., [0, 2] for 10^0 to 10^2)\n const actualMin = logBase ** extent[0];\n const actualMax = logBase ** extent[1];\n // Use a fraction of the actual range as the interval\n yInterval = (actualMax - actualMin) / 100;\n }\n const totalSeries = data.length;\n const yBuffer = getYBuffer({ yInterval, totalSeries, showAllSeries });\n\n // Detect if chart has multiple Y-axes by checking if any series uses yAxisIndex > 0\n const hasMultipleYAxes = seriesMapping.some((series) => series.yAxisIndex !== undefined && series.yAxisIndex > 0);\n\n return checkforNearbyTimeSeries(\n data,\n seriesMapping,\n pointInGrid,\n yBuffer,\n chart,\n format,\n seriesFormatMap,\n hasMultipleYAxes ? cursorPixelY : undefined\n );\n }\n\n // no nearby series found\n return EMPTY_TOOLTIP_DATA;\n}\n\n/*\n * Check if two numbers are within a specified percentage range\n */\nexport function isWithinPercentageRange({\n valueToCheck,\n baseValue,\n percentage,\n}: {\n valueToCheck: number;\n baseValue: number;\n percentage: number;\n}): boolean {\n const range = (percentage / 100) * baseValue;\n const lowerBound = baseValue - range;\n const upperBound = baseValue + range;\n return valueToCheck >= lowerBound && valueToCheck <= upperBound;\n}\n\n/*\n * Get range to check within for nearby series to show in tooltip.\n */\nexport function getYBuffer({\n yInterval,\n totalSeries,\n showAllSeries = false,\n}: {\n yInterval: number;\n totalSeries: number;\n showAllSeries?: boolean;\n}): number {\n if (showAllSeries) {\n return yInterval * 10; // roughly correlates with grid so entire canvas is searched\n }\n // never let nearby series range be less than roughly the size of a single tick\n const yBufferMin = yInterval * 0.3;\n\n // tooltip trigger area gets smaller with more series\n if (totalSeries > SHOW_FEWER_SERIES_LIMIT) {\n const adjustedBuffer = (yInterval * DYNAMIC_NEARBY_SERIES_MULTIPLIER) / totalSeries;\n return Math.max(yBufferMin, adjustedBuffer);\n }\n // increase multiplier to expand nearby series range\n return Math.max(yBufferMin, yInterval * INCREASE_NEARBY_SERIES_MULTIPLIER);\n}\n"],"names":["OPTIMIZED_MODE_SERIES_LIMIT","formatValue","batchDispatchNearbySeriesActions","getPointInGrid","getClosestTimestamp","EMPTY_TOOLTIP_DATA","INCREASE_NEARBY_SERIES_MULTIPLIER","DYNAMIC_NEARBY_SERIES_MULTIPLIER","SHOW_FEWER_SERIES_LIMIT","checkforNearbyTimeSeries","data","seriesMapping","pointInGrid","yBuffer","chart","format","seriesFormatMap","cursorPixelY","currentNearbySeriesData","cursorX","cursorY","dispatchAction","undefined","Array","isArray","nearbySeriesIndexes","emphasizedSeriesIndexes","nonEmphasizedSeriesIndexes","emphasizedDatapoints","duplicateDatapoints","totalSeries","length","yValueCounts","Map","firstTimeSeriesValues","values","closestTimestamp","yBufferPixels","cursorPoint","convertToPixel","bufferPoint","Math","abs","seriesIdx","currentSeries","currentDataset","currentDatasetValues","lineSeries","currentSeriesName","name","toString","seriesId","id","markerColor","color","seriesFormat","get","datumIdx","nearbyTimeSeries","xValue","yValue","isNearby","dataPointPixel","seriesIndex","pixelDistance","minPercentRange","percentRangeToCheck","max","isClosestToCursor","tightBufferPixels","isWithinPercentageRange","valueToCheck","baseValue","percentage","push","duplicateValuesCount","set","dataIndex","seriesName","type","formattedY","date","x","y","legacyCheckforNearbySeries","timeSeries","xAxis","xValueMilliSeconds","notBlur","escapeConnect","getNearbySeriesData","mousePos","pinnedPos","showAllSeries","cursorTargetMatchesChart","target","currentParent","parentElement","currentGrandparent","chartDom","getDom","plotCanvas","chartModel","yAxisScale","getComponent","axis","scale","isLogScale","yInterval","_interval","base","logBase","extent","_extent","actualMin","actualMax","getYBuffer","hasMultipleYAxes","some","series","yAxisIndex","range","lowerBound","upperBound","yBufferMin","adjustedBuffer"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { StackProps } from '@mui/material';
|
|
2
|
-
import { Transform } from '@perses-dev/core';
|
|
3
2
|
import { ReactElement } from 'react';
|
|
3
|
+
import { Transform } from '../model';
|
|
4
4
|
export interface TransformEditorProps extends Omit<StackProps, 'children' | 'value' | 'onChange'> {
|
|
5
5
|
value: Transform;
|
|
6
6
|
onChange: (transform: Transform) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransformEditor.d.ts","sourceRoot":"","sources":["../../src/TransformsEditor/TransformEditor.tsx"],"names":[],"mappings":"AAaA,OAAO,EAKL,UAAU,EAIX,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"TransformEditor.d.ts","sourceRoot":"","sources":["../../src/TransformsEditor/TransformEditor.tsx"],"names":[],"mappings":"AAaA,OAAO,EAKL,UAAU,EAIX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAGrC,OAAO,EAKL,SAAS,EACV,MAAM,UAAU,CAAC;AAiLlB,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,GAAG,UAAU,CAAC;IAC/F,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,CAAC;CAC1C;AAED,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,oBAAoB,GAAG,YAAY,CAwCjG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/TransformsEditor/TransformEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n Autocomplete,\n FormControlLabel,\n MenuItem,\n Stack,\n StackProps,\n Switch,\n Typography,\n TextField as MuiTextField,\n} from '@mui/material';\nimport {\n JoinByColumnValueTransform,\n MergeColumnsTransform,\n MergeIndexedColumnsTransform,\n MergeSeriesTransform,\n Transform,\n} from '@perses-dev/core';\nimport { ReactElement } from 'react';\nimport { TextField } from '../controls';\n\ninterface TransformSpecEditorProps<Spec> {\n value: Spec;\n onChange: (transform: Spec) => void;\n}\n\nfunction JoinByColumnValueTransformEditor({\n value,\n onChange,\n}: TransformSpecEditorProps<JoinByColumnValueTransform>): ReactElement {\n return (\n <Stack direction=\"row\">\n <Autocomplete\n freeSolo\n multiple\n id=\"join-columns\"\n sx={{ width: '100%' }}\n options={[]} // TODO: autofill columns name when query results is available to panel editors\n value={value.spec.columns ?? []}\n renderInput={(params) => <MuiTextField {...params} variant=\"outlined\" label=\"Columns\" required />}\n onChange={(_, columns) => {\n onChange({\n ...value,\n spec: {\n ...value.spec,\n columns: columns,\n },\n });\n }}\n />\n <FormControlLabel\n label=\"Enabled\"\n labelPlacement=\"start\"\n control={\n <Switch\n value={!value.spec.disabled}\n checked={!value.spec.disabled}\n onChange={(e) =>\n onChange({\n ...value,\n spec: { ...value.spec, disabled: !e.target.checked },\n })\n }\n />\n }\n />\n </Stack>\n );\n}\n\nfunction MergeColumnsTransformEditor({\n value,\n onChange,\n}: TransformSpecEditorProps<MergeColumnsTransform>): ReactElement {\n return (\n <Stack direction=\"row\" gap={1} alignItems=\"center\">\n <Autocomplete\n freeSolo\n multiple\n id=\"merge-columns-columns\"\n sx={{ width: '100%' }}\n options={[]}\n value={value.spec.columns ?? []}\n renderInput={(params) => <MuiTextField {...params} variant=\"outlined\" label=\"Columns\" required />}\n onChange={(_, columns) => {\n onChange({\n ...value,\n spec: {\n ...value.spec,\n columns: columns,\n },\n });\n }}\n />\n\n <TextField\n id=\"merge-columns-name\"\n variant=\"outlined\"\n label=\"Output Name\"\n value={value.spec.name ?? ''}\n sx={{ width: '100%' }}\n onChange={(name) => {\n onChange({\n ...value,\n spec: {\n ...value.spec,\n name: name,\n },\n });\n }}\n required\n />\n <FormControlLabel\n label=\"Enabled\"\n labelPlacement=\"start\"\n control={\n <Switch\n value={!value.spec.disabled}\n checked={!value.spec.disabled}\n onChange={(e) =>\n onChange({\n ...value,\n spec: { ...value.spec, disabled: !e.target.checked },\n })\n }\n />\n }\n />\n </Stack>\n );\n}\n\nfunction MergeIndexedColumnsTransformEditor({\n value,\n onChange,\n}: TransformSpecEditorProps<MergeIndexedColumnsTransform>): ReactElement {\n return (\n <Stack direction=\"row\">\n <TextField\n id=\"merge-indexed-columns\"\n variant=\"outlined\"\n label=\"Column\"\n placeholder=\"Example: 'value' for merging 'value #1', 'value #2' and 'value #...'\"\n value={value.spec.column ?? ''}\n sx={{ width: '100%' }}\n onChange={(column) => {\n onChange({\n ...value,\n spec: { ...value.spec, column: column },\n });\n }}\n required\n />\n <FormControlLabel\n label=\"Enabled\"\n labelPlacement=\"start\"\n control={\n <Switch\n value={!value.spec.disabled}\n checked={!value.spec.disabled}\n onChange={(e) =>\n onChange({\n ...value,\n spec: { ...value.spec, disabled: !e.target.checked },\n })\n }\n />\n }\n />\n </Stack>\n );\n}\n\nfunction MergeSeriesTransformEditor({ value, onChange }: TransformSpecEditorProps<MergeSeriesTransform>): ReactElement {\n return (\n <Stack direction=\"row\">\n <FormControlLabel\n label=\"Enabled\"\n labelPlacement=\"start\"\n control={\n <Switch\n value={!value.spec.disabled}\n checked={!value.spec.disabled}\n onChange={(e) =>\n onChange({\n ...value,\n spec: { ...value.spec, disabled: !e.target.checked },\n })\n }\n />\n }\n />\n </Stack>\n );\n}\n\nexport interface TransformEditorProps extends Omit<StackProps, 'children' | 'value' | 'onChange'> {\n value: Transform;\n onChange: (transform: Transform) => void;\n}\n\nexport function TransformEditor({ value, onChange, ...props }: TransformEditorProps): ReactElement {\n return (\n <Stack gap={2} sx={{ width: '100%' }} mt={1} {...props}>\n <TextField\n select\n label=\"Kind\"\n value={value.kind}\n onChange={(kind) => onChange({ ...value, kind: kind as unknown as Transform['kind'] } as Transform)}\n >\n <MenuItem value=\"JoinByColumnValue\">\n <Stack>\n <Typography>Join by column value</Typography>\n <Typography variant=\"caption\">Regroup rows with equal cell value in a column</Typography>\n </Stack>\n </MenuItem>\n <MenuItem value=\"MergeColumns\">\n <Stack>\n <Typography>Merge columns</Typography>\n <Typography variant=\"caption\">Multiple columns are merged to one column</Typography>\n </Stack>\n </MenuItem>\n <MenuItem value=\"MergeIndexedColumns\">\n <Stack>\n <Typography>Merge indexed columns</Typography>\n <Typography variant=\"caption\">Indexed columns are merged to one column</Typography>\n </Stack>\n </MenuItem>\n <MenuItem value=\"MergeSeries\">\n <Stack>\n <Typography>Merge series</Typography>\n <Typography variant=\"caption\">Series will be merged by their labels</Typography>\n </Stack>\n </MenuItem>\n </TextField>\n {value.kind === 'JoinByColumnValue' && <JoinByColumnValueTransformEditor value={value} onChange={onChange} />}\n {value.kind === 'MergeColumns' && <MergeColumnsTransformEditor value={value} onChange={onChange} />}\n {value.kind === 'MergeIndexedColumns' && <MergeIndexedColumnsTransformEditor value={value} onChange={onChange} />}\n {value.kind === 'MergeSeries' && <MergeSeriesTransformEditor value={value} onChange={onChange} />}\n </Stack>\n );\n}\n"],"names":["Autocomplete","FormControlLabel","MenuItem","Stack","Switch","Typography","TextField","MuiTextField","JoinByColumnValueTransformEditor","value","onChange","direction","freeSolo","multiple","id","sx","width","options","spec","columns","renderInput","params","variant","label","required","_","labelPlacement","control","disabled","checked","e","target","MergeColumnsTransformEditor","gap","alignItems","name","MergeIndexedColumnsTransformEditor","placeholder","column","MergeSeriesTransformEditor","TransformEditor","props","mt","select","kind"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/TransformsEditor/TransformEditor.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport {\n Autocomplete,\n FormControlLabel,\n MenuItem,\n Stack,\n StackProps,\n Switch,\n Typography,\n TextField as MuiTextField,\n} from '@mui/material';\n\nimport { ReactElement } from 'react';\n\nimport { TextField } from '../controls';\nimport {\n JoinByColumnValueTransform,\n MergeColumnsTransform,\n MergeIndexedColumnsTransform,\n MergeSeriesTransform,\n Transform,\n} from '../model';\n\ninterface TransformSpecEditorProps<Spec> {\n value: Spec;\n onChange: (transform: Spec) => void;\n}\n\nfunction JoinByColumnValueTransformEditor({\n value,\n onChange,\n}: TransformSpecEditorProps<JoinByColumnValueTransform>): ReactElement {\n return (\n <Stack direction=\"row\">\n <Autocomplete\n freeSolo\n multiple\n id=\"join-columns\"\n sx={{ width: '100%' }}\n options={[]} // TODO: autofill columns name when query results is available to panel editors\n value={value.spec.columns ?? []}\n renderInput={(params) => <MuiTextField {...params} variant=\"outlined\" label=\"Columns\" required />}\n onChange={(_, columns) => {\n onChange({\n ...value,\n spec: {\n ...value.spec,\n columns: columns,\n },\n });\n }}\n />\n <FormControlLabel\n label=\"Enabled\"\n labelPlacement=\"start\"\n control={\n <Switch\n value={!value.spec.disabled}\n checked={!value.spec.disabled}\n onChange={(e) =>\n onChange({\n ...value,\n spec: { ...value.spec, disabled: !e.target.checked },\n })\n }\n />\n }\n />\n </Stack>\n );\n}\n\nfunction MergeColumnsTransformEditor({\n value,\n onChange,\n}: TransformSpecEditorProps<MergeColumnsTransform>): ReactElement {\n return (\n <Stack direction=\"row\" gap={1} alignItems=\"center\">\n <Autocomplete\n freeSolo\n multiple\n id=\"merge-columns-columns\"\n sx={{ width: '100%' }}\n options={[]}\n value={value.spec.columns ?? []}\n renderInput={(params) => <MuiTextField {...params} variant=\"outlined\" label=\"Columns\" required />}\n onChange={(_, columns) => {\n onChange({\n ...value,\n spec: {\n ...value.spec,\n columns: columns,\n },\n });\n }}\n />\n\n <TextField\n id=\"merge-columns-name\"\n variant=\"outlined\"\n label=\"Output Name\"\n value={value.spec.name ?? ''}\n sx={{ width: '100%' }}\n onChange={(name) => {\n onChange({\n ...value,\n spec: {\n ...value.spec,\n name: name,\n },\n });\n }}\n required\n />\n <FormControlLabel\n label=\"Enabled\"\n labelPlacement=\"start\"\n control={\n <Switch\n value={!value.spec.disabled}\n checked={!value.spec.disabled}\n onChange={(e) =>\n onChange({\n ...value,\n spec: { ...value.spec, disabled: !e.target.checked },\n })\n }\n />\n }\n />\n </Stack>\n );\n}\n\nfunction MergeIndexedColumnsTransformEditor({\n value,\n onChange,\n}: TransformSpecEditorProps<MergeIndexedColumnsTransform>): ReactElement {\n return (\n <Stack direction=\"row\">\n <TextField\n id=\"merge-indexed-columns\"\n variant=\"outlined\"\n label=\"Column\"\n placeholder=\"Example: 'value' for merging 'value #1', 'value #2' and 'value #...'\"\n value={value.spec.column ?? ''}\n sx={{ width: '100%' }}\n onChange={(column) => {\n onChange({\n ...value,\n spec: { ...value.spec, column: column },\n });\n }}\n required\n />\n <FormControlLabel\n label=\"Enabled\"\n labelPlacement=\"start\"\n control={\n <Switch\n value={!value.spec.disabled}\n checked={!value.spec.disabled}\n onChange={(e) =>\n onChange({\n ...value,\n spec: { ...value.spec, disabled: !e.target.checked },\n })\n }\n />\n }\n />\n </Stack>\n );\n}\n\nfunction MergeSeriesTransformEditor({ value, onChange }: TransformSpecEditorProps<MergeSeriesTransform>): ReactElement {\n return (\n <Stack direction=\"row\">\n <FormControlLabel\n label=\"Enabled\"\n labelPlacement=\"start\"\n control={\n <Switch\n value={!value.spec.disabled}\n checked={!value.spec.disabled}\n onChange={(e) =>\n onChange({\n ...value,\n spec: { ...value.spec, disabled: !e.target.checked },\n })\n }\n />\n }\n />\n </Stack>\n );\n}\n\nexport interface TransformEditorProps extends Omit<StackProps, 'children' | 'value' | 'onChange'> {\n value: Transform;\n onChange: (transform: Transform) => void;\n}\n\nexport function TransformEditor({ value, onChange, ...props }: TransformEditorProps): ReactElement {\n return (\n <Stack gap={2} sx={{ width: '100%' }} mt={1} {...props}>\n <TextField\n select\n label=\"Kind\"\n value={value.kind}\n onChange={(kind) => onChange({ ...value, kind: kind as unknown as Transform['kind'] } as Transform)}\n >\n <MenuItem value=\"JoinByColumnValue\">\n <Stack>\n <Typography>Join by column value</Typography>\n <Typography variant=\"caption\">Regroup rows with equal cell value in a column</Typography>\n </Stack>\n </MenuItem>\n <MenuItem value=\"MergeColumns\">\n <Stack>\n <Typography>Merge columns</Typography>\n <Typography variant=\"caption\">Multiple columns are merged to one column</Typography>\n </Stack>\n </MenuItem>\n <MenuItem value=\"MergeIndexedColumns\">\n <Stack>\n <Typography>Merge indexed columns</Typography>\n <Typography variant=\"caption\">Indexed columns are merged to one column</Typography>\n </Stack>\n </MenuItem>\n <MenuItem value=\"MergeSeries\">\n <Stack>\n <Typography>Merge series</Typography>\n <Typography variant=\"caption\">Series will be merged by their labels</Typography>\n </Stack>\n </MenuItem>\n </TextField>\n {value.kind === 'JoinByColumnValue' && <JoinByColumnValueTransformEditor value={value} onChange={onChange} />}\n {value.kind === 'MergeColumns' && <MergeColumnsTransformEditor value={value} onChange={onChange} />}\n {value.kind === 'MergeIndexedColumns' && <MergeIndexedColumnsTransformEditor value={value} onChange={onChange} />}\n {value.kind === 'MergeSeries' && <MergeSeriesTransformEditor value={value} onChange={onChange} />}\n </Stack>\n );\n}\n"],"names":["Autocomplete","FormControlLabel","MenuItem","Stack","Switch","Typography","TextField","MuiTextField","JoinByColumnValueTransformEditor","value","onChange","direction","freeSolo","multiple","id","sx","width","options","spec","columns","renderInput","params","variant","label","required","_","labelPlacement","control","disabled","checked","e","target","MergeColumnsTransformEditor","gap","alignItems","name","MergeIndexedColumnsTransformEditor","placeholder","column","MergeSeriesTransformEditor","TransformEditor","props","mt","select","kind"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TransformEditorContainer.d.ts","sourceRoot":"","sources":["../../src/TransformsEditor/TransformEditorContainer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TransformEditorContainer.d.ts","sourceRoot":"","sources":["../../src/TransformsEditor/TransformEditorContainer.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,EAAmB,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE1E,MAAM,WAAW,6BAA8B,SAAQ,oBAAoB;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,wBAAgB,wBAAwB,CAAC,EACvC,KAAK,EACL,KAAK,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,6BAA6B,GAAG,YAAY,CAsD9C"}
|
|
@@ -17,7 +17,7 @@ import ChevronDown from 'mdi-material-ui/ChevronDown';
|
|
|
17
17
|
import EyeOffIcon from 'mdi-material-ui/EyeOffOutline';
|
|
18
18
|
import EyeIcon from 'mdi-material-ui/EyeOutline';
|
|
19
19
|
import DeleteIcon from 'mdi-material-ui/DeleteOutline';
|
|
20
|
-
import { TRANSFORM_TEXT } from '
|
|
20
|
+
import { TRANSFORM_TEXT } from '../model';
|
|
21
21
|
import { TransformEditor } from './TransformEditor';
|
|
22
22
|
export function TransformEditorContainer({ index, value, isCollapsed, onChange, onCollapse, onDelete, ...props }) {
|
|
23
23
|
function handleTransformDisable() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/TransformsEditor/TransformEditorContainer.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Divider, IconButton, Stack, Tooltip, Typography } from '@mui/material';\nimport ChevronRight from 'mdi-material-ui/ChevronRight';\nimport ChevronDown from 'mdi-material-ui/ChevronDown';\nimport EyeOffIcon from 'mdi-material-ui/EyeOffOutline';\nimport EyeIcon from 'mdi-material-ui/EyeOutline';\nimport DeleteIcon from 'mdi-material-ui/DeleteOutline';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/TransformsEditor/TransformEditorContainer.tsx"],"sourcesContent":["// Copyright The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { Divider, IconButton, Stack, Tooltip, Typography } from '@mui/material';\nimport ChevronRight from 'mdi-material-ui/ChevronRight';\nimport ChevronDown from 'mdi-material-ui/ChevronDown';\nimport EyeOffIcon from 'mdi-material-ui/EyeOffOutline';\nimport EyeIcon from 'mdi-material-ui/EyeOutline';\nimport DeleteIcon from 'mdi-material-ui/DeleteOutline';\nimport { ReactElement } from 'react';\nimport { Transform, TRANSFORM_TEXT } from '../model';\nimport { TransformEditor, TransformEditorProps } from './TransformEditor';\n\nexport interface TransformEditorContainerProps extends TransformEditorProps {\n index?: number;\n isCollapsed: boolean;\n onCollapse: (collapsed: boolean) => void;\n onDelete: () => void;\n}\n\nexport function TransformEditorContainer({\n index,\n value,\n isCollapsed,\n onChange,\n onCollapse,\n onDelete,\n ...props\n}: TransformEditorContainerProps): ReactElement {\n function handleTransformDisable(): void {\n onChange({ ...value, spec: { ...value.spec, disabled: !value.spec?.disabled } } as Transform);\n }\n\n return (\n <Stack {...props}>\n <Stack\n direction=\"row\"\n alignItems=\"center\"\n borderBottom={1}\n borderColor={(theme) => theme.palette.divider}\n justifyContent=\"space-between\"\n gap={4}\n >\n <Stack direction=\"row\" gap={1}>\n <IconButton data-testid={`transform-toggle#${index}`} size=\"small\" onClick={() => onCollapse(!isCollapsed)}>\n {isCollapsed ? <ChevronRight /> : <ChevronDown />}\n </IconButton>\n <Typography variant=\"overline\" component=\"h4\" sx={{ textTransform: 'none' }}>\n {value.kind ? (\n <span>\n <strong>{TRANSFORM_TEXT[value.kind]}</strong>\n </span>\n ) : (\n <strong>Select a transformation kind</strong>\n )}\n </Typography>\n </Stack>\n\n <Stack direction=\"row\" gap={1}>\n {isCollapsed && (\n <>\n <Tooltip\n title={value.spec?.disabled ? 'Enable transformation' : 'Disable transformation'}\n placement=\"top\"\n >\n <IconButton size=\"small\" sx={{ marginLeft: 'auto' }} onClick={handleTransformDisable}>\n {value.spec?.disabled ? <EyeOffIcon /> : <EyeIcon />}\n </IconButton>\n </Tooltip>\n <Divider flexItem orientation=\"vertical\" variant=\"middle\" />\n </>\n )}\n <Tooltip title=\"Remove transformation\" placement=\"top\">\n <IconButton size=\"small\" sx={{ marginLeft: 'auto' }} onClick={onDelete}>\n <DeleteIcon />\n </IconButton>\n </Tooltip>\n </Stack>\n </Stack>\n {!isCollapsed && <TransformEditor value={value} onChange={onChange} />}\n </Stack>\n );\n}\n"],"names":["Divider","IconButton","Stack","Tooltip","Typography","ChevronRight","ChevronDown","EyeOffIcon","EyeIcon","DeleteIcon","TRANSFORM_TEXT","TransformEditor","TransformEditorContainer","index","value","isCollapsed","onChange","onCollapse","onDelete","props","handleTransformDisable","spec","disabled","direction","alignItems","borderBottom","borderColor","theme","palette","divider","justifyContent","gap","data-testid","size","onClick","variant","component","sx","textTransform","kind","span","strong","title","placement","marginLeft","flexItem","orientation"],"mappings":"AAAA,+BAA+B;AAC/B,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,OAAO,EAAEC,UAAU,EAAEC,KAAK,EAAEC,OAAO,EAAEC,UAAU,QAAQ,gBAAgB;AAChF,OAAOC,kBAAkB,+BAA+B;AACxD,OAAOC,iBAAiB,8BAA8B;AACtD,OAAOC,gBAAgB,gCAAgC;AACvD,OAAOC,aAAa,6BAA6B;AACjD,OAAOC,gBAAgB,gCAAgC;AAEvD,SAAoBC,cAAc,QAAQ,WAAW;AACrD,SAASC,eAAe,QAA8B,oBAAoB;AAS1E,OAAO,SAASC,yBAAyB,EACvCC,KAAK,EACLC,KAAK,EACLC,WAAW,EACXC,QAAQ,EACRC,UAAU,EACVC,QAAQ,EACR,GAAGC,OAC2B;IAC9B,SAASC;QACPJ,SAAS;YAAE,GAAGF,KAAK;YAAEO,MAAM;gBAAE,GAAGP,MAAMO,IAAI;gBAAEC,UAAU,CAACR,MAAMO,IAAI,EAAEC;YAAS;QAAE;IAChF;IAEA,qBACE,MAACpB;QAAO,GAAGiB,KAAK;;0BACd,MAACjB;gBACCqB,WAAU;gBACVC,YAAW;gBACXC,cAAc;gBACdC,aAAa,CAACC,QAAUA,MAAMC,OAAO,CAACC,OAAO;gBAC7CC,gBAAe;gBACfC,KAAK;;kCAEL,MAAC7B;wBAAMqB,WAAU;wBAAMQ,KAAK;;0CAC1B,KAAC9B;gCAAW+B,eAAa,CAAC,iBAAiB,EAAEnB,OAAO;gCAAEoB,MAAK;gCAAQC,SAAS,IAAMjB,WAAW,CAACF;0CAC3FA,4BAAc,KAACV,kCAAkB,KAACC;;0CAErC,KAACF;gCAAW+B,SAAQ;gCAAWC,WAAU;gCAAKC,IAAI;oCAAEC,eAAe;gCAAO;0CACvExB,MAAMyB,IAAI,iBACT,KAACC;8CACC,cAAA,KAACC;kDAAQ/B,cAAc,CAACI,MAAMyB,IAAI,CAAC;;mDAGrC,KAACE;8CAAO;;;;;kCAKd,MAACvC;wBAAMqB,WAAU;wBAAMQ,KAAK;;4BACzBhB,6BACC;;kDACE,KAACZ;wCACCuC,OAAO5B,MAAMO,IAAI,EAAEC,WAAW,0BAA0B;wCACxDqB,WAAU;kDAEV,cAAA,KAAC1C;4CAAWgC,MAAK;4CAAQI,IAAI;gDAAEO,YAAY;4CAAO;4CAAGV,SAASd;sDAC3DN,MAAMO,IAAI,EAAEC,yBAAW,KAACf,gCAAgB,KAACC;;;kDAG9C,KAACR;wCAAQ6C,QAAQ;wCAACC,aAAY;wCAAWX,SAAQ;;;;0CAGrD,KAAChC;gCAAQuC,OAAM;gCAAwBC,WAAU;0CAC/C,cAAA,KAAC1C;oCAAWgC,MAAK;oCAAQI,IAAI;wCAAEO,YAAY;oCAAO;oCAAGV,SAAShB;8CAC5D,cAAA,KAACT;;;;;;;YAKR,CAACM,6BAAe,KAACJ;gBAAgBG,OAAOA;gBAAOE,UAAUA;;;;AAGhE"}
|