datastake-daf 0.6.195 → 0.6.196

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.
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datastake-daf",
3
- "version": "0.6.195",
3
+ "version": "0.6.196",
4
4
  "dependencies": {
5
5
  "@ant-design/icons": "^5.2.5",
6
6
  "@antv/g2": "^5.1.1",
@@ -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 afterChange={onChange} {...rest}>
62
+ <Carousel {...rest}>
66
63
  {children}
67
64
  </Carousel>
68
65
  </Widget>
@@ -7,87 +7,85 @@ const { Meta } = Card;
7
7
  const { useToken } = theme;
8
8
 
9
9
  export default function ProjectWidget({
10
- title,
11
- description,
12
- onLinkClick,
13
- image,
14
- linkIcon = "Link",
15
- sdgList = [],
16
- items = [],
17
- onCardClick,
18
- hideSDGList = false,
19
- t = (x) => x,
20
- ...props
10
+ title,
11
+ description,
12
+ onLinkClick,
13
+ image,
14
+ linkIcon = "Link",
15
+ sdgList,
16
+ items,
17
+ onCardClick,
18
+ hideSDGList = false,
19
+ t = (x) => x,
20
+ ...props
21
21
  }) {
22
- const [isHovered, setIsHovered] = React.useState(false);
23
- const { token } = useToken();
22
+ const [isHovered, setIsHovered] = React.useState(false);
23
+ const { token } = useToken();
24
24
 
25
- return (
26
- <Card
27
- style={{
28
- // flex: 1,
29
- width: 318,
30
- minWidth: 318,
31
- // minWidth: "200px",
32
- }}
33
- hoverable
34
- onMouseEnter={() => setIsHovered(true)}
35
- onMouseLeave={() => setIsHovered(false)}
36
- onClick={onCardClick}
37
- cover={
38
- <ImageContainer>
39
- {image ? (
40
- <div
41
- className="image"
42
- style={{
43
- backgroundImage: `url(${image})`,
44
- }}
45
- />
46
- ) : (
47
- <div
48
- style={{
49
- height: "103px",
50
- borderBottom: "1px solid var(--base-gray-30)",
51
- }}
52
- >
53
- <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
54
- </div>
55
- )}
25
+ return (
26
+ <Card
27
+ style={{
28
+ flex: 1,
29
+ width: "100%",
30
+ minWidth: "200px",
31
+ }}
32
+ hoverable
33
+ onMouseEnter={() => setIsHovered(true)}
34
+ onMouseLeave={() => setIsHovered(false)}
35
+ onClick={onCardClick}
36
+ cover={
37
+ <ImageContainer>
38
+ {image ? (
39
+ <div
40
+ className="image"
41
+ style={{
42
+ backgroundImage: `url(${image})`,
43
+ }}
44
+ />
45
+ ) : (
46
+ <div
47
+ style={{
48
+ height: "103px",
49
+ }}
50
+ >
51
+ <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
52
+ </div>
53
+ )}
56
54
 
57
- {onLinkClick && (
58
- <div className="icon-container" onClick={onLinkClick}>
59
- <CustomIcon
60
- name={linkIcon}
61
- width={16}
62
- height={16}
63
- color={isHovered ? token.colorPrimary7 : "black"}
64
- />
65
- </div>
66
- )}
67
- </ImageContainer>
68
- }
69
- {...props}
70
- >
71
- <Meta title={title || undefined} description={description || undefined} />
72
- <ProjectWidgetItems>
73
- {items.map((item, index) => (
74
- <li key={index} className="project-widget-item">
75
- <Label>{item.label}</Label>
76
- {item.render()}
77
- </li>
78
- ))}
79
- </ProjectWidgetItems>
55
+ {onLinkClick && (
56
+ <div className="icon-container" onClick={onLinkClick}>
57
+ <CustomIcon
58
+ name={linkIcon}
59
+ width={16}
60
+ height={16}
61
+ color={isHovered ? token.colorPrimary7 : "black"}
62
+ />
63
+ </div>
64
+ )}
65
+ </ImageContainer>
66
+ }
67
+ {...props}
68
+ >
69
+ <Meta title={title || undefined} description={description || undefined} />
70
+ <ProjectWidgetItems>
71
+ {items.map((item, index) => (
72
+ <li key={index} className="project-widget-item">
73
+ <Label>{item.label}</Label>
74
+ {item.render()}
75
+ </li>
76
+ ))}
77
+ </ProjectWidgetItems>
80
78
 
81
- {!hideSDGList && (
82
- <div
83
- style={{
84
- borderTop: "1px solid var(--base-gray-30)",
85
- paddingTop: "10px",
86
- }}
87
- >
88
- <SdgList sdgList={sdgList} t={t} />
89
- </div>
90
- )}
91
- </Card>
92
- );
79
+ {!hideSDGList && (
80
+ <div
81
+ style={{
82
+ borderTop: "1px solid var(--base-gray-30)",
83
+ paddingTop: "10px",
84
+ }}
85
+ >
86
+ <SdgList sdgList={sdgList} t={t} />
87
+ </div>
88
+ )}
89
+ </Card>
90
+ );
93
91
  }
@@ -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
- 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"
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
- 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>
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
- .daf-widget {
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;
@@ -22,7 +22,6 @@ export const Primary = {
22
22
  title: "Select a focus operator to visualise its supply chain",
23
23
  height: 500,
24
24
  icon: "KYC",
25
- circleColor: "#014A4B",
26
25
  description:
27
26
  "This is based on information compiled by your organisation and approved sources.",
28
27
  },
@@ -30,7 +30,7 @@
30
30
  }
31
31
 
32
32
  .icon-bubble-d {
33
- // background-color: #2b2c2d;
33
+ background-color: #2b2c2d;
34
34
  border-radius: 100%;
35
35
  width: 57px;
36
36
  height: 57px;
@@ -7,8 +7,6 @@ export default function WidgetPlaceholder({
7
7
  style = {},
8
8
  iconWidth = 22,
9
9
  iconHeight = 22,
10
- iconColor = "white",
11
- circleColor = "#2b2c2d",
12
10
  inDevelopment = false,
13
11
  description = "",
14
12
  }) {
@@ -38,16 +36,13 @@ export default function WidgetPlaceholder({
38
36
  </div>
39
37
  </div>
40
38
  ) : (
41
- <div
42
- className="icon-bubble-d"
43
- style={{ backgroundColor: circleColor }}
44
- >
39
+ <div className="icon-bubble-d">
45
40
  <div className="flex justify-content-center">
46
41
  <CustomIcon
47
42
  name={icon}
48
43
  width={iconWidth}
49
44
  height={iconHeight}
50
- color={iconColor}
45
+ color="white"
51
46
  />
52
47
  </div>
53
48
  </div>