datastake-daf 0.6.200 → 0.6.201
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 +96 -34
- package/dist/utils/index.js +3 -0
- package/package.json +1 -1
- package/src/@daf/core/components/Dashboard/Widget/CarouselWidget/index.jsx +1 -4
- package/src/@daf/core/components/Dashboard/Widget/WidgetCard/WidgetCard.stories.js +143 -19
- package/src/@daf/core/components/Dashboard/Widget/WidgetCard/WidgetCardContainer.jsx +79 -0
- package/src/@daf/core/components/Dashboard/Widget/WidgetCard/index.js +68 -28
- package/src/@daf/core/components/Dashboard/Widget/WidgetCard/style.js +24 -1
- package/src/@daf/core/components/Header/components/Tags.jsx +2 -2
- package/src/constants/locales/en/translation.js +1 -0
- package/src/constants/locales/fr/translation.js +1 -0
- package/src/constants/locales/sp/translation.js +1 -0
package/dist/components/index.js
CHANGED
|
@@ -12469,7 +12469,6 @@ function Tags({
|
|
|
12469
12469
|
className: "flex ml-3",
|
|
12470
12470
|
children: [mainTags.map((t, i) => /*#__PURE__*/jsxRuntime.jsx(antd.Tag, {
|
|
12471
12471
|
style: {
|
|
12472
|
-
width: '100px',
|
|
12473
12472
|
textAlign: 'center'
|
|
12474
12473
|
},
|
|
12475
12474
|
color: t.color || 'default',
|
|
@@ -12483,7 +12482,6 @@ function Tags({
|
|
|
12483
12482
|
}),
|
|
12484
12483
|
children: /*#__PURE__*/jsxRuntime.jsxs(antd.Tag, {
|
|
12485
12484
|
style: {
|
|
12486
|
-
width: '100px',
|
|
12487
12485
|
textAlign: 'center'
|
|
12488
12486
|
},
|
|
12489
12487
|
children: ["+", otherTags.length]
|
|
@@ -21028,9 +21026,27 @@ function ProjectWidget(_ref) {
|
|
|
21028
21026
|
}
|
|
21029
21027
|
|
|
21030
21028
|
const Style$x = dt.div`
|
|
21031
|
-
|
|
21029
|
+
height: 100%; /* Make the wrapper take full height */
|
|
21030
|
+
display: flex; /* Make this a flex container */
|
|
21031
|
+
${props => props.width ? `width: ${props.width};` : 'flex: 1;'} /* Use width if specified, otherwise flex */
|
|
21032
|
+
|
|
21033
|
+
> .daf-widget {
|
|
21032
21034
|
background-color: ${props => props.backgroundColor} !important;
|
|
21033
21035
|
border-color: ${props => props.backgroundBorderColor} !important;
|
|
21036
|
+
transition: box-shadow 0.2s ease-in-out;
|
|
21037
|
+
height: 100%; /* Ensure full height */
|
|
21038
|
+
width: 100%; /* Take full width of the container */
|
|
21039
|
+
|
|
21040
|
+
&:hover {
|
|
21041
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
21042
|
+
}
|
|
21043
|
+
|
|
21044
|
+
.widget-body {
|
|
21045
|
+
display: flex;
|
|
21046
|
+
flex-direction: column;
|
|
21047
|
+
flex: 1; /* Make widget body flexible */
|
|
21048
|
+
min-height: 0; /* Allow flex shrinking */
|
|
21049
|
+
}
|
|
21034
21050
|
}
|
|
21035
21051
|
|
|
21036
21052
|
.widget-card-logo-icon {
|
|
@@ -21043,6 +21059,11 @@ const Style$x = dt.div`
|
|
|
21043
21059
|
align-items: center;
|
|
21044
21060
|
border: 1px solid #E5E7EB;
|
|
21045
21061
|
}
|
|
21062
|
+
|
|
21063
|
+
.disabled-anchor {
|
|
21064
|
+
cursor: not-allowed;
|
|
21065
|
+
opacity: 0.5;
|
|
21066
|
+
}
|
|
21046
21067
|
`;
|
|
21047
21068
|
|
|
21048
21069
|
const {
|
|
@@ -21060,13 +21081,17 @@ const WidgetCard = _ref => {
|
|
|
21060
21081
|
loading = false,
|
|
21061
21082
|
iconColor,
|
|
21062
21083
|
buttonIcon,
|
|
21063
|
-
imageUrl
|
|
21084
|
+
imageUrl,
|
|
21085
|
+
buttonConfig = {},
|
|
21086
|
+
width,
|
|
21087
|
+
t = () => {}
|
|
21064
21088
|
} = _ref;
|
|
21065
21089
|
useToken$h();
|
|
21066
21090
|
return /*#__PURE__*/jsxRuntime.jsx(Style$x, {
|
|
21067
21091
|
backgroundColor: backgroundColor,
|
|
21068
21092
|
backgroundBorderColor: backgroundBorderColor,
|
|
21069
|
-
|
|
21093
|
+
width: width,
|
|
21094
|
+
children: /*#__PURE__*/jsxRuntime.jsx(Widget, {
|
|
21070
21095
|
title: /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
21071
21096
|
style: {
|
|
21072
21097
|
display: "flex",
|
|
@@ -21090,39 +21115,80 @@ const WidgetCard = _ref => {
|
|
|
21090
21115
|
addedHeader: /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
21091
21116
|
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
21092
21117
|
className: "flex-1"
|
|
21093
|
-
}), /*#__PURE__*/jsxRuntime.jsx(
|
|
21094
|
-
|
|
21095
|
-
|
|
21096
|
-
|
|
21097
|
-
|
|
21098
|
-
|
|
21099
|
-
|
|
21118
|
+
}), /*#__PURE__*/jsxRuntime.jsx(antd.Tooltip, {
|
|
21119
|
+
title: buttonConfig !== null && buttonConfig !== void 0 && buttonConfig.disabled ? (buttonConfig === null || buttonConfig === void 0 ? void 0 : buttonConfig.tooltipText) || t("Currently unavailable") : "",
|
|
21120
|
+
children: /*#__PURE__*/jsxRuntime.jsx("a", {
|
|
21121
|
+
className: formatClassname(["widget-card-logo-icon", (buttonConfig === null || buttonConfig === void 0 ? void 0 : buttonConfig.disabled) && "disabled-anchor"]),
|
|
21122
|
+
href: buttonConfig !== null && buttonConfig !== void 0 && buttonConfig.disabled ? undefined : link,
|
|
21123
|
+
onClick: buttonConfig !== null && buttonConfig !== void 0 && buttonConfig.disabled ? e => e.preventDefault() : undefined,
|
|
21124
|
+
children: /*#__PURE__*/jsxRuntime.jsx(CustomIcon, {
|
|
21125
|
+
name: buttonIcon,
|
|
21126
|
+
size: 16,
|
|
21127
|
+
color: buttonConfig !== null && buttonConfig !== void 0 && buttonConfig.disabled ? "#6C737F" : iconColor || antd.theme.colorPrimary
|
|
21128
|
+
})
|
|
21100
21129
|
})
|
|
21101
21130
|
})]
|
|
21102
21131
|
}),
|
|
21103
21132
|
loading: loading,
|
|
21104
|
-
className: "with-tabs",
|
|
21105
|
-
children:
|
|
21106
|
-
children: description
|
|
21107
|
-
}), data === null || data === void 0 ? void 0 : data.map(item => /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
21133
|
+
className: "with-tabs no-pt-body",
|
|
21134
|
+
children: /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
21108
21135
|
style: {
|
|
21109
21136
|
display: "flex",
|
|
21110
|
-
|
|
21137
|
+
flexDirection: "column",
|
|
21138
|
+
height: "100%",
|
|
21139
|
+
minHeight: "150px"
|
|
21111
21140
|
},
|
|
21112
|
-
children: [
|
|
21141
|
+
children: [/*#__PURE__*/jsxRuntime.jsx("div", {
|
|
21113
21142
|
style: {
|
|
21114
|
-
|
|
21115
|
-
|
|
21116
|
-
|
|
21143
|
+
flex: 1,
|
|
21144
|
+
display: "flex",
|
|
21145
|
+
flexDirection: "column",
|
|
21146
|
+
justifyContent: "flex-start",
|
|
21147
|
+
marginTop: "24px",
|
|
21148
|
+
marginBottom: "24px",
|
|
21149
|
+
minHeight: "0"
|
|
21117
21150
|
},
|
|
21118
|
-
|
|
21119
|
-
|
|
21120
|
-
|
|
21121
|
-
|
|
21122
|
-
|
|
21123
|
-
|
|
21151
|
+
children: description ? /*#__PURE__*/jsxRuntime.jsx("p", {
|
|
21152
|
+
style: {
|
|
21153
|
+
margin: 0,
|
|
21154
|
+
flex: 1,
|
|
21155
|
+
display: "flex",
|
|
21156
|
+
alignItems: "flex-start",
|
|
21157
|
+
minHeight: "0"
|
|
21158
|
+
},
|
|
21159
|
+
children: description
|
|
21160
|
+
}) : /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
21161
|
+
style: {
|
|
21162
|
+
flex: 1
|
|
21163
|
+
}
|
|
21164
|
+
})
|
|
21165
|
+
}), data && data.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
21166
|
+
style: {
|
|
21167
|
+
display: "flex",
|
|
21168
|
+
flexDirection: "column",
|
|
21169
|
+
gap: "8px"
|
|
21170
|
+
},
|
|
21171
|
+
children: data.map(item => /*#__PURE__*/jsxRuntime.jsxs("div", {
|
|
21172
|
+
style: {
|
|
21173
|
+
display: "flex",
|
|
21174
|
+
justifyContent: "space-between"
|
|
21175
|
+
},
|
|
21176
|
+
children: [item.isTag ? /*#__PURE__*/jsxRuntime.jsx(antd.Tag, {
|
|
21177
|
+
style: {
|
|
21178
|
+
width: '90px',
|
|
21179
|
+
textAlign: 'center',
|
|
21180
|
+
borderRadius: '10px'
|
|
21181
|
+
},
|
|
21182
|
+
color: item.tagColor || 'default',
|
|
21183
|
+
children: item.label
|
|
21184
|
+
}) : /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
21185
|
+
children: item.label
|
|
21186
|
+
}), /*#__PURE__*/jsxRuntime.jsx("span", {
|
|
21187
|
+
children: item.value
|
|
21188
|
+
})]
|
|
21189
|
+
}, item))
|
|
21124
21190
|
})]
|
|
21125
|
-
}
|
|
21191
|
+
})
|
|
21126
21192
|
})
|
|
21127
21193
|
});
|
|
21128
21194
|
};
|
|
@@ -21139,15 +21205,11 @@ function CarouselWidget(_ref) {
|
|
|
21139
21205
|
* @param {number} currentSlide - The index of the current slide after change
|
|
21140
21206
|
* @private
|
|
21141
21207
|
*/
|
|
21142
|
-
|
|
21143
|
-
console.log(currentSlide);
|
|
21144
|
-
};
|
|
21208
|
+
|
|
21145
21209
|
return /*#__PURE__*/jsxRuntime.jsx(Widget, {
|
|
21146
21210
|
title: title,
|
|
21147
21211
|
className: "with-border-header h-w-btn-header",
|
|
21148
|
-
children: /*#__PURE__*/jsxRuntime.jsx(antd.Carousel, _objectSpread2(_objectSpread2({
|
|
21149
|
-
afterChange: onChange
|
|
21150
|
-
}, rest), {}, {
|
|
21212
|
+
children: /*#__PURE__*/jsxRuntime.jsx(antd.Carousel, _objectSpread2(_objectSpread2({}, rest), {}, {
|
|
21151
21213
|
children: children
|
|
21152
21214
|
}))
|
|
21153
21215
|
});
|
package/dist/utils/index.js
CHANGED
|
@@ -6180,6 +6180,7 @@ const userHasInterface = (user, app, intf) => {
|
|
|
6180
6180
|
};
|
|
6181
6181
|
|
|
6182
6182
|
const en = {
|
|
6183
|
+
"Currently unavailable": "Currently unavailable",
|
|
6183
6184
|
Description: "Description",
|
|
6184
6185
|
"missing-inputs": "Missing Inputs",
|
|
6185
6186
|
"all-inputs-fullfilled": "All inputs in this section are fullfilled",
|
|
@@ -7372,6 +7373,7 @@ const en = {
|
|
|
7372
7373
|
};
|
|
7373
7374
|
|
|
7374
7375
|
const fr = {
|
|
7376
|
+
"Currently unavailable": "Actuellement indisponible",
|
|
7375
7377
|
"Description": "Description",
|
|
7376
7378
|
"missing-inputs": "Données Manquantes",
|
|
7377
7379
|
"all-inputs-fullfilled": "Toutes les données de cette section ont été saisies.",
|
|
@@ -9204,6 +9206,7 @@ const fr = {
|
|
|
9204
9206
|
};
|
|
9205
9207
|
|
|
9206
9208
|
const sp = {
|
|
9209
|
+
"Currently unavailable": "Actualmente no disponible",
|
|
9207
9210
|
"Description": "Descripción",
|
|
9208
9211
|
"missing-inputs": "Datos que Faltan",
|
|
9209
9212
|
"all-inputs-fullfilled": "Todas las entradas de esta sección están completas.",
|
package/package.json
CHANGED
|
@@ -53,16 +53,13 @@ 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
|
-
};
|
|
59
56
|
|
|
60
57
|
return (
|
|
61
58
|
<Widget
|
|
62
59
|
title={title}
|
|
63
60
|
className="with-border-header h-w-btn-header"
|
|
64
61
|
>
|
|
65
|
-
<Carousel
|
|
62
|
+
<Carousel {...rest}>
|
|
66
63
|
{children}
|
|
67
64
|
</Carousel>
|
|
68
65
|
</Widget>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import ThemeLayout from "../../../ThemeLayout";
|
|
2
2
|
import WidgetCard from "./index";
|
|
3
|
-
|
|
3
|
+
import WidgetCardContainer from "./WidgetCardContainer";
|
|
4
|
+
import Widget from "../index";
|
|
4
5
|
export default {
|
|
5
6
|
title: "Dashboard/Widgets/WidgetCard",
|
|
6
7
|
tags: ["autodocs"],
|
|
@@ -14,26 +15,149 @@ export default {
|
|
|
14
15
|
],
|
|
15
16
|
};
|
|
16
17
|
|
|
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
|
+
|
|
17
69
|
|
|
18
70
|
export const Primary = {
|
|
19
71
|
args: {
|
|
20
|
-
|
|
21
|
-
|
|
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"
|
|
72
|
+
...firstCard,
|
|
73
|
+
width: "300px"
|
|
38
74
|
},
|
|
39
75
|
};
|
|
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
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
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;
|
|
@@ -3,6 +3,7 @@ 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'
|
|
6
7
|
|
|
7
8
|
const { useToken } = theme;
|
|
8
9
|
|
|
@@ -18,39 +19,78 @@ const WidgetCard = ({
|
|
|
18
19
|
iconColor,
|
|
19
20
|
buttonIcon,
|
|
20
21
|
imageUrl,
|
|
22
|
+
buttonConfig = {},
|
|
23
|
+
width,
|
|
24
|
+
t = () => {},
|
|
21
25
|
}) => {
|
|
22
26
|
const { token } = useToken();
|
|
23
27
|
return (
|
|
24
|
-
<Style backgroundColor={backgroundColor} backgroundBorderColor={backgroundBorderColor}>
|
|
28
|
+
<Style backgroundColor={backgroundColor} backgroundBorderColor={backgroundBorderColor} width={width}>
|
|
25
29
|
<Widget
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
title={
|
|
31
|
+
<div style={{display: "flex", alignItems: "center"}}>
|
|
32
|
+
{imageUrl ? <img src={imageUrl} className="widget-card-logo-icon mr-2" />
|
|
33
|
+
: <div className="widget-card-logo-icon mr-2">
|
|
34
|
+
<CustomIcon name={logoIcon} width={25} height={25} />
|
|
35
|
+
</div>
|
|
36
|
+
}
|
|
37
|
+
<Tooltip title={title}>{title}</Tooltip>
|
|
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
|
+
)}
|
|
34
92
|
</div>
|
|
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>
|
|
93
|
+
</Widget>
|
|
54
94
|
</Style>
|
|
55
95
|
)
|
|
56
96
|
}
|
|
@@ -1,9 +1,27 @@
|
|
|
1
1
|
import styled from 'styled-components';
|
|
2
2
|
|
|
3
3
|
const Style = styled.div`
|
|
4
|
-
|
|
4
|
+
height: 100%; /* Make the wrapper take full height */
|
|
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 {
|
|
5
9
|
background-color: ${props => props.backgroundColor} !important;
|
|
6
10
|
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
|
+
}
|
|
7
25
|
}
|
|
8
26
|
|
|
9
27
|
.widget-card-logo-icon {
|
|
@@ -16,6 +34,11 @@ const Style = styled.div`
|
|
|
16
34
|
align-items: center;
|
|
17
35
|
border: 1px solid #E5E7EB;
|
|
18
36
|
}
|
|
37
|
+
|
|
38
|
+
.disabled-anchor {
|
|
39
|
+
cursor: not-allowed;
|
|
40
|
+
opacity: 0.5;
|
|
41
|
+
}
|
|
19
42
|
`;
|
|
20
43
|
|
|
21
44
|
export default Style;
|
|
@@ -8,7 +8,7 @@ export default function Tags({ tags = [] }) {
|
|
|
8
8
|
return (
|
|
9
9
|
<div className='flex ml-3'>
|
|
10
10
|
{mainTags.map((t, i) => (
|
|
11
|
-
<Tag style={{
|
|
11
|
+
<Tag style={{ textAlign: 'center' }} color={t.color || 'default'} key={`tag-${i}`}>{t.label}</Tag>
|
|
12
12
|
))}
|
|
13
13
|
|
|
14
14
|
{!!otherTags.length && (
|
|
@@ -26,7 +26,7 @@ export default function Tags({ tags = [] }) {
|
|
|
26
26
|
))}
|
|
27
27
|
</div>
|
|
28
28
|
)}>
|
|
29
|
-
<Tag style={{
|
|
29
|
+
<Tag style={{ textAlign: 'center' }}>+{otherTags.length}</Tag>
|
|
30
30
|
</Tooltip>
|
|
31
31
|
)}
|
|
32
32
|
</div>
|