@visns-studio/visns-components 5.9.4 → 5.9.5
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/package.json
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"awesome-debounce-promise": "^2.1.0",
|
|
23
23
|
"browser-image-compression": "^2.0.2",
|
|
24
24
|
"dayjs": "^1.11.13",
|
|
25
|
-
"fabric": "^6.6.
|
|
25
|
+
"fabric": "^6.6.7",
|
|
26
26
|
"file-saver": "^2.0.5",
|
|
27
27
|
"framer-motion": "^12.15.0",
|
|
28
28
|
"html-react-parser": "^5.2.5",
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
"yet-another-react-lightbox": "^3.23.2"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@babel/core": "^7.27.
|
|
71
|
-
"@babel/plugin-transform-runtime": "^7.27.
|
|
70
|
+
"@babel/core": "^7.27.4",
|
|
71
|
+
"@babel/plugin-transform-runtime": "^7.27.4",
|
|
72
72
|
"@babel/preset-env": "^7.27.2",
|
|
73
73
|
"@babel/preset-react": "^7.27.1",
|
|
74
74
|
"babel-loader": "^10.0.0",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"mini-css-extract-plugin": "^2.9.2",
|
|
79
79
|
"react": "^18.3.1",
|
|
80
80
|
"react-dom": "^18.3.1",
|
|
81
|
-
"sass": "^1.89.
|
|
81
|
+
"sass": "^1.89.1",
|
|
82
82
|
"sass-loader": "^16.0.5"
|
|
83
83
|
},
|
|
84
84
|
"peerDependencies": {
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
87
87
|
},
|
|
88
88
|
"name": "@visns-studio/visns-components",
|
|
89
|
-
"version": "5.9.
|
|
89
|
+
"version": "5.9.5",
|
|
90
90
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
91
91
|
"main": "src/index.js",
|
|
92
92
|
"files": [
|
|
@@ -653,22 +653,14 @@ function Form({
|
|
|
653
653
|
// especially when grouping is active
|
|
654
654
|
if (dataRef.current && Array.isArray(dataRef.current)) {
|
|
655
655
|
dataRef.current.forEach((obj) => {
|
|
656
|
-
if (
|
|
657
|
-
obj &&
|
|
658
|
-
obj.id !== undefined &&
|
|
659
|
-
obj.id !== null
|
|
660
|
-
) {
|
|
656
|
+
if (obj && obj.id !== undefined && obj.id !== null) {
|
|
661
657
|
s[obj.id] = obj;
|
|
662
658
|
}
|
|
663
659
|
});
|
|
664
660
|
} else if (param.data && Array.isArray(param.data)) {
|
|
665
661
|
// Fallback to param.data if dataRef.current is not available
|
|
666
662
|
param.data.forEach((obj) => {
|
|
667
|
-
if (
|
|
668
|
-
obj &&
|
|
669
|
-
obj.id !== undefined &&
|
|
670
|
-
obj.id !== null
|
|
671
|
-
) {
|
|
663
|
+
if (obj && obj.id !== undefined && obj.id !== null) {
|
|
672
664
|
s[obj.id] = obj;
|
|
673
665
|
}
|
|
674
666
|
});
|
|
@@ -1130,10 +1122,19 @@ function Form({
|
|
|
1130
1122
|
navigate(saveExit.redirectUrl);
|
|
1131
1123
|
}
|
|
1132
1124
|
}
|
|
1125
|
+
|
|
1126
|
+
toast.success(
|
|
1127
|
+
formSettings?.save?.toast?.success ||
|
|
1128
|
+
(method === 'POST'
|
|
1129
|
+
? 'Entry successfully saved into the system.'
|
|
1130
|
+
: 'Entry successfully updated.')
|
|
1131
|
+
);
|
|
1133
1132
|
} else {
|
|
1134
1133
|
toast.success(
|
|
1135
1134
|
formSettings?.save?.toast?.success ||
|
|
1136
|
-
|
|
1135
|
+
(method === 'POST'
|
|
1136
|
+
? 'Entry successfully saved into the system.'
|
|
1137
|
+
: 'Entry successfully updated.')
|
|
1137
1138
|
);
|
|
1138
1139
|
}
|
|
1139
1140
|
|
|
@@ -1151,8 +1152,10 @@ function Form({
|
|
|
1151
1152
|
formSettings?.save?.return?.type === 'table' &&
|
|
1152
1153
|
formSettings?.save?.return?.param
|
|
1153
1154
|
) {
|
|
1154
|
-
if (
|
|
1155
|
-
setTableProps(
|
|
1155
|
+
if (formSettings.save.return.props) {
|
|
1156
|
+
setTableProps(
|
|
1157
|
+
formSettings.save.return.props
|
|
1158
|
+
);
|
|
1156
1159
|
}
|
|
1157
1160
|
|
|
1158
1161
|
if (
|
|
@@ -1719,48 +1722,20 @@ function Form({
|
|
|
1719
1722
|
selected={selected}
|
|
1720
1723
|
onSelectionChange={handleSelectionChange}
|
|
1721
1724
|
{...(tableProps && tableProps.groupBy
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
setCollapsedGroups((prev) => {
|
|
1737
|
-
const newState = { ...prev };
|
|
1738
|
-
if (newState[groupValue]) {
|
|
1739
|
-
delete newState[groupValue];
|
|
1740
|
-
} else {
|
|
1741
|
-
newState[groupValue] = true;
|
|
1742
|
-
}
|
|
1743
|
-
console.log(
|
|
1744
|
-
'Updated collapsed groups:',
|
|
1745
|
-
newState
|
|
1746
|
-
);
|
|
1747
|
-
return newState;
|
|
1748
|
-
});
|
|
1749
|
-
},
|
|
1750
|
-
renderGroupTitle: (groupData) => {
|
|
1751
|
-
const groupValue =
|
|
1752
|
-
typeof groupData === 'string'
|
|
1753
|
-
? groupData
|
|
1754
|
-
: groupData?.value ||
|
|
1755
|
-
groupData?.name ||
|
|
1756
|
-
'';
|
|
1757
|
-
|
|
1758
|
-
// Use ReactDataGrid's built-in toggle functionality
|
|
1759
|
-
const collapsed =
|
|
1760
|
-
collapsedGroups[groupValue] ||
|
|
1761
|
-
false;
|
|
1762
|
-
const toggleGroup = () => {
|
|
1763
|
-
// Update the collapsed state
|
|
1725
|
+
? {
|
|
1726
|
+
defaultGroupBy: tableProps.groupBy,
|
|
1727
|
+
defaultCollapsed: true,
|
|
1728
|
+
collapsedGroups: collapsedGroups,
|
|
1729
|
+
onGroupToggle: (groupData) => {
|
|
1730
|
+
// Handle group expand/collapse events
|
|
1731
|
+
// Update collapsed groups state
|
|
1732
|
+
const groupValue =
|
|
1733
|
+
typeof groupData === 'string'
|
|
1734
|
+
? groupData
|
|
1735
|
+
: groupData?.value ||
|
|
1736
|
+
groupData?.name ||
|
|
1737
|
+
'';
|
|
1738
|
+
|
|
1764
1739
|
setCollapsedGroups((prev) => {
|
|
1765
1740
|
const newState = { ...prev };
|
|
1766
1741
|
if (newState[groupValue]) {
|
|
@@ -1772,339 +1747,400 @@ function Form({
|
|
|
1772
1747
|
groupValue
|
|
1773
1748
|
] = true;
|
|
1774
1749
|
}
|
|
1775
|
-
return newState;
|
|
1776
|
-
});
|
|
1777
|
-
};
|
|
1778
|
-
const groupCount =
|
|
1779
|
-
typeof groupData === 'object'
|
|
1780
|
-
? groupData?.count || 0
|
|
1781
|
-
: 0;
|
|
1782
|
-
const hasCheckboxColumn =
|
|
1783
|
-
tableData.columns.some(
|
|
1784
|
-
(col) =>
|
|
1785
|
-
col.id ===
|
|
1786
|
-
'__checkbox-column'
|
|
1787
|
-
);
|
|
1788
|
-
|
|
1789
|
-
// Handle group header click for selection
|
|
1790
|
-
const handleGroupHeaderClick = (
|
|
1791
|
-
e
|
|
1792
|
-
) => {
|
|
1793
|
-
// Prevent rapid clicks
|
|
1794
|
-
if (
|
|
1795
|
-
groupClickTimeoutRef.current
|
|
1796
|
-
) {
|
|
1797
1750
|
console.log(
|
|
1798
|
-
'
|
|
1751
|
+
'Updated collapsed groups:',
|
|
1752
|
+
newState
|
|
1799
1753
|
);
|
|
1800
|
-
return;
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1754
|
+
return newState;
|
|
1755
|
+
});
|
|
1756
|
+
},
|
|
1757
|
+
renderGroupTitle: (groupData) => {
|
|
1758
|
+
const groupValue =
|
|
1759
|
+
typeof groupData === 'string'
|
|
1760
|
+
? groupData
|
|
1761
|
+
: groupData?.value ||
|
|
1762
|
+
groupData?.name ||
|
|
1763
|
+
'';
|
|
1764
|
+
|
|
1765
|
+
// Use ReactDataGrid's built-in toggle functionality
|
|
1766
|
+
const collapsed =
|
|
1767
|
+
collapsedGroups[groupValue] ||
|
|
1768
|
+
false;
|
|
1769
|
+
const toggleGroup = () => {
|
|
1770
|
+
// Update the collapsed state
|
|
1771
|
+
setCollapsedGroups((prev) => {
|
|
1772
|
+
const newState = {
|
|
1773
|
+
...prev,
|
|
1774
|
+
};
|
|
1775
|
+
if (
|
|
1776
|
+
newState[groupValue]
|
|
1777
|
+
) {
|
|
1778
|
+
delete newState[
|
|
1779
|
+
groupValue
|
|
1780
|
+
];
|
|
1781
|
+
} else {
|
|
1782
|
+
newState[
|
|
1783
|
+
groupValue
|
|
1784
|
+
] = true;
|
|
1785
|
+
}
|
|
1786
|
+
return newState;
|
|
1787
|
+
});
|
|
1788
|
+
};
|
|
1789
|
+
const groupCount =
|
|
1790
|
+
typeof groupData === 'object'
|
|
1791
|
+
? groupData?.count || 0
|
|
1792
|
+
: 0;
|
|
1793
|
+
const hasCheckboxColumn =
|
|
1794
|
+
tableData.columns.some(
|
|
1795
|
+
(col) =>
|
|
1796
|
+
col.id ===
|
|
1797
|
+
'__checkbox-column'
|
|
1814
1798
|
);
|
|
1815
|
-
return;
|
|
1816
|
-
}
|
|
1817
|
-
|
|
1818
|
-
// Set timeout to prevent rapid clicks
|
|
1819
|
-
groupClickTimeoutRef.current =
|
|
1820
|
-
setTimeout(() => {
|
|
1821
|
-
groupClickTimeoutRef.current =
|
|
1822
|
-
null;
|
|
1823
|
-
}, 300);
|
|
1824
|
-
|
|
1825
|
-
// Toggle selection of all items in this group
|
|
1826
|
-
const isCurrentlySelected =
|
|
1827
|
-
isGroupSelected(groupValue);
|
|
1828
|
-
|
|
1829
|
-
handleGroupSelectionChange(
|
|
1830
|
-
groupValue,
|
|
1831
|
-
!isCurrentlySelected
|
|
1832
|
-
);
|
|
1833
|
-
};
|
|
1834
1799
|
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1800
|
+
// Handle group header click for selection
|
|
1801
|
+
const handleGroupHeaderClick = (
|
|
1802
|
+
e
|
|
1803
|
+
) => {
|
|
1804
|
+
// Prevent rapid clicks
|
|
1805
|
+
if (
|
|
1806
|
+
groupClickTimeoutRef.current
|
|
1807
|
+
) {
|
|
1808
|
+
console.log(
|
|
1809
|
+
'🖱️ Ignoring rapid click'
|
|
1810
|
+
);
|
|
1811
|
+
return;
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
// Don't trigger if clicking on the expand button or checkbox
|
|
1815
|
+
if (
|
|
1816
|
+
e.target.closest(
|
|
1817
|
+
'.group-expand-btn'
|
|
1818
|
+
) ||
|
|
1819
|
+
e.target.closest(
|
|
1820
|
+
'input[type="checkbox"]'
|
|
1821
|
+
)
|
|
1822
|
+
) {
|
|
1823
|
+
console.log(
|
|
1824
|
+
'🖱️ Ignoring click on expand button or checkbox'
|
|
1825
|
+
);
|
|
1826
|
+
return;
|
|
1840
1827
|
}
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
flexShrink: 0,
|
|
1863
|
-
transition:
|
|
1864
|
-
'background-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease',
|
|
1865
|
-
}}
|
|
1866
|
-
onMouseEnter={(e) => {
|
|
1867
|
-
e.currentTarget.style.background =
|
|
1868
|
-
'linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%)';
|
|
1869
|
-
e.currentTarget.style.boxShadow =
|
|
1870
|
-
'0 2px 8px rgba(0,0,0,0.15)';
|
|
1871
|
-
e.currentTarget.style.transform =
|
|
1872
|
-
'translateY(-1px)';
|
|
1873
|
-
}}
|
|
1874
|
-
onMouseLeave={(e) => {
|
|
1875
|
-
e.currentTarget.style.background =
|
|
1876
|
-
'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)';
|
|
1877
|
-
e.currentTarget.style.boxShadow =
|
|
1878
|
-
'0 1px 3px rgba(0,0,0,0.1)';
|
|
1879
|
-
e.currentTarget.style.transform =
|
|
1880
|
-
'translateY(0)';
|
|
1881
|
-
}}
|
|
1882
|
-
>
|
|
1883
|
-
{/* Left side - Group info and expand/collapse */}
|
|
1828
|
+
|
|
1829
|
+
// Set timeout to prevent rapid clicks
|
|
1830
|
+
groupClickTimeoutRef.current =
|
|
1831
|
+
setTimeout(() => {
|
|
1832
|
+
groupClickTimeoutRef.current =
|
|
1833
|
+
null;
|
|
1834
|
+
}, 300);
|
|
1835
|
+
|
|
1836
|
+
// Toggle selection of all items in this group
|
|
1837
|
+
const isCurrentlySelected =
|
|
1838
|
+
isGroupSelected(
|
|
1839
|
+
groupValue
|
|
1840
|
+
);
|
|
1841
|
+
|
|
1842
|
+
handleGroupSelectionChange(
|
|
1843
|
+
groupValue,
|
|
1844
|
+
!isCurrentlySelected
|
|
1845
|
+
);
|
|
1846
|
+
};
|
|
1847
|
+
|
|
1848
|
+
return (
|
|
1884
1849
|
<div
|
|
1850
|
+
className="group-header-clean group-header-fixed-height"
|
|
1851
|
+
onClick={
|
|
1852
|
+
handleGroupHeaderClick
|
|
1853
|
+
}
|
|
1885
1854
|
style={{
|
|
1886
1855
|
display: 'flex',
|
|
1887
1856
|
alignItems: 'center',
|
|
1888
|
-
|
|
1889
|
-
|
|
1857
|
+
justifyContent:
|
|
1858
|
+
'space-between',
|
|
1859
|
+
width: '100%',
|
|
1860
|
+
height: '34px', // Compact height
|
|
1861
|
+
padding: '6px 12px', // Reduced padding for compact design
|
|
1862
|
+
background:
|
|
1863
|
+
'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)',
|
|
1864
|
+
borderLeft:
|
|
1865
|
+
'4px solid var(--primary-color, #3b82f6)',
|
|
1890
1866
|
position: 'relative',
|
|
1867
|
+
overflow: 'hidden',
|
|
1868
|
+
boxShadow:
|
|
1869
|
+
'0 1px 3px rgba(0,0,0,0.1)',
|
|
1870
|
+
borderRadius:
|
|
1871
|
+
'0 4px 4px 0',
|
|
1872
|
+
cursor: 'pointer',
|
|
1873
|
+
boxSizing:
|
|
1874
|
+
'border-box',
|
|
1875
|
+
lineHeight: '1.1', // Compact line height
|
|
1876
|
+
flexShrink: 0,
|
|
1877
|
+
transition:
|
|
1878
|
+
'background-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease',
|
|
1879
|
+
}}
|
|
1880
|
+
onMouseEnter={(e) => {
|
|
1881
|
+
e.currentTarget.style.background =
|
|
1882
|
+
'linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%)';
|
|
1883
|
+
e.currentTarget.style.boxShadow =
|
|
1884
|
+
'0 2px 8px rgba(0,0,0,0.15)';
|
|
1885
|
+
e.currentTarget.style.transform =
|
|
1886
|
+
'translateY(-1px)';
|
|
1887
|
+
}}
|
|
1888
|
+
onMouseLeave={(e) => {
|
|
1889
|
+
e.currentTarget.style.background =
|
|
1890
|
+
'linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%)';
|
|
1891
|
+
e.currentTarget.style.boxShadow =
|
|
1892
|
+
'0 1px 3px rgba(0,0,0,0.1)';
|
|
1893
|
+
e.currentTarget.style.transform =
|
|
1894
|
+
'translateY(0)';
|
|
1891
1895
|
}}
|
|
1892
1896
|
>
|
|
1893
|
-
|
|
1894
|
-
className="group-expand-btn"
|
|
1895
|
-
onClick={(e) => {
|
|
1896
|
-
e.preventDefault();
|
|
1897
|
-
e.stopPropagation();
|
|
1898
|
-
if (
|
|
1899
|
-
typeof toggleGroup ===
|
|
1900
|
-
'function'
|
|
1901
|
-
) {
|
|
1902
|
-
toggleGroup();
|
|
1903
|
-
} else {
|
|
1904
|
-
console.warn(
|
|
1905
|
-
'toggleGroup is not a function:',
|
|
1906
|
-
toggleGroup
|
|
1907
|
-
);
|
|
1908
|
-
}
|
|
1909
|
-
}}
|
|
1910
|
-
style={{
|
|
1911
|
-
background:
|
|
1912
|
-
'var(--primary-color, #3b82f6)',
|
|
1913
|
-
border: 'none',
|
|
1914
|
-
borderRadius:
|
|
1915
|
-
'3px',
|
|
1916
|
-
color: 'white',
|
|
1917
|
-
width: '20px', // More compact
|
|
1918
|
-
height: '20px', // More compact
|
|
1919
|
-
display: 'flex',
|
|
1920
|
-
alignItems:
|
|
1921
|
-
'center',
|
|
1922
|
-
justifyContent:
|
|
1923
|
-
'center',
|
|
1924
|
-
marginRight:
|
|
1925
|
-
'8px', // Reduced margin
|
|
1926
|
-
cursor: 'pointer',
|
|
1927
|
-
fontSize: '11px', // Smaller font
|
|
1928
|
-
fontWeight:
|
|
1929
|
-
'bold',
|
|
1930
|
-
boxShadow:
|
|
1931
|
-
'0 1px 2px rgba(0,0,0,0.1)',
|
|
1932
|
-
transition:
|
|
1933
|
-
'all 0.15s ease',
|
|
1934
|
-
}}
|
|
1935
|
-
onMouseEnter={(e) => {
|
|
1936
|
-
e.target.style.transform =
|
|
1937
|
-
'scale(1.05)';
|
|
1938
|
-
e.target.style.background =
|
|
1939
|
-
'var(--secondary-color, #2563eb)';
|
|
1940
|
-
}}
|
|
1941
|
-
onMouseLeave={(e) => {
|
|
1942
|
-
e.target.style.transform =
|
|
1943
|
-
'scale(1)';
|
|
1944
|
-
e.target.style.background =
|
|
1945
|
-
'var(--primary-color, #3b82f6)';
|
|
1946
|
-
}}
|
|
1947
|
-
>
|
|
1948
|
-
{collapsed
|
|
1949
|
-
? '+'
|
|
1950
|
-
: '−'}
|
|
1951
|
-
</button>
|
|
1897
|
+
{/* Left side - Group info and expand/collapse */}
|
|
1952
1898
|
<div
|
|
1953
1899
|
style={{
|
|
1954
1900
|
display: 'flex',
|
|
1955
1901
|
alignItems:
|
|
1956
|
-
'center',
|
|
1957
|
-
|
|
1902
|
+
'center',
|
|
1903
|
+
flex: 1,
|
|
1904
|
+
zIndex: 2,
|
|
1905
|
+
position:
|
|
1906
|
+
'relative',
|
|
1958
1907
|
}}
|
|
1959
1908
|
>
|
|
1960
|
-
<
|
|
1909
|
+
<button
|
|
1910
|
+
className="group-expand-btn"
|
|
1911
|
+
onClick={(e) => {
|
|
1912
|
+
e.preventDefault();
|
|
1913
|
+
e.stopPropagation();
|
|
1914
|
+
if (
|
|
1915
|
+
typeof toggleGroup ===
|
|
1916
|
+
'function'
|
|
1917
|
+
) {
|
|
1918
|
+
toggleGroup();
|
|
1919
|
+
} else {
|
|
1920
|
+
console.warn(
|
|
1921
|
+
'toggleGroup is not a function:',
|
|
1922
|
+
toggleGroup
|
|
1923
|
+
);
|
|
1924
|
+
}
|
|
1925
|
+
}}
|
|
1961
1926
|
style={{
|
|
1927
|
+
background:
|
|
1928
|
+
'var(--primary-color, #3b82f6)',
|
|
1929
|
+
border: 'none',
|
|
1930
|
+
borderRadius:
|
|
1931
|
+
'3px',
|
|
1932
|
+
color: 'white',
|
|
1933
|
+
width: '20px', // More compact
|
|
1934
|
+
height: '20px', // More compact
|
|
1935
|
+
display:
|
|
1936
|
+
'flex',
|
|
1937
|
+
alignItems:
|
|
1938
|
+
'center',
|
|
1939
|
+
justifyContent:
|
|
1940
|
+
'center',
|
|
1941
|
+
marginRight:
|
|
1942
|
+
'8px', // Reduced margin
|
|
1943
|
+
cursor: 'pointer',
|
|
1962
1944
|
fontSize:
|
|
1963
|
-
'
|
|
1964
|
-
color: 'var(--secondary-color, #1f2937)',
|
|
1945
|
+
'11px', // Smaller font
|
|
1965
1946
|
fontWeight:
|
|
1966
|
-
'
|
|
1967
|
-
|
|
1968
|
-
'
|
|
1969
|
-
|
|
1970
|
-
'0.
|
|
1947
|
+
'bold',
|
|
1948
|
+
boxShadow:
|
|
1949
|
+
'0 1px 2px rgba(0,0,0,0.1)',
|
|
1950
|
+
transition:
|
|
1951
|
+
'all 0.15s ease',
|
|
1952
|
+
}}
|
|
1953
|
+
onMouseEnter={(
|
|
1954
|
+
e
|
|
1955
|
+
) => {
|
|
1956
|
+
e.target.style.transform =
|
|
1957
|
+
'scale(1.05)';
|
|
1958
|
+
e.target.style.background =
|
|
1959
|
+
'var(--secondary-color, #2563eb)';
|
|
1960
|
+
}}
|
|
1961
|
+
onMouseLeave={(
|
|
1962
|
+
e
|
|
1963
|
+
) => {
|
|
1964
|
+
e.target.style.transform =
|
|
1965
|
+
'scale(1)';
|
|
1966
|
+
e.target.style.background =
|
|
1967
|
+
'var(--primary-color, #3b82f6)';
|
|
1971
1968
|
}}
|
|
1972
1969
|
>
|
|
1973
|
-
{
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1970
|
+
{collapsed
|
|
1971
|
+
? '+'
|
|
1972
|
+
: '−'}
|
|
1973
|
+
</button>
|
|
1974
|
+
<div
|
|
1975
|
+
style={{
|
|
1976
|
+
display:
|
|
1977
|
+
'flex',
|
|
1978
|
+
alignItems:
|
|
1979
|
+
'center', // Changed to center for compact layout
|
|
1980
|
+
gap: '8px', // Add gap between elements
|
|
1981
|
+
}}
|
|
1982
|
+
>
|
|
1983
|
+
<strong
|
|
1977
1984
|
style={{
|
|
1978
|
-
color: '#6b7280',
|
|
1979
1985
|
fontSize:
|
|
1980
|
-
'0.
|
|
1986
|
+
'0.85rem', // Slightly smaller for compact design
|
|
1987
|
+
color: 'var(--secondary-color, #1f2937)',
|
|
1981
1988
|
fontWeight:
|
|
1982
|
-
'
|
|
1989
|
+
'600',
|
|
1990
|
+
textTransform:
|
|
1991
|
+
'uppercase',
|
|
1992
|
+
letterSpacing:
|
|
1993
|
+
'0.025em',
|
|
1994
|
+
}}
|
|
1995
|
+
>
|
|
1996
|
+
{groupValue}
|
|
1997
|
+
</strong>
|
|
1998
|
+
{groupCount >
|
|
1999
|
+
0 && (
|
|
2000
|
+
<span
|
|
2001
|
+
style={{
|
|
2002
|
+
color: '#6b7280',
|
|
2003
|
+
fontSize:
|
|
2004
|
+
'0.75rem', // Smaller for compact design
|
|
2005
|
+
fontWeight:
|
|
2006
|
+
'500',
|
|
2007
|
+
}}
|
|
2008
|
+
>
|
|
2009
|
+
(
|
|
2010
|
+
{
|
|
2011
|
+
groupCount
|
|
2012
|
+
}{' '}
|
|
2013
|
+
{groupCount ===
|
|
2014
|
+
1
|
|
2015
|
+
? 'item'
|
|
2016
|
+
: 'items'}
|
|
2017
|
+
)
|
|
2018
|
+
</span>
|
|
2019
|
+
)}
|
|
2020
|
+
{/* Click indicator */}
|
|
2021
|
+
<span
|
|
2022
|
+
style={{
|
|
2023
|
+
color: '#9ca3af',
|
|
2024
|
+
fontSize:
|
|
2025
|
+
'0.7rem',
|
|
2026
|
+
fontStyle:
|
|
2027
|
+
'italic',
|
|
2028
|
+
opacity: 0.8,
|
|
2029
|
+
marginLeft:
|
|
2030
|
+
'auto',
|
|
2031
|
+
userSelect:
|
|
2032
|
+
'none',
|
|
1983
2033
|
}}
|
|
1984
2034
|
>
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
? 'item'
|
|
1989
|
-
: 'items'}
|
|
1990
|
-
)
|
|
2035
|
+
Click to
|
|
2036
|
+
select/unselect
|
|
2037
|
+
all
|
|
1991
2038
|
</span>
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
2039
|
+
</div>
|
|
2040
|
+
</div>
|
|
2041
|
+
|
|
2042
|
+
{/* Right side - Group selection */}
|
|
2043
|
+
{hasCheckboxColumn && (
|
|
2044
|
+
<div
|
|
1995
2045
|
style={{
|
|
1996
|
-
|
|
2046
|
+
display:
|
|
2047
|
+
'flex',
|
|
2048
|
+
alignItems:
|
|
2049
|
+
'center',
|
|
2050
|
+
gap: '4px', // Reduced gap for compact design
|
|
1997
2051
|
fontSize:
|
|
1998
|
-
'0.
|
|
1999
|
-
|
|
2000
|
-
'
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2052
|
+
'0.75rem', // Smaller font for compact design
|
|
2053
|
+
background:
|
|
2054
|
+
'rgba(255, 255, 255, 0.9)',
|
|
2055
|
+
padding:
|
|
2056
|
+
'3px 8px', // Reduced padding for compact design
|
|
2057
|
+
borderRadius:
|
|
2058
|
+
'12px', // Smaller border radius
|
|
2059
|
+
border: '1px solid rgba(59, 130, 246, 0.3)',
|
|
2060
|
+
zIndex: 2,
|
|
2061
|
+
position:
|
|
2062
|
+
'relative',
|
|
2063
|
+
boxShadow:
|
|
2064
|
+
'0 1px 2px rgba(0,0,0,0.05)',
|
|
2006
2065
|
}}
|
|
2007
2066
|
>
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2067
|
+
<input
|
|
2068
|
+
type="checkbox"
|
|
2069
|
+
onChange={(
|
|
2070
|
+
e
|
|
2071
|
+
) => {
|
|
2072
|
+
e.stopPropagation();
|
|
2073
|
+
handleGroupSelectionChange(
|
|
2074
|
+
groupValue,
|
|
2075
|
+
e
|
|
2076
|
+
.target
|
|
2077
|
+
.checked
|
|
2078
|
+
);
|
|
2079
|
+
}}
|
|
2080
|
+
checked={isGroupSelected(
|
|
2081
|
+
groupValue
|
|
2082
|
+
)}
|
|
2083
|
+
style={{
|
|
2084
|
+
width: '14px', // Smaller checkbox for compact design
|
|
2085
|
+
height: '14px',
|
|
2086
|
+
cursor: 'pointer',
|
|
2087
|
+
accentColor:
|
|
2088
|
+
'var(--primary-color, #3b82f6)',
|
|
2089
|
+
}}
|
|
2090
|
+
/>
|
|
2091
|
+
<span
|
|
2092
|
+
style={{
|
|
2093
|
+
cursor: 'pointer',
|
|
2094
|
+
userSelect:
|
|
2095
|
+
'none',
|
|
2096
|
+
color: 'var(--secondary-color, #1f2937)',
|
|
2097
|
+
fontWeight:
|
|
2098
|
+
'500',
|
|
2099
|
+
fontSize:
|
|
2100
|
+
'0.7rem', // Smaller font for compact design
|
|
2101
|
+
}}
|
|
2102
|
+
onClick={(
|
|
2103
|
+
e
|
|
2104
|
+
) => {
|
|
2105
|
+
e.stopPropagation();
|
|
2106
|
+
const checkbox =
|
|
2107
|
+
e
|
|
2108
|
+
.target
|
|
2109
|
+
.previousElementSibling;
|
|
2110
|
+
checkbox.checked =
|
|
2111
|
+
!checkbox.checked;
|
|
2112
|
+
handleGroupSelectionChange(
|
|
2113
|
+
groupValue,
|
|
2114
|
+
checkbox.checked
|
|
2115
|
+
);
|
|
2116
|
+
}}
|
|
2117
|
+
>
|
|
2118
|
+
Select All
|
|
2119
|
+
</span>
|
|
2120
|
+
</div>
|
|
2121
|
+
)}
|
|
2014
2122
|
|
|
2015
|
-
|
|
2016
|
-
{hasCheckboxColumn && (
|
|
2123
|
+
{/* Background pattern */}
|
|
2017
2124
|
<div
|
|
2018
2125
|
style={{
|
|
2019
|
-
display: 'flex',
|
|
2020
|
-
alignItems:
|
|
2021
|
-
'center',
|
|
2022
|
-
gap: '4px', // Reduced gap for compact design
|
|
2023
|
-
fontSize:
|
|
2024
|
-
'0.75rem', // Smaller font for compact design
|
|
2025
|
-
background:
|
|
2026
|
-
'rgba(255, 255, 255, 0.9)',
|
|
2027
|
-
padding:
|
|
2028
|
-
'3px 8px', // Reduced padding for compact design
|
|
2029
|
-
borderRadius:
|
|
2030
|
-
'12px', // Smaller border radius
|
|
2031
|
-
border: '1px solid rgba(59, 130, 246, 0.3)',
|
|
2032
|
-
zIndex: 2,
|
|
2033
2126
|
position:
|
|
2034
|
-
'
|
|
2035
|
-
|
|
2036
|
-
|
|
2127
|
+
'absolute',
|
|
2128
|
+
top: 0,
|
|
2129
|
+
left: 0,
|
|
2130
|
+
right: 0,
|
|
2131
|
+
bottom: 0,
|
|
2132
|
+
background:
|
|
2133
|
+
'repeating-linear-gradient(45deg, transparent, transparent 2px, rgba(59, 130, 246, 0.03) 2px, rgba(59, 130, 246, 0.03) 4px)',
|
|
2134
|
+
zIndex: 1,
|
|
2135
|
+
pointerEvents:
|
|
2136
|
+
'none',
|
|
2037
2137
|
}}
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
groupValue,
|
|
2045
|
-
e.target
|
|
2046
|
-
.checked
|
|
2047
|
-
);
|
|
2048
|
-
}}
|
|
2049
|
-
checked={isGroupSelected(
|
|
2050
|
-
groupValue
|
|
2051
|
-
)}
|
|
2052
|
-
style={{
|
|
2053
|
-
width: '14px', // Smaller checkbox for compact design
|
|
2054
|
-
height: '14px',
|
|
2055
|
-
cursor: 'pointer',
|
|
2056
|
-
accentColor:
|
|
2057
|
-
'var(--primary-color, #3b82f6)',
|
|
2058
|
-
}}
|
|
2059
|
-
/>
|
|
2060
|
-
<span
|
|
2061
|
-
style={{
|
|
2062
|
-
cursor: 'pointer',
|
|
2063
|
-
userSelect:
|
|
2064
|
-
'none',
|
|
2065
|
-
color: 'var(--secondary-color, #1f2937)',
|
|
2066
|
-
fontWeight:
|
|
2067
|
-
'500',
|
|
2068
|
-
fontSize:
|
|
2069
|
-
'0.7rem', // Smaller font for compact design
|
|
2070
|
-
}}
|
|
2071
|
-
onClick={(e) => {
|
|
2072
|
-
e.stopPropagation();
|
|
2073
|
-
const checkbox =
|
|
2074
|
-
e.target
|
|
2075
|
-
.previousElementSibling;
|
|
2076
|
-
checkbox.checked =
|
|
2077
|
-
!checkbox.checked;
|
|
2078
|
-
handleGroupSelectionChange(
|
|
2079
|
-
groupValue,
|
|
2080
|
-
checkbox.checked
|
|
2081
|
-
);
|
|
2082
|
-
}}
|
|
2083
|
-
>
|
|
2084
|
-
Select All
|
|
2085
|
-
</span>
|
|
2086
|
-
</div>
|
|
2087
|
-
)}
|
|
2088
|
-
|
|
2089
|
-
{/* Background pattern */}
|
|
2090
|
-
<div
|
|
2091
|
-
style={{
|
|
2092
|
-
position: 'absolute',
|
|
2093
|
-
top: 0,
|
|
2094
|
-
left: 0,
|
|
2095
|
-
right: 0,
|
|
2096
|
-
bottom: 0,
|
|
2097
|
-
background:
|
|
2098
|
-
'repeating-linear-gradient(45deg, transparent, transparent 2px, rgba(59, 130, 246, 0.03) 2px, rgba(59, 130, 246, 0.03) 4px)',
|
|
2099
|
-
zIndex: 1,
|
|
2100
|
-
pointerEvents: 'none',
|
|
2101
|
-
}}
|
|
2102
|
-
/>
|
|
2103
|
-
</div>
|
|
2104
|
-
);
|
|
2105
|
-
},
|
|
2106
|
-
}
|
|
2107
|
-
: {})}
|
|
2138
|
+
/>
|
|
2139
|
+
</div>
|
|
2140
|
+
);
|
|
2141
|
+
},
|
|
2142
|
+
}
|
|
2143
|
+
: {})}
|
|
2108
2144
|
/>
|
|
2109
2145
|
</div>
|
|
2110
2146
|
)}
|
|
@@ -15,10 +15,12 @@ import parse from 'html-react-parser';
|
|
|
15
15
|
import moment from 'moment';
|
|
16
16
|
import numeral from 'numeral';
|
|
17
17
|
import { CloudDownload } from 'akar-icons';
|
|
18
|
+
import Popup from 'reactjs-popup';
|
|
18
19
|
|
|
19
20
|
import CustomFetch from '../Fetch';
|
|
20
21
|
import Download from '../Download';
|
|
21
22
|
import Field from '../Field';
|
|
23
|
+
import Form from '../Form';
|
|
22
24
|
import Table from '../DataGrid';
|
|
23
25
|
import TableFilter from '../TableFilter';
|
|
24
26
|
|
|
@@ -1485,6 +1487,11 @@ function GenericIndex({
|
|
|
1485
1487
|
const [tableData, setTableData] = useState([]);
|
|
1486
1488
|
const [tableInfo, setTableInfo] = useState({});
|
|
1487
1489
|
const [total, setTotal] = useState(0);
|
|
1490
|
+
|
|
1491
|
+
/** Custom Action Modal States */
|
|
1492
|
+
const [customActionModalShow, setCustomActionModalShow] = useState(false);
|
|
1493
|
+
const [customActionFormData, setCustomActionFormData] = useState({});
|
|
1494
|
+
const [customActionConfig, setCustomActionConfig] = useState(null);
|
|
1488
1495
|
const windowHeight = useWindowHeight();
|
|
1489
1496
|
const { config, setConfig, subnav, setSubnav } = useConfig(
|
|
1490
1497
|
setting,
|
|
@@ -1526,20 +1533,110 @@ function GenericIndex({
|
|
|
1526
1533
|
[setting, config]
|
|
1527
1534
|
);
|
|
1528
1535
|
|
|
1536
|
+
/** Custom Action Modal Functions */
|
|
1537
|
+
const handleCustomActionModal = useCallback(
|
|
1538
|
+
(customAction) => {
|
|
1539
|
+
try {
|
|
1540
|
+
// Get form configuration from root level (config.form)
|
|
1541
|
+
const rootFormConfig = config.form;
|
|
1542
|
+
|
|
1543
|
+
if (!rootFormConfig || !rootFormConfig.fields) {
|
|
1544
|
+
toast.error('Form configuration not found.');
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
// Filter out hidden fields from root-level form configuration
|
|
1549
|
+
const visibleFields = rootFormConfig.fields.filter(
|
|
1550
|
+
(field) => field.type !== 'hidden'
|
|
1551
|
+
);
|
|
1552
|
+
|
|
1553
|
+
// Add hidden field for selected rows
|
|
1554
|
+
const selectedRowIds = Object.keys(rowsSelected);
|
|
1555
|
+
const fieldsWithRows = [
|
|
1556
|
+
...visibleFields,
|
|
1557
|
+
{
|
|
1558
|
+
id: 'selected_rows',
|
|
1559
|
+
type: 'hidden',
|
|
1560
|
+
value: selectedRowIds,
|
|
1561
|
+
},
|
|
1562
|
+
];
|
|
1563
|
+
|
|
1564
|
+
// Prepare form data for the modal using root-level form config
|
|
1565
|
+
const modalFormData = {
|
|
1566
|
+
...rootFormConfig,
|
|
1567
|
+
fields: fieldsWithRows,
|
|
1568
|
+
// Use custom URL and method for submission
|
|
1569
|
+
customUrl: customAction.url,
|
|
1570
|
+
customMethod: customAction.method || 'POST',
|
|
1571
|
+
customDataId: false, // Don't append ID to URL
|
|
1572
|
+
create: {
|
|
1573
|
+
title: customAction.label,
|
|
1574
|
+
url: customAction.url,
|
|
1575
|
+
method: customAction.method || 'POST',
|
|
1576
|
+
},
|
|
1577
|
+
primaryKey: 'id',
|
|
1578
|
+
};
|
|
1579
|
+
|
|
1580
|
+
setCustomActionConfig(customAction);
|
|
1581
|
+
setCustomActionFormData(modalFormData);
|
|
1582
|
+
setCustomActionModalShow(true);
|
|
1583
|
+
} catch (error) {
|
|
1584
|
+
console.error('Error opening custom action modal:', error);
|
|
1585
|
+
toast.error('Error opening form. Please try again.');
|
|
1586
|
+
}
|
|
1587
|
+
},
|
|
1588
|
+
[config.form, rowsSelected]
|
|
1589
|
+
);
|
|
1590
|
+
|
|
1591
|
+
const closeCustomActionModal = useCallback(() => {
|
|
1592
|
+
setCustomActionModalShow(false);
|
|
1593
|
+
setCustomActionFormData({});
|
|
1594
|
+
setCustomActionConfig(null);
|
|
1595
|
+
}, []);
|
|
1596
|
+
|
|
1597
|
+
const handleCustomActionSubmit = useCallback(() => {
|
|
1598
|
+
// This is called after successful form submission by the Form component
|
|
1599
|
+
// Since we provide closeModal prop, the Form component won't show success message
|
|
1600
|
+
// So we need to show it here, then reload grid and close modal
|
|
1601
|
+
|
|
1602
|
+
console.log('Custom action submitted', customActionConfig);
|
|
1603
|
+
if (customActionConfig) {
|
|
1604
|
+
toast.success(
|
|
1605
|
+
customActionConfig.message?.success ||
|
|
1606
|
+
'Operation completed successfully.'
|
|
1607
|
+
);
|
|
1608
|
+
}
|
|
1609
|
+
gridRef.current?.reload();
|
|
1610
|
+
closeCustomActionModal();
|
|
1611
|
+
}, [customActionConfig, closeCustomActionModal]);
|
|
1612
|
+
|
|
1529
1613
|
const handleCustomAction = useCallback(async () => {
|
|
1530
1614
|
try {
|
|
1531
1615
|
// Get the custom action configuration using our helper
|
|
1532
1616
|
const customActionConfig = getFunctionConfig('customAction');
|
|
1533
1617
|
|
|
1534
1618
|
if (customActionConfig) {
|
|
1535
|
-
//
|
|
1536
|
-
|
|
1619
|
+
// Check if this is a modal type custom action
|
|
1620
|
+
if (customActionConfig.type === 'modal') {
|
|
1621
|
+
// Check if rows are selected for modal type actions
|
|
1622
|
+
if (!Object.keys(rowsSelected).length) {
|
|
1623
|
+
toast.warning(
|
|
1624
|
+
customActionConfig.message?.warning ||
|
|
1625
|
+
'Please select at least one row.'
|
|
1626
|
+
);
|
|
1627
|
+
return;
|
|
1628
|
+
}
|
|
1629
|
+
handleCustomActionModal(customActionConfig);
|
|
1630
|
+
} else {
|
|
1631
|
+
// Original implementation for non-modal custom actions
|
|
1632
|
+
console.log('Custom action triggered', customActionConfig);
|
|
1633
|
+
}
|
|
1537
1634
|
}
|
|
1538
1635
|
} catch (err) {
|
|
1539
1636
|
console.error(err);
|
|
1540
1637
|
toast.error('An error occurred while performing the custom action');
|
|
1541
1638
|
}
|
|
1542
|
-
}, [getFunctionConfig]);
|
|
1639
|
+
}, [getFunctionConfig, handleCustomActionModal, rowsSelected]);
|
|
1543
1640
|
|
|
1544
1641
|
const handleCheckboxUpdate = useCallback(async () => {
|
|
1545
1642
|
try {
|
|
@@ -2064,15 +2161,36 @@ function GenericIndex({
|
|
|
2064
2161
|
)}
|
|
2065
2162
|
|
|
2066
2163
|
{/* Render Custom Action button if customAction function is configured in any location */}
|
|
2067
|
-
{getFunctionConfig('customAction') &&
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2164
|
+
{getFunctionConfig('customAction') &&
|
|
2165
|
+
(() => {
|
|
2166
|
+
const customActionConfig =
|
|
2167
|
+
getFunctionConfig('customAction');
|
|
2168
|
+
const isModalType =
|
|
2169
|
+
customActionConfig.type === 'modal';
|
|
2170
|
+
const hasSelectedRows =
|
|
2171
|
+
Object.keys(rowsSelected).length > 0;
|
|
2172
|
+
const isDisabled =
|
|
2173
|
+
isModalType && !hasSelectedRows;
|
|
2174
|
+
|
|
2175
|
+
return (
|
|
2176
|
+
<button
|
|
2177
|
+
className={styles.btn}
|
|
2178
|
+
onClick={handleCustomAction}
|
|
2179
|
+
disabled={isDisabled}
|
|
2180
|
+
{...(isDisabled && {
|
|
2181
|
+
'data-tooltip-id':
|
|
2182
|
+
'system-tooltip',
|
|
2183
|
+
'data-tooltip-content':
|
|
2184
|
+
customActionConfig.message
|
|
2185
|
+
?.warning ||
|
|
2186
|
+
'Please select at least one row to perform this action',
|
|
2187
|
+
})}
|
|
2188
|
+
>
|
|
2189
|
+
{customActionConfig.label ||
|
|
2190
|
+
'Custom Action'}
|
|
2191
|
+
</button>
|
|
2192
|
+
);
|
|
2193
|
+
})()}
|
|
2076
2194
|
|
|
2077
2195
|
{setting.export?.label && (
|
|
2078
2196
|
<button
|
|
@@ -2086,6 +2204,43 @@ function GenericIndex({
|
|
|
2086
2204
|
);
|
|
2087
2205
|
})()}
|
|
2088
2206
|
</div>
|
|
2207
|
+
|
|
2208
|
+
{/* Custom Action Modal */}
|
|
2209
|
+
<Popup
|
|
2210
|
+
open={customActionModalShow}
|
|
2211
|
+
onClose={closeCustomActionModal}
|
|
2212
|
+
closeOnDocumentClick={false}
|
|
2213
|
+
contentStyle={{
|
|
2214
|
+
width: '80vw',
|
|
2215
|
+
maxWidth: '1200px',
|
|
2216
|
+
...(customActionFormData.verticalAlign === 'top' && {
|
|
2217
|
+
position: 'fixed',
|
|
2218
|
+
top: '5vh',
|
|
2219
|
+
left: '50%',
|
|
2220
|
+
transform: 'translateX(-50%)',
|
|
2221
|
+
margin: '0',
|
|
2222
|
+
}),
|
|
2223
|
+
}}
|
|
2224
|
+
>
|
|
2225
|
+
<div
|
|
2226
|
+
className={`modalwrap top--modal modalWide ${
|
|
2227
|
+
customActionFormData.verticalAlign === 'top'
|
|
2228
|
+
? 'modal-top-aligned'
|
|
2229
|
+
: ''
|
|
2230
|
+
}`}
|
|
2231
|
+
>
|
|
2232
|
+
<div className="modal">
|
|
2233
|
+
<Form
|
|
2234
|
+
closeModal={closeCustomActionModal}
|
|
2235
|
+
formSettings={customActionFormData}
|
|
2236
|
+
formType="create"
|
|
2237
|
+
fetchTable={handleCustomActionSubmit}
|
|
2238
|
+
style={userProfile?.settings?.style || {}}
|
|
2239
|
+
userProfile={userProfile}
|
|
2240
|
+
/>
|
|
2241
|
+
</div>
|
|
2242
|
+
</div>
|
|
2243
|
+
</Popup>
|
|
2089
2244
|
</>
|
|
2090
2245
|
);
|
|
2091
2246
|
}
|
|
@@ -214,12 +214,20 @@
|
|
|
214
214
|
font-size: 1.25em;
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
-
.btn:hover {
|
|
217
|
+
.btn:hover:not(:disabled) {
|
|
218
218
|
color: var(--primary-color);
|
|
219
219
|
background: var(--highlight-color);
|
|
220
220
|
border: 1px solid rgba(var(--highlight-color-rgb), 1.05);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
.btn:disabled {
|
|
224
|
+
opacity: 0.5;
|
|
225
|
+
cursor: not-allowed;
|
|
226
|
+
background: var(--primary-color);
|
|
227
|
+
color: var(--tertiary-color);
|
|
228
|
+
border: 1px solid rgba(var(--primary-color--rgb), 0.5);
|
|
229
|
+
}
|
|
230
|
+
|
|
223
231
|
.polActions {
|
|
224
232
|
position: fixed;
|
|
225
233
|
bottom: 15px;
|