@centreon/ui 24.5.8 → 24.5.9
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 +4 -8
- package/public/mockServiceWorker.js +100 -81
- package/src/ActionsList/index.stories.tsx +1 -7
- package/src/Dashboard/Dashboard.styles.ts +2 -3
- package/src/Dashboard/Item.tsx +5 -39
- package/src/Dashboard/Layout.tsx +2 -4
- package/src/Dashboard/utils.ts +1 -1
- package/src/Graph/BarStack/BarStack.stories.tsx +6 -8
- package/src/Graph/BarStack/ResponsiveBarStack.tsx +3 -3
- package/src/Graph/HeatMap/HeatMap.stories.tsx +0 -20
- package/src/Graph/LineChart/BasicComponents/Lines/RegularLines/index.tsx +8 -12
- package/src/Graph/LineChart/BasicComponents/Lines/StackedLines/index.tsx +8 -8
- package/src/Graph/LineChart/BasicComponents/Lines/Threshold/BasicThreshold.tsx +2 -1
- package/src/Graph/LineChart/BasicComponents/Lines/Threshold/ThresholdWithPatternLines.tsx +2 -1
- package/src/Graph/LineChart/BasicComponents/Lines/Threshold/ThresholdWithVariation.tsx +2 -1
- package/src/Graph/LineChart/BasicComponents/Lines/Threshold/index.tsx +2 -1
- package/src/Graph/LineChart/BasicComponents/Lines/index.tsx +2 -1
- package/src/Graph/LineChart/BasicComponents/Lines/models.ts +3 -0
- package/src/Graph/LineChart/Legend/LegendHeader.tsx +1 -4
- package/src/Graph/LineChart/LineChart.cypress.spec.tsx +0 -53
- package/src/Graph/LineChart/LineChart.tsx +2 -1
- package/src/Graph/LineChart/common/index.ts +1 -15
- package/src/Graph/LineChart/index.stories.tsx +3 -15
- package/src/Graph/LineChart/index.tsx +4 -2
- package/src/Graph/LineChart/useLineChartData.ts +18 -57
- package/src/Graph/PieChart/PieChart.stories.tsx +15 -11
- package/src/Graph/PieChart/ResponsivePie.tsx +1 -1
- package/src/Graph/Tree/DescendantNodes.tsx +0 -1
- package/src/Graph/Tree/Links.tsx +2 -15
- package/src/Graph/Tree/Tree.cypress.spec.tsx +0 -24
- package/src/Graph/Tree/Tree.stories.tsx +1 -17
- package/src/Graph/Tree/models.ts +0 -3
- package/src/Graph/common/utils.ts +1 -49
- package/src/Listing/Cell/index.tsx +23 -17
- package/src/TimePeriods/index.stories.tsx +12 -7
- package/src/TopCounterElements/TopCounterLayout.tsx +4 -3
- package/src/api/QueryProvider.tsx +1 -1
- package/src/api/useFetchQuery/index.test.ts +5 -0
- package/src/api/useFetchQuery/index.ts +7 -12
- package/src/api/useGraphQuery/index.ts +2 -9
- package/src/api/useMutationQuery/index.ts +5 -2
- package/src/api/useRequest/index.test.ts +3 -0
- package/src/api/useRequest/index.ts +6 -3
- package/src/components/Form/AccessRights/AccessRights.cypress.spec.tsx +13 -27
- package/src/components/Form/AccessRights/AccessRights.stories.tsx +19 -0
- package/src/components/Form/AccessRights/AccessRights.styles.ts +1 -1
- package/src/components/Form/AccessRights/AccessRights.tsx +5 -6
- package/src/components/Form/AccessRights/Actions/Actions.styles.ts +7 -3
- package/src/components/Form/AccessRights/Actions/Actions.tsx +32 -15
- package/src/components/Form/AccessRights/Actions/useActions.ts +37 -4
- package/src/components/Form/AccessRights/ShareInput/ShareInput.tsx +0 -1
- package/src/components/Form/AccessRights/models.ts +3 -0
- package/src/components/Form/AccessRights/storiesData.ts +3 -0
- package/src/components/Form/Dashboard/DashboardForm.stories.ts +39 -0
- package/src/components/Form/Dashboard/translatedLabels.ts +1 -0
- package/src/components/List/Item/ListItem.styles.ts +2 -2
- package/src/components/Modal/Modal.styles.ts +5 -5
- package/src/components/Zoom/Minimap.tsx +2 -4
- package/src/components/Zoom/Zoom.cypress.spec.tsx +13 -13
- package/src/components/Zoom/Zoom.tsx +1 -4
- package/src/components/Zoom/ZoomContent.tsx +2 -5
- package/src/components/index.ts +0 -1
- package/src/index.ts +1 -1
- package/src/utils/index.ts +0 -1
- package/src/utils/usePluralizedTranslation.ts +3 -20
- package/src/Dashboard/Dashboard.cypress.spec.tsx +0 -68
- package/src/Graph/LineChart/mockedData/curvesWithSameColor.json +0 -252
- package/src/api/logger.ts +0 -11
- package/src/components/Form/AccessRights/useAccessRightsChange.ts +0 -30
- package/src/components/Form/AccessRights/utils.ts +0 -18
- package/src/components/Tabs/Tab.styles.ts +0 -25
- package/src/components/Tabs/TabPanel.tsx +0 -22
- package/src/components/Tabs/Tabs.cypress.spec.tsx +0 -70
- package/src/components/Tabs/Tabs.stories.tsx +0 -55
- package/src/components/Tabs/Tabs.tsx +0 -55
- package/src/components/Tabs/index.ts +0 -6
- package/src/utils/resourcesStatusURL.ts +0 -166
- package/src/utils/usePluralizedTranslation.test.ts +0 -159
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@centreon/ui",
|
|
3
|
-
"version": "24.5.
|
|
3
|
+
"version": "24.5.9",
|
|
4
4
|
"description": "Centreon UI Components",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"update:deps": "pnpx npm-check-updates -i --format group",
|
|
@@ -53,8 +53,6 @@
|
|
|
53
53
|
"@cypress/webpack-dev-server": "^3.7.4",
|
|
54
54
|
"@faker-js/faker": "^8.4.1",
|
|
55
55
|
"@mdx-js/react": "^3.0.1",
|
|
56
|
-
"@modern-js/prod-server": "^2.49.2",
|
|
57
|
-
"@modern-js/storybook": "^2.49.2",
|
|
58
56
|
"@simonsmith/cypress-image-snapshot": "^9.0.1",
|
|
59
57
|
"@storybook/addon-a11y": "^7.0.9",
|
|
60
58
|
"@storybook/addon-docs": "^7.0.9",
|
|
@@ -62,7 +60,7 @@
|
|
|
62
60
|
"@storybook/addon-interactions": "^7.0.9",
|
|
63
61
|
"@storybook/addon-styling": "^1.0.6",
|
|
64
62
|
"@storybook/blocks": "^7.0.26",
|
|
65
|
-
"@storybook/builder-vite": "^7.
|
|
63
|
+
"@storybook/builder-vite": "^7.0.9",
|
|
66
64
|
"@storybook/jest": "^0.1.0",
|
|
67
65
|
"@storybook/manager-api": "^7.0.9",
|
|
68
66
|
"@storybook/mdx2-csf": "^1.1.0",
|
|
@@ -104,7 +102,7 @@
|
|
|
104
102
|
"use-resize-observer": "^9.1.0",
|
|
105
103
|
"vite": "^4.3.5",
|
|
106
104
|
"vite-plugin-istanbul": "^5.0.0",
|
|
107
|
-
"vite-plugin-svgr": "^3.
|
|
105
|
+
"vite-plugin-svgr": "^3.2.0",
|
|
108
106
|
"vite-plugin-turbosnap": "^1.0.3"
|
|
109
107
|
},
|
|
110
108
|
"dependencies": {
|
|
@@ -171,8 +169,6 @@
|
|
|
171
169
|
"output": "./junit.xml"
|
|
172
170
|
},
|
|
173
171
|
"msw": {
|
|
174
|
-
"workerDirectory":
|
|
175
|
-
"public"
|
|
176
|
-
]
|
|
172
|
+
"workerDirectory": "public"
|
|
177
173
|
}
|
|
178
174
|
}
|
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
/* tslint:disable */
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Mock Service Worker.
|
|
5
|
+
* Mock Service Worker (1.3.2).
|
|
6
6
|
* @see https://github.com/mswjs/msw
|
|
7
7
|
* - Please do NOT modify this file.
|
|
8
8
|
* - Please do NOT serve this file on production.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423'
|
|
13
|
-
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
|
|
11
|
+
const INTEGRITY_CHECKSUM = '3d6b9f06410d179a7f7404d4bf4c3c70'
|
|
14
12
|
const activeClientIds = new Set()
|
|
15
13
|
|
|
16
14
|
self.addEventListener('install', function () {
|
|
@@ -49,10 +47,7 @@ self.addEventListener('message', async function (event) {
|
|
|
49
47
|
case 'INTEGRITY_CHECK_REQUEST': {
|
|
50
48
|
sendToClient(client, {
|
|
51
49
|
type: 'INTEGRITY_CHECK_RESPONSE',
|
|
52
|
-
payload:
|
|
53
|
-
packageVersion: PACKAGE_VERSION,
|
|
54
|
-
checksum: INTEGRITY_CHECKSUM,
|
|
55
|
-
},
|
|
50
|
+
payload: INTEGRITY_CHECKSUM,
|
|
56
51
|
})
|
|
57
52
|
break
|
|
58
53
|
}
|
|
@@ -91,6 +86,12 @@ self.addEventListener('message', async function (event) {
|
|
|
91
86
|
|
|
92
87
|
self.addEventListener('fetch', function (event) {
|
|
93
88
|
const { request } = event
|
|
89
|
+
const accept = request.headers.get('accept') || ''
|
|
90
|
+
|
|
91
|
+
// Bypass server-sent events.
|
|
92
|
+
if (accept.includes('text/event-stream')) {
|
|
93
|
+
return
|
|
94
|
+
}
|
|
94
95
|
|
|
95
96
|
// Bypass navigation requests.
|
|
96
97
|
if (request.mode === 'navigate') {
|
|
@@ -111,8 +112,29 @@ self.addEventListener('fetch', function (event) {
|
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
// Generate unique request ID.
|
|
114
|
-
const requestId =
|
|
115
|
-
|
|
115
|
+
const requestId = Math.random().toString(16).slice(2)
|
|
116
|
+
|
|
117
|
+
event.respondWith(
|
|
118
|
+
handleRequest(event, requestId).catch((error) => {
|
|
119
|
+
if (error.name === 'NetworkError') {
|
|
120
|
+
console.warn(
|
|
121
|
+
'[MSW] Successfully emulated a network error for the "%s %s" request.',
|
|
122
|
+
request.method,
|
|
123
|
+
request.url,
|
|
124
|
+
)
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// At this point, any exception indicates an issue with the original request/response.
|
|
129
|
+
console.error(
|
|
130
|
+
`\
|
|
131
|
+
[MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`,
|
|
132
|
+
request.method,
|
|
133
|
+
request.url,
|
|
134
|
+
`${error.name}: ${error.message}`,
|
|
135
|
+
)
|
|
136
|
+
}),
|
|
137
|
+
)
|
|
116
138
|
})
|
|
117
139
|
|
|
118
140
|
async function handleRequest(event, requestId) {
|
|
@@ -124,24 +146,21 @@ async function handleRequest(event, requestId) {
|
|
|
124
146
|
// this message will pend indefinitely.
|
|
125
147
|
if (client && activeClientIds.has(client.id)) {
|
|
126
148
|
;(async function () {
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
type:
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
headers: Object.fromEntries(responseClone.headers.entries()),
|
|
141
|
-
},
|
|
149
|
+
const clonedResponse = response.clone()
|
|
150
|
+
sendToClient(client, {
|
|
151
|
+
type: 'RESPONSE',
|
|
152
|
+
payload: {
|
|
153
|
+
requestId,
|
|
154
|
+
type: clonedResponse.type,
|
|
155
|
+
ok: clonedResponse.ok,
|
|
156
|
+
status: clonedResponse.status,
|
|
157
|
+
statusText: clonedResponse.statusText,
|
|
158
|
+
body:
|
|
159
|
+
clonedResponse.body === null ? null : await clonedResponse.text(),
|
|
160
|
+
headers: Object.fromEntries(clonedResponse.headers.entries()),
|
|
161
|
+
redirected: clonedResponse.redirected,
|
|
142
162
|
},
|
|
143
|
-
|
|
144
|
-
)
|
|
163
|
+
})
|
|
145
164
|
})()
|
|
146
165
|
}
|
|
147
166
|
|
|
@@ -177,20 +196,20 @@ async function resolveMainClient(event) {
|
|
|
177
196
|
|
|
178
197
|
async function getResponse(event, client, requestId) {
|
|
179
198
|
const { request } = event
|
|
180
|
-
|
|
181
|
-
// Clone the request because it might've been already used
|
|
182
|
-
// (i.e. its body has been read and sent to the client).
|
|
183
|
-
const requestClone = request.clone()
|
|
199
|
+
const clonedRequest = request.clone()
|
|
184
200
|
|
|
185
201
|
function passthrough() {
|
|
186
|
-
|
|
202
|
+
// Clone the request because it might've been already used
|
|
203
|
+
// (i.e. its body has been read and sent to the client).
|
|
204
|
+
const headers = Object.fromEntries(clonedRequest.headers.entries())
|
|
187
205
|
|
|
188
|
-
// Remove
|
|
189
|
-
//
|
|
190
|
-
//
|
|
191
|
-
|
|
206
|
+
// Remove MSW-specific request headers so the bypassed requests
|
|
207
|
+
// comply with the server's CORS preflight check.
|
|
208
|
+
// Operate with the headers as an object because request "Headers"
|
|
209
|
+
// are immutable.
|
|
210
|
+
delete headers['x-msw-bypass']
|
|
192
211
|
|
|
193
|
-
return fetch(
|
|
212
|
+
return fetch(clonedRequest, { headers })
|
|
194
213
|
}
|
|
195
214
|
|
|
196
215
|
// Bypass mocking when the client is not active.
|
|
@@ -206,46 +225,57 @@ async function getResponse(event, client, requestId) {
|
|
|
206
225
|
return passthrough()
|
|
207
226
|
}
|
|
208
227
|
|
|
228
|
+
// Bypass requests with the explicit bypass header.
|
|
229
|
+
// Such requests can be issued by "ctx.fetch()".
|
|
230
|
+
if (request.headers.get('x-msw-bypass') === 'true') {
|
|
231
|
+
return passthrough()
|
|
232
|
+
}
|
|
233
|
+
|
|
209
234
|
// Notify the client that a request has been intercepted.
|
|
210
|
-
const
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
body: requestBuffer,
|
|
229
|
-
keepalive: request.keepalive,
|
|
230
|
-
},
|
|
235
|
+
const clientMessage = await sendToClient(client, {
|
|
236
|
+
type: 'REQUEST',
|
|
237
|
+
payload: {
|
|
238
|
+
id: requestId,
|
|
239
|
+
url: request.url,
|
|
240
|
+
method: request.method,
|
|
241
|
+
headers: Object.fromEntries(request.headers.entries()),
|
|
242
|
+
cache: request.cache,
|
|
243
|
+
mode: request.mode,
|
|
244
|
+
credentials: request.credentials,
|
|
245
|
+
destination: request.destination,
|
|
246
|
+
integrity: request.integrity,
|
|
247
|
+
redirect: request.redirect,
|
|
248
|
+
referrer: request.referrer,
|
|
249
|
+
referrerPolicy: request.referrerPolicy,
|
|
250
|
+
body: await request.text(),
|
|
251
|
+
bodyUsed: request.bodyUsed,
|
|
252
|
+
keepalive: request.keepalive,
|
|
231
253
|
},
|
|
232
|
-
|
|
233
|
-
)
|
|
254
|
+
})
|
|
234
255
|
|
|
235
256
|
switch (clientMessage.type) {
|
|
236
257
|
case 'MOCK_RESPONSE': {
|
|
237
258
|
return respondWithMock(clientMessage.data)
|
|
238
259
|
}
|
|
239
260
|
|
|
240
|
-
case '
|
|
261
|
+
case 'MOCK_NOT_FOUND': {
|
|
241
262
|
return passthrough()
|
|
242
263
|
}
|
|
264
|
+
|
|
265
|
+
case 'NETWORK_ERROR': {
|
|
266
|
+
const { name, message } = clientMessage.data
|
|
267
|
+
const networkError = new Error(message)
|
|
268
|
+
networkError.name = name
|
|
269
|
+
|
|
270
|
+
// Rejecting a "respondWith" promise emulates a network error.
|
|
271
|
+
throw networkError
|
|
272
|
+
}
|
|
243
273
|
}
|
|
244
274
|
|
|
245
275
|
return passthrough()
|
|
246
276
|
}
|
|
247
277
|
|
|
248
|
-
function sendToClient(client, message
|
|
278
|
+
function sendToClient(client, message) {
|
|
249
279
|
return new Promise((resolve, reject) => {
|
|
250
280
|
const channel = new MessageChannel()
|
|
251
281
|
|
|
@@ -257,28 +287,17 @@ function sendToClient(client, message, transferrables = []) {
|
|
|
257
287
|
resolve(event.data)
|
|
258
288
|
}
|
|
259
289
|
|
|
260
|
-
client.postMessage(
|
|
261
|
-
message,
|
|
262
|
-
[channel.port2].concat(transferrables.filter(Boolean)),
|
|
263
|
-
)
|
|
290
|
+
client.postMessage(message, [channel.port2])
|
|
264
291
|
})
|
|
265
292
|
}
|
|
266
293
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
// instance will have status code set to 0. Since it's not possible to create
|
|
271
|
-
// a Response instance with status code 0, handle that use-case separately.
|
|
272
|
-
if (response.status === 0) {
|
|
273
|
-
return Response.error()
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const mockedResponse = new Response(response.body, response)
|
|
277
|
-
|
|
278
|
-
Reflect.defineProperty(mockedResponse, IS_MOCKED_RESPONSE, {
|
|
279
|
-
value: true,
|
|
280
|
-
enumerable: true,
|
|
294
|
+
function sleep(timeMs) {
|
|
295
|
+
return new Promise((resolve) => {
|
|
296
|
+
setTimeout(resolve, timeMs)
|
|
281
297
|
})
|
|
298
|
+
}
|
|
282
299
|
|
|
283
|
-
|
|
300
|
+
async function respondWithMock(response) {
|
|
301
|
+
await sleep(response.delay)
|
|
302
|
+
return new Response(response.body, response)
|
|
284
303
|
}
|
|
@@ -4,8 +4,6 @@ import DeleteIcon from '@mui/icons-material/Delete';
|
|
|
4
4
|
import EditIcon from '@mui/icons-material/Edit';
|
|
5
5
|
import CopyIcon from '@mui/icons-material/ContentCopy';
|
|
6
6
|
|
|
7
|
-
import { ActionVariants } from './models';
|
|
8
|
-
|
|
9
7
|
import ActionsList from '.';
|
|
10
8
|
|
|
11
9
|
const actions = [
|
|
@@ -26,11 +24,7 @@ const actions = [
|
|
|
26
24
|
}
|
|
27
25
|
];
|
|
28
26
|
|
|
29
|
-
const actionsWithVariants
|
|
30
|
-
label: string;
|
|
31
|
-
onClick: () => void;
|
|
32
|
-
variant?: ActionVariants;
|
|
33
|
-
}> = [
|
|
27
|
+
const actionsWithVariants = [
|
|
34
28
|
{
|
|
35
29
|
label: 'No variant',
|
|
36
30
|
onClick: (): void => undefined
|
|
@@ -17,7 +17,7 @@ export const useDashboardLayoutStyles = makeStyles<boolean>()(
|
|
|
17
17
|
boxShadow: theme.shadows[3]
|
|
18
18
|
},
|
|
19
19
|
'& .react-grid-item.react-grid-placeholder': {
|
|
20
|
-
backgroundColor: alpha(theme.palette.primary.main, 0.
|
|
20
|
+
backgroundColor: alpha(theme.palette.primary.main, 0.7)
|
|
21
21
|
},
|
|
22
22
|
'& .react-grid-item.resizing': {
|
|
23
23
|
boxShadow: theme.shadows[3]
|
|
@@ -61,8 +61,7 @@ export const useDashboardLayoutStyles = makeStyles<boolean>()(
|
|
|
61
61
|
},
|
|
62
62
|
'& .react-resizable-handle:hover': {
|
|
63
63
|
opacity: 1
|
|
64
|
-
}
|
|
65
|
-
position: 'relative'
|
|
64
|
+
}
|
|
66
65
|
}
|
|
67
66
|
})
|
|
68
67
|
);
|
package/src/Dashboard/Item.tsx
CHANGED
|
@@ -3,21 +3,18 @@ import {
|
|
|
3
3
|
ForwardedRef,
|
|
4
4
|
forwardRef,
|
|
5
5
|
MouseEvent,
|
|
6
|
-
ReactElement
|
|
7
|
-
useEffect
|
|
6
|
+
ReactElement
|
|
8
7
|
} from 'react';
|
|
9
8
|
|
|
10
9
|
import { isNil, prop } from 'ramda';
|
|
11
10
|
|
|
12
11
|
import { Card, useTheme } from '@mui/material';
|
|
13
12
|
|
|
14
|
-
import { useMemoComponent
|
|
15
|
-
import LoadingSkeleton from '../LoadingSkeleton';
|
|
13
|
+
import { useMemoComponent } from '../utils';
|
|
16
14
|
|
|
17
15
|
import { useDashboardItemStyles } from './Dashboard.styles';
|
|
18
16
|
|
|
19
17
|
interface DashboardItemProps {
|
|
20
|
-
additionalMemoProps?: Array<unknown>;
|
|
21
18
|
canMove?: boolean;
|
|
22
19
|
children: ReactElement;
|
|
23
20
|
className?: string;
|
|
@@ -42,14 +39,10 @@ const Item = forwardRef<HTMLDivElement, DashboardItemProps>(
|
|
|
42
39
|
onTouchEnd,
|
|
43
40
|
id,
|
|
44
41
|
disablePadding = false,
|
|
45
|
-
canMove = false
|
|
46
|
-
additionalMemoProps = []
|
|
42
|
+
canMove = false
|
|
47
43
|
}: DashboardItemProps,
|
|
48
44
|
ref: ForwardedRef<HTMLDivElement>
|
|
49
45
|
): ReactElement => {
|
|
50
|
-
const { isInViewport, setElement } = useViewportIntersection({
|
|
51
|
-
rootMargin: '140px 0px 140px 0px'
|
|
52
|
-
});
|
|
53
46
|
const hasHeader = !isNil(header);
|
|
54
47
|
|
|
55
48
|
const { classes, cx } = useDashboardItemStyles({ hasHeader });
|
|
@@ -63,14 +56,6 @@ const Item = forwardRef<HTMLDivElement, DashboardItemProps>(
|
|
|
63
56
|
|
|
64
57
|
const cardContainerListeners = !hasHeader ? listeners : {};
|
|
65
58
|
|
|
66
|
-
useEffect(() => {
|
|
67
|
-
if (isNil(ref)) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
setElement(ref.current);
|
|
72
|
-
}, [ref]);
|
|
73
|
-
|
|
74
59
|
return useMemoComponent({
|
|
75
60
|
Component: (
|
|
76
61
|
<div
|
|
@@ -102,31 +87,12 @@ const Item = forwardRef<HTMLDivElement, DashboardItemProps>(
|
|
|
102
87
|
!disablePadding && classes.widgetPadding
|
|
103
88
|
)}
|
|
104
89
|
>
|
|
105
|
-
{
|
|
106
|
-
<LoadingSkeleton
|
|
107
|
-
animation={false}
|
|
108
|
-
data-widget-skeleton={id}
|
|
109
|
-
height="100%"
|
|
110
|
-
width="100%"
|
|
111
|
-
/>
|
|
112
|
-
) : (
|
|
113
|
-
children
|
|
114
|
-
)}
|
|
90
|
+
{children}
|
|
115
91
|
</div>
|
|
116
92
|
</Card>
|
|
117
93
|
</div>
|
|
118
94
|
),
|
|
119
|
-
memoProps:
|
|
120
|
-
? [
|
|
121
|
-
style,
|
|
122
|
-
className,
|
|
123
|
-
header,
|
|
124
|
-
theme.palette.mode,
|
|
125
|
-
canMove,
|
|
126
|
-
isInViewport,
|
|
127
|
-
...additionalMemoProps
|
|
128
|
-
]
|
|
129
|
-
: [isInViewport, theme.palette.mode, style]
|
|
95
|
+
memoProps: [style, className, header, theme.palette.mode, canMove]
|
|
130
96
|
});
|
|
131
97
|
}
|
|
132
98
|
);
|
package/src/Dashboard/Layout.tsx
CHANGED
|
@@ -16,7 +16,6 @@ import Grid from './Grid';
|
|
|
16
16
|
const ReactGridLayout = WidthProvider(GridLayout);
|
|
17
17
|
|
|
18
18
|
interface DashboardLayoutProps<T> {
|
|
19
|
-
additionalMemoProps?: Array<unknown>;
|
|
20
19
|
changeLayout?: (newLayout: Array<Layout>) => void;
|
|
21
20
|
children: Array<JSX.Element>;
|
|
22
21
|
displayGrid?: boolean;
|
|
@@ -29,8 +28,7 @@ const DashboardLayout = <T extends Layout>({
|
|
|
29
28
|
changeLayout,
|
|
30
29
|
displayGrid,
|
|
31
30
|
layout,
|
|
32
|
-
isStatic = false
|
|
33
|
-
additionalMemoProps = []
|
|
31
|
+
isStatic = false
|
|
34
32
|
}: DashboardLayoutProps<T>): JSX.Element => {
|
|
35
33
|
const { classes } = useDashboardLayoutStyles(isStatic);
|
|
36
34
|
|
|
@@ -74,7 +72,7 @@ const DashboardLayout = <T extends Layout>({
|
|
|
74
72
|
</ParentSize>
|
|
75
73
|
</ResponsiveHeight>
|
|
76
74
|
),
|
|
77
|
-
memoProps: [columns, layout, displayGrid, isStatic
|
|
75
|
+
memoProps: [columns, layout, displayGrid, isStatic]
|
|
78
76
|
});
|
|
79
77
|
};
|
|
80
78
|
|
package/src/Dashboard/utils.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { lt } from 'ramda';
|
|
2
2
|
import { Layout } from 'react-grid-layout';
|
|
3
3
|
|
|
4
|
+
export const maxColumns = 12;
|
|
4
5
|
const minColumns = 1;
|
|
5
6
|
const breakpoint = 768;
|
|
6
7
|
|
|
7
8
|
export const rowHeight = 64;
|
|
8
|
-
export const maxColumns = 12;
|
|
9
9
|
|
|
10
10
|
export const getIsSmallScreenSize = (): boolean =>
|
|
11
11
|
lt(window.innerWidth, breakpoint);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react';
|
|
2
2
|
|
|
3
3
|
import { BarType } from './models';
|
|
4
|
-
import ResponsiveBarStack from './ResponsiveBarStack';
|
|
5
4
|
|
|
6
5
|
import { BarStack } from '.';
|
|
7
6
|
|
|
@@ -27,12 +26,7 @@ const dataWithSmallNumber = [
|
|
|
27
26
|
];
|
|
28
27
|
|
|
29
28
|
const meta: Meta<typeof BarStack> = {
|
|
30
|
-
component: BarStack
|
|
31
|
-
parameters: {
|
|
32
|
-
chromatic: {
|
|
33
|
-
delay: 1000
|
|
34
|
-
}
|
|
35
|
-
}
|
|
29
|
+
component: BarStack
|
|
36
30
|
};
|
|
37
31
|
|
|
38
32
|
export default meta;
|
|
@@ -47,7 +41,11 @@ const TooltipContent = ({ label, color, value }: BarType): JSX.Element => {
|
|
|
47
41
|
};
|
|
48
42
|
|
|
49
43
|
const Template = (args): JSX.Element => {
|
|
50
|
-
return
|
|
44
|
+
return (
|
|
45
|
+
<div style={{ height: '300px', width: '500px' }}>
|
|
46
|
+
<BarStack {...args} />
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
51
49
|
};
|
|
52
50
|
|
|
53
51
|
export const Vertical: Story = {
|
|
@@ -20,7 +20,7 @@ const DefaultLengd = ({ scale, direction }: LegendProps): JSX.Element => (
|
|
|
20
20
|
<LegendComponent direction={direction} scale={scale} />
|
|
21
21
|
);
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const BarStack = ({
|
|
24
24
|
title,
|
|
25
25
|
data,
|
|
26
26
|
width,
|
|
@@ -73,7 +73,7 @@ const ResponsiveBarStack = ({
|
|
|
73
73
|
<div
|
|
74
74
|
className={classes.svgWrapper}
|
|
75
75
|
style={{
|
|
76
|
-
|
|
76
|
+
height,
|
|
77
77
|
width: svgWrapperWidth
|
|
78
78
|
}}
|
|
79
79
|
>
|
|
@@ -206,4 +206,4 @@ const ResponsiveBarStack = ({
|
|
|
206
206
|
);
|
|
207
207
|
};
|
|
208
208
|
|
|
209
|
-
export default
|
|
209
|
+
export default BarStack;
|
|
@@ -55,26 +55,6 @@ const Template = (args): JSX.Element => {
|
|
|
55
55
|
return <HeatMap {...args} arrowClassName={classes.arrow} />;
|
|
56
56
|
};
|
|
57
57
|
|
|
58
|
-
const TileContent = ({
|
|
59
|
-
data,
|
|
60
|
-
backgroundColor
|
|
61
|
-
}: {
|
|
62
|
-
backgroundColor: string;
|
|
63
|
-
data: Data;
|
|
64
|
-
}): JSX.Element => (
|
|
65
|
-
<div
|
|
66
|
-
style={{
|
|
67
|
-
alignItems: 'center',
|
|
68
|
-
backgroundColor,
|
|
69
|
-
display: 'flex',
|
|
70
|
-
height: '100%',
|
|
71
|
-
justifyContent: 'center'
|
|
72
|
-
}}
|
|
73
|
-
>
|
|
74
|
-
{data.counter}
|
|
75
|
-
</div>
|
|
76
|
-
);
|
|
77
|
-
|
|
78
58
|
export const normal: Story = {
|
|
79
59
|
args: {
|
|
80
60
|
children: TileContent,
|
|
@@ -6,11 +6,12 @@ import { equals, isNil, prop } from 'ramda';
|
|
|
6
6
|
|
|
7
7
|
import { getTime } from '../../../../common/timeSeries';
|
|
8
8
|
import { TimeValue } from '../../../../common/timeSeries/models';
|
|
9
|
-
import {
|
|
9
|
+
import { getFillColor } from '../../../common';
|
|
10
|
+
import { CurveType } from '../models';
|
|
10
11
|
|
|
11
12
|
interface Props {
|
|
12
13
|
areaColor: string;
|
|
13
|
-
curve:
|
|
14
|
+
curve: CurveType;
|
|
14
15
|
filled: boolean;
|
|
15
16
|
graphHeight: number;
|
|
16
17
|
highlight?: boolean;
|
|
@@ -39,9 +40,8 @@ const RegularLine = ({
|
|
|
39
40
|
graphHeight,
|
|
40
41
|
curve
|
|
41
42
|
}: Props): JSX.Element => {
|
|
42
|
-
const curveType = getCurveFactory(curve);
|
|
43
43
|
const props = {
|
|
44
|
-
curve
|
|
44
|
+
curve,
|
|
45
45
|
data: timeSeries,
|
|
46
46
|
defined: (value): boolean => !isNil(value[metric_id]),
|
|
47
47
|
opacity: 1,
|
|
@@ -55,7 +55,6 @@ const RegularLine = ({
|
|
|
55
55
|
if (filled) {
|
|
56
56
|
return (
|
|
57
57
|
<Shape.AreaClosed<TimeValue>
|
|
58
|
-
data-metric={metric_id}
|
|
59
58
|
fill={getFillColor({ areaColor, transparency })}
|
|
60
59
|
fillRule="nonzero"
|
|
61
60
|
key={metric_id}
|
|
@@ -66,7 +65,7 @@ const RegularLine = ({
|
|
|
66
65
|
);
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
return <Shape.LinePath<TimeValue>
|
|
68
|
+
return <Shape.LinePath<TimeValue> {...props} />;
|
|
70
69
|
};
|
|
71
70
|
|
|
72
71
|
export default memo(RegularLine, (prevProps, nextProps) => {
|
|
@@ -75,16 +74,14 @@ export default memo(RegularLine, (prevProps, nextProps) => {
|
|
|
75
74
|
graphHeight: prevGraphHeight,
|
|
76
75
|
highlight: prevHighlight,
|
|
77
76
|
xScale: prevXScale,
|
|
78
|
-
yScale: prevYScale
|
|
79
|
-
curve: prevCurve
|
|
77
|
+
yScale: prevYScale
|
|
80
78
|
} = prevProps;
|
|
81
79
|
const {
|
|
82
80
|
timeSeries: nextTimeSeries,
|
|
83
81
|
graphHeight: nextGraphHeight,
|
|
84
82
|
highlight: nextHighlight,
|
|
85
83
|
xScale: nextXScale,
|
|
86
|
-
yScale: nextYScale
|
|
87
|
-
curve: nextCurve
|
|
84
|
+
yScale: nextYScale
|
|
88
85
|
} = nextProps;
|
|
89
86
|
|
|
90
87
|
const prevXScaleRange = prevXScale.range();
|
|
@@ -97,7 +94,6 @@ export default memo(RegularLine, (prevProps, nextProps) => {
|
|
|
97
94
|
equals(prevGraphHeight, nextGraphHeight) &&
|
|
98
95
|
equals(prevHighlight, nextHighlight) &&
|
|
99
96
|
equals(prevXScaleRange, nextXScaleRange) &&
|
|
100
|
-
equals(prevYScaleDomain, nextYScaleDomain)
|
|
101
|
-
equals(prevCurve, nextCurve)
|
|
97
|
+
equals(prevYScaleDomain, nextYScaleDomain)
|
|
102
98
|
);
|
|
103
99
|
});
|
|
@@ -4,12 +4,13 @@ import { all, isNil, map, not, nth, path, pipe, prop } from 'ramda';
|
|
|
4
4
|
|
|
5
5
|
import StackedAnchorPoint from '../../../InteractiveComponents/AnchorPoint/StackedAnchorPoint';
|
|
6
6
|
import { StackValue } from '../../../InteractiveComponents/AnchorPoint/models';
|
|
7
|
-
import {
|
|
7
|
+
import { getFillColor } from '../../../common';
|
|
8
8
|
import { getTime } from '../../../../common/timeSeries';
|
|
9
9
|
import { Line, TimeValue } from '../../../../common/timeSeries/models';
|
|
10
|
+
import { CurveType } from '../models';
|
|
10
11
|
|
|
11
12
|
interface Props {
|
|
12
|
-
curve:
|
|
13
|
+
curve: CurveType;
|
|
13
14
|
displayAnchor: boolean;
|
|
14
15
|
lines: Array<Line>;
|
|
15
16
|
timeSeries: Array<TimeValue>;
|
|
@@ -25,11 +26,9 @@ const StackLines = ({
|
|
|
25
26
|
displayAnchor,
|
|
26
27
|
curve
|
|
27
28
|
}: Props): JSX.Element => {
|
|
28
|
-
const curveType = getCurveFactory(curve);
|
|
29
|
-
|
|
30
29
|
return (
|
|
31
30
|
<Shape.AreaStack
|
|
32
|
-
curve={
|
|
31
|
+
curve={curve}
|
|
33
32
|
data={timeSeries}
|
|
34
33
|
defined={(d): boolean => {
|
|
35
34
|
return pipe(
|
|
@@ -46,8 +45,10 @@ const StackLines = ({
|
|
|
46
45
|
>
|
|
47
46
|
{({ stacks, path: linePath }): Array<JSX.Element> => {
|
|
48
47
|
return stacks.map((stack, index) => {
|
|
49
|
-
const { areaColor, transparency, lineColor, highlight
|
|
50
|
-
|
|
48
|
+
const { areaColor, transparency, lineColor, highlight } = nth(
|
|
49
|
+
index,
|
|
50
|
+
lines
|
|
51
|
+
) as Line;
|
|
51
52
|
|
|
52
53
|
return (
|
|
53
54
|
<g key={`stack-${prop('key', stack)}`}>
|
|
@@ -64,7 +65,6 @@ const StackLines = ({
|
|
|
64
65
|
)}
|
|
65
66
|
<path
|
|
66
67
|
d={linePath(stack) || ''}
|
|
67
|
-
data-metric={metric_id}
|
|
68
68
|
fill={getFillColor({ areaColor, transparency })}
|
|
69
69
|
opacity={highlight === false ? 0.3 : 1}
|
|
70
70
|
stroke={lineColor}
|