datastake-daf 0.6.196 → 0.6.198
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/index.js +118 -131
- package/dist/utils/index.js +0 -3
- package/package.json +2 -2
- package/src/@daf/core/components/Dashboard/Globe/index.jsx +35 -0
- package/src/@daf/core/components/Dashboard/Globe/style.js +0 -11
- package/src/@daf/core/components/Dashboard/Widget/CarouselWidget/index.jsx +4 -1
- package/src/@daf/core/components/Dashboard/Widget/WidgetCard/WidgetCard.stories.js +19 -143
- package/src/@daf/core/components/Dashboard/Widget/WidgetCard/index.js +28 -68
- package/src/@daf/core/components/Dashboard/Widget/WidgetCard/style.js +1 -24
- package/src/@daf/core/components/EditForm/EditInputs.stories.js +1 -0
- package/src/@daf/core/components/EditForm/helper.js +40 -10
- package/src/constants/locales/en/translation.js +0 -1
- package/src/constants/locales/fr/translation.js +0 -1
- package/src/constants/locales/sp/translation.js +0 -1
- package/src/@daf/core/components/Dashboard/Widget/WidgetCard/WidgetCardContainer.jsx +0 -79
package/dist/components/index.js
CHANGED
|
@@ -18752,17 +18752,6 @@ const Style$A = dt.div`
|
|
|
18752
18752
|
position: relative;
|
|
18753
18753
|
width: 100%;
|
|
18754
18754
|
height: 472px;
|
|
18755
|
-
min-height: 300px;
|
|
18756
|
-
|
|
18757
|
-
@media (max-width: 768px) {
|
|
18758
|
-
height: 350px;
|
|
18759
|
-
min-height: 250px;
|
|
18760
|
-
}
|
|
18761
|
-
|
|
18762
|
-
@media (max-width: 480px) {
|
|
18763
|
-
height: 300px;
|
|
18764
|
-
min-height: 200px;
|
|
18765
|
-
}
|
|
18766
18755
|
|
|
18767
18756
|
.filter-cont {
|
|
18768
18757
|
position: absolute;
|
|
@@ -20050,6 +20039,22 @@ const useGlobe = ({
|
|
|
20050
20039
|
};
|
|
20051
20040
|
};
|
|
20052
20041
|
|
|
20042
|
+
typeof localStorage.getItem('is_collapsed') === 'string' ? localStorage.getItem('is_collapsed') === 'true' ? true : false : true;
|
|
20043
|
+
typeof localStorage.getItem('is_nested_sidebar_collapsed') === 'string' ? localStorage.getItem('is_nested_sidebar_collapsed') === 'true' : true;
|
|
20044
|
+
const ResizeContext = /*#__PURE__*/React.createContext({
|
|
20045
|
+
resizeLoading: false,
|
|
20046
|
+
windowWidth: 0,
|
|
20047
|
+
resizeDif: 0,
|
|
20048
|
+
isCollapsed: false,
|
|
20049
|
+
setIsCollapsed: () => {},
|
|
20050
|
+
isNestedSidebarCollapsed: false,
|
|
20051
|
+
setIsNestedSidebarCollapsed: () => {}
|
|
20052
|
+
});
|
|
20053
|
+
const useResizeContext = () => {
|
|
20054
|
+
const values = React.useContext(ResizeContext);
|
|
20055
|
+
return values;
|
|
20056
|
+
};
|
|
20057
|
+
|
|
20053
20058
|
function Globe(_ref) {
|
|
20054
20059
|
var _activeMarker$data, _activeMarker$data2;
|
|
20055
20060
|
let {
|
|
@@ -20090,6 +20095,11 @@ function Globe(_ref) {
|
|
|
20090
20095
|
});
|
|
20091
20096
|
}), [data]);
|
|
20092
20097
|
|
|
20098
|
+
// Get resize context for sidebar state changes
|
|
20099
|
+
const {
|
|
20100
|
+
isCollapsed
|
|
20101
|
+
} = useResizeContext();
|
|
20102
|
+
|
|
20093
20103
|
// Use custom hook to configure globe functionality
|
|
20094
20104
|
const {
|
|
20095
20105
|
container,
|
|
@@ -20133,6 +20143,33 @@ function Globe(_ref) {
|
|
|
20133
20143
|
return () => clearTimeout(timer);
|
|
20134
20144
|
}
|
|
20135
20145
|
}, [forceResize]);
|
|
20146
|
+
|
|
20147
|
+
// Force resize when sidebar state changes (handles width changes)
|
|
20148
|
+
React.useEffect(() => {
|
|
20149
|
+
if (forceResize) {
|
|
20150
|
+
// Trigger resize when sidebar collapses/expands
|
|
20151
|
+
const timer = setTimeout(() => {
|
|
20152
|
+
forceResize();
|
|
20153
|
+
}, 100);
|
|
20154
|
+
return () => clearTimeout(timer);
|
|
20155
|
+
}
|
|
20156
|
+
}, [isCollapsed, forceResize]);
|
|
20157
|
+
|
|
20158
|
+
// Force resize when window width changes (handles sidebar width changes)
|
|
20159
|
+
React.useEffect(() => {
|
|
20160
|
+
if (forceResize) {
|
|
20161
|
+
const handleResize = () => {
|
|
20162
|
+
// Small delay to ensure DOM has updated
|
|
20163
|
+
setTimeout(() => {
|
|
20164
|
+
forceResize();
|
|
20165
|
+
}, 100);
|
|
20166
|
+
};
|
|
20167
|
+
window.addEventListener('resize', handleResize);
|
|
20168
|
+
return () => {
|
|
20169
|
+
window.removeEventListener('resize', handleResize);
|
|
20170
|
+
};
|
|
20171
|
+
}
|
|
20172
|
+
}, [forceResize]);
|
|
20136
20173
|
return /*#__PURE__*/jsxRuntime.jsx(ComponentWithFocus, {
|
|
20137
20174
|
children: /*#__PURE__*/jsxRuntime.jsxs(Style$A, {
|
|
20138
20175
|
className: formatClassname([showSider && activeMarker && "with-sider"]),
|
|
@@ -20991,27 +21028,9 @@ function ProjectWidget(_ref) {
|
|
|
20991
21028
|
}
|
|
20992
21029
|
|
|
20993
21030
|
const Style$x = dt.div`
|
|
20994
|
-
|
|
20995
|
-
display: flex; /* Make this a flex container */
|
|
20996
|
-
${props => props.width ? `width: ${props.width};` : 'flex: 1;'} /* Use width if specified, otherwise flex */
|
|
20997
|
-
|
|
20998
|
-
> .daf-widget {
|
|
21031
|
+
.daf-widget {
|
|
20999
21032
|
background-color: ${props => props.backgroundColor} !important;
|
|
21000
21033
|
border-color: ${props => props.backgroundBorderColor} !important;
|
|
21001
|
-
transition: box-shadow 0.2s ease-in-out;
|
|
21002
|
-
height: 100%; /* Ensure full height */
|
|
21003
|
-
width: 100%; /* Take full width of the container */
|
|
21004
|
-
|
|
21005
|
-
&:hover {
|
|
21006
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
21007
|
-
}
|
|
21008
|
-
|
|
21009
|
-
.widget-body {
|
|
21010
|
-
display: flex;
|
|
21011
|
-
flex-direction: column;
|
|
21012
|
-
flex: 1; /* Make widget body flexible */
|
|
21013
|
-
min-height: 0; /* Allow flex shrinking */
|
|
21014
|
-
}
|
|
21015
21034
|
}
|
|
21016
21035
|
|
|
21017
21036
|
.widget-card-logo-icon {
|
|
@@ -21024,11 +21043,6 @@ const Style$x = dt.div`
|
|
|
21024
21043
|
align-items: center;
|
|
21025
21044
|
border: 1px solid #E5E7EB;
|
|
21026
21045
|
}
|
|
21027
|
-
|
|
21028
|
-
.disabled-anchor {
|
|
21029
|
-
cursor: not-allowed;
|
|
21030
|
-
opacity: 0.5;
|
|
21031
|
-
}
|
|
21032
21046
|
`;
|
|
21033
21047
|
|
|
21034
21048
|
const {
|
|
@@ -21046,17 +21060,13 @@ const WidgetCard = _ref => {
|
|
|
21046
21060
|
loading = false,
|
|
21047
21061
|
iconColor,
|
|
21048
21062
|
buttonIcon,
|
|
21049
|
-
imageUrl
|
|
21050
|
-
buttonConfig = {},
|
|
21051
|
-
width,
|
|
21052
|
-
t = () => {}
|
|
21063
|
+
imageUrl
|
|
21053
21064
|
} = _ref;
|
|
21054
21065
|
useToken$h();
|
|
21055
21066
|
return /*#__PURE__*/jsxRuntime.jsx(Style$x, {
|
|
21056
21067
|
backgroundColor: backgroundColor,
|
|
21057
21068
|
backgroundBorderColor: backgroundBorderColor,
|
|
21058
|
-
|
|
21059
|
-
children: /*#__PURE__*/jsxRuntime.jsx(Widget, {
|
|
21069
|
+
children: /*#__PURE__*/jsxRuntime.jsxs(Widget, {
|
|
21060
21070
|
title: /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
21061
21071
|
style: {
|
|
21062
21072
|
display: "flex",
|
|
@@ -21080,80 +21090,39 @@ const WidgetCard = _ref => {
|
|
|
21080
21090
|
addedHeader: /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
21081
21091
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
21082
21092
|
className: "flex-1"
|
|
21083
|
-
}), /*#__PURE__*/jsxRuntime.jsx(
|
|
21084
|
-
|
|
21085
|
-
|
|
21086
|
-
|
|
21087
|
-
|
|
21088
|
-
|
|
21089
|
-
|
|
21090
|
-
name: buttonIcon,
|
|
21091
|
-
size: 16,
|
|
21092
|
-
color: buttonConfig !== null && buttonConfig !== void 0 && buttonConfig.disabled ? "#6C737F" : iconColor || antd.theme.colorPrimary
|
|
21093
|
-
})
|
|
21093
|
+
}), /*#__PURE__*/jsxRuntime.jsx("a", {
|
|
21094
|
+
className: "widget-card-logo-icon",
|
|
21095
|
+
href: link,
|
|
21096
|
+
children: /*#__PURE__*/jsxRuntime.jsx(CustomIcon, {
|
|
21097
|
+
name: buttonIcon,
|
|
21098
|
+
size: 16,
|
|
21099
|
+
color: iconColor || antd.theme.colorPrimary
|
|
21094
21100
|
})
|
|
21095
21101
|
})]
|
|
21096
21102
|
}),
|
|
21097
21103
|
loading: loading,
|
|
21098
|
-
className: "with-tabs
|
|
21099
|
-
children: /*#__PURE__*/jsxRuntime.
|
|
21104
|
+
className: "with-tabs",
|
|
21105
|
+
children: [description && /*#__PURE__*/jsxRuntime.jsx("p", {
|
|
21106
|
+
children: description
|
|
21107
|
+
}), data === null || data === void 0 ? void 0 : data.map(item => /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
21100
21108
|
style: {
|
|
21101
21109
|
display: "flex",
|
|
21102
|
-
|
|
21103
|
-
height: "100%",
|
|
21104
|
-
minHeight: "150px"
|
|
21110
|
+
justifyContent: "space-between"
|
|
21105
21111
|
},
|
|
21106
|
-
children: [/*#__PURE__*/jsxRuntime.jsx(
|
|
21112
|
+
children: [item.isTag ? /*#__PURE__*/jsxRuntime.jsx(antd.Tag, {
|
|
21107
21113
|
style: {
|
|
21108
|
-
|
|
21109
|
-
|
|
21110
|
-
|
|
21111
|
-
justifyContent: "flex-start",
|
|
21112
|
-
marginTop: "24px",
|
|
21113
|
-
marginBottom: "24px",
|
|
21114
|
-
minHeight: "0"
|
|
21115
|
-
},
|
|
21116
|
-
children: description ? /*#__PURE__*/jsxRuntime.jsx("p", {
|
|
21117
|
-
style: {
|
|
21118
|
-
margin: 0,
|
|
21119
|
-
flex: 1,
|
|
21120
|
-
display: "flex",
|
|
21121
|
-
alignItems: "flex-start",
|
|
21122
|
-
minHeight: "0"
|
|
21123
|
-
},
|
|
21124
|
-
children: description
|
|
21125
|
-
}) : /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
21126
|
-
style: {
|
|
21127
|
-
flex: 1
|
|
21128
|
-
}
|
|
21129
|
-
})
|
|
21130
|
-
}), data && data.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
21131
|
-
style: {
|
|
21132
|
-
display: "flex",
|
|
21133
|
-
flexDirection: "column",
|
|
21134
|
-
gap: "8px"
|
|
21114
|
+
width: '90px',
|
|
21115
|
+
textAlign: 'center',
|
|
21116
|
+
borderRadius: '10px'
|
|
21135
21117
|
},
|
|
21136
|
-
|
|
21137
|
-
|
|
21138
|
-
|
|
21139
|
-
|
|
21140
|
-
|
|
21141
|
-
|
|
21142
|
-
style: {
|
|
21143
|
-
width: '90px',
|
|
21144
|
-
textAlign: 'center',
|
|
21145
|
-
borderRadius: '10px'
|
|
21146
|
-
},
|
|
21147
|
-
color: item.tagColor || 'default',
|
|
21148
|
-
children: item.label
|
|
21149
|
-
}) : /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
21150
|
-
children: item.label
|
|
21151
|
-
}), /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
21152
|
-
children: item.value
|
|
21153
|
-
})]
|
|
21154
|
-
}, item))
|
|
21118
|
+
color: item.tagColor || 'default',
|
|
21119
|
+
children: item.label
|
|
21120
|
+
}) : /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
21121
|
+
children: item.label
|
|
21122
|
+
}), /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
21123
|
+
children: item.value
|
|
21155
21124
|
})]
|
|
21156
|
-
})
|
|
21125
|
+
}, item))]
|
|
21157
21126
|
})
|
|
21158
21127
|
});
|
|
21159
21128
|
};
|
|
@@ -21170,11 +21139,15 @@ function CarouselWidget(_ref) {
|
|
|
21170
21139
|
* @param {number} currentSlide - The index of the current slide after change
|
|
21171
21140
|
* @private
|
|
21172
21141
|
*/
|
|
21173
|
-
|
|
21142
|
+
const onChange = currentSlide => {
|
|
21143
|
+
console.log(currentSlide);
|
|
21144
|
+
};
|
|
21174
21145
|
return /*#__PURE__*/jsxRuntime.jsx(Widget, {
|
|
21175
21146
|
title: title,
|
|
21176
21147
|
className: "with-border-header h-w-btn-header",
|
|
21177
|
-
children: /*#__PURE__*/jsxRuntime.jsx(antd.Carousel, _objectSpread2(_objectSpread2({
|
|
21148
|
+
children: /*#__PURE__*/jsxRuntime.jsx(antd.Carousel, _objectSpread2(_objectSpread2({
|
|
21149
|
+
afterChange: onChange
|
|
21150
|
+
}, rest), {}, {
|
|
21178
21151
|
children: children
|
|
21179
21152
|
}))
|
|
21180
21153
|
});
|
|
@@ -37202,6 +37175,13 @@ const inputTypeComponent$1 = {
|
|
|
37202
37175
|
},
|
|
37203
37176
|
children: (opts || []).map((option, i) => {
|
|
37204
37177
|
const otherProps = {};
|
|
37178
|
+
|
|
37179
|
+
// Handle disabled property from option
|
|
37180
|
+
if (option.disabled !== undefined) {
|
|
37181
|
+
otherProps.disabled = option.disabled;
|
|
37182
|
+
}
|
|
37183
|
+
|
|
37184
|
+
// Handle other dynamic properties from option.options
|
|
37205
37185
|
if (option.options) {
|
|
37206
37186
|
Object.keys(option.options).forEach(prop => {
|
|
37207
37187
|
if (eval(option.options[prop])) {
|
|
@@ -37213,10 +37193,17 @@ const inputTypeComponent$1 = {
|
|
|
37213
37193
|
}
|
|
37214
37194
|
return option.items ? /*#__PURE__*/jsxRuntime.jsx(antd.Select.OptGroup, {
|
|
37215
37195
|
label: option.label,
|
|
37216
|
-
children: option.items.map((og, j) =>
|
|
37217
|
-
|
|
37218
|
-
|
|
37219
|
-
|
|
37196
|
+
children: option.items.map((og, j) => {
|
|
37197
|
+
const groupOtherProps = {};
|
|
37198
|
+
if (og.disabled !== undefined) {
|
|
37199
|
+
groupOtherProps.disabled = og.disabled;
|
|
37200
|
+
}
|
|
37201
|
+
return /*#__PURE__*/jsxRuntime.jsx(antd.Select.Option, {
|
|
37202
|
+
value: og.value,
|
|
37203
|
+
...groupOtherProps,
|
|
37204
|
+
children: og.label
|
|
37205
|
+
}, `${i}${j}`);
|
|
37206
|
+
})
|
|
37220
37207
|
}) : /*#__PURE__*/jsxRuntime.jsx(antd.Select.Option, {
|
|
37221
37208
|
value: option.value,
|
|
37222
37209
|
...otherProps,
|
|
@@ -37323,6 +37310,13 @@ const inputTypeComponent$1 = {
|
|
|
37323
37310
|
placeholder: getMetaPlaceholer(inputMeta, t) || getInputProp(props.placeholder, formsValue) || t('Select all relevant options'),
|
|
37324
37311
|
children: (opts || []).map((option, i) => {
|
|
37325
37312
|
const otherProps = {};
|
|
37313
|
+
|
|
37314
|
+
// Handle disabled property from option
|
|
37315
|
+
if (option.disabled !== undefined) {
|
|
37316
|
+
otherProps.disabled = option.disabled;
|
|
37317
|
+
}
|
|
37318
|
+
|
|
37319
|
+
// Handle other dynamic properties from option.options
|
|
37326
37320
|
if (option.options) {
|
|
37327
37321
|
Object.keys(option.options).forEach(prop => {
|
|
37328
37322
|
if (eval(option.options[prop])) {
|
|
@@ -37332,15 +37326,24 @@ const inputTypeComponent$1 = {
|
|
|
37332
37326
|
}
|
|
37333
37327
|
});
|
|
37334
37328
|
}
|
|
37329
|
+
|
|
37330
|
+
// If option is disabled and currently selected, remove it from selection
|
|
37335
37331
|
if (otherProps.disabled && (value || []).includes(option.value)) {
|
|
37336
37332
|
updateFormValues$1(repeatIndex, repeatValues, inputName, (value || []).filter(v => v !== option.value), formsValue, name, form);
|
|
37337
37333
|
}
|
|
37338
37334
|
return option.items ? /*#__PURE__*/jsxRuntime.jsx(antd.Select.OptGroup, {
|
|
37339
37335
|
label: option.label,
|
|
37340
|
-
children: option.items.map((og, j) =>
|
|
37341
|
-
|
|
37342
|
-
|
|
37343
|
-
|
|
37336
|
+
children: option.items.map((og, j) => {
|
|
37337
|
+
const groupOtherProps = {};
|
|
37338
|
+
if (og.disabled !== undefined) {
|
|
37339
|
+
groupOtherProps.disabled = og.disabled;
|
|
37340
|
+
}
|
|
37341
|
+
return /*#__PURE__*/jsxRuntime.jsx(antd.Select.Option, {
|
|
37342
|
+
value: og.value,
|
|
37343
|
+
...groupOtherProps,
|
|
37344
|
+
children: og.label
|
|
37345
|
+
}, `${i}${j}`);
|
|
37346
|
+
})
|
|
37344
37347
|
}) : /*#__PURE__*/jsxRuntime.jsx(antd.Select.Option, {
|
|
37345
37348
|
value: option.value,
|
|
37346
37349
|
...otherProps,
|
|
@@ -51595,22 +51598,6 @@ function useConfig(data) {
|
|
|
51595
51598
|
return config;
|
|
51596
51599
|
}
|
|
51597
51600
|
|
|
51598
|
-
typeof localStorage.getItem('is_collapsed') === 'string' ? localStorage.getItem('is_collapsed') === 'true' ? true : false : true;
|
|
51599
|
-
typeof localStorage.getItem('is_nested_sidebar_collapsed') === 'string' ? localStorage.getItem('is_nested_sidebar_collapsed') === 'true' : true;
|
|
51600
|
-
const ResizeContext = /*#__PURE__*/React.createContext({
|
|
51601
|
-
resizeLoading: false,
|
|
51602
|
-
windowWidth: 0,
|
|
51603
|
-
resizeDif: 0,
|
|
51604
|
-
isCollapsed: false,
|
|
51605
|
-
setIsCollapsed: () => {},
|
|
51606
|
-
isNestedSidebarCollapsed: false,
|
|
51607
|
-
setIsNestedSidebarCollapsed: () => {}
|
|
51608
|
-
});
|
|
51609
|
-
const useResizeContext = () => {
|
|
51610
|
-
const values = React.useContext(ResizeContext);
|
|
51611
|
-
return values;
|
|
51612
|
-
};
|
|
51613
|
-
|
|
51614
51601
|
const DAYS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
|
|
51615
51602
|
function UserActivity({
|
|
51616
51603
|
loading,
|
package/dist/utils/index.js
CHANGED
|
@@ -6180,7 +6180,6 @@ const userHasInterface = (user, app, intf) => {
|
|
|
6180
6180
|
};
|
|
6181
6181
|
|
|
6182
6182
|
const en = {
|
|
6183
|
-
"Currently unavailable": "Currently unavailable",
|
|
6184
6183
|
Description: "Description",
|
|
6185
6184
|
"missing-inputs": "Missing Inputs",
|
|
6186
6185
|
"all-inputs-fullfilled": "All inputs in this section are fullfilled",
|
|
@@ -7373,7 +7372,6 @@ const en = {
|
|
|
7373
7372
|
};
|
|
7374
7373
|
|
|
7375
7374
|
const fr = {
|
|
7376
|
-
"Currently unavailable": "Actuellement indisponible",
|
|
7377
7375
|
"Description": "Description",
|
|
7378
7376
|
"missing-inputs": "Données Manquantes",
|
|
7379
7377
|
"all-inputs-fullfilled": "Toutes les données de cette section ont été saisies.",
|
|
@@ -9206,7 +9204,6 @@ const fr = {
|
|
|
9206
9204
|
};
|
|
9207
9205
|
|
|
9208
9206
|
const sp = {
|
|
9209
|
-
"Currently unavailable": "Actualmente no disponible",
|
|
9210
9207
|
"Description": "Descripción",
|
|
9211
9208
|
"missing-inputs": "Datos que Faltan",
|
|
9212
9209
|
"all-inputs-fullfilled": "Todas las entradas de esta sección están completas.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "datastake-daf",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.198",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@ant-design/icons": "^5.2.5",
|
|
6
6
|
"@antv/g2": "^5.1.1",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"buffer": "^6.0.3",
|
|
16
16
|
"countries-list": "^2.6.1",
|
|
17
17
|
"country-city-location": "^1.0.13",
|
|
18
|
-
"datastake-daf": "
|
|
18
|
+
"datastake-daf": "0.6.184",
|
|
19
19
|
"dayjs": "^1.11.12",
|
|
20
20
|
"deepmerge": "^4.3.1",
|
|
21
21
|
"dot-object": "^2.1.5",
|
|
@@ -8,6 +8,7 @@ import CustomIcon from "../../Icon/CustomIcon.jsx";
|
|
|
8
8
|
import ComponentWithFocus from "../ComponentWithFocus/index.jsx";
|
|
9
9
|
import { formatClassname } from "../../../../../helpers/ClassesHelper";
|
|
10
10
|
import Filters from "../../Filters/FloatingFilters/index.js";
|
|
11
|
+
import { useResizeContext } from "../../../context/Resize/index.js";
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Globe Component
|
|
@@ -129,6 +130,9 @@ function Globe({
|
|
|
129
130
|
[data],
|
|
130
131
|
);
|
|
131
132
|
|
|
133
|
+
// Get resize context for sidebar state changes
|
|
134
|
+
const { isCollapsed } = useResizeContext();
|
|
135
|
+
|
|
132
136
|
// Use custom hook to configure globe functionality
|
|
133
137
|
const { container, activeMarker, mapOptionsButtonsConfig, forceResize } = useGlobe({
|
|
134
138
|
data: mappedData,
|
|
@@ -171,6 +175,37 @@ function Globe({
|
|
|
171
175
|
}
|
|
172
176
|
}, [forceResize]);
|
|
173
177
|
|
|
178
|
+
// Force resize when sidebar state changes (handles width changes)
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
if (forceResize) {
|
|
181
|
+
// Trigger resize when sidebar collapses/expands
|
|
182
|
+
const timer = setTimeout(() => {
|
|
183
|
+
forceResize();
|
|
184
|
+
}, 100);
|
|
185
|
+
|
|
186
|
+
return () => clearTimeout(timer);
|
|
187
|
+
}
|
|
188
|
+
}, [isCollapsed, forceResize]);
|
|
189
|
+
|
|
190
|
+
// Force resize when window width changes (handles sidebar width changes)
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
if (forceResize) {
|
|
193
|
+
const handleResize = () => {
|
|
194
|
+
// Small delay to ensure DOM has updated
|
|
195
|
+
setTimeout(() => {
|
|
196
|
+
forceResize();
|
|
197
|
+
}, 100);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
window.addEventListener('resize', handleResize);
|
|
201
|
+
|
|
202
|
+
return () => {
|
|
203
|
+
window.removeEventListener('resize', handleResize);
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}, [forceResize]);
|
|
207
|
+
|
|
208
|
+
|
|
174
209
|
return (
|
|
175
210
|
<ComponentWithFocus>
|
|
176
211
|
<Style className={formatClassname([showSider && activeMarker && "with-sider"])}>
|
|
@@ -6,17 +6,6 @@ const Style = styled.div`
|
|
|
6
6
|
position: relative;
|
|
7
7
|
width: 100%;
|
|
8
8
|
height: 472px;
|
|
9
|
-
min-height: 300px;
|
|
10
|
-
|
|
11
|
-
@media (max-width: 768px) {
|
|
12
|
-
height: 350px;
|
|
13
|
-
min-height: 250px;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
@media (max-width: 480px) {
|
|
17
|
-
height: 300px;
|
|
18
|
-
min-height: 200px;
|
|
19
|
-
}
|
|
20
9
|
|
|
21
10
|
.filter-cont {
|
|
22
11
|
position: absolute;
|
|
@@ -53,13 +53,16 @@ function CarouselWidget({title, children, ...rest}) {
|
|
|
53
53
|
* @param {number} currentSlide - The index of the current slide after change
|
|
54
54
|
* @private
|
|
55
55
|
*/
|
|
56
|
+
const onChange = (currentSlide) => {
|
|
57
|
+
console.log(currentSlide);
|
|
58
|
+
};
|
|
56
59
|
|
|
57
60
|
return (
|
|
58
61
|
<Widget
|
|
59
62
|
title={title}
|
|
60
63
|
className="with-border-header h-w-btn-header"
|
|
61
64
|
>
|
|
62
|
-
<Carousel {...rest}>
|
|
65
|
+
<Carousel afterChange={onChange} {...rest}>
|
|
63
66
|
{children}
|
|
64
67
|
</Carousel>
|
|
65
68
|
</Widget>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import ThemeLayout from "../../../ThemeLayout";
|
|
2
2
|
import WidgetCard from "./index";
|
|
3
|
-
|
|
4
|
-
import Widget from "../index";
|
|
3
|
+
|
|
5
4
|
export default {
|
|
6
5
|
title: "Dashboard/Widgets/WidgetCard",
|
|
7
6
|
tags: ["autodocs"],
|
|
@@ -15,149 +14,26 @@ export default {
|
|
|
15
14
|
],
|
|
16
15
|
};
|
|
17
16
|
|
|
18
|
-
const firstCard = {
|
|
19
|
-
loading: false,
|
|
20
|
-
"title": "Test",
|
|
21
|
-
"link": "/app/mines/summary/LOC-00000000271",
|
|
22
|
-
"logoIcon": "Kobo",
|
|
23
|
-
"description": "This is a description of the widget card. It can be long and scrollable.",
|
|
24
|
-
"buttonIcon": 'ArrowUpRight',
|
|
25
|
-
"iconColor": "#ff0000",
|
|
26
|
-
"imageUrl": "https://picsum.photos/200/300",
|
|
27
|
-
"data": [
|
|
28
|
-
{
|
|
29
|
-
"label": "Type",
|
|
30
|
-
"value": "Test",
|
|
31
|
-
"isTag": true,
|
|
32
|
-
tagColor: 'blue'
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
"backgroundColor": "#F6FEF9",
|
|
36
|
-
"backgroundBorderColor": "#B0F3CB",
|
|
37
|
-
"buttonConfig": {
|
|
38
|
-
"disabled": true
|
|
39
|
-
},
|
|
40
|
-
t: (s) => s,
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const secondCard = {
|
|
44
|
-
loading: false,
|
|
45
|
-
"title": "Test",
|
|
46
|
-
"link": "/app/mines/summary/LOC-00000000271",
|
|
47
|
-
"logoIcon": "Kobo",
|
|
48
|
-
"description": "This is a description of the widget card. It can be long and scrollable. This is a description of the widget card. It can be long and scrollable.",
|
|
49
|
-
"buttonIcon": 'ArrowUpRight',
|
|
50
|
-
"iconColor": "#ff0000",
|
|
51
|
-
"imageUrl": "https://picsum.photos/200/300",
|
|
52
|
-
"data": [
|
|
53
|
-
{
|
|
54
|
-
"label": "Type",
|
|
55
|
-
"value": "Test",
|
|
56
|
-
"isTag": true,
|
|
57
|
-
tagColor: 'blue'
|
|
58
|
-
}
|
|
59
|
-
],
|
|
60
|
-
"backgroundColor": "#F6FEF9",
|
|
61
|
-
"backgroundBorderColor": "#B0F3CB",
|
|
62
|
-
"buttonConfig": {
|
|
63
|
-
"disabled": true
|
|
64
|
-
},
|
|
65
|
-
t: (s) => s,
|
|
66
|
-
width: "300px"
|
|
67
|
-
}
|
|
68
|
-
|
|
69
17
|
|
|
70
18
|
export const Primary = {
|
|
71
19
|
args: {
|
|
72
|
-
|
|
73
|
-
|
|
20
|
+
loading: false,
|
|
21
|
+
"title": "Test",
|
|
22
|
+
"link": "/app/mines/summary/LOC-00000000271",
|
|
23
|
+
"logoIcon": "Kobo",
|
|
24
|
+
"description": "This is a description of the widget card. It can be long and scrollable.",
|
|
25
|
+
"buttonIcon": 'ArrowUpRight',
|
|
26
|
+
"iconColor": "#ff0000",
|
|
27
|
+
"imageUrl": "https://picsum.photos/200/300",
|
|
28
|
+
"data": [
|
|
29
|
+
{
|
|
30
|
+
"label": "Type",
|
|
31
|
+
"value": "Mine Summary",
|
|
32
|
+
"isTag": true,
|
|
33
|
+
tagColor: 'blue'
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"backgroundColor": "#F6FEF9",
|
|
37
|
+
"backgroundBorderColor": "#B0F3CB"
|
|
74
38
|
},
|
|
75
39
|
};
|
|
76
|
-
|
|
77
|
-
export const InsideWidget = {
|
|
78
|
-
render: (args) => (
|
|
79
|
-
<Widget title="Widget Card" description={"Connect to external data sources for unified access and management."} className="with-border-header h-w-btn-header">
|
|
80
|
-
<div className="flex flex-row gap-4" style={{alignItems: 'stretch', height: '100%'}}>
|
|
81
|
-
<WidgetCard {...firstCard} width="400px" />
|
|
82
|
-
<WidgetCard {...secondCard} width="400px" />
|
|
83
|
-
</div>
|
|
84
|
-
</Widget>
|
|
85
|
-
),
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export const UsingContainer = {
|
|
89
|
-
render: (args) => (
|
|
90
|
-
<Widget title="Widget Card Container" description={"Using the new WidgetCardContainer component"} className="with-border-header h-w-btn-header">
|
|
91
|
-
<WidgetCardContainer
|
|
92
|
-
cards={[
|
|
93
|
-
{
|
|
94
|
-
...firstCard,
|
|
95
|
-
width: "400px",
|
|
96
|
-
description: "Short description"
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
...secondCard,
|
|
100
|
-
width: "350px",
|
|
101
|
-
description: "This is a much longer description that takes up more space to demonstrate how the component handles different content lengths while maintaining perfect alignment of bottom elements."
|
|
102
|
-
}
|
|
103
|
-
]}
|
|
104
|
-
gap="16px"
|
|
105
|
-
/>
|
|
106
|
-
</Widget>
|
|
107
|
-
),
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export const MultipleCards = {
|
|
111
|
-
render: (args) => (
|
|
112
|
-
<Widget title="Multiple Cards with Container" description={"Demonstrating multiple cards with different content lengths"} className="with-border-header h-w-btn-header">
|
|
113
|
-
<WidgetCardContainer
|
|
114
|
-
cards={[
|
|
115
|
-
{
|
|
116
|
-
...firstCard,
|
|
117
|
-
width: "500px",
|
|
118
|
-
description: "Short description"
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
...secondCard,
|
|
122
|
-
width: "200px"
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
...firstCard,
|
|
126
|
-
width: "350px",
|
|
127
|
-
title: "Third Card",
|
|
128
|
-
description: "This is an even longer description that should expand to fill the available space while maintaining alignment with other cards."
|
|
129
|
-
}
|
|
130
|
-
]}
|
|
131
|
-
gap="16px"
|
|
132
|
-
/>
|
|
133
|
-
</Widget>
|
|
134
|
-
),
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export const FlexWidths = {
|
|
138
|
-
render: (args) => (
|
|
139
|
-
<Widget title="Flexible Widths" description={"Cards without width will flex to fill space"} className="with-border-header h-w-btn-header">
|
|
140
|
-
<WidgetCardContainer
|
|
141
|
-
cards={[
|
|
142
|
-
{
|
|
143
|
-
...firstCard,
|
|
144
|
-
width: "200px",
|
|
145
|
-
description: "Fixed width card"
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
...secondCard,
|
|
149
|
-
width: "250px",
|
|
150
|
-
description: "This card will flex to fill remaining space"
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
...firstCard,
|
|
154
|
-
width: "250px",
|
|
155
|
-
title: "Fixed Width",
|
|
156
|
-
description: "Another fixed width card"
|
|
157
|
-
}
|
|
158
|
-
]}
|
|
159
|
-
gap="16px"
|
|
160
|
-
/>
|
|
161
|
-
</Widget>
|
|
162
|
-
),
|
|
163
|
-
}
|
|
@@ -3,7 +3,6 @@ import Widget from '../index.jsx'
|
|
|
3
3
|
import { theme, Tooltip, Tag } from 'antd'
|
|
4
4
|
import CustomIcon from '../../../Icon/CustomIcon.jsx'
|
|
5
5
|
import Style from './style.js'
|
|
6
|
-
import { formatClassname } from '../../../../../../helpers/ClassesHelper.js'
|
|
7
6
|
|
|
8
7
|
const { useToken } = theme;
|
|
9
8
|
|
|
@@ -19,78 +18,39 @@ const WidgetCard = ({
|
|
|
19
18
|
iconColor,
|
|
20
19
|
buttonIcon,
|
|
21
20
|
imageUrl,
|
|
22
|
-
buttonConfig = {},
|
|
23
|
-
width,
|
|
24
|
-
t = () => {},
|
|
25
21
|
}) => {
|
|
26
22
|
const { token } = useToken();
|
|
27
23
|
return (
|
|
28
|
-
<Style backgroundColor={backgroundColor} backgroundBorderColor={backgroundBorderColor}
|
|
24
|
+
<Style backgroundColor={backgroundColor} backgroundBorderColor={backgroundBorderColor}>
|
|
29
25
|
<Widget
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</div>
|
|
39
|
-
}
|
|
40
|
-
addedHeader={
|
|
41
|
-
<>
|
|
42
|
-
<div className="flex-1" />
|
|
43
|
-
<Tooltip title={buttonConfig?.disabled ? (buttonConfig?.tooltipText || t("Currently unavailable")) : ""}>
|
|
44
|
-
<a
|
|
45
|
-
className={formatClassname(["widget-card-logo-icon", buttonConfig?.disabled && "disabled-anchor"])}
|
|
46
|
-
href={buttonConfig?.disabled ? undefined : link}
|
|
47
|
-
onClick={buttonConfig?.disabled ? (e) => e.preventDefault() : undefined}
|
|
48
|
-
>
|
|
49
|
-
<CustomIcon name={buttonIcon} size={16} color={buttonConfig?.disabled ? "#6C737F" : (iconColor || theme.colorPrimary)} />
|
|
50
|
-
</a>
|
|
51
|
-
</Tooltip>
|
|
52
|
-
</>
|
|
53
|
-
}
|
|
54
|
-
loading={loading}
|
|
55
|
-
className="with-tabs no-pt-body"
|
|
56
|
-
>
|
|
57
|
-
<div style={{display: "flex", flexDirection: "column", height: "100%", minHeight: "150px"}}>
|
|
58
|
-
<div style={{
|
|
59
|
-
flex: 1,
|
|
60
|
-
display: "flex",
|
|
61
|
-
flexDirection: "column",
|
|
62
|
-
justifyContent: "flex-start",
|
|
63
|
-
marginTop: "24px",
|
|
64
|
-
marginBottom: "24px",
|
|
65
|
-
minHeight: "0"
|
|
66
|
-
}}>
|
|
67
|
-
{description ? (
|
|
68
|
-
<p style={{
|
|
69
|
-
margin: 0,
|
|
70
|
-
flex: 1,
|
|
71
|
-
display: "flex",
|
|
72
|
-
alignItems: "flex-start",
|
|
73
|
-
minHeight: "0"
|
|
74
|
-
}}>
|
|
75
|
-
{description}
|
|
76
|
-
</p>
|
|
77
|
-
) : (
|
|
78
|
-
<div style={{flex: 1}} />
|
|
79
|
-
)}
|
|
80
|
-
</div>
|
|
81
|
-
|
|
82
|
-
{data && data.length > 0 && (
|
|
83
|
-
<div style={{display: "flex", flexDirection: "column", gap: "8px"}}>
|
|
84
|
-
{data.map((item) => (
|
|
85
|
-
<div key={item} style={{display: "flex", justifyContent: "space-between"}}>
|
|
86
|
-
{item.isTag ? <Tag style={{width: '90px', textAlign: 'center', borderRadius: '10px'}} color={item.tagColor || 'default'}>{item.label}</Tag> : <span>{item.label}</span>}
|
|
87
|
-
<span>{item.value}</span>
|
|
88
|
-
</div>
|
|
89
|
-
))}
|
|
90
|
-
</div>
|
|
91
|
-
)}
|
|
26
|
+
title={
|
|
27
|
+
<div style={{display: "flex", alignItems: "center"}}>
|
|
28
|
+
{imageUrl ? <img src={imageUrl} className="widget-card-logo-icon mr-2" />
|
|
29
|
+
: <div className="widget-card-logo-icon mr-2">
|
|
30
|
+
<CustomIcon name={logoIcon} width={25} height={25} />
|
|
31
|
+
</div>
|
|
32
|
+
}
|
|
33
|
+
<Tooltip title={title}>{title}</Tooltip>
|
|
92
34
|
</div>
|
|
93
|
-
|
|
35
|
+
}
|
|
36
|
+
addedHeader={
|
|
37
|
+
<>
|
|
38
|
+
<div className="flex-1" /><a className="widget-card-logo-icon" href={link}>
|
|
39
|
+
<CustomIcon name={buttonIcon} size={16} color={iconColor || theme.colorPrimary} />
|
|
40
|
+
</a>
|
|
41
|
+
</>
|
|
42
|
+
}
|
|
43
|
+
loading={loading}
|
|
44
|
+
className="with-tabs"
|
|
45
|
+
>
|
|
46
|
+
{description && <p>{description}</p>}
|
|
47
|
+
{data?.map((item) => (
|
|
48
|
+
<div key={item} style={{display: "flex", justifyContent: "space-between"}}>
|
|
49
|
+
{item.isTag ? <Tag style={{width: '90px', textAlign: 'center', borderRadius: '10px'}} color={item.tagColor || 'default'}>{item.label}</Tag> : <span>{item.label}</span>}
|
|
50
|
+
<span>{item.value}</span>
|
|
51
|
+
</div>
|
|
52
|
+
))}
|
|
53
|
+
</Widget>
|
|
94
54
|
</Style>
|
|
95
55
|
)
|
|
96
56
|
}
|
|
@@ -1,27 +1,9 @@
|
|
|
1
1
|
import styled from 'styled-components';
|
|
2
2
|
|
|
3
3
|
const Style = styled.div`
|
|
4
|
-
|
|
5
|
-
display: flex; /* Make this a flex container */
|
|
6
|
-
${props => props.width ? `width: ${props.width};` : 'flex: 1;'} /* Use width if specified, otherwise flex */
|
|
7
|
-
|
|
8
|
-
> .daf-widget {
|
|
4
|
+
.daf-widget {
|
|
9
5
|
background-color: ${props => props.backgroundColor} !important;
|
|
10
6
|
border-color: ${props => props.backgroundBorderColor} !important;
|
|
11
|
-
transition: box-shadow 0.2s ease-in-out;
|
|
12
|
-
height: 100%; /* Ensure full height */
|
|
13
|
-
width: 100%; /* Take full width of the container */
|
|
14
|
-
|
|
15
|
-
&:hover {
|
|
16
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.widget-body {
|
|
20
|
-
display: flex;
|
|
21
|
-
flex-direction: column;
|
|
22
|
-
flex: 1; /* Make widget body flexible */
|
|
23
|
-
min-height: 0; /* Allow flex shrinking */
|
|
24
|
-
}
|
|
25
7
|
}
|
|
26
8
|
|
|
27
9
|
.widget-card-logo-icon {
|
|
@@ -34,11 +16,6 @@ const Style = styled.div`
|
|
|
34
16
|
align-items: center;
|
|
35
17
|
border: 1px solid #E5E7EB;
|
|
36
18
|
}
|
|
37
|
-
|
|
38
|
-
.disabled-anchor {
|
|
39
|
-
cursor: not-allowed;
|
|
40
|
-
opacity: 0.5;
|
|
41
|
-
}
|
|
42
19
|
`;
|
|
43
20
|
|
|
44
21
|
export default Style;
|
|
@@ -692,6 +692,13 @@ export const inputTypeComponent = {
|
|
|
692
692
|
>
|
|
693
693
|
{(opts || []).map((option, i) => {
|
|
694
694
|
const otherProps = {};
|
|
695
|
+
|
|
696
|
+
// Handle disabled property from option
|
|
697
|
+
if (option.disabled !== undefined) {
|
|
698
|
+
otherProps.disabled = option.disabled;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Handle other dynamic properties from option.options
|
|
695
702
|
if (option.options) {
|
|
696
703
|
Object.keys(option.options).forEach(prop => {
|
|
697
704
|
if (eval(option.options[prop])) {
|
|
@@ -701,13 +708,20 @@ export const inputTypeComponent = {
|
|
|
701
708
|
}
|
|
702
709
|
});
|
|
703
710
|
}
|
|
711
|
+
|
|
704
712
|
return option.items ?
|
|
705
713
|
<Select.OptGroup label={option.label}>
|
|
706
|
-
{option.items.map((og, j) =>
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
714
|
+
{option.items.map((og, j) => {
|
|
715
|
+
const groupOtherProps = {};
|
|
716
|
+
if (og.disabled !== undefined) {
|
|
717
|
+
groupOtherProps.disabled = og.disabled;
|
|
718
|
+
}
|
|
719
|
+
return (
|
|
720
|
+
<Select.Option value={og.value} key={`${i}${j}`} {...groupOtherProps}>
|
|
721
|
+
{og.label}
|
|
722
|
+
</Select.Option>
|
|
723
|
+
);
|
|
724
|
+
})}
|
|
711
725
|
</Select.OptGroup> :
|
|
712
726
|
<Select.Option value={option.value} key={option.value} {...otherProps}>
|
|
713
727
|
{isEvaluation ? (
|
|
@@ -798,6 +812,13 @@ export const inputTypeComponent = {
|
|
|
798
812
|
>
|
|
799
813
|
{(opts || []).map((option, i) => {
|
|
800
814
|
const otherProps = {};
|
|
815
|
+
|
|
816
|
+
// Handle disabled property from option
|
|
817
|
+
if (option.disabled !== undefined) {
|
|
818
|
+
otherProps.disabled = option.disabled;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// Handle other dynamic properties from option.options
|
|
801
822
|
if (option.options) {
|
|
802
823
|
Object.keys(option.options).forEach(prop => {
|
|
803
824
|
if (eval(option.options[prop])) {
|
|
@@ -807,16 +828,25 @@ export const inputTypeComponent = {
|
|
|
807
828
|
}
|
|
808
829
|
});
|
|
809
830
|
}
|
|
831
|
+
|
|
832
|
+
// If option is disabled and currently selected, remove it from selection
|
|
810
833
|
if (otherProps.disabled && (value || []).includes(option.value)) {
|
|
811
834
|
updateFormValues(repeatIndex, repeatValues, inputName, (value || []).filter(v => v !== option.value), formsValue, name, form)
|
|
812
835
|
}
|
|
836
|
+
|
|
813
837
|
return option.items ?
|
|
814
838
|
<Select.OptGroup label={option.label}>
|
|
815
|
-
{option.items.map((og, j) =>
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
839
|
+
{option.items.map((og, j) => {
|
|
840
|
+
const groupOtherProps = {};
|
|
841
|
+
if (og.disabled !== undefined) {
|
|
842
|
+
groupOtherProps.disabled = og.disabled;
|
|
843
|
+
}
|
|
844
|
+
return (
|
|
845
|
+
<Select.Option value={og.value} key={`${i}${j}`} {...groupOtherProps}>
|
|
846
|
+
{og.label}
|
|
847
|
+
</Select.Option>
|
|
848
|
+
);
|
|
849
|
+
})}
|
|
820
850
|
</Select.OptGroup> :
|
|
821
851
|
<Select.Option value={option.value} key={i} {...otherProps}>
|
|
822
852
|
{option.label}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import WidgetCard from './index.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* WidgetCardContainer Component - A container that renders multiple WidgetCards with consistent heights
|
|
6
|
-
*
|
|
7
|
-
* @component
|
|
8
|
-
* @example
|
|
9
|
-
* // Basic usage
|
|
10
|
-
* <WidgetCardContainer
|
|
11
|
-
* cards={[
|
|
12
|
-
* { title: "Card 1", description: "Short description", width: "300px" },
|
|
13
|
-
* { title: "Card 2", description: "Much longer description text here", width: "400px" }
|
|
14
|
-
* ]}
|
|
15
|
-
* />
|
|
16
|
-
*
|
|
17
|
-
* @param {Object} props - Component props
|
|
18
|
-
* @param {Array} props.cards - Array of widget card configurations
|
|
19
|
-
* @param {string} [props.gap="16px"] - Gap between cards
|
|
20
|
-
* @param {string} [props.className] - Additional CSS classes
|
|
21
|
-
* @param {Object} [props.containerStyle] - Additional container styles
|
|
22
|
-
* @param {string} [props.direction="row"] - Flex direction (row or column)
|
|
23
|
-
*
|
|
24
|
-
* @features
|
|
25
|
-
* - ✅ Equal heights for all cards regardless of content
|
|
26
|
-
* - ✅ Individual width control per card
|
|
27
|
-
* - ✅ Bottom content alignment across all cards
|
|
28
|
-
* - ✅ Flexible description areas that expand
|
|
29
|
-
* - ✅ Responsive layout support
|
|
30
|
-
*
|
|
31
|
-
* @returns {JSX.Element} The rendered WidgetCardContainer component
|
|
32
|
-
*/
|
|
33
|
-
const WidgetCardContainer = ({
|
|
34
|
-
cards = [],
|
|
35
|
-
gap = "16px",
|
|
36
|
-
className = "",
|
|
37
|
-
containerStyle = {},
|
|
38
|
-
direction = "row",
|
|
39
|
-
...props
|
|
40
|
-
}) => {
|
|
41
|
-
if (!cards || cards.length === 0) {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const containerStyles = {
|
|
46
|
-
display: "flex",
|
|
47
|
-
flexDirection: direction,
|
|
48
|
-
gap: gap,
|
|
49
|
-
alignItems: "stretch", // Ensure equal heights
|
|
50
|
-
height: "100%",
|
|
51
|
-
minHeight: "200px", // Ensure minimum height for proper stretching
|
|
52
|
-
...containerStyle
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
return (
|
|
56
|
-
<div
|
|
57
|
-
className={`widget-card-container ${className}`}
|
|
58
|
-
style={containerStyles}
|
|
59
|
-
{...props}
|
|
60
|
-
>
|
|
61
|
-
{cards.map((cardConfig, index) => {
|
|
62
|
-
const {
|
|
63
|
-
width,
|
|
64
|
-
...cardProps
|
|
65
|
-
} = cardConfig;
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<WidgetCard
|
|
69
|
-
key={cardConfig.key || cardConfig.title || index}
|
|
70
|
-
width={width}
|
|
71
|
-
{...cardProps}
|
|
72
|
-
/>
|
|
73
|
-
);
|
|
74
|
-
})}
|
|
75
|
-
</div>
|
|
76
|
-
);
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export default WidgetCardContainer;
|