@cratis/components 0.1.9 → 0.1.12
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/cjs/CommandForm/CommandFormFields.js +9 -3
- package/dist/cjs/CommandForm/CommandFormFields.js.map +1 -1
- package/dist/cjs/CommandForm/ValidationMessage.js +24 -0
- package/dist/cjs/CommandForm/ValidationMessage.js.map +1 -0
- package/dist/cjs/CommandForm/asCommandFormField.js +47 -0
- package/dist/cjs/CommandForm/asCommandFormField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/CheckboxField.js +13 -0
- package/dist/cjs/CommandForm/fields/CheckboxField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/DropdownField.js +13 -0
- package/dist/cjs/CommandForm/fields/DropdownField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/InputTextField.js +13 -0
- package/dist/cjs/CommandForm/fields/InputTextField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/NumberField.js +13 -0
- package/dist/cjs/CommandForm/fields/NumberField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/SliderField.js +17 -0
- package/dist/cjs/CommandForm/fields/SliderField.js.map +1 -0
- package/dist/cjs/CommandForm/fields/TextAreaField.js +13 -0
- package/dist/cjs/CommandForm/fields/TextAreaField.js.map +1 -0
- package/dist/cjs/CommandForm/index.js +15 -7
- package/dist/cjs/CommandForm/index.js.map +1 -1
- package/dist/cjs/PivotViewer/PivotViewer.css +1258 -0
- package/dist/cjs/PivotViewer/PivotViewer.js +14 -0
- package/dist/cjs/PivotViewer/PivotViewer.js.map +1 -1
- package/dist/cjs/PivotViewer/components/PivotCanvas.js +33 -10
- package/dist/cjs/PivotViewer/components/PivotCanvas.js.map +1 -1
- package/dist/cjs/PivotViewer/components/PivotViewerMain.js +1 -1
- package/dist/cjs/PivotViewer/components/PivotViewerMain.js.map +1 -1
- package/dist/cjs/PivotViewer/components/Spinner.css +77 -0
- package/dist/cjs/PivotViewer/components/pivot/sprites.js +79 -15
- package/dist/cjs/PivotViewer/components/pivot/sprites.js.map +1 -1
- package/dist/cjs/PivotViewer/components/pivot/visibility.js +36 -10
- package/dist/cjs/PivotViewer/components/pivot/visibility.js.map +1 -1
- package/dist/cjs/PivotViewer/engine/layout.js +2 -1
- package/dist/cjs/PivotViewer/engine/layout.js.map +1 -1
- package/dist/cjs/PivotViewer/hooks/usePivotEngine.js +37 -2
- package/dist/cjs/PivotViewer/hooks/usePivotEngine.js.map +1 -1
- package/dist/cjs/PivotViewer/index.js +3 -0
- package/dist/cjs/PivotViewer/index.js.map +1 -1
- package/dist/cjs/PivotViewer/types.js +22 -0
- package/dist/cjs/PivotViewer/types.js.map +1 -0
- package/dist/cjs/TimeMachine/EventsView.css +213 -0
- package/dist/cjs/TimeMachine/TimeMachine.css +567 -0
- package/dist/cjs/TimeMachine/TimeMachine.js +8 -3
- package/dist/cjs/TimeMachine/TimeMachine.js.map +1 -1
- package/dist/esm/CommandForm/CommandForm.stories.d.ts +1 -0
- package/dist/esm/CommandForm/CommandForm.stories.d.ts.map +1 -1
- package/dist/esm/CommandForm/CommandForm.stories.js +34 -1
- package/dist/esm/CommandForm/CommandForm.stories.js.map +1 -1
- package/dist/esm/CommandForm/CommandFormFields.d.ts.map +1 -1
- package/dist/esm/CommandForm/CommandFormFields.js +9 -3
- package/dist/esm/CommandForm/CommandFormFields.js.map +1 -1
- package/dist/esm/CommandForm/UserRegistrationCommand.d.ts +63 -0
- package/dist/esm/CommandForm/UserRegistrationCommand.d.ts.map +1 -0
- package/dist/esm/CommandForm/UserRegistrationCommand.js +143 -0
- package/dist/esm/CommandForm/UserRegistrationCommand.js.map +1 -0
- package/dist/esm/CommandForm/ValidationMessage.d.ts +8 -0
- package/dist/esm/CommandForm/ValidationMessage.d.ts.map +1 -0
- package/dist/esm/CommandForm/ValidationMessage.js +22 -0
- package/dist/esm/CommandForm/ValidationMessage.js.map +1 -0
- package/dist/esm/CommandForm/asCommandFormField.d.ts +32 -0
- package/dist/esm/CommandForm/asCommandFormField.d.ts.map +1 -0
- package/dist/esm/CommandForm/asCommandFormField.js +45 -0
- package/dist/esm/CommandForm/asCommandFormField.js.map +1 -0
- package/dist/esm/CommandForm/fields/CheckboxField.d.ts +10 -0
- package/dist/esm/CommandForm/fields/CheckboxField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/CheckboxField.js +11 -0
- package/dist/esm/CommandForm/fields/CheckboxField.js.map +1 -0
- package/dist/esm/CommandForm/fields/DropdownField.d.ts +15 -0
- package/dist/esm/CommandForm/fields/DropdownField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/DropdownField.js +11 -0
- package/dist/esm/CommandForm/fields/DropdownField.js.map +1 -0
- package/dist/esm/CommandForm/fields/InputTextField.d.ts +11 -0
- package/dist/esm/CommandForm/fields/InputTextField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/InputTextField.js +11 -0
- package/dist/esm/CommandForm/fields/InputTextField.js.map +1 -0
- package/dist/esm/CommandForm/fields/NumberField.d.ts +13 -0
- package/dist/esm/CommandForm/fields/NumberField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/NumberField.js +11 -0
- package/dist/esm/CommandForm/fields/NumberField.js.map +1 -0
- package/dist/esm/CommandForm/fields/SliderField.d.ts +12 -0
- package/dist/esm/CommandForm/fields/SliderField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/SliderField.js +15 -0
- package/dist/esm/CommandForm/fields/SliderField.js.map +1 -0
- package/dist/esm/CommandForm/fields/TextAreaField.d.ts +12 -0
- package/dist/esm/CommandForm/fields/TextAreaField.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/TextAreaField.js +11 -0
- package/dist/esm/CommandForm/fields/TextAreaField.js.map +1 -0
- package/dist/esm/CommandForm/fields/index.d.ts +7 -0
- package/dist/esm/CommandForm/fields/index.d.ts.map +1 -0
- package/dist/esm/CommandForm/fields/index.js +7 -0
- package/dist/esm/CommandForm/fields/index.js.map +1 -0
- package/dist/esm/CommandForm/index.d.ts +3 -4
- package/dist/esm/CommandForm/index.d.ts.map +1 -1
- package/dist/esm/CommandForm/index.js +8 -4
- package/dist/esm/CommandForm/index.js.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.css +1258 -0
- package/dist/esm/PivotViewer/PivotViewer.d.ts.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.js +14 -0
- package/dist/esm/PivotViewer/PivotViewer.js.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.stories.d.ts +1 -0
- package/dist/esm/PivotViewer/PivotViewer.stories.d.ts.map +1 -1
- package/dist/esm/PivotViewer/PivotViewer.stories.js +43 -3
- package/dist/esm/PivotViewer/PivotViewer.stories.js.map +1 -1
- package/dist/esm/PivotViewer/components/PivotCanvas.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/PivotCanvas.js +33 -10
- package/dist/esm/PivotViewer/components/PivotCanvas.js.map +1 -1
- package/dist/esm/PivotViewer/components/PivotViewerMain.js +1 -1
- package/dist/esm/PivotViewer/components/PivotViewerMain.js.map +1 -1
- package/dist/esm/PivotViewer/components/Spinner.css +77 -0
- package/dist/esm/PivotViewer/components/pivot/sprites.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/sprites.js +79 -15
- package/dist/esm/PivotViewer/components/pivot/sprites.js.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/visibility.d.ts.map +1 -1
- package/dist/esm/PivotViewer/components/pivot/visibility.js +36 -10
- package/dist/esm/PivotViewer/components/pivot/visibility.js.map +1 -1
- package/dist/esm/PivotViewer/engine/layout.js +2 -1
- package/dist/esm/PivotViewer/engine/layout.js.map +1 -1
- package/dist/esm/PivotViewer/engine/pivot.worker.d.ts.map +1 -1
- package/dist/esm/PivotViewer/engine/pivot.worker.js +22 -7
- package/dist/esm/PivotViewer/engine/pivot.worker.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/useFilteredData.d.ts +2 -2
- package/dist/esm/PivotViewer/hooks/useFilteredData.d.ts.map +1 -1
- package/dist/esm/PivotViewer/hooks/useFilteredData.js +4 -2
- package/dist/esm/PivotViewer/hooks/useFilteredData.js.map +1 -1
- package/dist/esm/PivotViewer/hooks/usePivotEngine.d.ts.map +1 -1
- package/dist/esm/PivotViewer/hooks/usePivotEngine.js +37 -2
- package/dist/esm/PivotViewer/hooks/usePivotEngine.js.map +1 -1
- package/dist/esm/PivotViewer/index.d.ts +2 -1
- package/dist/esm/PivotViewer/index.d.ts.map +1 -1
- package/dist/esm/PivotViewer/index.js +1 -0
- package/dist/esm/PivotViewer/index.js.map +1 -1
- package/dist/esm/PivotViewer/types.d.ts +4 -1
- package/dist/esm/PivotViewer/types.d.ts.map +1 -1
- package/dist/esm/PivotViewer/types.js +19 -2
- package/dist/esm/PivotViewer/types.js.map +1 -1
- package/dist/esm/TimeMachine/EventsView.css +213 -0
- package/dist/esm/TimeMachine/TimeMachine.css +567 -0
- package/dist/esm/TimeMachine/TimeMachine.d.ts.map +1 -1
- package/dist/esm/TimeMachine/TimeMachine.js +8 -3
- package/dist/esm/TimeMachine/TimeMachine.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +31 -32
- package/.storybook/main.ts +0 -24
- package/CommandDialog/CommandDialog.stories.tsx +0 -25
- package/CommandDialog/CommandDialog.tsx +0 -161
- package/CommandDialog/index.ts +0 -4
- package/CommandForm/CommandForm.stories.tsx +0 -24
- package/CommandForm/CommandForm.tsx +0 -266
- package/CommandForm/CommandFormField.tsx +0 -27
- package/CommandForm/CommandFormFields.tsx +0 -142
- package/CommandForm/DatePickerField.tsx +0 -57
- package/CommandForm/DropdownField.tsx +0 -65
- package/CommandForm/InputTextField.tsx +0 -62
- package/CommandForm/SliderField.tsx +0 -68
- package/CommandForm/index.ts +0 -10
- package/Common/ErrorBoundary.stories.tsx +0 -10
- package/Common/ErrorBoundary.tsx +0 -41
- package/Common/FormElement.stories.tsx +0 -10
- package/Common/FormElement.tsx +0 -20
- package/Common/Page.stories.tsx +0 -10
- package/Common/Page.tsx +0 -21
- package/Common/index.ts +0 -6
- package/DataPage/DataPage.stories.tsx +0 -10
- package/DataPage/DataPage.tsx +0 -191
- package/DataPage/index.ts +0 -4
- package/DataTables/DataTableForObservableQuery.stories.tsx +0 -10
- package/DataTables/DataTableForObservableQuery.tsx +0 -97
- package/DataTables/DataTableForQuery.stories.tsx +0 -10
- package/DataTables/DataTableForQuery.tsx +0 -97
- package/DataTables/index.ts +0 -5
- package/Dialogs/BusyIndicatorDialog.stories.tsx +0 -26
- package/Dialogs/BusyIndicatorDialog.tsx +0 -26
- package/Dialogs/ConfirmationDialog.stories.tsx +0 -36
- package/Dialogs/ConfirmationDialog.tsx +0 -75
- package/Dialogs/index.ts +0 -5
- package/Dropdown/Dropdown.tsx +0 -23
- package/Dropdown/index.ts +0 -4
- package/PivotViewer/PivotViewer.stories.tsx +0 -24
- package/PivotViewer/PivotViewer.tsx +0 -791
- package/PivotViewer/components/AxisLabels.tsx +0 -69
- package/PivotViewer/components/DetailPanel.tsx +0 -108
- package/PivotViewer/components/FilterPanel.tsx +0 -189
- package/PivotViewer/components/FilterPanelContainer.tsx +0 -10
- package/PivotViewer/components/PivotCanvas.tsx +0 -660
- package/PivotViewer/components/PivotViewerMain.tsx +0 -229
- package/PivotViewer/components/RangeHistogramFilter.tsx +0 -220
- package/PivotViewer/components/Spinner.tsx +0 -21
- package/PivotViewer/components/Toolbar.tsx +0 -130
- package/PivotViewer/components/ToolbarContainer.tsx +0 -10
- package/PivotViewer/components/index.ts +0 -12
- package/PivotViewer/components/pivot/animation.ts +0 -108
- package/PivotViewer/components/pivot/buckets.ts +0 -152
- package/PivotViewer/components/pivot/colorResolver.ts +0 -67
- package/PivotViewer/components/pivot/constants.ts +0 -46
- package/PivotViewer/components/pivot/sprites.ts +0 -265
- package/PivotViewer/components/pivot/visibility.ts +0 -319
- package/PivotViewer/constants.ts +0 -9
- package/PivotViewer/engine/layout.ts +0 -149
- package/PivotViewer/engine/pivot.worker.ts +0 -86
- package/PivotViewer/engine/store.ts +0 -437
- package/PivotViewer/engine/types.ts +0 -255
- package/PivotViewer/hooks/index.ts +0 -13
- package/PivotViewer/hooks/useContainerDimensions.ts +0 -45
- package/PivotViewer/hooks/useDimensionState.ts +0 -53
- package/PivotViewer/hooks/useFilterOptions.ts +0 -36
- package/PivotViewer/hooks/useFilterPanelDrag.ts +0 -49
- package/PivotViewer/hooks/useFilterState.ts +0 -106
- package/PivotViewer/hooks/useFilteredData.ts +0 -119
- package/PivotViewer/hooks/usePanning.ts +0 -163
- package/PivotViewer/hooks/usePivotEngine.ts +0 -252
- package/PivotViewer/hooks/useSelectedItem.ts +0 -402
- package/PivotViewer/hooks/useWheelZoom.ts +0 -114
- package/PivotViewer/hooks/useZoomState.ts +0 -34
- package/PivotViewer/index.ts +0 -7
- package/PivotViewer/types.ts +0 -59
- package/PivotViewer/utils/animations.ts +0 -249
- package/PivotViewer/utils/constants.ts +0 -20
- package/PivotViewer/utils/index.ts +0 -6
- package/PivotViewer/utils/selection.ts +0 -292
- package/PivotViewer/utils/utils.ts +0 -259
- package/TimeMachine/EventsView.stories.tsx +0 -10
- package/TimeMachine/EventsView.tsx +0 -119
- package/TimeMachine/Properties.stories.tsx +0 -10
- package/TimeMachine/Properties.tsx +0 -98
- package/TimeMachine/ReadModelView.stories.tsx +0 -10
- package/TimeMachine/ReadModelView.tsx +0 -143
- package/TimeMachine/TimeMachine.stories.tsx +0 -10
- package/TimeMachine/TimeMachine.tsx +0 -244
- package/TimeMachine/index.ts +0 -8
- package/TimeMachine/types.ts +0 -23
- package/dist/cjs/CommandForm/DatePickerField.js +0 -31
- package/dist/cjs/CommandForm/DatePickerField.js.map +0 -1
- package/dist/cjs/CommandForm/DropdownField.js +0 -31
- package/dist/cjs/CommandForm/DropdownField.js.map +0 -1
- package/dist/cjs/CommandForm/InputTextField.js +0 -32
- package/dist/cjs/CommandForm/InputTextField.js.map +0 -1
- package/dist/cjs/CommandForm/SliderField.js +0 -34
- package/dist/cjs/CommandForm/SliderField.js.map +0 -1
- package/dist/esm/CommandForm/DatePickerField.d.ts +0 -20
- package/dist/esm/CommandForm/DatePickerField.d.ts.map +0 -1
- package/dist/esm/CommandForm/DatePickerField.js +0 -29
- package/dist/esm/CommandForm/DatePickerField.js.map +0 -1
- package/dist/esm/CommandForm/DropdownField.d.ts +0 -24
- package/dist/esm/CommandForm/DropdownField.d.ts.map +0 -1
- package/dist/esm/CommandForm/DropdownField.js +0 -29
- package/dist/esm/CommandForm/DropdownField.js.map +0 -1
- package/dist/esm/CommandForm/InputTextField.d.ts +0 -20
- package/dist/esm/CommandForm/InputTextField.d.ts.map +0 -1
- package/dist/esm/CommandForm/InputTextField.js +0 -30
- package/dist/esm/CommandForm/InputTextField.js.map +0 -1
- package/dist/esm/CommandForm/SliderField.d.ts +0 -23
- package/dist/esm/CommandForm/SliderField.d.ts.map +0 -1
- package/dist/esm/CommandForm/SliderField.js +0 -32
- package/dist/esm/CommandForm/SliderField.js.map +0 -1
- package/global.d.ts +0 -11
- package/index.ts +0 -22
- package/useOverlayZIndex.ts +0 -32
- package/vite.config.ts +0 -80
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import { useEffect, useState } from 'react';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Hook to track container dimensions using ResizeObserver.
|
|
8
|
-
*
|
|
9
|
-
* @param containerRef - Ref to the container element.
|
|
10
|
-
* @param dependency - Optional dependency to trigger updates.
|
|
11
|
-
* @returns Dimensions of the container.
|
|
12
|
-
*/
|
|
13
|
-
export function useContainerDimensions(
|
|
14
|
-
containerRef: React.RefObject<HTMLDivElement>,
|
|
15
|
-
dependency?: unknown
|
|
16
|
-
) {
|
|
17
|
-
const [dimensions, setDimensions] = useState({ width: 1200, height: 600 });
|
|
18
|
-
|
|
19
|
-
useEffect(() => {
|
|
20
|
-
const container = containerRef.current;
|
|
21
|
-
if (!container) return;
|
|
22
|
-
|
|
23
|
-
const updateDimensions = () => {
|
|
24
|
-
setDimensions({
|
|
25
|
-
width: container.clientWidth,
|
|
26
|
-
height: container.clientHeight,
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// Initial dimensions
|
|
31
|
-
updateDimensions();
|
|
32
|
-
|
|
33
|
-
// Observe for resize changes
|
|
34
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
35
|
-
updateDimensions();
|
|
36
|
-
});
|
|
37
|
-
resizeObserver.observe(container);
|
|
38
|
-
|
|
39
|
-
return () => {
|
|
40
|
-
resizeObserver.disconnect();
|
|
41
|
-
};
|
|
42
|
-
}, [containerRef, dependency]);
|
|
43
|
-
|
|
44
|
-
return dimensions;
|
|
45
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import { useMemo, useState, useEffect, useCallback } from 'react';
|
|
5
|
-
import type { PivotDimension } from '../types';
|
|
6
|
-
|
|
7
|
-
export type PivotDimensionFilter = string | null;
|
|
8
|
-
|
|
9
|
-
export function useDimensionState<TItem extends object>(
|
|
10
|
-
dimensions: PivotDimension<TItem>[],
|
|
11
|
-
defaultDimensionKey?: string
|
|
12
|
-
) {
|
|
13
|
-
const dimensionMap = useMemo(() => {
|
|
14
|
-
const map = new Map<string, PivotDimension<TItem>>();
|
|
15
|
-
dimensions.forEach((dimension) => map.set(dimension.key, dimension));
|
|
16
|
-
return map;
|
|
17
|
-
}, [dimensions]);
|
|
18
|
-
|
|
19
|
-
const initialDimension = useMemo(() => {
|
|
20
|
-
if (defaultDimensionKey && dimensionMap.has(defaultDimensionKey)) {
|
|
21
|
-
return defaultDimensionKey;
|
|
22
|
-
}
|
|
23
|
-
return dimensions[0]?.key ?? '';
|
|
24
|
-
}, [defaultDimensionKey, dimensionMap, dimensions]);
|
|
25
|
-
|
|
26
|
-
const [activeDimensionKey, setActiveDimensionKey] = useState(initialDimension);
|
|
27
|
-
const [dimensionFilter, setDimensionFilter] = useState<string | null>(null);
|
|
28
|
-
|
|
29
|
-
useEffect(() => {
|
|
30
|
-
setActiveDimensionKey((previous) => {
|
|
31
|
-
if (previous && dimensionMap.has(previous)) {
|
|
32
|
-
return previous;
|
|
33
|
-
}
|
|
34
|
-
return initialDimension;
|
|
35
|
-
});
|
|
36
|
-
setDimensionFilter(null);
|
|
37
|
-
}, [dimensionMap, initialDimension]);
|
|
38
|
-
|
|
39
|
-
const activeDimension = dimensionMap.get(activeDimensionKey) ?? dimensions[0];
|
|
40
|
-
|
|
41
|
-
const handleAxisLabelClick = useCallback((groupKey: string) => {
|
|
42
|
-
setDimensionFilter((prev) => (prev === groupKey ? null : groupKey));
|
|
43
|
-
}, []);
|
|
44
|
-
|
|
45
|
-
return {
|
|
46
|
-
dimensionMap,
|
|
47
|
-
activeDimensionKey,
|
|
48
|
-
setActiveDimensionKey,
|
|
49
|
-
activeDimension,
|
|
50
|
-
dimensionFilter,
|
|
51
|
-
handleAxisLabelClick,
|
|
52
|
-
};
|
|
53
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import { useMemo } from 'react';
|
|
5
|
-
import type { PivotFilter, PivotFilterOption, PivotPrimitive } from '../types';
|
|
6
|
-
import { applyFilters, computeFilterOptions, computeNumericRange } from '../utils/utils';
|
|
7
|
-
import type { FilterState, RangeFilterState } from '../types';
|
|
8
|
-
|
|
9
|
-
export function useFilterOptions<TItem extends object>(
|
|
10
|
-
data: TItem[],
|
|
11
|
-
filters: PivotFilter<TItem>[] | undefined,
|
|
12
|
-
filterState: FilterState,
|
|
13
|
-
rangeFilterState: RangeFilterState
|
|
14
|
-
) {
|
|
15
|
-
return useMemo(() => {
|
|
16
|
-
if (!filters?.length) {
|
|
17
|
-
return [] as {
|
|
18
|
-
filter: PivotFilter<TItem>;
|
|
19
|
-
options: PivotFilterOption[];
|
|
20
|
-
numericRange?: { min: number; max: number; values: PivotPrimitive[] };
|
|
21
|
-
}[];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return filters.map((filter) => {
|
|
25
|
-
const baseData = applyFilters(data, filters, filterState, rangeFilterState, filter.key);
|
|
26
|
-
|
|
27
|
-
if (filter.type === 'number') {
|
|
28
|
-
const numericRange = computeNumericRange(baseData, filter);
|
|
29
|
-
return { filter, options: [], numericRange };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const options = computeFilterOptions(baseData, filter);
|
|
33
|
-
return { filter, options };
|
|
34
|
-
});
|
|
35
|
-
}, [data, filters, filterState, rangeFilterState]);
|
|
36
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import { useState, useCallback, useEffect } from 'react';
|
|
5
|
-
|
|
6
|
-
export function useFilterPanelDrag() {
|
|
7
|
-
const [filterPanelPos, setFilterPanelPos] = useState({ x: 16, y: 88 });
|
|
8
|
-
const [isDraggingPanel, setIsDraggingPanel] = useState(false);
|
|
9
|
-
const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
|
|
10
|
-
|
|
11
|
-
const handleFilterPanelDragStart = useCallback((e: React.MouseEvent) => {
|
|
12
|
-
(e as any).preventDefault?.();
|
|
13
|
-
setIsDraggingPanel(true);
|
|
14
|
-
setDragOffset({
|
|
15
|
-
x: e.clientX - filterPanelPos.x,
|
|
16
|
-
y: e.clientY - filterPanelPos.y,
|
|
17
|
-
});
|
|
18
|
-
}, [filterPanelPos]);
|
|
19
|
-
|
|
20
|
-
const handleFilterPanelDrag = useCallback((e: MouseEvent) => {
|
|
21
|
-
if (!isDraggingPanel) return;
|
|
22
|
-
setFilterPanelPos({
|
|
23
|
-
x: Math.max(0, e.clientX - dragOffset.x),
|
|
24
|
-
y: Math.max(60, e.clientY - dragOffset.y),
|
|
25
|
-
});
|
|
26
|
-
}, [isDraggingPanel, dragOffset]);
|
|
27
|
-
|
|
28
|
-
const handleFilterPanelDragEnd = useCallback(() => {
|
|
29
|
-
setIsDraggingPanel(false);
|
|
30
|
-
}, []);
|
|
31
|
-
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
if (isDraggingPanel) {
|
|
34
|
-
document.addEventListener('mousemove', handleFilterPanelDrag);
|
|
35
|
-
document.addEventListener('mouseup', handleFilterPanelDragEnd);
|
|
36
|
-
return () => {
|
|
37
|
-
document.removeEventListener('mousemove', handleFilterPanelDrag);
|
|
38
|
-
document.removeEventListener('mouseup', handleFilterPanelDragEnd);
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
return undefined;
|
|
42
|
-
}, [isDraggingPanel, handleFilterPanelDrag, handleFilterPanelDragEnd]);
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
filterPanelPos,
|
|
46
|
-
isDraggingPanel,
|
|
47
|
-
handleFilterPanelDragStart,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import { useState, useEffect, useCallback } from 'react';
|
|
5
|
-
import { buildFilterState, buildRangeFilterState } from '../utils/utils';
|
|
6
|
-
import { FilterState, RangeFilterState, PivotFilter } from '../types';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Hook to manage filter state.
|
|
10
|
-
*/
|
|
11
|
-
export function useFilterState<TItem extends object>(
|
|
12
|
-
filters: PivotFilter<TItem>[] | undefined
|
|
13
|
-
) {
|
|
14
|
-
const [filterState, setFilterState] = useState<FilterState>(() => buildFilterState(filters));
|
|
15
|
-
const [rangeFilterState, setRangeFilterState] = useState<RangeFilterState>(() => buildRangeFilterState(filters));
|
|
16
|
-
const [expandedFilterKey, setExpandedFilterKey] = useState<string | null>(filters?.[0]?.key ?? null);
|
|
17
|
-
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
setFilterState((prev) => {
|
|
20
|
-
const next = buildFilterState(filters);
|
|
21
|
-
if (!filters) return next;
|
|
22
|
-
|
|
23
|
-
filters.forEach((filter) => {
|
|
24
|
-
if (prev[filter.key]) {
|
|
25
|
-
next[filter.key] = new Set(prev[filter.key]);
|
|
26
|
-
}
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
return next;
|
|
30
|
-
});
|
|
31
|
-
setRangeFilterState((prev) => {
|
|
32
|
-
const next = buildRangeFilterState(filters);
|
|
33
|
-
if (!filters) return next;
|
|
34
|
-
filters.forEach((filter) => {
|
|
35
|
-
if (filter.type === 'number' && filter.key in prev) {
|
|
36
|
-
next[filter.key] = prev[filter.key];
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
return next;
|
|
40
|
-
});
|
|
41
|
-
}, [filters]);
|
|
42
|
-
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
if (!filters?.length) {
|
|
45
|
-
setExpandedFilterKey(null);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
setExpandedFilterKey((current) => {
|
|
50
|
-
if (current && filters.some((filter) => filter.key === current)) {
|
|
51
|
-
return current;
|
|
52
|
-
}
|
|
53
|
-
return filters[0]?.key ?? null;
|
|
54
|
-
});
|
|
55
|
-
}, [filters]);
|
|
56
|
-
|
|
57
|
-
const handleToggleFilter = useCallback((filterKey: string, optionKey: string, multi: boolean | undefined) => {
|
|
58
|
-
setFilterState((prev) => {
|
|
59
|
-
const next: FilterState = { ...prev };
|
|
60
|
-
const current = new Set(prev[filterKey] ?? []);
|
|
61
|
-
|
|
62
|
-
if (multi) {
|
|
63
|
-
if (current.has(optionKey)) {
|
|
64
|
-
current.delete(optionKey);
|
|
65
|
-
} else {
|
|
66
|
-
current.add(optionKey);
|
|
67
|
-
}
|
|
68
|
-
} else {
|
|
69
|
-
if (current.has(optionKey)) {
|
|
70
|
-
current.clear();
|
|
71
|
-
} else {
|
|
72
|
-
current.clear();
|
|
73
|
-
current.add(optionKey);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
next[filterKey] = current;
|
|
78
|
-
return next;
|
|
79
|
-
});
|
|
80
|
-
}, []);
|
|
81
|
-
|
|
82
|
-
const handleClearFilter = useCallback((filterKey: string) => {
|
|
83
|
-
setFilterState((prev) => {
|
|
84
|
-
const next: FilterState = { ...prev };
|
|
85
|
-
next[filterKey] = new Set();
|
|
86
|
-
return next;
|
|
87
|
-
});
|
|
88
|
-
}, []);
|
|
89
|
-
|
|
90
|
-
const handleRangeChange = useCallback((filterKey: string, range: [number, number] | null) => {
|
|
91
|
-
setRangeFilterState((prev) => ({
|
|
92
|
-
...prev,
|
|
93
|
-
[filterKey]: range,
|
|
94
|
-
}));
|
|
95
|
-
}, []);
|
|
96
|
-
|
|
97
|
-
return {
|
|
98
|
-
filterState,
|
|
99
|
-
rangeFilterState,
|
|
100
|
-
expandedFilterKey,
|
|
101
|
-
setExpandedFilterKey,
|
|
102
|
-
handleToggleFilter,
|
|
103
|
-
handleClearFilter,
|
|
104
|
-
handleRangeChange,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import { useMemo } from 'react';
|
|
5
|
-
import type { PivotDimension, PivotFilter, PivotGroup } from '../types';
|
|
6
|
-
import { applyFilters, groupData, toKey } from '../utils/utils';
|
|
7
|
-
import type { FilterState, RangeFilterState } from '../utils/utils';
|
|
8
|
-
|
|
9
|
-
export function useFilteredData<TItem extends object>(
|
|
10
|
-
data: TItem[],
|
|
11
|
-
filters: PivotFilter<TItem>[] | undefined,
|
|
12
|
-
filterState: FilterState,
|
|
13
|
-
rangeFilterState: RangeFilterState,
|
|
14
|
-
activeDimension: PivotDimension<TItem> | undefined,
|
|
15
|
-
dimensionFilter: string | null,
|
|
16
|
-
searchTerm: string,
|
|
17
|
-
searchFields?: (keyof TItem)[]
|
|
18
|
-
) {
|
|
19
|
-
const filteredData = useMemo(() => {
|
|
20
|
-
let dataWithFilters = applyFilters(data, filters, filterState, rangeFilterState);
|
|
21
|
-
|
|
22
|
-
if (dimensionFilter && activeDimension) {
|
|
23
|
-
dataWithFilters = dataWithFilters.filter((item) => {
|
|
24
|
-
const value = activeDimension.getValue(item);
|
|
25
|
-
const key = toKey(value);
|
|
26
|
-
return key === dimensionFilter;
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (!searchTerm) {
|
|
31
|
-
return dataWithFilters;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Optimize search by using indexOf instead of includes for better performance
|
|
35
|
-
return dataWithFilters.filter((item) => {
|
|
36
|
-
if (searchFields && searchFields.length) {
|
|
37
|
-
for (const field of searchFields) {
|
|
38
|
-
const value = item[field];
|
|
39
|
-
if (value !== undefined && String(value).toLowerCase().indexOf(searchTerm) !== -1) {
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return false;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Fallback to JSON stringify - less efficient but comprehensive
|
|
47
|
-
return JSON.stringify(item).toLowerCase().indexOf(searchTerm) !== -1;
|
|
48
|
-
});
|
|
49
|
-
}, [data, filters, filterState, rangeFilterState, dimensionFilter, activeDimension, searchFields, searchTerm]);
|
|
50
|
-
|
|
51
|
-
const allGroupsForBuckets = useMemo(() => {
|
|
52
|
-
if (!activeDimension) {
|
|
53
|
-
return [] as PivotGroup<TItem>[];
|
|
54
|
-
}
|
|
55
|
-
const dataWithoutDimensionFilter = applyFilters(data, filters, filterState, rangeFilterState);
|
|
56
|
-
return groupData(dataWithoutDimensionFilter, activeDimension);
|
|
57
|
-
}, [data, filters, filterState, rangeFilterState, activeDimension]);
|
|
58
|
-
|
|
59
|
-
const groupedGroups = useMemo(() => {
|
|
60
|
-
if (!activeDimension) {
|
|
61
|
-
return [] as PivotGroup<TItem>[];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (dimensionFilter) {
|
|
65
|
-
const filteredGroup = allGroupsForBuckets.find((group) => group.key === dimensionFilter);
|
|
66
|
-
return filteredGroup ? [filteredGroup] : [];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return groupData(filteredData, activeDimension);
|
|
70
|
-
}, [filteredData, activeDimension, dimensionFilter, allGroupsForBuckets]);
|
|
71
|
-
|
|
72
|
-
const collectionGroup = useMemo(() => {
|
|
73
|
-
if (filteredData.length === 0) {
|
|
74
|
-
return [] as PivotGroup<TItem>[];
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Sort by active dimension when in collection mode
|
|
78
|
-
const sortedData = activeDimension
|
|
79
|
-
? [...filteredData].sort((a, b) => {
|
|
80
|
-
const valueA = activeDimension.getValue(a);
|
|
81
|
-
const valueB = activeDimension.getValue(b);
|
|
82
|
-
|
|
83
|
-
// Handle null/undefined
|
|
84
|
-
if (valueA == null && valueB == null) return 0;
|
|
85
|
-
if (valueA == null) return 1;
|
|
86
|
-
if (valueB == null) return -1;
|
|
87
|
-
|
|
88
|
-
// Handle dates
|
|
89
|
-
if (valueA instanceof Date && valueB instanceof Date) {
|
|
90
|
-
return valueA.getTime() - valueB.getTime();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Handle numbers
|
|
94
|
-
if (typeof valueA === 'number' && typeof valueB === 'number') {
|
|
95
|
-
return valueA - valueB;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Handle strings
|
|
99
|
-
return String(valueA).localeCompare(String(valueB));
|
|
100
|
-
})
|
|
101
|
-
: filteredData;
|
|
102
|
-
|
|
103
|
-
return [
|
|
104
|
-
{
|
|
105
|
-
key: 'collection-all',
|
|
106
|
-
label: 'All Events',
|
|
107
|
-
value: null,
|
|
108
|
-
items: sortedData,
|
|
109
|
-
} as PivotGroup<TItem>,
|
|
110
|
-
];
|
|
111
|
-
}, [filteredData, activeDimension]);
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
filteredData,
|
|
115
|
-
allGroupsForBuckets,
|
|
116
|
-
groupedGroups,
|
|
117
|
-
collectionGroup,
|
|
118
|
-
};
|
|
119
|
-
}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
-
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
-
|
|
4
|
-
import { useState, useRef, useCallback } from 'react';
|
|
5
|
-
|
|
6
|
-
export function usePanning(
|
|
7
|
-
containerRef: React.RefObject<HTMLDivElement | null>,
|
|
8
|
-
onBackgroundClick?: () => void,
|
|
9
|
-
onScrollChange?: (scroll: { x: number; y: number }) => void
|
|
10
|
-
) {
|
|
11
|
-
const [isPanning, setIsPanning] = useState(false);
|
|
12
|
-
const panStartRef = useRef<{ x: number; y: number; scrollLeft: number; scrollTop: number } | null>(null);
|
|
13
|
-
const velocityRef = useRef({ x: 0, y: 0 });
|
|
14
|
-
const lastMouseRef = useRef<{ x: number; y: number; time: number } | null>(null);
|
|
15
|
-
const inertiaAnimationRef = useRef<number | null>(null);
|
|
16
|
-
const didDragRef = useRef(false);
|
|
17
|
-
const clickedOnBackgroundRef = useRef(false);
|
|
18
|
-
|
|
19
|
-
const stopInertia = useCallback(() => {
|
|
20
|
-
if (inertiaAnimationRef.current) {
|
|
21
|
-
cancelAnimationFrame(inertiaAnimationRef.current);
|
|
22
|
-
inertiaAnimationRef.current = null;
|
|
23
|
-
}
|
|
24
|
-
}, []);
|
|
25
|
-
|
|
26
|
-
const handlePanStart = useCallback((e: React.MouseEvent | MouseEvent, isExplicitlyOnCard?: boolean) => {
|
|
27
|
-
const container = containerRef.current;
|
|
28
|
-
if (!container) return;
|
|
29
|
-
|
|
30
|
-
stopInertia();
|
|
31
|
-
|
|
32
|
-
const target = e.target as HTMLElement;
|
|
33
|
-
// Check if explicitly on card (from Pixi) or via DOM (fallback)
|
|
34
|
-
const isOnCard = isExplicitlyOnCard ?? !!target.closest('.pv-card');
|
|
35
|
-
|
|
36
|
-
clickedOnBackgroundRef.current = !isOnCard;
|
|
37
|
-
didDragRef.current = false;
|
|
38
|
-
velocityRef.current = { x: 0, y: 0 };
|
|
39
|
-
|
|
40
|
-
if (e.button === 1 || (e.button === 0 && (e.altKey || !isOnCard))) {
|
|
41
|
-
if (!isOnCard) {
|
|
42
|
-
(e as any).preventDefault?.();
|
|
43
|
-
}
|
|
44
|
-
setIsPanning(true);
|
|
45
|
-
panStartRef.current = {
|
|
46
|
-
x: e.clientX,
|
|
47
|
-
y: e.clientY,
|
|
48
|
-
scrollLeft: container.scrollLeft,
|
|
49
|
-
scrollTop: container.scrollTop,
|
|
50
|
-
};
|
|
51
|
-
lastMouseRef.current = { x: e.clientX, y: e.clientY, time: performance.now() };
|
|
52
|
-
}
|
|
53
|
-
}, [containerRef, stopInertia]);
|
|
54
|
-
|
|
55
|
-
const handlePanMove = useCallback((e: React.MouseEvent | MouseEvent) => {
|
|
56
|
-
const panStart = panStartRef.current;
|
|
57
|
-
if (!isPanning || !panStart) return;
|
|
58
|
-
|
|
59
|
-
const dx = e.clientX - panStart.x;
|
|
60
|
-
const dy = e.clientY - panStart.y;
|
|
61
|
-
|
|
62
|
-
// Mark as dragged if moved more than 3 pixels
|
|
63
|
-
if (Math.abs(dx) > 3 || Math.abs(dy) > 3) {
|
|
64
|
-
didDragRef.current = true;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Camera moves opposite to drag direction
|
|
68
|
-
const newCameraX = panStart.scrollLeft - dx;
|
|
69
|
-
const newCameraY = panStart.scrollTop - dy;
|
|
70
|
-
|
|
71
|
-
// Update camera position
|
|
72
|
-
// Update container scroll directly so the visual camera follows the drag
|
|
73
|
-
const container = containerRef.current;
|
|
74
|
-
if (container) {
|
|
75
|
-
container.scrollLeft = Math.max(0, Math.round(newCameraX));
|
|
76
|
-
container.scrollTop = Math.max(0, Math.round(newCameraY));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Also notify parent about scroll change (keeps external state in sync)
|
|
80
|
-
if (onScrollChange) {
|
|
81
|
-
onScrollChange({ x: container ? container.scrollLeft : newCameraX, y: container ? container.scrollTop : newCameraY });
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Track velocity for inertia
|
|
85
|
-
const now = performance.now();
|
|
86
|
-
const last = lastMouseRef.current;
|
|
87
|
-
if (last) {
|
|
88
|
-
const dt = now - last.time;
|
|
89
|
-
if (dt > 0 && dt < 50) {
|
|
90
|
-
const instantVx = (last.x - e.clientX) / dt;
|
|
91
|
-
const instantVy = (last.y - e.clientY) / dt;
|
|
92
|
-
velocityRef.current = {
|
|
93
|
-
x: velocityRef.current.x * 0.5 + instantVx * 0.5,
|
|
94
|
-
y: velocityRef.current.y * 0.5 + instantVy * 0.5,
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
lastMouseRef.current = { x: e.clientX, y: e.clientY, time: now };
|
|
99
|
-
}, [isPanning, containerRef, onScrollChange]);
|
|
100
|
-
|
|
101
|
-
const handlePanEnd = useCallback(() => {
|
|
102
|
-
const wasPanning = isPanning;
|
|
103
|
-
const velocity = { ...velocityRef.current };
|
|
104
|
-
|
|
105
|
-
setIsPanning(false);
|
|
106
|
-
panStartRef.current = null;
|
|
107
|
-
|
|
108
|
-
// If clicked on background and didn't drag, trigger deselect
|
|
109
|
-
if (clickedOnBackgroundRef.current && !didDragRef.current && onBackgroundClick) {
|
|
110
|
-
onBackgroundClick();
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (!wasPanning) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const container = containerRef.current;
|
|
118
|
-
if (!container) {
|
|
119
|
-
lastMouseRef.current = null;
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const speed = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y);
|
|
124
|
-
|
|
125
|
-
// Start inertia if moving fast enough
|
|
126
|
-
if (speed > 0.3) {
|
|
127
|
-
let vx = velocity.x * 16;
|
|
128
|
-
let vy = velocity.y * 16;
|
|
129
|
-
|
|
130
|
-
const animate = () => {
|
|
131
|
-
const currentSpeed = Math.sqrt(vx * vx + vy * vy);
|
|
132
|
-
|
|
133
|
-
if (currentSpeed < 0.5) {
|
|
134
|
-
inertiaAnimationRef.current = null;
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
container.scrollLeft += vx;
|
|
139
|
-
container.scrollTop += vy;
|
|
140
|
-
|
|
141
|
-
// Decay
|
|
142
|
-
vx *= 0.95;
|
|
143
|
-
vy *= 0.95;
|
|
144
|
-
|
|
145
|
-
inertiaAnimationRef.current = requestAnimationFrame(animate);
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
inertiaAnimationRef.current = requestAnimationFrame(animate);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
lastMouseRef.current = null;
|
|
152
|
-
}, [isPanning, containerRef, onBackgroundClick]);
|
|
153
|
-
|
|
154
|
-
return {
|
|
155
|
-
isPanning,
|
|
156
|
-
handlePanStart,
|
|
157
|
-
handlePanMove,
|
|
158
|
-
handlePanEnd,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|