ar-design 0.4.13 → 0.4.14
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/assets/css/components/data-display/table/properties-popup.css +42 -0
- package/dist/assets/css/components/data-display/table/styles.css +20 -0
- package/dist/components/data-display/table/FilterPopup.d.ts +6 -2
- package/dist/components/data-display/table/FilterPopup.js +7 -9
- package/dist/components/data-display/table/Helpers.d.ts +2 -0
- package/dist/components/data-display/table/Helpers.js +10 -0
- package/dist/components/data-display/table/IProps.d.ts +5 -0
- package/dist/components/data-display/table/PropertiesPopup.d.ts +23 -0
- package/dist/components/data-display/table/PropertiesPopup.js +91 -0
- package/dist/components/data-display/table/THeadCell.d.ts +17 -2
- package/dist/components/data-display/table/THeadCell.js +36 -4
- package/dist/components/data-display/table/index.js +48 -5
- package/dist/components/icons/Compiler.js +10 -0
- package/dist/libs/types/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
.ar-table-properties-popup {
|
|
2
|
+
position: absolute;
|
|
3
|
+
background-color: var(--white);
|
|
4
|
+
width: 225px;
|
|
5
|
+
padding: 0.5rem 0;
|
|
6
|
+
border-radius: var(--border-radius-sm);
|
|
7
|
+
box-shadow: 0px 10px 15px -5px rgba(var(--black-rgb), 0.1);
|
|
8
|
+
transition:
|
|
9
|
+
top 350ms,
|
|
10
|
+
left 1s cubic-bezier(0.68, -0.6, 0.32, 1.6);
|
|
11
|
+
z-index: 1052;
|
|
12
|
+
|
|
13
|
+
> ul {
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
align-items: flex-start;
|
|
18
|
+
|
|
19
|
+
> li {
|
|
20
|
+
display: flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
gap: 0.5rem;
|
|
23
|
+
width: 100%;
|
|
24
|
+
padding: 0.5rem;
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
transition: background 250ms ease-in-out;
|
|
27
|
+
user-select: none;
|
|
28
|
+
|
|
29
|
+
&:hover {
|
|
30
|
+
background-color: var(--gray-100);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
> span {
|
|
34
|
+
position: relative;
|
|
35
|
+
|
|
36
|
+
&:first-child {
|
|
37
|
+
top: 2.5px;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
@import url("./scroll.css");
|
|
2
2
|
@import url("./filter-popup.css");
|
|
3
|
+
@import url("./properties-popup.css");
|
|
3
4
|
|
|
4
5
|
.ar-table {
|
|
5
6
|
display: flex;
|
|
@@ -147,6 +148,25 @@
|
|
|
147
148
|
text-align: right;
|
|
148
149
|
}
|
|
149
150
|
|
|
151
|
+
> div {
|
|
152
|
+
display: flex;
|
|
153
|
+
justify-content: space-between;
|
|
154
|
+
align-items: center;
|
|
155
|
+
gap: 1rem;
|
|
156
|
+
width: 100%;
|
|
157
|
+
|
|
158
|
+
> span {
|
|
159
|
+
display: flex;
|
|
160
|
+
align-items: center;
|
|
161
|
+
gap: 0.5rem;
|
|
162
|
+
|
|
163
|
+
> span {
|
|
164
|
+
position: relative;
|
|
165
|
+
top: 2.5px;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
150
170
|
> .table-cell {
|
|
151
171
|
padding: 0 1rem;
|
|
152
172
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import React, { MutableRefObject, ReactNode } from "react";
|
|
1
|
+
import React, { Dispatch, MutableRefObject, ReactNode, SetStateAction } from "react";
|
|
2
2
|
interface IProps {
|
|
3
3
|
children: ReactNode;
|
|
4
|
+
open: {
|
|
5
|
+
get: boolean;
|
|
6
|
+
set: Dispatch<SetStateAction<boolean>>;
|
|
7
|
+
};
|
|
4
8
|
tableContent: MutableRefObject<HTMLDivElement | null>;
|
|
5
9
|
coordinate: {
|
|
6
10
|
x: number;
|
|
@@ -8,5 +12,5 @@ interface IProps {
|
|
|
8
12
|
};
|
|
9
13
|
buttons: MutableRefObject<(HTMLSpanElement | null)[]>;
|
|
10
14
|
}
|
|
11
|
-
declare const FilterPopup: ({ children, tableContent, coordinate, buttons }: IProps) => false | React.ReactPortal;
|
|
15
|
+
declare const FilterPopup: ({ children, open, tableContent, coordinate, buttons }: IProps) => false | React.ReactPortal;
|
|
12
16
|
export default FilterPopup;
|
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import React, { useEffect, useRef
|
|
2
|
+
import React, { useEffect, useRef } from "react";
|
|
3
3
|
import ReactDOM from "react-dom";
|
|
4
|
-
const FilterPopup = ({ children, tableContent, coordinate, buttons }) => {
|
|
4
|
+
const FilterPopup = ({ children, open, tableContent, coordinate, buttons }) => {
|
|
5
5
|
// refs
|
|
6
6
|
const _arTableFilterPopup = useRef(null);
|
|
7
|
-
// states
|
|
8
|
-
const [open, setOpen] = useState(false);
|
|
9
7
|
// methods
|
|
10
8
|
const handleClickOutSide = (event) => {
|
|
11
9
|
const target = event.target;
|
|
12
10
|
const clickedInsidePopup = _arTableFilterPopup.current && _arTableFilterPopup.current.contains(target);
|
|
13
11
|
const isOneOfButtons = buttons.current.some((button) => button === target || button?.contains(target));
|
|
14
12
|
if (!clickedInsidePopup && !isOneOfButtons)
|
|
15
|
-
|
|
13
|
+
handleClose();
|
|
16
14
|
};
|
|
17
15
|
const handleKeys = (event) => {
|
|
18
16
|
const key = event.key;
|
|
19
17
|
if (key === "Escape")
|
|
20
|
-
|
|
18
|
+
open.set(false);
|
|
21
19
|
};
|
|
22
|
-
const handleOpen = () =>
|
|
23
|
-
const handleClose = () =>
|
|
20
|
+
const handleOpen = () => open.set(true);
|
|
21
|
+
const handleClose = () => open.set(false);
|
|
24
22
|
// useEffects
|
|
25
23
|
useEffect(() => {
|
|
26
24
|
buttons.current.map((button) => {
|
|
@@ -54,7 +52,7 @@ const FilterPopup = ({ children, tableContent, coordinate, buttons }) => {
|
|
|
54
52
|
}
|
|
55
53
|
};
|
|
56
54
|
}, []);
|
|
57
|
-
return (open &&
|
|
55
|
+
return (open.get &&
|
|
58
56
|
ReactDOM.createPortal(React.createElement("div", { ref: _arTableFilterPopup, className: "ar-table-filter-popup", style: { top: coordinate.y, left: coordinate.x } }, children), document.body));
|
|
59
57
|
};
|
|
60
58
|
export default FilterPopup;
|
|
@@ -7,6 +7,10 @@ export type FilterValue = {
|
|
|
7
7
|
value: string | number | boolean;
|
|
8
8
|
operator: FilterOperator;
|
|
9
9
|
};
|
|
10
|
+
export type Sort<T> = {
|
|
11
|
+
key: keyof T;
|
|
12
|
+
direction: "asc" | "desc" | null;
|
|
13
|
+
};
|
|
10
14
|
export type SearchedParam = {
|
|
11
15
|
[key: string]: FilterValue | FilterValue[];
|
|
12
16
|
};
|
|
@@ -73,6 +77,7 @@ interface IProps<T> extends IChildren {
|
|
|
73
77
|
rowBackgroundColor?: (item: T) => string;
|
|
74
78
|
selections?: (selectionItems: T[]) => void;
|
|
75
79
|
previousSelections?: T[];
|
|
80
|
+
sortedParams?: (params: Sort<T>[], query: string) => void;
|
|
76
81
|
searchedParams?: (params: SearchedParam | null, query: string, operator: FilterOperator) => void;
|
|
77
82
|
onEditable?: (item: T, trackByValue: string) => void;
|
|
78
83
|
onDnD?: (item: T[]) => void;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React, { Dispatch, MutableRefObject, SetStateAction } from "react";
|
|
2
|
+
import { TableColumnType } from "../../../libs/types";
|
|
3
|
+
import { Sort } from "./IProps";
|
|
4
|
+
interface IProps<T> {
|
|
5
|
+
open: {
|
|
6
|
+
get: boolean;
|
|
7
|
+
set: Dispatch<SetStateAction<boolean>>;
|
|
8
|
+
};
|
|
9
|
+
sort: {
|
|
10
|
+
get: Sort<T>[];
|
|
11
|
+
set: Dispatch<SetStateAction<Sort<T>[]>>;
|
|
12
|
+
currentColumn: TableColumnType<T> | null;
|
|
13
|
+
};
|
|
14
|
+
tableContent: MutableRefObject<HTMLDivElement | null>;
|
|
15
|
+
coordinate: {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
};
|
|
19
|
+
buttons: MutableRefObject<(HTMLSpanElement | null)[]>;
|
|
20
|
+
}
|
|
21
|
+
declare function PropertiesPopup<T extends object>({ open, sort, tableContent, coordinate, buttons }: IProps<T>): false | React.ReactPortal;
|
|
22
|
+
declare const _default: typeof PropertiesPopup;
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React, { memo, useEffect, useMemo, useRef } from "react";
|
|
3
|
+
import ReactDOM from "react-dom";
|
|
4
|
+
import { ARIcon } from "../../icons";
|
|
5
|
+
import { ExtractKey } from "./Helpers";
|
|
6
|
+
function PropertiesPopup({ open, sort, tableContent, coordinate, buttons }) {
|
|
7
|
+
// refs
|
|
8
|
+
const _arTablePropertiesPopup = useRef(null);
|
|
9
|
+
// methods
|
|
10
|
+
// const handleClickOutSide = useCallback(() => {
|
|
11
|
+
// (event: MouseEvent) => {
|
|
12
|
+
// const target = event.target as HTMLElement;
|
|
13
|
+
// const clickedInsidePopup = _arTablePropertiesPopup.current && _arTablePropertiesPopup.current.contains(target);
|
|
14
|
+
// const isOneOfButtons = buttons.current.some((button) => button === target || button?.contains(target));
|
|
15
|
+
// if (!clickedInsidePopup && !isOneOfButtons) handleClose();
|
|
16
|
+
// };
|
|
17
|
+
// }, []);
|
|
18
|
+
const handleSort = useMemo(() => {
|
|
19
|
+
return (columnKey, direction) => {
|
|
20
|
+
if (!columnKey)
|
|
21
|
+
return;
|
|
22
|
+
sort.set((prev) => {
|
|
23
|
+
const index = prev.findIndex((s) => s.key === columnKey);
|
|
24
|
+
if (index !== -1)
|
|
25
|
+
return [{ key: columnKey, direction }];
|
|
26
|
+
return [{ key: columnKey, direction }];
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}, []);
|
|
30
|
+
const handleKeys = (event) => {
|
|
31
|
+
const key = event.key;
|
|
32
|
+
if (key === "Escape")
|
|
33
|
+
open.set(false);
|
|
34
|
+
};
|
|
35
|
+
const handleOpen = () => open.set(true);
|
|
36
|
+
const handleClose = () => open.set(false);
|
|
37
|
+
// useEffects
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
buttons.current.map((button) => {
|
|
40
|
+
if (button)
|
|
41
|
+
button.addEventListener("click", handleOpen);
|
|
42
|
+
});
|
|
43
|
+
return () => {
|
|
44
|
+
buttons.current.map((button) => {
|
|
45
|
+
if (button)
|
|
46
|
+
button.removeEventListener("click", handleOpen);
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
}, [buttons]);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
const firstFilterButton = buttons.current[0];
|
|
52
|
+
if (firstFilterButton) {
|
|
53
|
+
const rect = firstFilterButton.getBoundingClientRect();
|
|
54
|
+
coordinate.x = rect.left;
|
|
55
|
+
coordinate.y = rect.top + rect.height;
|
|
56
|
+
}
|
|
57
|
+
if (tableContent.current) {
|
|
58
|
+
tableContent.current.addEventListener("scroll", handleClose);
|
|
59
|
+
}
|
|
60
|
+
// document.addEventListener("click", handleClickOutSide);
|
|
61
|
+
document.addEventListener("keydown", handleKeys);
|
|
62
|
+
return () => {
|
|
63
|
+
// document.removeEventListener("click", handleClickOutSide);
|
|
64
|
+
document.removeEventListener("keydown", handleKeys);
|
|
65
|
+
if (tableContent.current) {
|
|
66
|
+
tableContent.current.removeEventListener("scroll", handleClose);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}, []);
|
|
70
|
+
const currentKey = ExtractKey(sort.currentColumn?.key);
|
|
71
|
+
const currentSort = sort.get?.find((s) => s.key === currentKey);
|
|
72
|
+
return (open.get &&
|
|
73
|
+
ReactDOM.createPortal(React.createElement("div", { ref: _arTablePropertiesPopup, className: "ar-table-properties-popup", style: { top: coordinate.y, left: coordinate.x } },
|
|
74
|
+
React.createElement("ul", null,
|
|
75
|
+
currentSort && (!currentSort.direction || currentSort.direction === "desc") && (React.createElement("li", { onClick: () => handleSort(currentKey, "asc") },
|
|
76
|
+
React.createElement("span", null,
|
|
77
|
+
React.createElement(ARIcon, { icon: "ArrowUp" })),
|
|
78
|
+
React.createElement("span", null, "Sort Ascending"))),
|
|
79
|
+
currentSort && (!currentSort.direction || currentSort.direction === "asc") && (React.createElement("li", { onClick: () => handleSort(currentKey, "desc") },
|
|
80
|
+
React.createElement("span", null,
|
|
81
|
+
React.createElement(ARIcon, { icon: "ArrowDown" })),
|
|
82
|
+
React.createElement("span", null, "Sort Descending"))),
|
|
83
|
+
currentSort && currentSort.direction && (React.createElement("li", { onClick: () => {
|
|
84
|
+
sort.set((prev) => prev.filter((s) => s.key !== currentKey));
|
|
85
|
+
open.set(false);
|
|
86
|
+
} },
|
|
87
|
+
React.createElement("span", null,
|
|
88
|
+
React.createElement(ARIcon, { icon: "ChevronExpand" })),
|
|
89
|
+
React.createElement("span", null, "Clear Sort"))))), document.body));
|
|
90
|
+
}
|
|
91
|
+
export default memo(PropertiesPopup);
|
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
import React from "react";
|
|
1
|
+
import React, { Dispatch, SetStateAction } from "react";
|
|
2
2
|
import { TableColumnType } from "../../../libs/types";
|
|
3
|
-
|
|
3
|
+
import { Sort } from "./IProps";
|
|
4
|
+
declare const MemoizedTHeadCell: <T>({ open, sort, columns, propertiesButton, setSortCurrentColumn, setPropertiesButtonCoordinate, }: {
|
|
5
|
+
open: {
|
|
6
|
+
get: boolean;
|
|
7
|
+
set: Dispatch<SetStateAction<boolean>>;
|
|
8
|
+
};
|
|
9
|
+
sort: {
|
|
10
|
+
get: Sort<T>[];
|
|
11
|
+
set: Dispatch<SetStateAction<Sort<T>[]>>;
|
|
12
|
+
};
|
|
4
13
|
columns: TableColumnType<T>[];
|
|
14
|
+
propertiesButton: React.MutableRefObject<(HTMLSpanElement | null)[]>;
|
|
15
|
+
setSortCurrentColumn: React.Dispatch<React.SetStateAction<TableColumnType<T> | null>>;
|
|
16
|
+
setPropertiesButtonCoordinate: React.Dispatch<React.SetStateAction<{
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
}>>;
|
|
5
20
|
}) => React.JSX.Element;
|
|
6
21
|
declare const THeadCell: typeof MemoizedTHeadCell;
|
|
7
22
|
export default THeadCell;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
|
|
1
|
+
import React, { memo } from "react";
|
|
2
|
+
import Button from "../../form/button";
|
|
3
|
+
import { ARIcon } from "../../icons";
|
|
4
|
+
import { ExtractKey } from "./Helpers";
|
|
5
|
+
const MemoizedTHeadCell = function ({ open, sort, columns, propertiesButton, setSortCurrentColumn, setPropertiesButtonCoordinate, }) {
|
|
3
6
|
return (React.createElement(React.Fragment, null, columns.map((c, cIndex) => {
|
|
7
|
+
const _direction = sort.get.find((s) => s.key === c.key)?.direction;
|
|
4
8
|
let _className = [];
|
|
5
9
|
if (c.config?.sticky)
|
|
6
10
|
_className.push(`sticky-${c.config.sticky}`);
|
|
@@ -19,9 +23,37 @@ const MemoizedTHeadCell = function ({ columns }) {
|
|
|
19
23
|
{ style: {} }), ...(c.config?.sticky && {
|
|
20
24
|
"data-sticky-position": c.config.sticky,
|
|
21
25
|
}) },
|
|
22
|
-
React.createElement("
|
|
26
|
+
React.createElement("div", null,
|
|
27
|
+
React.createElement("span", { style: { fontWeight: 500 } },
|
|
28
|
+
React.createElement("span", null,
|
|
29
|
+
_direction === "asc" && React.createElement(ARIcon, { icon: "ArrowUp" }),
|
|
30
|
+
_direction === "desc" && React.createElement(ARIcon, { icon: "ArrowDown" })),
|
|
31
|
+
c.title),
|
|
32
|
+
React.createElement("span", { ref: (element) => (propertiesButton.current[cIndex] = element), className: "properties-field", onClick: (event) => {
|
|
33
|
+
event.stopPropagation();
|
|
34
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
35
|
+
const screenCenterX = window.innerWidth / 2;
|
|
36
|
+
const coordinateX = rect.x > screenCenterX ? rect.x + rect.width - 225 : rect.x;
|
|
37
|
+
const coordinateY = rect.y + rect.height;
|
|
38
|
+
setSortCurrentColumn(c);
|
|
39
|
+
setPropertiesButtonCoordinate({
|
|
40
|
+
x: coordinateX,
|
|
41
|
+
y: coordinateY,
|
|
42
|
+
});
|
|
43
|
+
sort.set((prev) => {
|
|
44
|
+
const key = ExtractKey(c.key);
|
|
45
|
+
const index = prev.findIndex((s) => s.key === key);
|
|
46
|
+
if (index === -1)
|
|
47
|
+
return [...prev, { key, direction: null }];
|
|
48
|
+
return prev;
|
|
49
|
+
});
|
|
50
|
+
open.set(true);
|
|
51
|
+
} },
|
|
52
|
+
React.createElement(Button, { variant: "borderless", icon: {
|
|
53
|
+
element: React.createElement(ARIcon, { size: 16, icon: "ThreeDotsVertical", fill: "var(--dark)", strokeWidth: 0 }),
|
|
54
|
+
} })))));
|
|
23
55
|
})));
|
|
24
56
|
};
|
|
25
57
|
// React.memo kullanımı sırasında generic tipi koruyoruz.
|
|
26
|
-
const THeadCell =
|
|
58
|
+
const THeadCell = memo(MemoizedTHeadCell);
|
|
27
59
|
export default THeadCell;
|
|
@@ -18,6 +18,8 @@ import Tooltip from "../../feedback/tooltip";
|
|
|
18
18
|
import Editable from "./Editable";
|
|
19
19
|
import { flushSync } from "react-dom";
|
|
20
20
|
import { createRoot } from "react-dom/client";
|
|
21
|
+
import PropertiesPopup from "./PropertiesPopup";
|
|
22
|
+
import { ExtractKey } from "./Helpers";
|
|
21
23
|
const filterOption = [
|
|
22
24
|
{ value: FilterOperator.Contains, text: "İçerir" },
|
|
23
25
|
{ value: FilterOperator.DoesNotContains, text: "İçermez" },
|
|
@@ -29,7 +31,7 @@ const filterOption = [
|
|
|
29
31
|
{ value: FilterOperator.NotBlank, text: "Boş değil" },
|
|
30
32
|
];
|
|
31
33
|
const { Row, Column } = Grid;
|
|
32
|
-
const Table = forwardRef(({ children, trackBy, title, description, data, columns, actions, rowBackgroundColor, selections, previousSelections, searchedParams, onEditable, onDnD, pagination, config = { isSearchable: false }, }, ref) => {
|
|
34
|
+
const Table = forwardRef(({ children, trackBy, title, description, data, columns, actions, rowBackgroundColor, selections, previousSelections, sortedParams, searchedParams, onEditable, onDnD, pagination, config = { isSearchable: false }, }, ref) => {
|
|
33
35
|
// refs
|
|
34
36
|
const _innerRef = useRef(null);
|
|
35
37
|
const _tableWrapper = useRef(null);
|
|
@@ -42,6 +44,8 @@ const Table = forwardRef(({ children, trackBy, title, description, data, columns
|
|
|
42
44
|
// refs -> Search
|
|
43
45
|
const _searchTextInputs = useRef([]);
|
|
44
46
|
const _searchTimeOut = useRef(null);
|
|
47
|
+
// refs -> Properties
|
|
48
|
+
const _propertiesButton = useRef([]);
|
|
45
49
|
// refs -> Filter
|
|
46
50
|
const _filterButton = useRef([]);
|
|
47
51
|
// refs -> Selection
|
|
@@ -65,12 +69,22 @@ const Table = forwardRef(({ children, trackBy, title, description, data, columns
|
|
|
65
69
|
const [searchedText, setSearchedText] = useState(null);
|
|
66
70
|
const [_searchedParams, setSearchedParams] = useState(null);
|
|
67
71
|
const [checkboxSelectedParams, setCheckboxSelectedParams] = useState(null);
|
|
72
|
+
// states -> Sort
|
|
73
|
+
const [sortConfig, setSortConfig] = useState([]);
|
|
74
|
+
const [sortCurrentColumn, setSortCurrentColumn] = useState(null);
|
|
75
|
+
// states -> Properties
|
|
76
|
+
const [openProperties, setOpenProperties] = useState(false);
|
|
77
|
+
const [propertiesButtonCoordinate, setPropertiesButtonCoordinate] = useState({
|
|
78
|
+
x: 0,
|
|
79
|
+
y: 0,
|
|
80
|
+
});
|
|
68
81
|
// states -> Filter
|
|
69
82
|
const [filterButtonCoordinate, setFilterButtonCoordinate] = useState({ x: 0, y: 0 });
|
|
70
83
|
const [filterPopupContent, setFilterPopupContent] = useState(null);
|
|
71
84
|
const [filterPopupOption, setFilterPopupOption] = useState(null);
|
|
72
85
|
const [filterPopupOptionSearchText, setFilterPopupOptionSearchText] = useState(null);
|
|
73
86
|
// states -> Filter Fields Backup
|
|
87
|
+
const [openFilter, setOpenFilter] = useState(false);
|
|
74
88
|
const [filterCurrentColumn, setFilterCurrentColumn] = useState(null);
|
|
75
89
|
const [filterCurrentDataType, setFilterCurrentDataType] = useState(null);
|
|
76
90
|
const [filterCurrentIndex, setFilterCurrentIndex] = useState(null);
|
|
@@ -211,7 +225,9 @@ const Table = forwardRef(({ children, trackBy, title, description, data, columns
|
|
|
211
225
|
});
|
|
212
226
|
}, []);
|
|
213
227
|
const handleFilterPopupContent = (c, dataType, index) => {
|
|
214
|
-
const key =
|
|
228
|
+
const key = ExtractKey(c.key);
|
|
229
|
+
if (!key)
|
|
230
|
+
return;
|
|
215
231
|
const value = Array.isArray(searchedText?.[key])
|
|
216
232
|
? "" // veya ihtiyacına göre birleştirme yap: searchedText[key].map(v => v.value).join(", ").
|
|
217
233
|
: searchedText?.[key]?.value;
|
|
@@ -357,13 +373,27 @@ const Table = forwardRef(({ children, trackBy, title, description, data, columns
|
|
|
357
373
|
else {
|
|
358
374
|
setTotalRecords(data.length);
|
|
359
375
|
}
|
|
376
|
+
// Sorting...
|
|
377
|
+
if (sortConfig.length > 0) {
|
|
378
|
+
_data.sort((a, b) => {
|
|
379
|
+
for (const config of sortConfig) {
|
|
380
|
+
const aValue = a[config.key];
|
|
381
|
+
const bValue = b[config.key];
|
|
382
|
+
if (aValue < bValue)
|
|
383
|
+
return config.direction === "asc" ? -1 : 1;
|
|
384
|
+
if (aValue > bValue)
|
|
385
|
+
return config.direction === "asc" ? 1 : -1;
|
|
386
|
+
}
|
|
387
|
+
return 0;
|
|
388
|
+
});
|
|
389
|
+
}
|
|
360
390
|
if (pagination && !config.isServerSide) {
|
|
361
391
|
const indexOfLastRow = currentPage * selectedPerPage;
|
|
362
392
|
const indexOfFirstRow = indexOfLastRow - selectedPerPage;
|
|
363
393
|
_data = _data.slice(indexOfFirstRow, indexOfLastRow);
|
|
364
394
|
}
|
|
365
395
|
return _data;
|
|
366
|
-
}, [data, searchedText, currentPage, selectedPerPage]);
|
|
396
|
+
}, [data, searchedText, currentPage, selectedPerPage, sortConfig]);
|
|
367
397
|
const renderRow = (item, index, deph) => {
|
|
368
398
|
const isHasSubitems = _subrowSelector in item;
|
|
369
399
|
let _rowColor = {};
|
|
@@ -485,6 +515,17 @@ const Table = forwardRef(({ children, trackBy, title, description, data, columns
|
|
|
485
515
|
_selectionItems.current = validSelections;
|
|
486
516
|
}
|
|
487
517
|
}, [previousSelections, data, trackBy]);
|
|
518
|
+
useEffect(() => {
|
|
519
|
+
if (config?.isServerSide && sortedParams) {
|
|
520
|
+
const sortRecord = {};
|
|
521
|
+
sortConfig?.forEach((s) => {
|
|
522
|
+
if (s.direction)
|
|
523
|
+
sortRecord[String(s.key)] = s.direction;
|
|
524
|
+
});
|
|
525
|
+
const query = new URLSearchParams(sortRecord);
|
|
526
|
+
sortedParams(sortConfig ?? [], query.toString());
|
|
527
|
+
}
|
|
528
|
+
}, [sortConfig]);
|
|
488
529
|
useEffect(() => {
|
|
489
530
|
if (config?.isServerSide && searchedParams) {
|
|
490
531
|
const searchRecord = {};
|
|
@@ -727,7 +768,7 @@ const Table = forwardRef(({ children, trackBy, title, description, data, columns
|
|
|
727
768
|
});
|
|
728
769
|
}
|
|
729
770
|
} }))),
|
|
730
|
-
React.createElement(THeadCell, { columns: columns })),
|
|
771
|
+
React.createElement(THeadCell, { open: { get: openProperties, set: setOpenProperties }, sort: { get: sortConfig, set: setSortConfig }, columns: columns, propertiesButton: _propertiesButton, setSortCurrentColumn: setSortCurrentColumn, setPropertiesButtonCoordinate: setPropertiesButtonCoordinate })),
|
|
731
772
|
config?.isSearchable && (React.createElement("tr", { key: "isSearchable" },
|
|
732
773
|
selections && (React.createElement("th", { key: `column-selections`, className: "selection-col sticky-left", "data-sticky-position": "left" })),
|
|
733
774
|
columns.map((c, cIndex) => {
|
|
@@ -770,6 +811,7 @@ const Table = forwardRef(({ children, trackBy, title, description, data, columns
|
|
|
770
811
|
setFilterCurrentColumn(c);
|
|
771
812
|
setFilterCurrentDataType(dataType);
|
|
772
813
|
setFilterCurrentIndex(cIndex);
|
|
814
|
+
setOpenFilter(true);
|
|
773
815
|
handleFilterPopupContent(c, dataType, cIndex);
|
|
774
816
|
} },
|
|
775
817
|
React.createElement(Button, { variant: "borderless", icon: {
|
|
@@ -777,7 +819,8 @@ const Table = forwardRef(({ children, trackBy, title, description, data, columns
|
|
|
777
819
|
} }))))));
|
|
778
820
|
})))),
|
|
779
821
|
React.createElement("tbody", { ref: _tBody }, renderTBody))),
|
|
780
|
-
React.createElement(FilterPopup, { tableContent: _tableContent, coordinate: filterButtonCoordinate, buttons: _filterButton }, filterPopupContent),
|
|
822
|
+
React.createElement(FilterPopup, { open: { get: openFilter, set: setOpenFilter }, tableContent: _tableContent, coordinate: filterButtonCoordinate, buttons: _filterButton }, filterPopupContent),
|
|
823
|
+
React.createElement(PropertiesPopup, { open: { get: openProperties, set: setOpenProperties }, sort: { get: sortConfig, set: setSortConfig, currentColumn: sortCurrentColumn }, tableContent: _tableContent, coordinate: propertiesButtonCoordinate, buttons: _propertiesButton }),
|
|
781
824
|
pagination && (React.createElement("div", { className: "footer" },
|
|
782
825
|
React.createElement("span", null, isMobile ? (React.createElement(React.Fragment, null,
|
|
783
826
|
React.createElement("strong", null,
|
|
@@ -10,10 +10,16 @@ class Icon {
|
|
|
10
10
|
switch (icon) {
|
|
11
11
|
case "Add":
|
|
12
12
|
return (React.createElement("path", { d: "M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0 0 1 8 4" }));
|
|
13
|
+
case "ArrowDown":
|
|
14
|
+
return (React.createElement("path", { fillRule: "evenodd", d: "M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1" }));
|
|
15
|
+
case "ArrowDownUp":
|
|
16
|
+
return (React.createElement("path", { fillRule: "evenodd", d: "M11.5 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L11 2.707V14.5a.5.5 0 0 0 .5.5m-7-14a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L4 13.293V1.5a.5.5 0 0 1 .5-.5" }));
|
|
13
17
|
case "ArrowLeft":
|
|
14
18
|
return (React.createElement("path", { fillRule: "evenodd", d: "M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8", stroke: this._stroke, strokeWidth: this._strokeWidth, strokeMiterlimit: "10", strokeLinecap: "round", strokeLinejoin: "round" }));
|
|
15
19
|
case "ArrowRight":
|
|
16
20
|
return (React.createElement("path", { fillRule: "evenodd", d: "M1 8a.5.5 0 0 1 .5-.5h11.793l-3.147-3.146a.5.5 0 0 1 .708-.708l4 4a.5.5 0 0 1 0 .708l-4 4a.5.5 0 0 1-.708-.708L13.293 8.5H1.5A.5.5 0 0 1 1 8", stroke: this._stroke, strokeWidth: this._strokeWidth, strokeMiterlimit: "10", strokeLinecap: "round", strokeLinejoin: "round" }));
|
|
21
|
+
case "ArrowUp":
|
|
22
|
+
return (React.createElement("path", { fillRule: "evenodd", d: "M8 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L7.5 2.707V14.5a.5.5 0 0 0 .5.5" }));
|
|
17
23
|
case "Bold":
|
|
18
24
|
return (React.createElement("path", { d: "M8.21 13c2.106 0 3.412-1.087 3.412-2.823 0-1.306-.984-2.283-2.324-2.386v-.055a2.176 2.176 0 0 0 1.852-2.14c0-1.51-1.162-2.46-3.014-2.46H3.843V13zM5.908 4.674h1.696c.963 0 1.517.451 1.517 1.244 0 .834-.629 1.32-1.73 1.32H5.908V4.673zm0 6.788V8.598h1.73c1.217 0 1.88.492 1.88 1.415 0 .943-.643 1.449-1.832 1.449H5.907z" }));
|
|
19
25
|
case "BulletList":
|
|
@@ -31,6 +37,8 @@ class Icon {
|
|
|
31
37
|
return (React.createElement("path", { d: "M4.146 3.646a.5.5 0 0 0 0 .708L7.793 8l-3.647 3.646a.5.5 0 0 0 .708.708l4-4a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708 0M11.5 1a.5.5 0 0 1 .5.5v13a.5.5 0 0 1-1 0v-13a.5.5 0 0 1 .5-.5", fillRule: "evenodd", stroke: this._stroke, strokeWidth: this._strokeWidth, strokeMiterlimit: "10", strokeLinecap: "round", strokeLinejoin: "round" }));
|
|
32
38
|
case "ChevronDown":
|
|
33
39
|
return (React.createElement("path", { fillRule: "evenodd", d: "M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708" }));
|
|
40
|
+
case "ChevronExpand":
|
|
41
|
+
return (React.createElement("path", { fillRule: "evenodd", d: "M3.646 9.146a.5.5 0 0 1 .708 0L8 12.793l3.646-3.647a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 0-.708m0-2.292a.5.5 0 0 0 .708 0L8 3.207l3.646 3.647a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 0 0 0 .708" }));
|
|
34
42
|
case "ChevronUp":
|
|
35
43
|
return (React.createElement("path", { fillRule: "evenodd", d: "M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708z" }));
|
|
36
44
|
case "CloseCircle":
|
|
@@ -120,6 +128,8 @@ class Icon {
|
|
|
120
128
|
return (React.createElement("path", { fillRule: "evenodd", d: "M2 12.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5m0-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5" }));
|
|
121
129
|
case "TextAlingRight":
|
|
122
130
|
return (React.createElement("path", { fillRule: "evenodd", d: "M6 12.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m-4-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5m4-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m-4-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5" }));
|
|
131
|
+
case "ThreeDotsVertical":
|
|
132
|
+
return (React.createElement("path", { d: "M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0" }));
|
|
123
133
|
case "TickCircle":
|
|
124
134
|
return (React.createElement(React.Fragment, null,
|
|
125
135
|
React.createElement("path", { d: "M12 22c5.5 0 10-4.5 10-10S17.5 2 12 2 2 6.5 2 12s4.5 10 10 10Z", stroke: this._stroke, strokeWidth: this._strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
@@ -85,7 +85,7 @@ export type Errors<TData> = Partial<{
|
|
|
85
85
|
}>;
|
|
86
86
|
export type MimeTypes = "image/jpeg" | "image/png" | "image/gif" | "image/webp" | "image/svg+xml" | "image/bmp" | "image/tiff" | "application/pdf" | "application/msword" | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/vnd.ms-excel" | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | "application/vnd.openxmlformats-officedocument.presentationml.presentation" | "application/zip" | "application/x-rar-compressed" | "application/x-7z-compressed" | "application/gzip" | "application/json" | "application/xml" | "text/plain" | "text/csv" | "text/html" | "video/mp4" | "video/quicktime" | "video/x-msvideo" | "video/x-matroska" | "video/webm" | "video/x-flv" | "audio/mpeg" | "audio/wav" | "audio/ogg" | "audio/aac" | "audio/flac" | "application/octet-stream";
|
|
87
87
|
export type FileCategory = "image" | "document" | "spreadsheet" | "presentation" | "archive" | "text" | "video" | "audio" | "json" | "xml" | "binary" | "other";
|
|
88
|
-
export type Icons = "Add" | "ArrowLeft" | "ArrowRight" | "Bold" | "BulletList" | "CameraReels" | "CheckAll" | "ChevronBarLeft" | "ChevronBarRight" | "ChevronDown" | "ChevronUp" | "CloseCircle" | "CloseSquare" | "CloudUpload-Fill" | "Dash" | "Document" | "Download" | "ExclamationCircle" | "ExclamationDiamond-Fill" | "Eye-Fill" | "File" | "FileEarmark-Fill" | "FileTypeCsv" | "FileTypeDoc" | "FileTypeDocx" | "FileTypeHtml" | "FileTypeJson" | "FileTypePdf" | "FileTypePptx" | "FileTypeTxt" | "FileTypeXls" | "FileTypeXlsx" | "FileTypeXml" | "FileTypeZip" | "Filter" | "Floppy-Fill" | "Folder" | "Front" | "GripVertical" | "Import" | "Inbox-Fill" | "Information-Circle-Fill" | "Italic" | "NumberList" | "Strikethrough" | "TextAlingCenter" | "TextAlingLeft" | "TextAlingRight" | "TickCircle" | "Trash-Fill" | "Underline" | "Upload" | "Warning" | "XCircle-Fill";
|
|
88
|
+
export type Icons = "Add" | "ArrowDown" | "ArrowDownUp" | "ArrowLeft" | "ArrowRight" | "ArrowUp" | "Bold" | "BulletList" | "CameraReels" | "CheckAll" | "ChevronBarLeft" | "ChevronBarRight" | "ChevronDown" | "ChevronExpand" | "ChevronUp" | "CloseCircle" | "CloseSquare" | "CloudUpload-Fill" | "Dash" | "Document" | "Download" | "ExclamationCircle" | "ExclamationDiamond-Fill" | "Eye-Fill" | "File" | "FileEarmark-Fill" | "FileTypeCsv" | "FileTypeDoc" | "FileTypeDocx" | "FileTypeHtml" | "FileTypeJson" | "FileTypePdf" | "FileTypePptx" | "FileTypeTxt" | "FileTypeXls" | "FileTypeXlsx" | "FileTypeXml" | "FileTypeZip" | "Filter" | "Floppy-Fill" | "Folder" | "Front" | "GripVertical" | "Import" | "Inbox-Fill" | "Information-Circle-Fill" | "Italic" | "NumberList" | "Strikethrough" | "TextAlingCenter" | "TextAlingLeft" | "TextAlingRight" | "ThreeDotsVertical" | "TickCircle" | "Trash-Fill" | "Underline" | "Upload" | "Warning" | "XCircle-Fill";
|
|
89
89
|
export type PieChartDataType = {
|
|
90
90
|
value: number;
|
|
91
91
|
text: string;
|