@addev-be/ui 0.2.6 → 0.2.7
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/assets/icons/arrow-down-1-9.svg +1 -0
- package/assets/icons/arrow-down-big-small.svg +1 -0
- package/assets/icons/arrow-up-9-1.svg +1 -0
- package/assets/icons/arrow-up-big-small.svg +1 -0
- package/assets/icons/chevron-down.svg +1 -0
- package/assets/icons/ellipsis.svg +1 -0
- package/assets/icons/sigma.svg +1 -0
- package/assets/icons/table-footer-slash.svg +5 -0
- package/assets/icons/table-footer.svg +4 -0
- package/assets/icons/table.svg +1 -0
- package/assets/icons/tally.svg +1 -0
- package/assets/icons/x-bar.svg +4 -0
- package/dist/Icons.d.ts +13 -1
- package/dist/Icons.js +25 -1
- package/dist/components/data/AdvancedRequestDataGrid/index.js +3 -3
- package/dist/components/data/DataGrid/DataGridColumnsModal/hooks.js +2 -1
- package/dist/components/data/DataGrid/DataGridFilterMenu/index.js +85 -7
- package/dist/components/data/DataGrid/DataGridFilterMenu/styles.d.ts +3 -9
- package/dist/components/data/DataGrid/DataGridFilterMenu/styles.js +10 -37
- package/dist/components/data/DataGrid/DataGridFooter.d.ts +1 -1
- package/dist/components/data/DataGrid/DataGridFooter.js +35 -12
- package/dist/components/data/DataGrid/DataGridHeader.js +1 -1
- package/dist/components/data/DataGrid/DataGridHeaderCell.js +6 -22
- package/dist/components/data/DataGrid/helpers/columns.d.ts +1 -1
- package/dist/components/data/DataGrid/helpers/columns.js +71 -16
- package/dist/components/data/DataGrid/hooks/useDataGrid.d.ts +1 -1
- package/dist/components/data/DataGrid/hooks/useDataGrid.js +60 -30
- package/dist/components/data/DataGrid/hooks/useDataGridCopy.d.ts +2 -2
- package/dist/components/data/DataGrid/hooks/useDataGridCopy.js +41 -39
- package/dist/components/data/DataGrid/index.d.ts +4 -2
- package/dist/components/data/DataGrid/index.js +22 -12
- package/dist/components/data/DataGrid/styles.d.ts +8 -4
- package/dist/components/data/DataGrid/styles.js +27 -17
- package/dist/components/data/DataGrid/types.d.ts +8 -1
- package/dist/components/data/SqlRequestDataGrid/helpers/columns.d.ts +1 -1
- package/dist/components/data/SqlRequestDataGrid/helpers/columns.js +24 -11
- package/dist/components/data/SqlRequestDataGrid/index.js +105 -33
- package/dist/components/ui/ContextMenu/index.d.ts +11 -0
- package/dist/components/ui/ContextMenu/index.js +58 -0
- package/dist/components/ui/ContextMenu/styles.d.ts +18 -0
- package/dist/components/ui/ContextMenu/styles.js +56 -0
- package/dist/services/advancedRequests.d.ts +1 -1
- package/dist/services/sqlRequests.d.ts +9 -4
- package/dist/services/sqlRequests.js +1 -0
- package/package.json +1 -1
- package/src/Icons.tsx +24 -0
- package/src/components/data/AdvancedRequestDataGrid/index.tsx +3 -5
- package/src/components/data/DataGrid/DataGridColumnsModal/hooks.tsx +2 -1
- package/src/components/data/DataGrid/DataGridFilterMenu/index.tsx +173 -9
- package/src/components/data/DataGrid/DataGridFilterMenu/styles.ts +13 -64
- package/src/components/data/DataGrid/DataGridFooter.tsx +20 -22
- package/src/components/data/DataGrid/DataGridHeader.tsx +5 -5
- package/src/components/data/DataGrid/DataGridHeaderCell.tsx +3 -38
- package/src/components/data/DataGrid/helpers/columns.tsx +98 -7
- package/src/components/data/DataGrid/hooks/useDataGrid.tsx +58 -17
- package/src/components/data/DataGrid/hooks/useDataGridCopy.ts +35 -30
- package/src/components/data/DataGrid/index.tsx +21 -14
- package/src/components/data/DataGrid/styles.ts +28 -7
- package/src/components/data/DataGrid/types.ts +20 -1
- package/src/components/data/SqlRequestDataGrid/helpers/columns.tsx +38 -3
- package/src/components/data/SqlRequestDataGrid/index.tsx +116 -21
- package/src/components/ui/ContextMenu/index.tsx +73 -0
- package/src/components/ui/ContextMenu/styles.ts +115 -0
- package/src/services/advancedRequests.ts +1 -1
- package/src/services/sqlRequests.ts +16 -5
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
|
|
3
|
+
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
|
4
|
+
return cooked;
|
|
5
|
+
};
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
23
|
+
if (mod && mod.__esModule) return mod;
|
|
24
|
+
var result = {};
|
|
25
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
26
|
+
__setModuleDefault(result, mod);
|
|
27
|
+
return result;
|
|
28
|
+
};
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.Divider = exports.MenuItemContainer = exports.SubMenu = exports.MenuContainer = void 0;
|
|
31
|
+
var styled_components_1 = __importStar(require("styled-components"));
|
|
32
|
+
var menuContainerCss = (0, styled_components_1.css)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: absolute;\n color: var(--color-neutral-900);\n border-radius: var(--rounded-md);\n padding: var(--space-1) 0;\n box-shadow: var(--shadow-lg);\n background-color: var(--color-neutral-100);\n min-width: 20em;\n outline: 1px solid var(--color-neutral-200);\n display: flex;\n flex-direction: column;\n"], ["\n position: absolute;\n color: var(--color-neutral-900);\n border-radius: var(--rounded-md);\n padding: var(--space-1) 0;\n box-shadow: var(--shadow-lg);\n background-color: var(--color-neutral-100);\n min-width: 20em;\n outline: 1px solid var(--color-neutral-200);\n display: flex;\n flex-direction: column;\n"])));
|
|
33
|
+
exports.MenuContainer = styled_components_1.default.div.attrs({
|
|
34
|
+
className: 'MenuContainer',
|
|
35
|
+
})(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n ", "\n inset: 0;\n"], ["\n ", "\n inset: 0;\n"])), menuContainerCss);
|
|
36
|
+
exports.MenuContainer.displayName = 'MenuContainer';
|
|
37
|
+
exports.SubMenu = styled_components_1.default.div.attrs({
|
|
38
|
+
className: 'SubMenu',
|
|
39
|
+
})(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n ", "\n top: 0;\n left: 100%;\n margin-top: -var(--space-1);\n"], ["\n ", "\n top: 0;\n left: 100%;\n margin-top: -var(--space-1);\n"])), menuContainerCss);
|
|
40
|
+
exports.SubMenu.displayName = 'SubMenu';
|
|
41
|
+
exports.MenuItemContainer = styled_components_1.default.div.attrs({
|
|
42
|
+
className: 'MenuItemContainer',
|
|
43
|
+
})(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n position: relative;\n display: flex;\n align-items: center;\n font-family: var(--font-sans);\n font-weight: normal;\n text-align: left;\n padding: var(--space-1) var(--space-2);\n font-size: var(--text-base);\n line-height: var(--leading-6);\n border: none;\n cursor: pointer;\n\n ", "\n\n ", "\n\n svg {\n fill: currentColor;\n width: var(--space-4);\n height: var(--space-4);\n margin-right: var(--space-2);\n }\n\n & > ", " {\n display: none;\n margin-top: calc(0px - var(--space-1));\n }\n &.opened > ", " {\n display: block;\n }\n"], ["\n position: relative;\n display: flex;\n align-items: center;\n font-family: var(--font-sans);\n font-weight: normal;\n text-align: left;\n padding: var(--space-1) var(--space-2);\n font-size: var(--text-base);\n line-height: var(--leading-6);\n border: none;\n cursor: pointer;\n\n ", "\n\n ", "\n\n svg {\n fill: currentColor;\n width: var(--space-4);\n height: var(--space-4);\n margin-right: var(--space-2);\n }\n\n & > ", " {\n display: none;\n margin-top: calc(0px - var(--space-1));\n }\n &.opened > ", " {\n display: block;\n }\n"])), function (_a) {
|
|
44
|
+
var $withArrow = _a.$withArrow;
|
|
45
|
+
return $withArrow && (0, styled_components_1.css)(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n &::after {\n content: '';\n position: absolute;\n right: var(--space-2);\n top: 50%;\n transform: translateY(-50%);\n border: 4px solid transparent;\n border-left-color: var(--color-neutral-600);\n }\n "], ["\n &::after {\n content: '';\n position: absolute;\n right: var(--space-2);\n top: 50%;\n transform: translateY(-50%);\n border: 4px solid transparent;\n border-left-color: var(--color-neutral-600);\n }\n "])));
|
|
46
|
+
}, function (_a) {
|
|
47
|
+
var $color = _a.$color, disabled = _a.disabled;
|
|
48
|
+
return disabled
|
|
49
|
+
? (0, styled_components_1.css)(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n color: var(--color-neutral-300);\n background-color: var(--color-neutral-100);\n cursor: default;\n "], ["\n color: var(--color-neutral-300);\n background-color: var(--color-neutral-100);\n cursor: default;\n "]))) : $color
|
|
50
|
+
? (0, styled_components_1.css)(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n color: var(--color-", "-600);\n background-color: var(--color-neutral-100);\n &:hover {\n background-color: var(--color-", "-200);\n }\n "], ["\n color: var(--color-", "-600);\n background-color: var(--color-neutral-100);\n &:hover {\n background-color: var(--color-", "-200);\n }\n "])), $color, $color) : (0, styled_components_1.css)(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n color: var(--color-neutral-900);\n background-color: var(--color-neutral-100);\n &:hover {\n background-color: var(--color-neutral-200);\n }\n "], ["\n color: var(--color-neutral-900);\n background-color: var(--color-neutral-100);\n &:hover {\n background-color: var(--color-neutral-200);\n }\n "])));
|
|
51
|
+
}, exports.SubMenu, exports.SubMenu);
|
|
52
|
+
exports.MenuItemContainer.displayName = 'MenuItemContainer';
|
|
53
|
+
exports.Divider = styled_components_1.default.div.attrs({
|
|
54
|
+
className: 'Divider',
|
|
55
|
+
})(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n border-top: 1px solid var(--color-neutral-200);\n margin: var(--space-1) 0;\n"], ["\n border-top: 1px solid var(--color-neutral-200);\n margin: var(--space-1) 0;\n"])));
|
|
56
|
+
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5, templateObject_6, templateObject_7, templateObject_8, templateObject_9;
|
|
@@ -14,27 +14,32 @@ export type ConditionDTO = {
|
|
|
14
14
|
};
|
|
15
15
|
export type OrderByDTO = {
|
|
16
16
|
field: string;
|
|
17
|
+
type: string;
|
|
17
18
|
direction?: 'ASC' | 'DESC';
|
|
18
19
|
};
|
|
20
|
+
export type SqlRequestFooterFunction = 'sum' | 'avg' | 'count' | 'max' | 'min';
|
|
19
21
|
export type SqlRequestDTO = {
|
|
20
22
|
columns?: string[];
|
|
21
23
|
returnColumns?: string[];
|
|
24
|
+
columnTypes?: string[];
|
|
25
|
+
totalColumns?: Record<string, SqlRequestFooterFunction>;
|
|
22
26
|
conditions?: ConditionDTO[];
|
|
23
27
|
orderBy?: OrderByDTO[];
|
|
24
28
|
start?: number;
|
|
25
29
|
length?: number;
|
|
26
|
-
|
|
30
|
+
getCount?: boolean;
|
|
27
31
|
unique?: boolean;
|
|
28
32
|
};
|
|
29
33
|
export type SqlRequestRow<R> = {
|
|
30
|
-
[K in keyof R]: R[K] extends string | number | null ? R[K] : string | number | null;
|
|
34
|
+
[K in keyof R]: R[K] extends string | number | null | undefined ? R[K] : string | number | null | undefined;
|
|
31
35
|
};
|
|
32
36
|
export type SqlResponseDTO<T = any> = {
|
|
33
37
|
data: SqlRequestRow<T>[];
|
|
34
|
-
|
|
38
|
+
count?: number;
|
|
39
|
+
totals?: Record<string, string | number | null | undefined>;
|
|
35
40
|
};
|
|
36
41
|
type SqlRequestHandler<T> = (request: SqlRequestDTO) => Promise<SqlResponseDTO<T>>;
|
|
37
42
|
export declare const useSqlRequestHandler: <T = any>(name: string) => [SqlRequestHandler<T>, SqlRequestHandler<{
|
|
38
43
|
Id: string;
|
|
39
|
-
}
|
|
44
|
+
}>, SqlRequestHandler<Partial<T>>];
|
|
40
45
|
export {};
|
|
@@ -6,5 +6,6 @@ var hooks_1 = require("./hooks");
|
|
|
6
6
|
var useSqlRequestHandler = function (name) { return [
|
|
7
7
|
(0, hooks_1.useWebSocketRequestHandler)(name),
|
|
8
8
|
(0, hooks_1.useWebSocketRequestHandler)(name),
|
|
9
|
+
(0, hooks_1.useWebSocketRequestHandler)(name),
|
|
9
10
|
]; };
|
|
10
11
|
exports.useSqlRequestHandler = useSqlRequestHandler;
|
package/package.json
CHANGED
package/src/Icons.tsx
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { FC, SVGProps, useEffect, useState } from 'react';
|
|
2
2
|
|
|
3
|
+
import ArrowDown19Icon from '../assets/icons/arrow-down-1-9.svg?react';
|
|
3
4
|
import ArrowDownAZIcon from '../assets/icons/arrow-down-a-z.svg?react';
|
|
5
|
+
import ArrowDownBigSmallIcon from '../assets/icons/arrow-down-big-small.svg?react';
|
|
6
|
+
import ArrowUp91Icon from '../assets/icons/arrow-up-9-1.svg?react';
|
|
7
|
+
import ArrowUpBigSmallIcon from '../assets/icons/arrow-up-big-small.svg?react';
|
|
4
8
|
import ArrowUpZAIcon from '../assets/icons/arrow-up-z-a.svg?react';
|
|
5
9
|
import ArrowsRotateIcon from '../assets/icons/arrows-rotate.svg?react';
|
|
6
10
|
import ArrowsUpDownIcon from '../assets/icons/arrows-up-down.svg?react';
|
|
7
11
|
import CheckIcon from '../assets/icons/check.svg?react';
|
|
12
|
+
import ChevronDownIcon from '../assets/icons/chevron-down.svg?react';
|
|
8
13
|
import CopyIcon from '../assets/icons/copy.svg?react';
|
|
9
14
|
import DownIcon from '../assets/icons/down.svg?react';
|
|
15
|
+
import EllipsisIcon from '../assets/icons/ellipsis.svg?react';
|
|
10
16
|
import FilterFullIcon from '../assets/icons/filter-full.svg?react';
|
|
11
17
|
import FilterIcon from '../assets/icons/filter.svg?react';
|
|
12
18
|
import FilterSlashIcon from '../assets/icons/filter-slash.svg?react';
|
|
@@ -17,10 +23,16 @@ import MagnifierIcon from '../assets/icons/magnifier.svg?react';
|
|
|
17
23
|
import PhoneIcon from '../assets/icons/phone.svg?react';
|
|
18
24
|
import PlusIcon from '../assets/icons/plus.svg?react';
|
|
19
25
|
import RightIcon from '../assets/icons/right.svg?react';
|
|
26
|
+
import SigmaIcon from '../assets/icons/sigma.svg?react';
|
|
20
27
|
import SpinnerIcon from '../assets/icons/spinner-third.svg?react';
|
|
21
28
|
import TableColumnsIcon from '../assets/icons/table-columns.svg?react';
|
|
29
|
+
import TableFooterIcon from '../assets/icons/table-footer.svg?react';
|
|
30
|
+
import TableFooterSlashIcon from '../assets/icons/table-footer-slash.svg?react';
|
|
31
|
+
import TableIcon from '../assets/icons/table.svg?react';
|
|
32
|
+
import TallyIcon from '../assets/icons/tally.svg?react';
|
|
22
33
|
import UpIcon from '../assets/icons/up.svg?react';
|
|
23
34
|
import UserTieIcon from '../assets/icons/user-tie.svg?react';
|
|
35
|
+
import XBarIcon from '../assets/icons/x-bar.svg?react';
|
|
24
36
|
|
|
25
37
|
type IconFCProps = SVGProps<SVGSVGElement>;
|
|
26
38
|
export type IconFC = FC<IconFCProps>;
|
|
@@ -57,12 +69,18 @@ export const LoadingIcon: FC<IconFCProps> = ({ className, ...props }) => (
|
|
|
57
69
|
|
|
58
70
|
export {
|
|
59
71
|
ArrowDownAZIcon,
|
|
72
|
+
ArrowDown19Icon,
|
|
73
|
+
ArrowDownBigSmallIcon,
|
|
60
74
|
ArrowUpZAIcon,
|
|
75
|
+
ArrowUpBigSmallIcon,
|
|
76
|
+
ArrowUp91Icon,
|
|
61
77
|
ArrowsRotateIcon,
|
|
62
78
|
ArrowsUpDownIcon,
|
|
63
79
|
CheckIcon,
|
|
80
|
+
ChevronDownIcon,
|
|
64
81
|
CopyIcon,
|
|
65
82
|
DownIcon,
|
|
83
|
+
EllipsisIcon,
|
|
66
84
|
FilterFullIcon,
|
|
67
85
|
FilterIcon,
|
|
68
86
|
FilterSlashIcon,
|
|
@@ -73,8 +91,14 @@ export {
|
|
|
73
91
|
PhoneIcon,
|
|
74
92
|
PlusIcon,
|
|
75
93
|
RightIcon,
|
|
94
|
+
SigmaIcon,
|
|
76
95
|
SpinnerIcon,
|
|
77
96
|
TableColumnsIcon,
|
|
97
|
+
TableFooterIcon,
|
|
98
|
+
TableFooterSlashIcon,
|
|
99
|
+
TableIcon,
|
|
100
|
+
TallyIcon,
|
|
78
101
|
UpIcon,
|
|
79
102
|
UserTieIcon,
|
|
103
|
+
XBarIcon,
|
|
80
104
|
};
|
|
@@ -95,8 +95,8 @@ export const AdvancedRequestDataGrid = <R,>({
|
|
|
95
95
|
})
|
|
96
96
|
).then((response) => {
|
|
97
97
|
if (getTotal) {
|
|
98
|
-
currentRows.current = Array(response.
|
|
99
|
-
if (getTotal) setTotal(response.
|
|
98
|
+
currentRows.current = Array(response.count).fill(null);
|
|
99
|
+
if (getTotal) setTotal(response.count ?? 0);
|
|
100
100
|
}
|
|
101
101
|
const parsedRows = parseJsonObjectFields(
|
|
102
102
|
response.data,
|
|
@@ -121,9 +121,7 @@ export const AdvancedRequestDataGrid = <R,>({
|
|
|
121
121
|
],
|
|
122
122
|
conditions: [
|
|
123
123
|
...(props.conditions ?? []),
|
|
124
|
-
...Object.values(
|
|
125
|
-
_.pickBy(conditions, (condition, key) => key !== columnKey)
|
|
126
|
-
),
|
|
124
|
+
...Object.values(_.pickBy(conditions, (_, key) => key !== columnKey)),
|
|
127
125
|
].filter((condition) => condition.field !== columnKey),
|
|
128
126
|
orderBy: [
|
|
129
127
|
{
|
|
@@ -12,8 +12,9 @@ export const useDataGridColumnsModal = <R,>(context: DataGridContext<R>) => {
|
|
|
12
12
|
const [currentColumns, setCurrentColumns] = useState(columns);
|
|
13
13
|
|
|
14
14
|
const openModal = useCallback(() => {
|
|
15
|
+
setCurrentColumns(columns);
|
|
15
16
|
setIsVisible(true);
|
|
16
|
-
}, []);
|
|
17
|
+
}, [columns]);
|
|
17
18
|
const closeModal = useCallback(() => {
|
|
18
19
|
setIsVisible(false);
|
|
19
20
|
}, []);
|
|
@@ -3,8 +3,29 @@
|
|
|
3
3
|
|
|
4
4
|
import * as styles from './styles';
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
ArrowDown19Icon,
|
|
8
|
+
ArrowDownAZIcon,
|
|
9
|
+
ArrowDownBigSmallIcon,
|
|
10
|
+
ArrowUp91Icon,
|
|
11
|
+
ArrowUpBigSmallIcon,
|
|
12
|
+
ArrowUpZAIcon,
|
|
13
|
+
FilterIcon,
|
|
14
|
+
FilterSlashIcon,
|
|
15
|
+
IconFC,
|
|
16
|
+
MagnifierIcon,
|
|
17
|
+
SigmaIcon,
|
|
18
|
+
TableFooterIcon,
|
|
19
|
+
TableFooterSlashIcon,
|
|
20
|
+
TallyIcon,
|
|
21
|
+
XBarIcon,
|
|
22
|
+
} from '../../../../Icons';
|
|
23
|
+
import {
|
|
24
|
+
DataGridContext,
|
|
25
|
+
DataGridFilterType,
|
|
26
|
+
DataGridFilterValue,
|
|
27
|
+
DataGridFooterPredefinedFunction,
|
|
28
|
+
} from '../types';
|
|
8
29
|
import {
|
|
9
30
|
applyFilters,
|
|
10
31
|
defaultRendererAndFormatter,
|
|
@@ -20,6 +41,7 @@ import {
|
|
|
20
41
|
useState,
|
|
21
42
|
} from 'react';
|
|
22
43
|
|
|
44
|
+
import { ContextMenu } from '../../../ui/ContextMenu';
|
|
23
45
|
import { FilterValuesScroller } from '../FilterValuesScroller';
|
|
24
46
|
import { Input } from '../../../forms';
|
|
25
47
|
import { useFilterModal } from './hooks';
|
|
@@ -31,6 +53,32 @@ type FilterValuesProps<R> = {
|
|
|
31
53
|
onClose?: () => void;
|
|
32
54
|
};
|
|
33
55
|
|
|
56
|
+
const sortAsc: Record<DataGridFilterType, [string, IconFC]> = {
|
|
57
|
+
number: ['Trier du plus petit au plus grand', ArrowDown19Icon],
|
|
58
|
+
text: ['Trier de A à Z', ArrowDownAZIcon],
|
|
59
|
+
// date: 'Trier du plus ancien au plus récent',
|
|
60
|
+
};
|
|
61
|
+
const sortDesc: Record<DataGridFilterType, [string, IconFC]> = {
|
|
62
|
+
number: ['Trier du plus grand au plus petit', ArrowUp91Icon],
|
|
63
|
+
text: ['Trier de Z à A', ArrowUpZAIcon],
|
|
64
|
+
// date: 'Trier du plus récent au plus ancien',
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const footerFunctionsTexts: Record<DataGridFooterPredefinedFunction, string> = {
|
|
68
|
+
average: 'Moyenne',
|
|
69
|
+
count: 'Nombre',
|
|
70
|
+
max: 'Maximum',
|
|
71
|
+
min: 'Minimum',
|
|
72
|
+
sum: 'Somme',
|
|
73
|
+
};
|
|
74
|
+
const footerFunctionsIcons: Record<DataGridFooterPredefinedFunction, IconFC> = {
|
|
75
|
+
average: XBarIcon,
|
|
76
|
+
count: TallyIcon,
|
|
77
|
+
max: ArrowUpBigSmallIcon,
|
|
78
|
+
min: ArrowDownBigSmallIcon,
|
|
79
|
+
sum: SigmaIcon,
|
|
80
|
+
};
|
|
81
|
+
|
|
34
82
|
export const DataGridFilterMenu = <R,>({
|
|
35
83
|
columnKey,
|
|
36
84
|
context,
|
|
@@ -39,10 +87,13 @@ export const DataGridFilterMenu = <R,>({
|
|
|
39
87
|
const { openModal, modal } = useFilterModal({ columnKey, context });
|
|
40
88
|
const {
|
|
41
89
|
filters = {},
|
|
90
|
+
footers = {},
|
|
42
91
|
rows,
|
|
43
92
|
columns,
|
|
44
93
|
setFilters,
|
|
45
94
|
filterValuesLoader,
|
|
95
|
+
setSorts,
|
|
96
|
+
setFooters,
|
|
46
97
|
} = useContext(context);
|
|
47
98
|
const column = columns[columnKey] ?? {};
|
|
48
99
|
const textFilterInputRef = useRef<HTMLInputElement>(null);
|
|
@@ -63,7 +114,13 @@ export const DataGridFilterMenu = <R,>({
|
|
|
63
114
|
.map(([, filter]) => filter);
|
|
64
115
|
const availableRows = applyFilters(rows, otherFilters);
|
|
65
116
|
const values = availableRows.map((row) => column.filter!.getter(row));
|
|
66
|
-
setAvailableValues(() =>
|
|
117
|
+
setAvailableValues(() =>
|
|
118
|
+
uniq(values).sort(
|
|
119
|
+
column.filter?.type === 'number'
|
|
120
|
+
? (a, b) => (a as number) - (b as number)
|
|
121
|
+
: (a, b) => (a as string).localeCompare(b as string)
|
|
122
|
+
)
|
|
123
|
+
);
|
|
67
124
|
}
|
|
68
125
|
}, [column.filter, columnKey, filterValuesLoader, filters, rows]);
|
|
69
126
|
|
|
@@ -169,17 +226,124 @@ export const DataGridFilterMenu = <R,>({
|
|
|
169
226
|
toggleValues,
|
|
170
227
|
]);
|
|
171
228
|
|
|
229
|
+
const onSortAscClicked = useCallback(() => {
|
|
230
|
+
setSorts({ [columnKey]: 'asc' });
|
|
231
|
+
onClose?.();
|
|
232
|
+
}, [columnKey, onClose, setSorts]);
|
|
233
|
+
const onSortDescClicked = useCallback(() => {
|
|
234
|
+
setSorts({ [columnKey]: 'desc' });
|
|
235
|
+
onClose?.();
|
|
236
|
+
}, [columnKey, onClose, setSorts]);
|
|
237
|
+
|
|
238
|
+
const hasFilters = filters[columnKey]?.values.length > 0;
|
|
239
|
+
const [[sortAscText, SortAscIcon], [sortDescText, SortDescIcon]] = [
|
|
240
|
+
sortAsc[column.filter?.type ?? 'text'],
|
|
241
|
+
sortDesc[column.filter?.type ?? 'text'],
|
|
242
|
+
];
|
|
243
|
+
|
|
244
|
+
const isFooterVisible =
|
|
245
|
+
columnKey in footers && footers[columnKey] !== undefined;
|
|
246
|
+
const showFooter = useCallback(
|
|
247
|
+
(key: string) => {
|
|
248
|
+
setFooters((prevFooters) => ({
|
|
249
|
+
...prevFooters,
|
|
250
|
+
[columnKey]: key,
|
|
251
|
+
}));
|
|
252
|
+
onClose?.();
|
|
253
|
+
},
|
|
254
|
+
[columnKey, onClose, setFooters]
|
|
255
|
+
);
|
|
256
|
+
const hideFooter = useCallback(() => {
|
|
257
|
+
setFooters((prevFooters) => {
|
|
258
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
259
|
+
const { [columnKey]: _, ...newFooters } = prevFooters;
|
|
260
|
+
return newFooters;
|
|
261
|
+
});
|
|
262
|
+
onClose?.();
|
|
263
|
+
}, [columnKey, onClose, setFooters]);
|
|
264
|
+
|
|
172
265
|
return (
|
|
173
|
-
<
|
|
266
|
+
<ContextMenu>
|
|
174
267
|
{modal}
|
|
175
|
-
|
|
268
|
+
{column.sortGetter && (
|
|
269
|
+
<>
|
|
270
|
+
<ContextMenu.Item onClick={onSortAscClicked}>
|
|
271
|
+
<SortAscIcon />
|
|
272
|
+
{sortAscText}
|
|
273
|
+
</ContextMenu.Item>
|
|
274
|
+
<ContextMenu.Item onClick={onSortDescClicked}>
|
|
275
|
+
<SortDescIcon />
|
|
276
|
+
{sortDescText}
|
|
277
|
+
</ContextMenu.Item>
|
|
278
|
+
<ContextMenu.Divider />
|
|
279
|
+
</>
|
|
280
|
+
)}
|
|
281
|
+
{isFooterVisible && typeof column.footer === 'function' && (
|
|
282
|
+
<>
|
|
283
|
+
<ContextMenu.Item onClick={hideFooter}>
|
|
284
|
+
<TableFooterSlashIcon />
|
|
285
|
+
Masquer le total
|
|
286
|
+
</ContextMenu.Item>
|
|
287
|
+
<ContextMenu.Divider />
|
|
288
|
+
</>
|
|
289
|
+
)}
|
|
290
|
+
{!isFooterVisible && typeof column.footer === 'function' && (
|
|
291
|
+
<>
|
|
292
|
+
<ContextMenu.Item onClick={() => showFooter('count')}>
|
|
293
|
+
<TableFooterIcon />
|
|
294
|
+
Afficher le total
|
|
295
|
+
</ContextMenu.Item>
|
|
296
|
+
<ContextMenu.Divider />
|
|
297
|
+
</>
|
|
298
|
+
)}
|
|
299
|
+
{typeof column.footer === 'object' && (
|
|
300
|
+
<>
|
|
301
|
+
<ContextMenu.ParentItem>
|
|
302
|
+
<TableFooterIcon />
|
|
303
|
+
Afficher le total
|
|
304
|
+
<ContextMenu.SubMenu>
|
|
305
|
+
{Object.keys(column.footer).map((key) => {
|
|
306
|
+
const TotalIcon =
|
|
307
|
+
footerFunctionsIcons[
|
|
308
|
+
key as DataGridFooterPredefinedFunction
|
|
309
|
+
] ?? TableFooterIcon;
|
|
310
|
+
return (
|
|
311
|
+
<ContextMenu.Item key={key} onClick={() => showFooter(key)}>
|
|
312
|
+
<TotalIcon />
|
|
313
|
+
{key in footerFunctionsTexts
|
|
314
|
+
? footerFunctionsTexts[
|
|
315
|
+
key as DataGridFooterPredefinedFunction
|
|
316
|
+
]
|
|
317
|
+
: key}
|
|
318
|
+
</ContextMenu.Item>
|
|
319
|
+
);
|
|
320
|
+
})}
|
|
321
|
+
<ContextMenu.Divider />
|
|
322
|
+
<ContextMenu.Item
|
|
323
|
+
onClick={hideFooter}
|
|
324
|
+
disabled={!isFooterVisible}
|
|
325
|
+
>
|
|
326
|
+
<TableFooterSlashIcon />
|
|
327
|
+
Masquer le total
|
|
328
|
+
</ContextMenu.Item>
|
|
329
|
+
</ContextMenu.SubMenu>
|
|
330
|
+
</ContextMenu.ParentItem>
|
|
331
|
+
<ContextMenu.Divider />
|
|
332
|
+
</>
|
|
333
|
+
)}
|
|
334
|
+
<ContextMenu.Item onClick={openModal}>
|
|
176
335
|
<FilterIcon />
|
|
177
336
|
Filtrer ...
|
|
178
|
-
</
|
|
179
|
-
<
|
|
337
|
+
</ContextMenu.Item>
|
|
338
|
+
<ContextMenu.Item
|
|
339
|
+
$color="danger"
|
|
340
|
+
onClick={clearFilter}
|
|
341
|
+
disabled={!hasFilters}
|
|
342
|
+
>
|
|
180
343
|
<FilterSlashIcon />
|
|
181
344
|
Supprimer le filtre
|
|
182
|
-
</
|
|
345
|
+
</ContextMenu.Item>
|
|
346
|
+
<ContextMenu.Divider />
|
|
183
347
|
<styles.InputContainer>
|
|
184
348
|
<MagnifierIcon />
|
|
185
349
|
<Input
|
|
@@ -195,6 +359,6 @@ export const DataGridFilterMenu = <R,>({
|
|
|
195
359
|
<styles.CheckboxesContainer>
|
|
196
360
|
{checkboxesComponent}
|
|
197
361
|
</styles.CheckboxesContainer>
|
|
198
|
-
</
|
|
362
|
+
</ContextMenu>
|
|
199
363
|
);
|
|
200
364
|
};
|
|
@@ -1,70 +1,11 @@
|
|
|
1
|
-
import styled
|
|
2
|
-
|
|
3
|
-
import { ThemeColor } from '../../../../providers/ThemeProvider/types';
|
|
4
|
-
|
|
5
|
-
export const Menu = styled.div.attrs({
|
|
6
|
-
className: 'Menu',
|
|
7
|
-
})`
|
|
8
|
-
position: absolute;
|
|
9
|
-
inset: 0;
|
|
10
|
-
color: var(--color-neutral-900);
|
|
11
|
-
border-radius: var(--rounded-md);
|
|
12
|
-
padding: var(--space-1) 0;
|
|
13
|
-
box-shadow: var(--shadow-lg);
|
|
14
|
-
background-color: var(--color-neutral-100);
|
|
15
|
-
min-width: 20em;
|
|
16
|
-
outline: 1px solid var(--color-neutral-200);
|
|
17
|
-
display: flex;
|
|
18
|
-
flex-direction: column;
|
|
19
|
-
`;
|
|
20
|
-
|
|
21
|
-
export const MenuItem = styled.button.attrs({
|
|
22
|
-
className: 'MenuItem',
|
|
23
|
-
})<{ $color?: ThemeColor }>`
|
|
24
|
-
display: flex;
|
|
25
|
-
align-items: center;
|
|
26
|
-
width: 100%;
|
|
27
|
-
font-family: var(--font-sans);
|
|
28
|
-
font-weight: normal;
|
|
29
|
-
text-align: left;
|
|
30
|
-
padding: var(--space-1) var(--space-2);
|
|
31
|
-
font-size: var(--text-base);
|
|
32
|
-
line-height: var(--leading-6);
|
|
33
|
-
border: none;
|
|
34
|
-
cursor: pointer;
|
|
35
|
-
|
|
36
|
-
${({ $color }) =>
|
|
37
|
-
$color
|
|
38
|
-
? css`
|
|
39
|
-
color: var(--color-${$color}-600);
|
|
40
|
-
background-color: var(--color-neutral-100);
|
|
41
|
-
&:hover {
|
|
42
|
-
background-color: var(--color-${$color}-200);
|
|
43
|
-
}
|
|
44
|
-
`
|
|
45
|
-
: css`
|
|
46
|
-
color: var(--color-neutral-900);
|
|
47
|
-
background-color: var(--color-neutral-100);
|
|
48
|
-
&:hover {
|
|
49
|
-
background-color: var(--color-neutral-200);
|
|
50
|
-
}
|
|
51
|
-
`}
|
|
52
|
-
|
|
53
|
-
svg {
|
|
54
|
-
fill: currentColor;
|
|
55
|
-
width: var(--space-4);
|
|
56
|
-
height: var(--space-4);
|
|
57
|
-
margin-right: var(--space-2);
|
|
58
|
-
}
|
|
59
|
-
`;
|
|
1
|
+
import styled from 'styled-components';
|
|
60
2
|
|
|
61
3
|
export const InputContainer = styled.div.attrs({
|
|
62
4
|
className: 'InputContainer',
|
|
63
5
|
})`
|
|
64
6
|
position: relative;
|
|
65
7
|
border-radius: var(--rounded-md);
|
|
66
|
-
padding: 0 var(--space-
|
|
67
|
-
margin-top: var(--space-1);
|
|
8
|
+
padding: 0 var(--space-1);
|
|
68
9
|
|
|
69
10
|
svg {
|
|
70
11
|
position: absolute;
|
|
@@ -89,12 +30,20 @@ export const CheckboxesContainer = styled.div.attrs({
|
|
|
89
30
|
font-weight: normal;
|
|
90
31
|
user-select: none;
|
|
91
32
|
padding: var(--space-2);
|
|
92
|
-
margin: var(--space-
|
|
93
|
-
|
|
33
|
+
margin: var(--space-1);
|
|
34
|
+
margin-bottom: 0;
|
|
35
|
+
border: 1px solid var(--color-neutral-300);
|
|
94
36
|
border-radius: var(--rounded-md);
|
|
95
37
|
box-shadow: var(--shadow-inner);
|
|
96
|
-
background-color: var(--color-neutral-
|
|
38
|
+
background-color: var(--color-neutral-0);
|
|
97
39
|
height: 20em;
|
|
98
40
|
overflow-y: hidden;
|
|
99
41
|
white-space: nowrap;
|
|
100
42
|
`;
|
|
43
|
+
|
|
44
|
+
export const Separator = styled.div.attrs({
|
|
45
|
+
className: 'Separator',
|
|
46
|
+
})`
|
|
47
|
+
border-top: 1px solid var(--color-neutral-200);
|
|
48
|
+
margin: var(--space-1) 0;
|
|
49
|
+
`;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-unnecessary-type-constraint */
|
|
3
3
|
|
|
4
|
+
import * as styles from './styles';
|
|
5
|
+
|
|
4
6
|
import { DataGridContext } from './types';
|
|
5
|
-
import { getScrollBarSize } from '../../../helpers/getScrollbarSize';
|
|
6
7
|
import { useDataGridContext } from './hooks';
|
|
7
8
|
|
|
8
|
-
const SCROLL_BAR_SIZE = getScrollBarSize();
|
|
9
|
-
|
|
10
9
|
export const DataGridFooter = <R,>({
|
|
11
10
|
context,
|
|
12
11
|
}: {
|
|
@@ -17,28 +16,27 @@ export const DataGridFooter = <R,>({
|
|
|
17
16
|
rows,
|
|
18
17
|
selectedRows,
|
|
19
18
|
sortedRows,
|
|
20
|
-
rowHeight = 48,
|
|
21
19
|
selectable,
|
|
20
|
+
footers = {},
|
|
21
|
+
gridTemplateColumns,
|
|
22
|
+
footerFunctions,
|
|
22
23
|
} = useDataGridContext(context);
|
|
23
24
|
|
|
25
|
+
if (!Object.keys(footers).length) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
24
29
|
return (
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
{visibleColumns.map(([key, col]) => (
|
|
37
|
-
<div key={key} style={{ width: (col.width ?? 150) + 'px' }}>
|
|
38
|
-
{col.footer?.(rows, sortedRows, selectedRows)}
|
|
39
|
-
</div>
|
|
40
|
-
))}
|
|
41
|
-
</tr>
|
|
42
|
-
</tfoot>
|
|
30
|
+
<styles.DataGridFooterRow $gridTemplateColumns={gridTemplateColumns}>
|
|
31
|
+
{!!selectable && <styles.HeaderSelectionCell />}
|
|
32
|
+
{visibleColumns.map(([key, col]) => (
|
|
33
|
+
<styles.DataGridHeaderCellContainer
|
|
34
|
+
key={key}
|
|
35
|
+
style={{ width: (col.width ?? 150) + 'px' }}
|
|
36
|
+
>
|
|
37
|
+
{footerFunctions?.[key]?.(rows, sortedRows, selectedRows)}
|
|
38
|
+
</styles.DataGridHeaderCellContainer>
|
|
39
|
+
))}
|
|
40
|
+
</styles.DataGridFooterRow>
|
|
43
41
|
);
|
|
44
42
|
};
|
|
@@ -102,11 +102,11 @@ export const DataGridHeader = <R,>({
|
|
|
102
102
|
$headerColor={headerColor}
|
|
103
103
|
>
|
|
104
104
|
{!!selectable && (
|
|
105
|
-
<styles.HeaderSelectionCell
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
/>
|
|
105
|
+
<styles.HeaderSelectionCell
|
|
106
|
+
$headerColor={headerColor}
|
|
107
|
+
onClick={() => toggleAll(!(checkboxStatus ?? true))}
|
|
108
|
+
>
|
|
109
|
+
<IndeterminateCheckbox checked={checkboxStatus} readOnly />
|
|
110
110
|
</styles.HeaderSelectionCell>
|
|
111
111
|
)}
|
|
112
112
|
{visibleColumns.map(([key, col], index) => (
|