@ocelescope/filter 0.10.1 → 0.10.2
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/README.md +3 -5
- package/dist/index.js +111 -203
- package/package.json +19 -17
package/README.md
CHANGED
|
@@ -31,14 +31,12 @@ export default {
|
|
|
31
31
|
} satisfies OcelescopeConfig;
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
This module's
|
|
35
|
-
`@mantine/dates`
|
|
36
|
-
|
|
37
|
-
`@mantine/core/styles.css`:
|
|
34
|
+
This module's date filters rely on the Mantine dates stylesheet. Add
|
|
35
|
+
`@mantine/dates` to your app's `dependencies` and import its styles once in
|
|
36
|
+
your app entry point (`pages/_app.tsx`), after `@mantine/core/styles.css`:
|
|
38
37
|
|
|
39
38
|
```tsx
|
|
40
39
|
import "@mantine/dates/styles.css";
|
|
41
|
-
import "@mantine/charts/styles.css";
|
|
42
40
|
```
|
|
43
41
|
|
|
44
42
|
## About
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AttributesTable, RelationTable, defineModule, defineModuleRoute, useCurrentOcel, useInvalidate } from "@ocelescope/core";
|
|
1
|
+
import { ActivityPicker, AttributesTable, ObjectTypePicker, RelationTable, defineModule, defineModuleRoute, useCurrentOcel, useInvalidate } from "@ocelescope/core";
|
|
2
2
|
import { CheckIcon, FilterIcon, PlusIcon, RotateCcwIcon, Trash2Icon, XIcon } from "lucide-react";
|
|
3
|
-
import { ActionIcon, ActionIconGroup, Box, Grid, Group,
|
|
3
|
+
import { ActionIcon, ActionIconGroup, Box, Grid, Group, InlineStyles, LoadingOverlay, NumberInput, RangeSlider, Scroller, Stack, Switch, Tabs, Text, TextInput, useMantineTheme } from "@mantine/core";
|
|
4
4
|
import hash from "object-hash";
|
|
5
5
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
|
6
6
|
import { customFetch } from "@ocelescope/api-client";
|
|
@@ -9,8 +9,8 @@ import { useRouter } from "next/router.js";
|
|
|
9
9
|
import { memo, useMemo, useState } from "react";
|
|
10
10
|
import { DateTimePicker } from "@mantine/dates";
|
|
11
11
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
12
|
+
import { useTimeInfo } from "@ocelescope/api-base";
|
|
13
|
+
import EChartsReact from "echarts-for-react";
|
|
14
14
|
import dayjs from "dayjs";
|
|
15
15
|
import isBetween from "dayjs/plugin/isBetween.js";
|
|
16
16
|
//#region src/lib/fetcher.ts
|
|
@@ -572,41 +572,57 @@ dayjs.extend(isBetween);
|
|
|
572
572
|
var dayjs_default = dayjs;
|
|
573
573
|
//#endregion
|
|
574
574
|
//#region src/components/FilterViews/TimeFrameFilter.tsx
|
|
575
|
+
const DATE_FORMAT = "YYYY-MM-DD HH:mm";
|
|
575
576
|
const TimeGraph = memo(({ timeInfo, startDate, endDate }) => {
|
|
576
|
-
const
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
577
|
+
const theme = useMantineTheme();
|
|
578
|
+
const option = useMemo(() => {
|
|
579
|
+
const buckets = timeInfo.date_distribution.map(({ start_timestamp, end_timestamp, entity_count }) => ({
|
|
580
|
+
label: `${dayjs_default(start_timestamp).format(DATE_FORMAT)} - ${dayjs_default(end_timestamp).format(DATE_FORMAT)}`,
|
|
581
|
+
count: Object.values(entity_count).reduce((acc, curr) => acc + curr, 0),
|
|
582
|
+
isInRange: (!startDate || dayjs_default(end_timestamp).isAfter(dayjs_default(startDate))) && (!endDate || dayjs_default(start_timestamp).isBefore(dayjs_default(endDate)))
|
|
583
|
+
}));
|
|
584
|
+
return {
|
|
585
|
+
tooltip: {
|
|
586
|
+
trigger: "axis",
|
|
587
|
+
axisPointer: { type: "shadow" }
|
|
588
|
+
},
|
|
589
|
+
grid: {
|
|
590
|
+
left: 0,
|
|
591
|
+
right: 0,
|
|
592
|
+
top: 8,
|
|
593
|
+
bottom: 0
|
|
594
|
+
},
|
|
595
|
+
xAxis: {
|
|
596
|
+
type: "category",
|
|
597
|
+
data: buckets.map(({ label }) => label),
|
|
598
|
+
show: false
|
|
599
|
+
},
|
|
600
|
+
yAxis: {
|
|
601
|
+
type: "value",
|
|
602
|
+
show: false
|
|
603
|
+
},
|
|
604
|
+
series: [{
|
|
605
|
+
type: "bar",
|
|
606
|
+
name: "count",
|
|
607
|
+
barCategoryGap: 0,
|
|
608
|
+
data: buckets.map(({ count, isInRange }) => ({
|
|
609
|
+
value: count,
|
|
610
|
+
itemStyle: {
|
|
611
|
+
color: theme.colors.blue[6],
|
|
612
|
+
opacity: isInRange ? 1 : .25
|
|
613
|
+
}
|
|
614
|
+
}))
|
|
615
|
+
}]
|
|
616
|
+
};
|
|
584
617
|
}, [
|
|
585
618
|
timeInfo,
|
|
586
619
|
startDate,
|
|
587
|
-
endDate
|
|
620
|
+
endDate,
|
|
621
|
+
theme
|
|
588
622
|
]);
|
|
589
|
-
return /* @__PURE__ */ jsx(
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
data,
|
|
593
|
-
dataKey: "date",
|
|
594
|
-
type: "stacked",
|
|
595
|
-
series: [{
|
|
596
|
-
name: "value",
|
|
597
|
-
color: "blue",
|
|
598
|
-
label: "count"
|
|
599
|
-
}, {
|
|
600
|
-
name: "disabledValue",
|
|
601
|
-
color: "red",
|
|
602
|
-
label: "count"
|
|
603
|
-
}],
|
|
604
|
-
withYAxis: false,
|
|
605
|
-
withXAxis: false,
|
|
606
|
-
barChartProps: {
|
|
607
|
-
barCategoryGap: 0,
|
|
608
|
-
barGap: 0
|
|
609
|
-
}
|
|
623
|
+
return /* @__PURE__ */ jsx(EChartsReact, {
|
|
624
|
+
option,
|
|
625
|
+
style: { height: 300 }
|
|
610
626
|
});
|
|
611
627
|
});
|
|
612
628
|
const TimeFrameSlider = ({ timeInfo, startTime, endTime, onChange }) => {
|
|
@@ -632,7 +648,7 @@ const TimeFrameSlider = ({ timeInfo, startTime, endTime, onChange }) => {
|
|
|
632
648
|
value: [startIndex, endIndex],
|
|
633
649
|
label: (value) => {
|
|
634
650
|
const bucket = distribution[value];
|
|
635
|
-
return bucket ? dayjs_default(bucket.start_timestamp).format(
|
|
651
|
+
return bucket ? dayjs_default(bucket.start_timestamp).format(DATE_FORMAT) : null;
|
|
636
652
|
},
|
|
637
653
|
onChange: ([start, end]) => {
|
|
638
654
|
onChange([start === startIndex ? startTime : distribution[start]?.start_timestamp ?? startTime, distribution[end]?.end_timestamp ?? endTime]);
|
|
@@ -659,13 +675,11 @@ const TimeFrameFilter = {
|
|
|
659
675
|
children: /* @__PURE__ */ jsx(Watch, {
|
|
660
676
|
control,
|
|
661
677
|
name: ["time_frame.0.time_range.0", "time_frame.0.time_range.1"],
|
|
662
|
-
render: ([startTime, endTime]) => {
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
});
|
|
668
|
-
}
|
|
678
|
+
render: ([startTime, endTime]) => /* @__PURE__ */ jsx(TimeGraph, {
|
|
679
|
+
timeInfo,
|
|
680
|
+
startDate: startTime ?? void 0,
|
|
681
|
+
endDate: endTime ?? void 0
|
|
682
|
+
})
|
|
669
683
|
})
|
|
670
684
|
}), /* @__PURE__ */ jsx(Controller, {
|
|
671
685
|
control,
|
|
@@ -718,173 +732,70 @@ const TimeFrameFilter = {
|
|
|
718
732
|
}
|
|
719
733
|
};
|
|
720
734
|
//#endregion
|
|
721
|
-
//#region src/util/color.ts
|
|
722
|
-
const assignUniqueColors = (strings) => {
|
|
723
|
-
const numStrings = strings.length;
|
|
724
|
-
const uniqueStrings = Array.from(new Set(strings));
|
|
725
|
-
const colorMap = {};
|
|
726
|
-
uniqueStrings.forEach((str, index) => {
|
|
727
|
-
const hsl = `hsl(${index * 360 / numStrings}, 70%, 50%)`;
|
|
728
|
-
colorMap[str] = hsl;
|
|
729
|
-
});
|
|
730
|
-
return colorMap;
|
|
731
|
-
};
|
|
732
|
-
const BarChartSelect = memo(({ values, selected, onSelect }) => {
|
|
733
|
-
const colorMap = useMemo(() => {
|
|
734
|
-
return assignUniqueColors(Array.from(new Set(values.map(({ key }) => key))));
|
|
735
|
-
}, [values]);
|
|
736
|
-
const data = useMemo(() => [...values].sort((a, b) => b.value - a.value).map(({ value, key }) => ({
|
|
737
|
-
key,
|
|
738
|
-
value,
|
|
739
|
-
color: selected.includes(key) ? colorMap[key] : "rgba(128, 128, 128, 0.3)"
|
|
740
|
-
})), [
|
|
741
|
-
values,
|
|
742
|
-
selected,
|
|
743
|
-
colorMap
|
|
744
|
-
]);
|
|
745
|
-
return /* @__PURE__ */ jsx(BarChart, {
|
|
746
|
-
h: 30 * values.length,
|
|
747
|
-
data,
|
|
748
|
-
minBarSize: 30,
|
|
749
|
-
tooltipProps: { content: ({ label }) => /* @__PURE__ */ jsx(Paper, {
|
|
750
|
-
px: "md",
|
|
751
|
-
py: "sm",
|
|
752
|
-
withBorder: true,
|
|
753
|
-
shadow: "md",
|
|
754
|
-
radius: "md",
|
|
755
|
-
children: /* @__PURE__ */ jsx(Text, { children: label })
|
|
756
|
-
}) },
|
|
757
|
-
dataKey: "key",
|
|
758
|
-
orientation: "vertical",
|
|
759
|
-
yAxisProps: { width: 130 },
|
|
760
|
-
series: [{
|
|
761
|
-
name: "value",
|
|
762
|
-
color: "gray.6"
|
|
763
|
-
}],
|
|
764
|
-
gridAxis: "none",
|
|
765
|
-
barChartProps: { onClick: ({ activeLabel }) => {
|
|
766
|
-
if (!activeLabel) return;
|
|
767
|
-
onSelect(String(activeLabel));
|
|
768
|
-
} }
|
|
769
|
-
});
|
|
770
|
-
});
|
|
771
|
-
//#endregion
|
|
772
|
-
//#region src/components/inputs/EntityTypeFilter.tsx
|
|
773
|
-
const EntityTypeFilterInput = ({ entityTypes, onChange, showGraph = false, selectedEntityTypes, label, mode, onModeChange }) => {
|
|
774
|
-
const isExclude = mode === "exclude";
|
|
775
|
-
const maxCount = useMemo(() => entityTypes.reduce((max, { value }) => Math.max(max, value), 0), [entityTypes]);
|
|
776
|
-
const [range, setRange] = useState([0, 100]);
|
|
777
|
-
const frequencyMarks = useMemo(() => {
|
|
778
|
-
if (maxCount === 0) return [];
|
|
779
|
-
const percentages = new Set(entityTypes.map(({ value }) => Math.round(value / maxCount * 100)));
|
|
780
|
-
return Array.from(percentages).map((value) => ({ value }));
|
|
781
|
-
}, [entityTypes, maxCount]);
|
|
782
|
-
const applyRange = ([low, high]) => {
|
|
783
|
-
setRange([low, high]);
|
|
784
|
-
const minCount = low / 100 * maxCount;
|
|
785
|
-
const maxCountInBand = high / 100 * maxCount;
|
|
786
|
-
const inBand = (count) => count >= minCount && count <= maxCountInBand;
|
|
787
|
-
onChange(entityTypes.filter(({ value: count }) => isExclude ? !inBand(count) : inBand(count)).map(({ key }) => key));
|
|
788
|
-
};
|
|
789
|
-
const highlighted = isExclude ? entityTypes.map(({ key }) => key).filter((key) => !selectedEntityTypes.includes(key)) : selectedEntityTypes;
|
|
790
|
-
const toggle = (key) => onChange(selectedEntityTypes.includes(key) ? selectedEntityTypes.filter((v) => v !== key) : [...selectedEntityTypes, key]);
|
|
791
|
-
return /* @__PURE__ */ jsxs(Stack, {
|
|
792
|
-
gap: "md",
|
|
793
|
-
children: [showGraph && /* @__PURE__ */ jsxs(Stack, {
|
|
794
|
-
gap: "xs",
|
|
795
|
-
style: { minHeight: 0 },
|
|
796
|
-
children: [/* @__PURE__ */ jsx(ScrollArea.Autosize, {
|
|
797
|
-
mah: "60vh",
|
|
798
|
-
type: "auto",
|
|
799
|
-
children: /* @__PURE__ */ jsx(BarChartSelect, {
|
|
800
|
-
selected: highlighted,
|
|
801
|
-
values: entityTypes ?? [],
|
|
802
|
-
onSelect: toggle
|
|
803
|
-
})
|
|
804
|
-
}), /* @__PURE__ */ jsxs(Stack, {
|
|
805
|
-
gap: 2,
|
|
806
|
-
children: [/* @__PURE__ */ jsx(Text, {
|
|
807
|
-
size: "sm",
|
|
808
|
-
fw: 500,
|
|
809
|
-
children: "Frequency range (% of most frequent)"
|
|
810
|
-
}), /* @__PURE__ */ jsx(RangeSlider, {
|
|
811
|
-
min: 0,
|
|
812
|
-
max: 100,
|
|
813
|
-
value: range,
|
|
814
|
-
onChange: applyRange,
|
|
815
|
-
disabled: maxCount === 0,
|
|
816
|
-
label: (value) => `${value}%`,
|
|
817
|
-
minRange: 0,
|
|
818
|
-
marks: frequencyMarks,
|
|
819
|
-
inverted: mode === "include",
|
|
820
|
-
mb: "sm"
|
|
821
|
-
})]
|
|
822
|
-
})]
|
|
823
|
-
}), /* @__PURE__ */ jsxs(Group, {
|
|
824
|
-
align: "flex-end",
|
|
825
|
-
gap: "sm",
|
|
826
|
-
wrap: "nowrap",
|
|
827
|
-
children: [/* @__PURE__ */ jsx(MultiSelect, {
|
|
828
|
-
flex: 1,
|
|
829
|
-
label: isExclude ? `Excluded ${label}` : label,
|
|
830
|
-
data: entityTypes.map(({ key }) => key),
|
|
831
|
-
value: selectedEntityTypes,
|
|
832
|
-
searchable: true,
|
|
833
|
-
hidePickedOptions: true,
|
|
834
|
-
nothingFoundMessage: "No event type found",
|
|
835
|
-
onChange: (newValues) => onChange(newValues),
|
|
836
|
-
clearable: true,
|
|
837
|
-
styles: { input: {
|
|
838
|
-
flexWrap: "nowrap",
|
|
839
|
-
overflowX: "auto",
|
|
840
|
-
overflowY: "hidden"
|
|
841
|
-
} }
|
|
842
|
-
}), /* @__PURE__ */ jsx(Switch, {
|
|
843
|
-
mb: 8,
|
|
844
|
-
label: "Exclude",
|
|
845
|
-
checked: isExclude,
|
|
846
|
-
onChange: (event) => onModeChange(event.currentTarget.checked ? "exclude" : "include")
|
|
847
|
-
})]
|
|
848
|
-
})]
|
|
849
|
-
});
|
|
850
|
-
};
|
|
851
|
-
//#endregion
|
|
852
735
|
//#region src/components/FilterViews/TypeForm.tsx
|
|
736
|
+
const PICKER_CLASS = "ocelescope-type-filter-picker";
|
|
737
|
+
const FillHeightStyles = () => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(InlineStyles, {
|
|
738
|
+
deduplicate: true,
|
|
739
|
+
selector: `.${PICKER_CLASS} :has([role="listbox"])`,
|
|
740
|
+
styles: {
|
|
741
|
+
flex: 1,
|
|
742
|
+
minHeight: 0
|
|
743
|
+
}
|
|
744
|
+
}), /* @__PURE__ */ jsx(InlineStyles, {
|
|
745
|
+
deduplicate: true,
|
|
746
|
+
selector: `.${PICKER_CLASS} [role="listbox"]`,
|
|
747
|
+
styles: {
|
|
748
|
+
flex: 1,
|
|
749
|
+
minHeight: 0,
|
|
750
|
+
maxHeight: "none !important"
|
|
751
|
+
}
|
|
752
|
+
})] });
|
|
853
753
|
const EntityFilter = (entityType) => ({ ocelId, control }) => {
|
|
854
754
|
const isEvents = entityType === "events";
|
|
855
|
-
const
|
|
856
|
-
return /* @__PURE__ */ jsx(
|
|
857
|
-
name: isEvents ? `activity.0
|
|
755
|
+
const Picker = isEvents ? ActivityPicker : ObjectTypePicker;
|
|
756
|
+
return /* @__PURE__ */ jsx(Controller, {
|
|
757
|
+
name: isEvents ? `activity.0` : `object_type.0`,
|
|
858
758
|
control,
|
|
859
|
-
render: ({ field
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
759
|
+
render: ({ field }) => {
|
|
760
|
+
const filter = field.value;
|
|
761
|
+
const selected = filter?.type === "activity" ? filter.event_types : filter?.type === "object_type" ? filter.object_types : [];
|
|
762
|
+
return /* @__PURE__ */ jsxs(Stack, {
|
|
763
|
+
gap: 4,
|
|
764
|
+
flex: 1,
|
|
765
|
+
mih: 0,
|
|
766
|
+
className: PICKER_CLASS,
|
|
767
|
+
children: [/* @__PURE__ */ jsx(FillHeightStyles, {}), /* @__PURE__ */ jsx(Picker, {
|
|
768
|
+
variant: "list",
|
|
769
|
+
multiple: true,
|
|
770
|
+
cutoff: true,
|
|
771
|
+
ocelId,
|
|
772
|
+
ocelVersion: "original",
|
|
773
|
+
value: selected,
|
|
774
|
+
onChange: (next) => field.onChange(isEvents ? {
|
|
775
|
+
type: "activity",
|
|
776
|
+
event_types: next,
|
|
777
|
+
mode: "include"
|
|
778
|
+
} : {
|
|
779
|
+
type: "object_type",
|
|
780
|
+
object_types: next,
|
|
781
|
+
mode: "include"
|
|
782
|
+
})
|
|
783
|
+
})]
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
});
|
|
876
787
|
};
|
|
877
788
|
//#endregion
|
|
878
789
|
//#region src/components/FilterViews/index.tsx
|
|
879
790
|
const FILTER_MAP = {
|
|
880
791
|
activity: {
|
|
881
792
|
title: "Activity",
|
|
882
|
-
description: "Filters the event log by activity (the event type).
|
|
793
|
+
description: "Filters the event log by activity (the event type). Only events of the selected activities are kept. The list shows how many events exist per activity to help you decide what to keep.",
|
|
883
794
|
ViewComponent: EntityFilter("events"),
|
|
884
795
|
generateDefault: () => [{
|
|
885
796
|
type: "activity",
|
|
886
797
|
event_types: [],
|
|
887
|
-
mode: "
|
|
798
|
+
mode: "include"
|
|
888
799
|
}],
|
|
889
800
|
cleanUpFilters: (filter) => {
|
|
890
801
|
if (!filter[0] || filter[0].event_types.length === 0) return [];
|
|
@@ -893,12 +804,12 @@ const FILTER_MAP = {
|
|
|
893
804
|
},
|
|
894
805
|
object_type: {
|
|
895
806
|
title: "Object Type",
|
|
896
|
-
description: "Filters the log by object type.
|
|
807
|
+
description: "Filters the log by object type. Only objects of the selected types are kept. The list shows how many objects exist per type to help you decide what to keep.",
|
|
897
808
|
ViewComponent: EntityFilter("objects"),
|
|
898
809
|
generateDefault: () => [{
|
|
899
810
|
type: "object_type",
|
|
900
811
|
object_types: [],
|
|
901
|
-
mode: "
|
|
812
|
+
mode: "include"
|
|
902
813
|
}],
|
|
903
814
|
cleanUpFilters: (filter) => {
|
|
904
815
|
if (!filter[0] || filter[0].object_types.length === 0) return [];
|
|
@@ -912,12 +823,9 @@ const FILTER_MAP = {
|
|
|
912
823
|
o2o_count: O2OCountFilter
|
|
913
824
|
};
|
|
914
825
|
const generateDefaultFilter = (currentFilters) => {
|
|
915
|
-
const
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
[curr.type]: acc[curr.type] ? [...acc[curr.type] ?? [], curr] : [curr]
|
|
919
|
-
};
|
|
920
|
-
}, {});
|
|
826
|
+
const grouped = {};
|
|
827
|
+
for (const filter of currentFilters) grouped[filter.type] = [...grouped[filter.type] ?? [], filter];
|
|
828
|
+
const groupedFilter = grouped;
|
|
921
829
|
const missingFilterKeys = Object.keys(FILTER_MAP).filter((key) => !(key in groupedFilter));
|
|
922
830
|
return {
|
|
923
831
|
...groupedFilter,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ocelescope/filter",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.10.
|
|
4
|
+
"version": "0.10.2",
|
|
5
5
|
"description": "A module for basic filtering of OCELs",
|
|
6
6
|
"author": "Görkem-Emre Öztürk <goerkem.oeztuerk@rwth-aachen.de>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -28,34 +28,36 @@
|
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"@dagrejs/dagre": "^3.0.0",
|
|
31
|
-
"@mantine/
|
|
32
|
-
"@mantine/
|
|
33
|
-
"@mantine/
|
|
34
|
-
"@mantine/
|
|
35
|
-
"@
|
|
36
|
-
"@ocelescope/api-
|
|
37
|
-
"@ocelescope/
|
|
38
|
-
"@
|
|
39
|
-
"@tanstack/react-query": "^5.90.21",
|
|
31
|
+
"@mantine/core": "^9.7.2",
|
|
32
|
+
"@mantine/dates": "^9.7.2",
|
|
33
|
+
"@mantine/hooks": "^9.7.2",
|
|
34
|
+
"@mantine/notifications": "^9.7.2",
|
|
35
|
+
"@ocelescope/api-base": "^0.10.2",
|
|
36
|
+
"@ocelescope/api-client": "^0.10.2",
|
|
37
|
+
"@ocelescope/core": "^0.10.2",
|
|
38
|
+
"@tanstack/react-query": "^5.104.2",
|
|
40
39
|
"axios": "^1.20.0",
|
|
41
40
|
"dayjs": "^1.11.23",
|
|
42
|
-
"
|
|
41
|
+
"echarts": "^6.1.0",
|
|
42
|
+
"echarts-for-react": "^3.0.6",
|
|
43
|
+
"lucide-react": "^1.56.0",
|
|
43
44
|
"mantine-datatable": "^9.4.0",
|
|
44
|
-
"next": "16.
|
|
45
|
+
"next": "16.4.0",
|
|
45
46
|
"object-hash": "^3.0.0",
|
|
46
47
|
"react": "^19.3.0",
|
|
47
48
|
"react-dom": "^19.3.0",
|
|
48
|
-
"react-hook-form": "^7.
|
|
49
|
-
"recharts": "^3.2.1"
|
|
49
|
+
"react-hook-form": "^7.90.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@mantine/notifications": "^9.
|
|
53
|
-
"@ocelescope/api-config": "^0.10.
|
|
52
|
+
"@mantine/notifications": "^9.7.2",
|
|
53
|
+
"@ocelescope/api-config": "^0.10.2",
|
|
54
54
|
"@types/node": "^26.6.1",
|
|
55
55
|
"@types/object-hash": "^3.0.6",
|
|
56
56
|
"@types/react": "^19.3.0",
|
|
57
57
|
"@types/react-dom": "^19.3.0",
|
|
58
|
-
"
|
|
58
|
+
"echarts": "^6.1.0",
|
|
59
|
+
"echarts-for-react": "^3.0.6",
|
|
60
|
+
"tsdown": "^0.23.1",
|
|
59
61
|
"typescript": "^6.0.3"
|
|
60
62
|
},
|
|
61
63
|
"scripts": {
|