rez-table-listing-mui 0.0.25 → 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 +101 -8
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +6 -10
- package/src/App.tsx +172 -129
- 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 +3 -6
- package/src/components/index.scss +4 -0
- package/src/components/login/index.tsx +49 -0
- package/src/components/table-body.tsx +6 -4
- package/src/components/table-head.tsx +0 -10
- package/src/components/topbar/index.scss +5 -0
- package/src/components/topbar/index.tsx +54 -19
- package/src/components/viewmore/index.tsx +2 -2
- package/src/libs/hooks/useCraftTable.tsx +29 -5
- package/src/libs/hooks/useDefaultColumns.tsx +2 -2
- 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 +5 -5
- 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;
|
|
@@ -32,8 +32,6 @@ function TableWrapper<T>({
|
|
|
32
32
|
loadingOptions = { isLoading: false },
|
|
33
33
|
customRenderFn = {},
|
|
34
34
|
// styleOptions,
|
|
35
|
-
// searchValue, // 👈 ADD
|
|
36
|
-
// onSearchChange, // 👈 ADD
|
|
37
35
|
shouldHideColumn,
|
|
38
36
|
}: CraftTableProps<T>) {
|
|
39
37
|
if (!Array.isArray(data)) {
|
|
@@ -118,13 +116,11 @@ function TableWrapper<T>({
|
|
|
118
116
|
const craftTopbarOptions: TopbarOptionsProps = {
|
|
119
117
|
showColumnToggle: true,
|
|
120
118
|
showCompactTableToggle: true,
|
|
121
|
-
showFullscreenToggle: true,
|
|
122
119
|
showChangeLayoutToggle: true,
|
|
123
120
|
viewMoreToggle: true,
|
|
124
|
-
showAddNewButton: true,
|
|
125
121
|
showSearch: true,
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
showSortingToggle: true,
|
|
123
|
+
showFilterToggle: true,
|
|
128
124
|
tableStates,
|
|
129
125
|
|
|
130
126
|
// Add other conditions above topbarOptions
|
|
@@ -262,6 +258,7 @@ function TableWrapper<T>({
|
|
|
262
258
|
topbarOptions={craftTopbarOptions}
|
|
263
259
|
isCompactTable={isCompactTable}
|
|
264
260
|
setIsCompactTable={setIsCompactTable}
|
|
261
|
+
isFullscreen={isFullscreen}
|
|
265
262
|
fullscreenToggle={handleFullscreenToggle}
|
|
266
263
|
paginationComponent={
|
|
267
264
|
craftPaginationOptions?.showPagination === true &&
|
|
@@ -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;
|
|
@@ -97,12 +97,14 @@ function TableBody<T>({
|
|
|
97
97
|
return (
|
|
98
98
|
<React.Fragment key={row.id}>
|
|
99
99
|
{renderedRow}
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
{NestedComponent && (
|
|
101
|
+
<tr>
|
|
102
|
+
{/* <td colSpan={table.getAllLeafColumns().length}>//commented out to remove extra line on opening of
|
|
102
103
|
{NestedComponent && <NestedComponent {...{ row }} />}
|
|
103
104
|
</td> */}
|
|
104
|
-
|
|
105
|
-
|
|
105
|
+
{<NestedComponent {...{ row }} />}
|
|
106
|
+
</tr>
|
|
107
|
+
)}
|
|
106
108
|
</React.Fragment>
|
|
107
109
|
);
|
|
108
110
|
} else {
|
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
import DraggableTableHeader from "./table-head-dnd-cell";
|
|
18
18
|
import TableHeadPin from "./table-head-pin";
|
|
19
19
|
import Checkbox from "./inputs/checkbox";
|
|
20
|
-
import TableHeadPopover from "./table-head-popover";
|
|
21
20
|
|
|
22
21
|
interface TableHeadProps<T> {
|
|
23
22
|
table: Table<T>;
|
|
@@ -41,15 +40,6 @@ function TableHead<T>({
|
|
|
41
40
|
|
|
42
41
|
// Popover
|
|
43
42
|
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
|
|
44
|
-
const [wrap, setWrap] = useState(false);
|
|
45
|
-
|
|
46
|
-
const handleClose = () => {
|
|
47
|
-
setAnchorEl(null);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const toggleWrap = () => {
|
|
51
|
-
setWrap((prev) => !prev);
|
|
52
|
-
};
|
|
53
43
|
|
|
54
44
|
const handleHover = (event: React.MouseEvent<HTMLElement>) => {
|
|
55
45
|
setAnchorEl((prev) => (prev ? null : event.currentTarget));
|