rez-table-listing-mui 0.0.24 → 0.0.26
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/.env.uat +1 -0
- package/.eslintrc.cjs +11 -9
- package/dist/index.d.ts +104 -11
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +6 -10
- package/src/App.tsx +185 -142
- package/src/assets/svg.tsx +33 -2
- package/src/components/common/confirm-modal/index.tsx +200 -0
- package/src/components/filter/components/attributes-filter.tsx +26 -0
- package/src/components/filter/components/forms/components/Attributes-select.tsx +180 -0
- package/src/components/filter/components/forms/components/Date.tsx +58 -0
- package/src/components/filter/components/forms/components/Dropdown.tsx +62 -0
- package/src/components/filter/components/forms/components/Filter-criteria.tsx +164 -0
- package/src/components/filter/components/forms/components/Multi-Select.tsx +57 -0
- package/src/components/filter/components/forms/components/Select.tsx +53 -0
- package/src/components/filter/components/forms/components/Textfield.tsx +43 -0
- package/src/components/filter/components/forms/components/styles.tsx +11 -0
- package/src/components/filter/components/forms/index.tsx +424 -0
- package/src/components/filter/components/main-filter.tsx +53 -0
- package/src/components/filter/components/saved-edit-filter.tsx +101 -0
- package/src/components/filter/components/saved-filter.tsx +148 -0
- package/src/components/filter/components/search/index.tsx +56 -0
- package/src/components/filter/components/tabs/custom-tab-panel.tsx +29 -0
- package/src/components/filter/components/tabs/index.tsx +52 -0
- package/src/components/filter/index.tsx +258 -0
- package/src/components/index-table.tsx +20 -14
- package/src/components/index.scss +4 -0
- package/src/components/login/index.tsx +49 -0
- package/src/components/search/index.tsx +0 -1
- package/src/components/table-body-dnd-cell.tsx +3 -3
- package/src/components/table-body.tsx +8 -5
- package/src/components/table-head-popover.tsx +2 -1
- package/src/components/table-head.tsx +0 -10
- package/src/components/topbar/index.scss +6 -1
- package/src/components/topbar/index.tsx +59 -33
- package/src/components/viewmore/index.tsx +33 -17
- package/src/libs/hooks/useCraftTable.tsx +32 -6
- package/src/libs/hooks/useDefaultColumns.tsx +6 -5
- package/src/libs/hooks/useEntityTableAPI.tsx +183 -0
- package/src/libs/hooks/useEntityTableHooks.ts +25 -0
- package/src/libs/utils/apiColumn.ts +123 -0
- package/src/libs/utils/common.ts +42 -0
- package/src/main.tsx +6 -3
- package/src/types/common.ts +67 -0
- package/src/types/filter.ts +211 -0
- package/src/types/table-options.ts +15 -2
- package/src/types/table.ts +7 -6
- package/tsconfig.json +1 -1
- package/vite.config.ts +3 -3
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import {
|
|
3
|
+
FilterFormComponentProps,
|
|
4
|
+
FilterMasterStateProps,
|
|
5
|
+
FilterOperationListProps,
|
|
6
|
+
} from "../../../types/filter";
|
|
7
|
+
import {
|
|
8
|
+
Box,
|
|
9
|
+
IconButton,
|
|
10
|
+
List,
|
|
11
|
+
ListItem,
|
|
12
|
+
ListItemText,
|
|
13
|
+
Typography,
|
|
14
|
+
} from "@mui/material";
|
|
15
|
+
import CustomSearch from "./search";
|
|
16
|
+
import { DeleteIcon } from "../../../assets/svg";
|
|
17
|
+
import SavedFilterEditComponent from "./saved-edit-filter";
|
|
18
|
+
|
|
19
|
+
const SavedFilter = ({
|
|
20
|
+
columnsData,
|
|
21
|
+
dropdownData,
|
|
22
|
+
tableStates,
|
|
23
|
+
selectedFilters,
|
|
24
|
+
setSelectedFilters,
|
|
25
|
+
editMode,
|
|
26
|
+
setEditMode,
|
|
27
|
+
setDeleteFilterModalOpen,
|
|
28
|
+
setSavedFilterModalOpen,
|
|
29
|
+
}: FilterFormComponentProps) => {
|
|
30
|
+
const { setFilterMaster, setFilterToDelete } = tableStates;
|
|
31
|
+
const [searchTerm, setSearchTerm] = useState<string>("");
|
|
32
|
+
|
|
33
|
+
// reset savedFilterEditValue when component unmounts
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
return () => {
|
|
36
|
+
setFilterMaster(
|
|
37
|
+
(prev) =>
|
|
38
|
+
({
|
|
39
|
+
...prev,
|
|
40
|
+
saved_filters: {
|
|
41
|
+
...prev?.attributes,
|
|
42
|
+
selectedId: "",
|
|
43
|
+
selectedName: "",
|
|
44
|
+
},
|
|
45
|
+
} as FilterMasterStateProps)
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
setSelectedFilters([]);
|
|
49
|
+
setEditMode && setEditMode(false);
|
|
50
|
+
};
|
|
51
|
+
}, []);
|
|
52
|
+
|
|
53
|
+
const handleListItemClick = (filter: FilterOperationListProps) => {
|
|
54
|
+
setFilterMaster(
|
|
55
|
+
(prev) =>
|
|
56
|
+
({
|
|
57
|
+
...prev,
|
|
58
|
+
saved_filters: {
|
|
59
|
+
...prev?.attributes,
|
|
60
|
+
selectedId: filter.value,
|
|
61
|
+
selectedName: filter.label,
|
|
62
|
+
},
|
|
63
|
+
} as FilterMasterStateProps)
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
setEditMode && setEditMode(true);
|
|
67
|
+
setFilterToDelete(filter);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const renderList = () => (
|
|
71
|
+
<>
|
|
72
|
+
<CustomSearch value={searchTerm} onChange={setSearchTerm} />
|
|
73
|
+
|
|
74
|
+
{columnsData.saved_filter.length === 0 ? (
|
|
75
|
+
<Typography sx={{ mt: 2 }}>No saved filters yet.</Typography>
|
|
76
|
+
) : (
|
|
77
|
+
<List
|
|
78
|
+
sx={{
|
|
79
|
+
display: "flex",
|
|
80
|
+
flexDirection: "column",
|
|
81
|
+
gap: 1,
|
|
82
|
+
mt: 2,
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
{columnsData.saved_filter
|
|
86
|
+
.filter((filter) =>
|
|
87
|
+
filter.label?.toLowerCase().includes(searchTerm.toLowerCase())
|
|
88
|
+
)
|
|
89
|
+
.map((filter) => (
|
|
90
|
+
<ListItem
|
|
91
|
+
key={filter.value}
|
|
92
|
+
sx={{
|
|
93
|
+
cursor: "pointer",
|
|
94
|
+
border: "1px solid #ccc",
|
|
95
|
+
borderRadius: "8px",
|
|
96
|
+
display: "flex",
|
|
97
|
+
justifyContent: "space-between",
|
|
98
|
+
alignItems: "center",
|
|
99
|
+
}}
|
|
100
|
+
onClick={() => handleListItemClick(filter)}
|
|
101
|
+
>
|
|
102
|
+
<ListItemText primary={filter.label} />
|
|
103
|
+
|
|
104
|
+
<Box onClick={(e) => e.stopPropagation()}>
|
|
105
|
+
<IconButton
|
|
106
|
+
size="small"
|
|
107
|
+
onClick={() => {
|
|
108
|
+
setFilterToDelete(filter); // Store the filter to delete
|
|
109
|
+
|
|
110
|
+
setDeleteFilterModalOpen &&
|
|
111
|
+
setDeleteFilterModalOpen(true); // Open the delete confirmation modal
|
|
112
|
+
}}
|
|
113
|
+
>
|
|
114
|
+
<DeleteIcon />
|
|
115
|
+
</IconButton>
|
|
116
|
+
</Box>
|
|
117
|
+
</ListItem>
|
|
118
|
+
))}
|
|
119
|
+
</List>
|
|
120
|
+
)}
|
|
121
|
+
</>
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<Box>
|
|
126
|
+
{/* Render search input and list */}
|
|
127
|
+
{!editMode && renderList()}
|
|
128
|
+
|
|
129
|
+
{editMode && (
|
|
130
|
+
<SavedFilterEditComponent
|
|
131
|
+
columnsData={columnsData}
|
|
132
|
+
dropdownData={dropdownData}
|
|
133
|
+
tableStates={tableStates}
|
|
134
|
+
selectedFilters={selectedFilters}
|
|
135
|
+
setSelectedFilters={setSelectedFilters}
|
|
136
|
+
editMode={editMode}
|
|
137
|
+
setEditMode={setEditMode}
|
|
138
|
+
searchTerm={searchTerm}
|
|
139
|
+
setSearchTerm={setSearchTerm}
|
|
140
|
+
setSavedFilterModalOpen={setSavedFilterModalOpen}
|
|
141
|
+
setDeleteFilterModalOpen={setDeleteFilterModalOpen}
|
|
142
|
+
/>
|
|
143
|
+
)}
|
|
144
|
+
</Box>
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export default SavedFilter;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { TextField, InputAdornment } from "@mui/material";
|
|
3
|
+
import SearchIcon from "@mui/icons-material/Search";
|
|
4
|
+
|
|
5
|
+
interface SearchInputProps {
|
|
6
|
+
value: string;
|
|
7
|
+
onChange: (value: string) => void;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const CustomSearch = ({
|
|
12
|
+
value = "",
|
|
13
|
+
onChange,
|
|
14
|
+
placeholder = "Search...",
|
|
15
|
+
}: SearchInputProps) => {
|
|
16
|
+
const [search, setSearch] = useState(value);
|
|
17
|
+
|
|
18
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
19
|
+
const val = e.target.value;
|
|
20
|
+
setSearch(val);
|
|
21
|
+
onChange?.(val);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<TextField
|
|
26
|
+
fullWidth
|
|
27
|
+
size="small"
|
|
28
|
+
value={search}
|
|
29
|
+
onChange={handleChange}
|
|
30
|
+
placeholder={placeholder}
|
|
31
|
+
InputProps={{
|
|
32
|
+
startAdornment: (
|
|
33
|
+
<InputAdornment position="start">
|
|
34
|
+
<SearchIcon sx={{ color: "#888888", fontSize: "20px" }} />
|
|
35
|
+
</InputAdornment>
|
|
36
|
+
),
|
|
37
|
+
}}
|
|
38
|
+
sx={{
|
|
39
|
+
mt: 2,
|
|
40
|
+
"& .MuiOutlinedInput-root": {
|
|
41
|
+
borderRadius: "6px",
|
|
42
|
+
fontSize: "14px",
|
|
43
|
+
bgcolor: "#fafafa",
|
|
44
|
+
"& fieldset": {
|
|
45
|
+
borderColor: "#c1c1c1",
|
|
46
|
+
},
|
|
47
|
+
"&.Mui-focused fieldset": {
|
|
48
|
+
borderColor: "#7A5AF8",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
}}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export default CustomSearch;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Box from "@mui/material/Box";
|
|
3
|
+
|
|
4
|
+
interface TabPanelProps {
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
index: number;
|
|
7
|
+
value: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const CustomTabPanel = ({
|
|
11
|
+
children,
|
|
12
|
+
value,
|
|
13
|
+
index,
|
|
14
|
+
...other
|
|
15
|
+
}: TabPanelProps) => {
|
|
16
|
+
return (
|
|
17
|
+
<div
|
|
18
|
+
role="tabpanel"
|
|
19
|
+
hidden={value !== index}
|
|
20
|
+
id={`simple-tabpanel-${index}`}
|
|
21
|
+
aria-labelledby={`simple-tab-${index}`}
|
|
22
|
+
{...other}
|
|
23
|
+
>
|
|
24
|
+
{value === index && <Box sx={{ p: 3 }}>{children}</Box>}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default CustomTabPanel;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Tabs, Tab, TabsProps } from "@mui/material";
|
|
2
|
+
|
|
3
|
+
export interface TabItem {
|
|
4
|
+
label: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
interface StyledTabsProps extends TabsProps {
|
|
8
|
+
tabItems: TabItem[];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const CustomTabs = ({
|
|
12
|
+
value,
|
|
13
|
+
onChange,
|
|
14
|
+
tabItems,
|
|
15
|
+
...tabsProps
|
|
16
|
+
}: StyledTabsProps) => {
|
|
17
|
+
return (
|
|
18
|
+
<Tabs
|
|
19
|
+
value={value}
|
|
20
|
+
onChange={onChange}
|
|
21
|
+
variant="fullWidth"
|
|
22
|
+
sx={{
|
|
23
|
+
px: "12px",
|
|
24
|
+
borderBottom: `1px solid #ccc`,
|
|
25
|
+
"& .MuiTabs-indicator": {
|
|
26
|
+
backgroundColor: "black",
|
|
27
|
+
},
|
|
28
|
+
}}
|
|
29
|
+
{...tabsProps}
|
|
30
|
+
>
|
|
31
|
+
{tabItems.map((tab, idx) => (
|
|
32
|
+
<Tab
|
|
33
|
+
key={idx}
|
|
34
|
+
label={tab.label}
|
|
35
|
+
sx={{
|
|
36
|
+
fontSize: "14px",
|
|
37
|
+
textTransform: "capitalize",
|
|
38
|
+
color: "#888888",
|
|
39
|
+
fontWeight: "normal",
|
|
40
|
+
whiteSpace: "nowrap",
|
|
41
|
+
"&.Mui-selected": {
|
|
42
|
+
color: "black",
|
|
43
|
+
fontWeight: "bold",
|
|
44
|
+
},
|
|
45
|
+
}}
|
|
46
|
+
/>
|
|
47
|
+
))}
|
|
48
|
+
</Tabs>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default CustomTabs;
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { Box, Drawer, IconButton, Typography } from "@mui/material";
|
|
3
|
+
import CloseIcon from "@mui/icons-material/Close";
|
|
4
|
+
import { FilterDrawerProps, UpdatedFilterStateProps } from "../../types/filter";
|
|
5
|
+
|
|
6
|
+
import ConfirmModal, { InputField } from "../common/confirm-modal";
|
|
7
|
+
import CustomTabPanel from "./components/tabs/custom-tab-panel";
|
|
8
|
+
import CustomTabs, { TabItem } from "./components/tabs/index";
|
|
9
|
+
import MainFilter from "./components/main-filter";
|
|
10
|
+
import SavedFilter from "./components/saved-filter";
|
|
11
|
+
import AttributesFilter from "./components/attributes-filter";
|
|
12
|
+
|
|
13
|
+
const FilterDrawer = ({
|
|
14
|
+
open,
|
|
15
|
+
onClose,
|
|
16
|
+
columnsData,
|
|
17
|
+
tableStates,
|
|
18
|
+
onDeleteFilter,
|
|
19
|
+
onSaveFilter,
|
|
20
|
+
onUpdateFilter,
|
|
21
|
+
dropdownData,
|
|
22
|
+
}: FilterDrawerProps) => {
|
|
23
|
+
const [tabValue, setTabValue] = useState(0);
|
|
24
|
+
const [editMode, setEditMode] = useState(false);
|
|
25
|
+
const [selectedFilters, setSelectedFilters] = useState<
|
|
26
|
+
UpdatedFilterStateProps[]
|
|
27
|
+
>([]);
|
|
28
|
+
|
|
29
|
+
// remove this
|
|
30
|
+
const [saveFilterModalOpen, setSaveFilterModalOpen] = useState(false);
|
|
31
|
+
const [deleteFilterModalOpen, setDeleteFilterModalOpen] = useState(false);
|
|
32
|
+
|
|
33
|
+
const [searchTerm, setSearchTerm] = useState<string>("");
|
|
34
|
+
|
|
35
|
+
const { filters, filterToDelete } = tableStates;
|
|
36
|
+
|
|
37
|
+
const filterNameInput: InputField = {
|
|
38
|
+
label: "Filter Name",
|
|
39
|
+
placeholder: 'e.g., "Website Leads - This Week"',
|
|
40
|
+
required: true,
|
|
41
|
+
type: "text",
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (!columnsData || !columnsData.column_list) {
|
|
46
|
+
setSelectedFilters([]);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const updated = filters?.map((filter) => {
|
|
51
|
+
const matchingColumn = columnsData.column_list.find(
|
|
52
|
+
(column) => column.attribute_key === filter.filter_attribute
|
|
53
|
+
);
|
|
54
|
+
const matchingDropdownList =
|
|
55
|
+
columnsData.operation_list[matchingColumn?.data_type || "text"];
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
...filter,
|
|
59
|
+
id: matchingColumn?.id ?? "",
|
|
60
|
+
name: matchingColumn?.name,
|
|
61
|
+
data_type: matchingColumn?.data_type,
|
|
62
|
+
dropdown_list: matchingDropdownList,
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
setSelectedFilters(updated || []);
|
|
67
|
+
}, [filters, columnsData, tabValue]);
|
|
68
|
+
|
|
69
|
+
const handleTabChange = (event: React.SyntheticEvent, newValue: number) => {
|
|
70
|
+
setTabValue(newValue);
|
|
71
|
+
if (newValue !== 1) {
|
|
72
|
+
setEditMode(false);
|
|
73
|
+
setSelectedFilters([]);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
//FOR TABS
|
|
78
|
+
const tabItems: TabItem[] = [
|
|
79
|
+
{ label: "Filter" },
|
|
80
|
+
{ label: "Saved Filter" },
|
|
81
|
+
{ label: "Attributes" },
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<Drawer
|
|
86
|
+
anchor="right"
|
|
87
|
+
open={open}
|
|
88
|
+
onClose={onClose}
|
|
89
|
+
ModalProps={{
|
|
90
|
+
keepMounted: true,
|
|
91
|
+
}}
|
|
92
|
+
sx={{
|
|
93
|
+
"& .MuiPaper-root": {
|
|
94
|
+
overflowY: "auto",
|
|
95
|
+
},
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
98
|
+
<Box sx={{ width: "400px" }}>
|
|
99
|
+
<Box
|
|
100
|
+
sx={{
|
|
101
|
+
display: "flex",
|
|
102
|
+
alignItems: "center",
|
|
103
|
+
justifyContent: "space-between",
|
|
104
|
+
bgcolor: "#EEEEEE",
|
|
105
|
+
height: "50px",
|
|
106
|
+
px: 2,
|
|
107
|
+
borderBottom: "1px solid #ccc",
|
|
108
|
+
mx: "auto",
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
<Typography variant="h6" fontWeight="bold" fontSize="18px">
|
|
112
|
+
Filter
|
|
113
|
+
</Typography>
|
|
114
|
+
<IconButton
|
|
115
|
+
onClick={(e) => {
|
|
116
|
+
e.stopPropagation();
|
|
117
|
+
onClose && onClose();
|
|
118
|
+
}}
|
|
119
|
+
aria-label="close"
|
|
120
|
+
>
|
|
121
|
+
<CloseIcon fontSize="small" />
|
|
122
|
+
</IconButton>
|
|
123
|
+
</Box>
|
|
124
|
+
|
|
125
|
+
<CustomTabs
|
|
126
|
+
value={tabValue}
|
|
127
|
+
onChange={handleTabChange}
|
|
128
|
+
tabItems={tabItems}
|
|
129
|
+
/>
|
|
130
|
+
|
|
131
|
+
<Box>
|
|
132
|
+
<CustomTabPanel value={tabValue} index={0}>
|
|
133
|
+
{tabValue === 0 && (
|
|
134
|
+
<MainFilter
|
|
135
|
+
columnsData={columnsData}
|
|
136
|
+
tableStates={tableStates}
|
|
137
|
+
selectedFilters={selectedFilters}
|
|
138
|
+
setSelectedFilters={setSelectedFilters}
|
|
139
|
+
setSavedFilterModalOpen={setSaveFilterModalOpen}
|
|
140
|
+
dropdownData={dropdownData}
|
|
141
|
+
/>
|
|
142
|
+
)}
|
|
143
|
+
</CustomTabPanel>
|
|
144
|
+
|
|
145
|
+
<CustomTabPanel value={tabValue} index={1}>
|
|
146
|
+
{tabValue === 1 && (
|
|
147
|
+
<SavedFilter
|
|
148
|
+
columnsData={columnsData}
|
|
149
|
+
tableStates={tableStates}
|
|
150
|
+
selectedFilters={selectedFilters}
|
|
151
|
+
setSelectedFilters={setSelectedFilters}
|
|
152
|
+
editMode={editMode}
|
|
153
|
+
setEditMode={setEditMode}
|
|
154
|
+
setDeleteFilterModalOpen={setDeleteFilterModalOpen}
|
|
155
|
+
setSavedFilterModalOpen={setSaveFilterModalOpen}
|
|
156
|
+
dropdownData={dropdownData}
|
|
157
|
+
/>
|
|
158
|
+
)}
|
|
159
|
+
</CustomTabPanel>
|
|
160
|
+
|
|
161
|
+
<CustomTabPanel value={tabValue} index={2}>
|
|
162
|
+
{tabValue === 2 && (
|
|
163
|
+
<AttributesFilter
|
|
164
|
+
columnsData={columnsData}
|
|
165
|
+
tableStates={tableStates}
|
|
166
|
+
dropdownData={dropdownData}
|
|
167
|
+
searchTerm={searchTerm}
|
|
168
|
+
setSearchTerm={setSearchTerm}
|
|
169
|
+
/>
|
|
170
|
+
)}
|
|
171
|
+
</CustomTabPanel>
|
|
172
|
+
</Box>
|
|
173
|
+
|
|
174
|
+
<ConfirmModal
|
|
175
|
+
open={saveFilterModalOpen}
|
|
176
|
+
onClose={() => setSaveFilterModalOpen(false)}
|
|
177
|
+
title={editMode ? "Replace Existing Filter ?" : "Save Filter"}
|
|
178
|
+
description={
|
|
179
|
+
editMode
|
|
180
|
+
? "You already have a filter applied. Applying a new filter will replace the current one. Do you want to continue?"
|
|
181
|
+
: "Give a name to this filter so you can easily reuse it later."
|
|
182
|
+
}
|
|
183
|
+
buttons={[
|
|
184
|
+
{
|
|
185
|
+
label: "Cancel",
|
|
186
|
+
onClick: () => {
|
|
187
|
+
setSaveFilterModalOpen(false);
|
|
188
|
+
},
|
|
189
|
+
variant: "outlined",
|
|
190
|
+
color: "primary",
|
|
191
|
+
sx: {
|
|
192
|
+
color: "#7A5AF8",
|
|
193
|
+
border: `1px solid #7A5AF8`,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
label: editMode ? "Replace Filter" : "Save",
|
|
198
|
+
onClick: (inputValue) => {
|
|
199
|
+
if (editMode) {
|
|
200
|
+
onUpdateFilter && onUpdateFilter(inputValue || "");
|
|
201
|
+
setSaveFilterModalOpen(false);
|
|
202
|
+
setEditMode(false);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
onSaveFilter && onSaveFilter(inputValue || "");
|
|
207
|
+
setSaveFilterModalOpen(false);
|
|
208
|
+
|
|
209
|
+
setTabValue(1);
|
|
210
|
+
},
|
|
211
|
+
variant: "contained",
|
|
212
|
+
color: "primary",
|
|
213
|
+
sx: {
|
|
214
|
+
color: "white",
|
|
215
|
+
backgroundColor: editMode ? "#7A5AF8" : "#7A5AF8",
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
]}
|
|
219
|
+
input={editMode ? undefined : filterNameInput}
|
|
220
|
+
/>
|
|
221
|
+
|
|
222
|
+
<ConfirmModal
|
|
223
|
+
open={deleteFilterModalOpen}
|
|
224
|
+
onClose={() => setDeleteFilterModalOpen(false)}
|
|
225
|
+
title="Delete Saved Filter?"
|
|
226
|
+
description={`You're about to delete the saved filter: "${
|
|
227
|
+
filterToDelete?.label || "[Filter Name]"
|
|
228
|
+
}". This action cannot be undone. Are you sure you want to continue?`}
|
|
229
|
+
buttons={[
|
|
230
|
+
{
|
|
231
|
+
label: "Cancel",
|
|
232
|
+
onClick: () => {
|
|
233
|
+
setDeleteFilterModalOpen(false);
|
|
234
|
+
},
|
|
235
|
+
variant: "outlined",
|
|
236
|
+
color: "primary",
|
|
237
|
+
sx: { color: "#7A5AF8", border: `1px solid #7A5AF8` },
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
label: "Delete",
|
|
241
|
+
onClick: () => {
|
|
242
|
+
onDeleteFilter && onDeleteFilter();
|
|
243
|
+
|
|
244
|
+
setDeleteFilterModalOpen(false);
|
|
245
|
+
setEditMode && setEditMode(false);
|
|
246
|
+
},
|
|
247
|
+
variant: "contained",
|
|
248
|
+
sx: { color: "white", backgroundColor: "#f63d68" },
|
|
249
|
+
},
|
|
250
|
+
]}
|
|
251
|
+
maxWidth="xs"
|
|
252
|
+
/>
|
|
253
|
+
</Box>
|
|
254
|
+
</Drawer>
|
|
255
|
+
);
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
export default FilterDrawer;
|
|
@@ -19,6 +19,7 @@ import Topbar from "./topbar";
|
|
|
19
19
|
import DefaultPagination from "./pagination/default";
|
|
20
20
|
import TableDND from "./table-dnd";
|
|
21
21
|
import Table from "./table";
|
|
22
|
+
import { useFullscreenPopoverContainer } from "../libs/hooks/useFullScreen";
|
|
22
23
|
|
|
23
24
|
function TableWrapper<T>({
|
|
24
25
|
data = [],
|
|
@@ -30,10 +31,8 @@ function TableWrapper<T>({
|
|
|
30
31
|
nestedComponent,
|
|
31
32
|
loadingOptions = { isLoading: false },
|
|
32
33
|
customRenderFn = {},
|
|
34
|
+
// styleOptions,
|
|
33
35
|
shouldHideColumn,
|
|
34
|
-
styleOptions,
|
|
35
|
-
searchValue, // 👈 ADD
|
|
36
|
-
onSearchChange, // 👈 ADD
|
|
37
36
|
}: CraftTableProps<T>) {
|
|
38
37
|
if (!Array.isArray(data)) {
|
|
39
38
|
throw new Error("data must be an array of objects.");
|
|
@@ -117,13 +116,12 @@ function TableWrapper<T>({
|
|
|
117
116
|
const craftTopbarOptions: TopbarOptionsProps = {
|
|
118
117
|
showColumnToggle: true,
|
|
119
118
|
showCompactTableToggle: true,
|
|
120
|
-
showFullscreenToggle: true,
|
|
121
119
|
showChangeLayoutToggle: true,
|
|
122
120
|
viewMoreToggle: true,
|
|
123
|
-
showAddNewButton: true,
|
|
124
121
|
showSearch: true,
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
showSortingToggle: true,
|
|
123
|
+
showFilterToggle: true,
|
|
124
|
+
tableStates,
|
|
127
125
|
|
|
128
126
|
// Add other conditions above topbarOptions
|
|
129
127
|
...topbarOptions,
|
|
@@ -226,6 +224,7 @@ function TableWrapper<T>({
|
|
|
226
224
|
});
|
|
227
225
|
|
|
228
226
|
const { isLoading, loadingComponent, loaderText } = loadingOptions;
|
|
227
|
+
const { isFullscreen } = useFullscreenPopoverContainer();
|
|
229
228
|
|
|
230
229
|
const handleFullscreenToggle = () => {
|
|
231
230
|
if (!document.fullscreenElement) {
|
|
@@ -237,10 +236,10 @@ function TableWrapper<T>({
|
|
|
237
236
|
}
|
|
238
237
|
};
|
|
239
238
|
|
|
240
|
-
const tableWrapperProps = {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
};
|
|
239
|
+
// const tableWrapperProps = {
|
|
240
|
+
// ...(styleOptions?.wrapperStyle && { style: styleOptions.wrapperStyle }),
|
|
241
|
+
// className: "ts__table__wrapper",
|
|
242
|
+
// };
|
|
244
243
|
|
|
245
244
|
return (
|
|
246
245
|
<div className="ts__table__container" ref={tableRef}>
|
|
@@ -259,6 +258,7 @@ function TableWrapper<T>({
|
|
|
259
258
|
topbarOptions={craftTopbarOptions}
|
|
260
259
|
isCompactTable={isCompactTable}
|
|
261
260
|
setIsCompactTable={setIsCompactTable}
|
|
261
|
+
isFullscreen={isFullscreen}
|
|
262
262
|
fullscreenToggle={handleFullscreenToggle}
|
|
263
263
|
paginationComponent={
|
|
264
264
|
craftPaginationOptions?.showPagination === true &&
|
|
@@ -270,12 +270,18 @@ function TableWrapper<T>({
|
|
|
270
270
|
/>
|
|
271
271
|
) : null
|
|
272
272
|
}
|
|
273
|
-
searchValue={searchValue} // 👈 new
|
|
274
|
-
onSearchChange={onSearchChange}
|
|
273
|
+
// searchValue={searchValue} // 👈 new
|
|
274
|
+
// onSearchChange={onSearchChange}
|
|
275
|
+
tableStates={tableStates}
|
|
275
276
|
/>
|
|
276
277
|
)}
|
|
277
278
|
|
|
278
|
-
<div
|
|
279
|
+
<div
|
|
280
|
+
// {...tableWrapperProps}
|
|
281
|
+
className={`ts__table__wrapper ${
|
|
282
|
+
isFullscreen ? "is-fullscreen" : ""
|
|
283
|
+
}`}
|
|
284
|
+
>
|
|
279
285
|
{enableColumnReordering ? (
|
|
280
286
|
<TableDND
|
|
281
287
|
table={table}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import Button from "@mui/material/Button";
|
|
4
|
+
|
|
5
|
+
const LoginButton = () => {
|
|
6
|
+
const [loading, setLoading] = useState(false);
|
|
7
|
+
|
|
8
|
+
const handleLogin = async () => {
|
|
9
|
+
setLoading(true);
|
|
10
|
+
try {
|
|
11
|
+
const response = await axios.post(
|
|
12
|
+
"http://13.200.182.92:9091/api/auth/login",
|
|
13
|
+
{
|
|
14
|
+
email_id: "admin@rezolut.in",
|
|
15
|
+
password: "Admin@123",
|
|
16
|
+
}
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const token = response.data.accessToken;
|
|
20
|
+
|
|
21
|
+
if (token) {
|
|
22
|
+
localStorage.setItem("authToken", token);
|
|
23
|
+
alert("Login successful");
|
|
24
|
+
window.location.reload(); // reload app to re-trigger axios with token
|
|
25
|
+
} else {
|
|
26
|
+
alert("Token not found in response.");
|
|
27
|
+
}
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error("Login failed:", error);
|
|
30
|
+
alert("Login failed. Check console for details.");
|
|
31
|
+
} finally {
|
|
32
|
+
setLoading(false);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<Button
|
|
38
|
+
onClick={handleLogin}
|
|
39
|
+
disabled={loading}
|
|
40
|
+
variant="outlined"
|
|
41
|
+
size="small"
|
|
42
|
+
color="primary"
|
|
43
|
+
>
|
|
44
|
+
{loading ? "Logging in..." : "Login"}
|
|
45
|
+
</Button>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export default LoginButton;
|