@ultraviolet/plus 0.5.0 → 0.5.2
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/index.d.ts +261 -1
- package/dist/src/components/EstimateCost/Components/CustomUnitInput.js +48 -0
- package/dist/src/components/EstimateCost/Components/Item.js +327 -0
- package/dist/src/components/EstimateCost/Components/LineThrough.js +15 -0
- package/dist/src/components/EstimateCost/Components/NumberInput.js +41 -0
- package/dist/src/components/EstimateCost/Components/Region.js +50 -0
- package/dist/src/components/EstimateCost/Components/Regular.js +44 -0
- package/dist/src/components/EstimateCost/Components/Strong.js +37 -0
- package/dist/src/components/EstimateCost/Components/Unit.js +61 -0
- package/dist/src/components/EstimateCost/Components/UnitInput.js +122 -0
- package/dist/src/components/EstimateCost/Components/Zone.js +50 -0
- package/dist/src/components/EstimateCost/EstimateCost.js +126 -0
- package/dist/src/components/EstimateCost/EstimateCostContent.js +296 -0
- package/dist/src/components/EstimateCost/EstimateCostProvider.js +39 -0
- package/dist/src/components/EstimateCost/OverlayComponent.js +139 -0
- package/dist/src/components/EstimateCost/OverlayContext.js +19 -0
- package/dist/src/components/EstimateCost/componentStyle.js +196 -0
- package/dist/src/components/EstimateCost/constants.js +31 -0
- package/dist/src/components/EstimateCost/helper.js +23 -0
- package/dist/src/components/EstimateCost/locales/en.js +23 -0
- package/dist/src/index.js +2 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ import { ReactNode, MouseEventHandler, ComponentProps } from 'react';
|
|
|
3
3
|
import * as _emotion_react_jsx_runtime from '@emotion/react/jsx-runtime';
|
|
4
4
|
import { langs } from '@uiw/codemirror-extensions-langs';
|
|
5
5
|
import CodeMirror from '@uiw/react-codemirror';
|
|
6
|
+
import { Alert } from '@ultraviolet/ui';
|
|
7
|
+
import * as _emotion_styled from '@emotion/styled';
|
|
8
|
+
import * as _emotion_react from '@emotion/react';
|
|
6
9
|
|
|
7
10
|
type ContentCardProps = {
|
|
8
11
|
direction?: 'row' | 'column';
|
|
@@ -62,4 +65,261 @@ type CodeEditorProps = {
|
|
|
62
65
|
};
|
|
63
66
|
declare const CodeEditor: ({ title, value, onChange, extensions, onBlur, height, readOnly, }: CodeEditorProps) => _emotion_react_jsx_runtime.JSX.Element;
|
|
64
67
|
|
|
65
|
-
|
|
68
|
+
declare const _default: {
|
|
69
|
+
readonly 'estimate.cost.description': "This summary provides a cost estimation based on your configuration, the amount of time you expect to use the resource for, and the scale of your expected usage. For the purposes of this calculation, we consider that 1 month equals to 730 hours.";
|
|
70
|
+
readonly 'estimate.cost.label': "Estimated cost";
|
|
71
|
+
readonly 'estimate.cost.beta.free': "Free During Beta";
|
|
72
|
+
readonly 'estimate.cost.beta.discount': "% off during Beta";
|
|
73
|
+
readonly 'estimate.cost.beta.badge': "Beta Version";
|
|
74
|
+
readonly 'estimate.cost.units.seconds.label': "Second(s)";
|
|
75
|
+
readonly 'estimate.cost.units.minutes.label': "Minute(s)";
|
|
76
|
+
readonly 'estimate.cost.units.hours.label': "Hour(s)";
|
|
77
|
+
readonly 'estimate.cost.units.days.label': "Day(s)";
|
|
78
|
+
readonly 'estimate.cost.units.months.label': "Month(s)";
|
|
79
|
+
readonly 'estimate.cost.units.years.label': "Year(s)";
|
|
80
|
+
readonly 'estimate.cost.fees.oneTime.title': "One time fees";
|
|
81
|
+
readonly 'estimate.cost.fees.monthly.title': "Each month";
|
|
82
|
+
readonly 'estimate.cost.fees.commitment': "Commitment Fees";
|
|
83
|
+
readonly 'estimate.cost.units.gb.label': "GB";
|
|
84
|
+
readonly 'estimate.cost.notDefined': "Not defined";
|
|
85
|
+
readonly 'estimate.cost.submit.label': "Create";
|
|
86
|
+
readonly 'estimate.cost.region.label': "Region";
|
|
87
|
+
readonly 'estimate.cost.az.label': "Availability Zone";
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
type EstimateCostProps = {
|
|
91
|
+
/**
|
|
92
|
+
* Text to display into an alert on the top of the EstimateCost component.
|
|
93
|
+
*/
|
|
94
|
+
alert?: ReactNode;
|
|
95
|
+
/**
|
|
96
|
+
* Type of the alert defined by the Scaleway UI Alert component.
|
|
97
|
+
*/
|
|
98
|
+
alertVariant?: ComponentProps<typeof Alert>['sentiment'];
|
|
99
|
+
children: ReactNode;
|
|
100
|
+
/**
|
|
101
|
+
* Individual fees to display at the bottom of the EstimateCost component.
|
|
102
|
+
*/
|
|
103
|
+
commitmentFees?: number;
|
|
104
|
+
/**
|
|
105
|
+
* Content to display into the fees part, it can be any component but in order to have a consistent design, it is recommended to use `<EstimateCost.Regular>` and `<EstimateCost.Strong>` components.
|
|
106
|
+
*/
|
|
107
|
+
commitmentFeesContent?: ReactNode;
|
|
108
|
+
/**
|
|
109
|
+
* By default, a description exists but if you need you can customize it with this prop.
|
|
110
|
+
*/
|
|
111
|
+
description?: ReactNode;
|
|
112
|
+
/**
|
|
113
|
+
* Hide the floating estimate cost overlay shown in the bottom of the page.
|
|
114
|
+
*/
|
|
115
|
+
hideOverlay?: boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Disable left button on the overlay.
|
|
118
|
+
*/
|
|
119
|
+
disableOverlayLeft?: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Disable right button (submit) on the overlay.
|
|
122
|
+
*/
|
|
123
|
+
disableOverlayRight?: boolean;
|
|
124
|
+
/**
|
|
125
|
+
* This is a global discount for all estimate cost, all sub items will be impacted by this discount.
|
|
126
|
+
* The discount is a percentage, so 0.1 means 10% discount. Discount = 1 means 100% so it means free.
|
|
127
|
+
* This is usually associate with beta products and prop `isBeta`.
|
|
128
|
+
*/
|
|
129
|
+
discount?: number;
|
|
130
|
+
/**
|
|
131
|
+
* The default time unit to select.
|
|
132
|
+
*/
|
|
133
|
+
defaultTimeUnit?: Units;
|
|
134
|
+
/**
|
|
135
|
+
* List of time unit the price can be calculated with. Can only be an array of `seconds`, `minutes`, `hours`, `days` or `months`.
|
|
136
|
+
*/
|
|
137
|
+
timeUnits?: Units[];
|
|
138
|
+
/**
|
|
139
|
+
* Hide the selectable time unit on the top of the component.
|
|
140
|
+
*/
|
|
141
|
+
hideTimeUnit?: boolean;
|
|
142
|
+
/**
|
|
143
|
+
* Hide the total price at the bottom of the component.
|
|
144
|
+
*/
|
|
145
|
+
hideTotal?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Show a badge beta on the total price with how much discount is applied.
|
|
148
|
+
*/
|
|
149
|
+
isBeta?: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* It will display another individual line at the bottom of the component with a monthly price. It can be used when you display hourly price, but you have one or many items that are billed monthly.
|
|
152
|
+
*/
|
|
153
|
+
monthlyFees?: number;
|
|
154
|
+
/**
|
|
155
|
+
* Content to display into monthly fees part, it can be any component but in order to have a consistent design, it is recommended to use `<EstimateCost.Regular>` and `<EstimateCost.Strong>` components.
|
|
156
|
+
*/
|
|
157
|
+
monthlyFeesContent?: ReactNode;
|
|
158
|
+
/**
|
|
159
|
+
* Label of the item, it describes what kind of fees is related to. (ex: "Installation fee")
|
|
160
|
+
*/
|
|
161
|
+
monthlyFeesLabel?: string;
|
|
162
|
+
/**
|
|
163
|
+
* Content that will be shown on the left side of the overlay.
|
|
164
|
+
*/
|
|
165
|
+
OverlayLeft?: (props: {
|
|
166
|
+
children: ReactNode;
|
|
167
|
+
disabled?: boolean;
|
|
168
|
+
}) => JSX.Element;
|
|
169
|
+
/**
|
|
170
|
+
* Content that will be shown on the left side of the overlay.
|
|
171
|
+
*/
|
|
172
|
+
OverlayRight?: (props: {
|
|
173
|
+
children?: ReactNode;
|
|
174
|
+
disabled?: boolean;
|
|
175
|
+
}) => JSX.Element;
|
|
176
|
+
/**
|
|
177
|
+
* Time unit to use on the overlay. It can be different from estimate cost.
|
|
178
|
+
*/
|
|
179
|
+
overlayUnit?: Units;
|
|
180
|
+
/**
|
|
181
|
+
* Locales for the component. By default, it will use the english locales.
|
|
182
|
+
*/
|
|
183
|
+
locales?: typeof _default;
|
|
184
|
+
/**
|
|
185
|
+
* Defines the currency to be shown in the component.
|
|
186
|
+
* To find out all currencies checkout https://en.wikipedia.org/wiki/ISO_4217#List_of_ISO_4217_currency_codes section "Code" of the table.
|
|
187
|
+
*/
|
|
188
|
+
currency?: string;
|
|
189
|
+
/**
|
|
190
|
+
* Defines the way we display numbers depending on locale (ex: 1,000.00 or 1 000,00).
|
|
191
|
+
* To understand better please read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#locales
|
|
192
|
+
*/
|
|
193
|
+
numberLocales?: string;
|
|
194
|
+
};
|
|
195
|
+
type Units = 'seconds' | 'minutes' | 'hours' | 'days' | 'months';
|
|
196
|
+
type Iteration = {
|
|
197
|
+
unit: Units;
|
|
198
|
+
value: number;
|
|
199
|
+
};
|
|
200
|
+
type BareEstimateProduct = {
|
|
201
|
+
id: string;
|
|
202
|
+
};
|
|
203
|
+
type EstimateProduct = BareEstimateProduct & {
|
|
204
|
+
amount: number;
|
|
205
|
+
price: number;
|
|
206
|
+
amountFree: number;
|
|
207
|
+
isVariant: boolean;
|
|
208
|
+
maxAmount: number;
|
|
209
|
+
noIteration: boolean;
|
|
210
|
+
longFractionDigits: boolean;
|
|
211
|
+
discount: number;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
declare const EstimateCost: {
|
|
215
|
+
({ description, alert, alertVariant, defaultTimeUnit, timeUnits, hideOverlay, disableOverlayLeft, disableOverlayRight, hideTimeUnit, hideTotal, discount, OverlayRight, OverlayLeft, isBeta, commitmentFees, commitmentFeesContent, monthlyFees, monthlyFeesLabel, monthlyFeesContent, overlayUnit, children, locales, numberLocales, currency, }: EstimateCostProps): _emotion_react_jsx_runtime.JSX.Element;
|
|
216
|
+
LineThrough: _emotion_styled.StyledComponent<{
|
|
217
|
+
theme?: _emotion_react.Theme | undefined;
|
|
218
|
+
as?: react.ElementType<any> | undefined;
|
|
219
|
+
} & {
|
|
220
|
+
isActive?: boolean | undefined;
|
|
221
|
+
}, react.DetailedHTMLProps<react.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {}>;
|
|
222
|
+
Item: ({ discount, priceText, discountText, label, tooltipInfo, subLabel, price: basePrice, monthlyPrice, unit: baseUnit, amount: currentAmount, onAmountChange, amountFree, maxAmount, longFractionDigits, noIteration, noIterationText, noBorder, noPrice, isDefined, children, isFirstElement, isLastElement, isPrimaryBackground, productsCallback, iteration: receivedIteration, shouldBeHidden, hideFromOverlay, textNotDefined, animated, tabulation, labelTextVariant, labelTextProminence, notice, }: {
|
|
223
|
+
amount?: number | undefined;
|
|
224
|
+
amountFree?: number | undefined;
|
|
225
|
+
animated?: boolean | undefined;
|
|
226
|
+
children?: ReactNode;
|
|
227
|
+
discount?: number | undefined;
|
|
228
|
+
discountText?: string | undefined;
|
|
229
|
+
hideFromOverlay?: boolean | undefined;
|
|
230
|
+
isDefined?: boolean | undefined;
|
|
231
|
+
isFirstElement?: boolean | undefined;
|
|
232
|
+
isLastElement?: boolean | undefined;
|
|
233
|
+
isPrimaryBackground?: boolean | undefined;
|
|
234
|
+
iteration?: Iteration | undefined;
|
|
235
|
+
label?: ReactNode;
|
|
236
|
+
labelTextVariant?: "body" | "caption" | "code" | "heading" | "bodySmall" | "bodySmallStrong" | "bodySmallStronger" | "bodyStrong" | "bodyStronger" | "captionSmall" | "captionSmallStrong" | "captionSmallStronger" | "captionStrong" | "captionStronger" | "headingLarge" | "headingSmall" | undefined;
|
|
237
|
+
labelTextProminence?: "strong" | "default" | "stronger" | "weak" | undefined;
|
|
238
|
+
longFractionDigits?: boolean | undefined;
|
|
239
|
+
maxAmount?: number | undefined;
|
|
240
|
+
monthlyPrice?: number | undefined;
|
|
241
|
+
noBorder?: boolean | undefined;
|
|
242
|
+
noIteration?: boolean | undefined;
|
|
243
|
+
noIterationText?: string | undefined;
|
|
244
|
+
noPrice?: boolean | undefined;
|
|
245
|
+
notice?: string | undefined;
|
|
246
|
+
onAmountChange?: ((amount: number) => void) | undefined;
|
|
247
|
+
price?: number | undefined;
|
|
248
|
+
priceText?: ReactNode;
|
|
249
|
+
productsCallback?: {
|
|
250
|
+
add: (product: EstimateProduct) => void;
|
|
251
|
+
remove: (product: BareEstimateProduct) => void;
|
|
252
|
+
} | undefined;
|
|
253
|
+
shouldBeHidden?: boolean | undefined;
|
|
254
|
+
subLabel?: string | undefined;
|
|
255
|
+
tabulation?: number | undefined;
|
|
256
|
+
textNotDefined?: string | undefined;
|
|
257
|
+
tooltipInfo?: string | undefined;
|
|
258
|
+
unit?: (string & {}) | "seconds" | "minutes" | "hours" | "days" | "months" | "mb" | "gb" | "tb" | "years" | undefined;
|
|
259
|
+
}) => _emotion_react_jsx_runtime.JSX.Element;
|
|
260
|
+
NumberInput: ({ amount, minValue, maxValue, getAmountValue, itemCallback, }: {
|
|
261
|
+
amount?: number | undefined;
|
|
262
|
+
itemCallback?: ((amount?: number | undefined, isVariant?: boolean | undefined) => void) | undefined;
|
|
263
|
+
getAmountValue?: ((amount?: number | undefined) => void) | undefined;
|
|
264
|
+
minValue?: number | undefined;
|
|
265
|
+
maxValue?: number | undefined;
|
|
266
|
+
}) => _emotion_react_jsx_runtime.JSX.Element;
|
|
267
|
+
Unit: ({ amount, itemCallback, getAmountValue, unit, }: {
|
|
268
|
+
amount?: number | undefined;
|
|
269
|
+
itemCallback?: ((amount?: number | undefined, isVariant?: boolean | undefined) => void) | undefined;
|
|
270
|
+
getAmountValue?: ((amount?: number | undefined) => void) | undefined;
|
|
271
|
+
unit?: string | undefined;
|
|
272
|
+
}) => _emotion_react_jsx_runtime.JSX.Element;
|
|
273
|
+
Strong: ({ variant, children, isDisabledOnOverlay, }: {
|
|
274
|
+
variant?: "big" | "small" | "normal" | "capitalized" | undefined;
|
|
275
|
+
children?: ReactNode;
|
|
276
|
+
isDisabledOnOverlay?: boolean | undefined;
|
|
277
|
+
}) => _emotion_react_jsx_runtime.JSX.Element;
|
|
278
|
+
Regular: ({ variant, isDisabledOnOverlay, children, className, }: {
|
|
279
|
+
variant?: "big" | "small" | "normal" | "capitalized" | undefined;
|
|
280
|
+
isDisabledOnOverlay?: boolean | undefined;
|
|
281
|
+
children?: ReactNode;
|
|
282
|
+
className?: string | undefined;
|
|
283
|
+
}) => _emotion_react_jsx_runtime.JSX.Element | null;
|
|
284
|
+
Image: _emotion_styled.StyledComponent<{
|
|
285
|
+
theme?: _emotion_react.Theme | undefined;
|
|
286
|
+
as?: react.ElementType<any> | undefined;
|
|
287
|
+
}, react.DetailedHTMLProps<react.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, {}>;
|
|
288
|
+
Region: ({ label, image, shouldBeHidden, priceText, animated, isFirstElement, isLastElement, productsCallback, iteration, discount, }: {
|
|
289
|
+
shouldBeHidden?: boolean | undefined;
|
|
290
|
+
priceText?: ReactNode;
|
|
291
|
+
animated?: boolean | undefined;
|
|
292
|
+
isFirstElement?: boolean | undefined;
|
|
293
|
+
isLastElement?: boolean | undefined;
|
|
294
|
+
productsCallback?: {
|
|
295
|
+
add: (product: EstimateProduct) => void;
|
|
296
|
+
remove: (product: BareEstimateProduct) => void;
|
|
297
|
+
} | undefined;
|
|
298
|
+
iteration?: Iteration | undefined;
|
|
299
|
+
discount?: number | undefined;
|
|
300
|
+
label: string;
|
|
301
|
+
image: string;
|
|
302
|
+
}) => _emotion_react_jsx_runtime.JSX.Element;
|
|
303
|
+
Zone: ({ label, image, shouldBeHidden, priceText, animated, isFirstElement, isLastElement, productsCallback, iteration, discount, }: {
|
|
304
|
+
shouldBeHidden?: boolean | undefined;
|
|
305
|
+
priceText?: string | undefined;
|
|
306
|
+
animated?: boolean | undefined;
|
|
307
|
+
isFirstElement?: boolean | undefined;
|
|
308
|
+
isLastElement?: boolean | undefined;
|
|
309
|
+
productsCallback?: {
|
|
310
|
+
add: (product: EstimateProduct) => void;
|
|
311
|
+
remove: (product: BareEstimateProduct) => void;
|
|
312
|
+
} | undefined;
|
|
313
|
+
iteration?: Iteration | undefined;
|
|
314
|
+
discount?: number | undefined;
|
|
315
|
+
label: string;
|
|
316
|
+
image: string;
|
|
317
|
+
}) => _emotion_react_jsx_runtime.JSX.Element;
|
|
318
|
+
Ellipsis: ({ children, maxWidth, "data-testid": dataTestId, }: {
|
|
319
|
+
children: ReactNode;
|
|
320
|
+
maxWidth?: number | undefined;
|
|
321
|
+
'data-testid'?: string | undefined;
|
|
322
|
+
}) => _emotion_react_jsx_runtime.JSX.Element;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
export { CodeEditor, ContentCard, ContentCardGroup, EstimateCost, _default as estimateCostDefaultLocales };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useEstimateCost } from '../EstimateCostProvider.js';
|
|
3
|
+
import { UnitInput } from './UnitInput.js';
|
|
4
|
+
import { jsx } from '@emotion/react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
const CustomUnitInput = _ref => {
|
|
7
|
+
let {
|
|
8
|
+
defaultTimeUnit = 'hours',
|
|
9
|
+
setIteration,
|
|
10
|
+
iteration,
|
|
11
|
+
timeUnits
|
|
12
|
+
} = _ref;
|
|
13
|
+
const {
|
|
14
|
+
locales
|
|
15
|
+
} = useEstimateCost();
|
|
16
|
+
const options = useMemo(() => timeUnits.map(unit => ({
|
|
17
|
+
value: unit,
|
|
18
|
+
label: locales[`estimate.cost.units.${unit}.label`]
|
|
19
|
+
})), [timeUnits, locales]);
|
|
20
|
+
const defaultOption = useMemo(() => options.find(_ref2 => {
|
|
21
|
+
let {
|
|
22
|
+
value
|
|
23
|
+
} = _ref2;
|
|
24
|
+
return value === defaultTimeUnit;
|
|
25
|
+
}), [defaultTimeUnit, options]);
|
|
26
|
+
return jsx(UnitInput, {
|
|
27
|
+
name: "iteration",
|
|
28
|
+
onChange: inputValue => setIteration({
|
|
29
|
+
unit: iteration.unit,
|
|
30
|
+
value: inputValue
|
|
31
|
+
}),
|
|
32
|
+
onChangeUnitValue: unitValue => {
|
|
33
|
+
setIteration({
|
|
34
|
+
unit: unitValue,
|
|
35
|
+
value: iteration.value
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
placeholder: "0",
|
|
39
|
+
value: iteration.value,
|
|
40
|
+
unitValue: iteration.unit || defaultOption?.value,
|
|
41
|
+
minValue: 1,
|
|
42
|
+
size: "medium",
|
|
43
|
+
options: options,
|
|
44
|
+
selectInputWidth: 300
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export { CustomUnitInput };
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import _styled from '@emotion/styled/base';
|
|
2
|
+
import { css } from '@emotion/react';
|
|
3
|
+
import { Text, Tooltip, Stack, Icon, zoomIn, Badge } from '@ultraviolet/ui';
|
|
4
|
+
import { useMemo, useState, useEffect, useCallback, useId, Children, isValidElement, cloneElement } from 'react';
|
|
5
|
+
import flattenChildren from 'react-flatten-children';
|
|
6
|
+
import { useEstimateCost } from '../EstimateCostProvider.js';
|
|
7
|
+
import { useOverlay } from '../OverlayContext.js';
|
|
8
|
+
import { Cell, StyledDiv, PriceCell, OverlayRow, StyledLeftSide } from '../componentStyle.js';
|
|
9
|
+
import { multiplier, maximumFractionDigitsLong, maximumFractionDigits, MAX_CELL_WIDTH } from '../constants.js';
|
|
10
|
+
import { calculatePrice } from '../helper.js';
|
|
11
|
+
import { jsxs, jsx, Fragment } from '@emotion/react/jsx-runtime';
|
|
12
|
+
|
|
13
|
+
function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
|
|
14
|
+
const TIME_RELATED_UNIT = ['seconds', 'minutes', 'hours', 'days', 'months'];
|
|
15
|
+
const StyledResourceName = /*#__PURE__*/_styled('div', {
|
|
16
|
+
shouldForwardProp: prop => !['isOverlay', 'animated'].includes(prop),
|
|
17
|
+
target: "e1kzy2rr7"
|
|
18
|
+
})("text-align:", _ref => {
|
|
19
|
+
let {
|
|
20
|
+
isOverlay
|
|
21
|
+
} = _ref;
|
|
22
|
+
return isOverlay ? 'initial' : 'right';
|
|
23
|
+
}, ";", _ref2 => {
|
|
24
|
+
let {
|
|
25
|
+
isOverlay,
|
|
26
|
+
animated
|
|
27
|
+
} = _ref2;
|
|
28
|
+
return isOverlay ? /*#__PURE__*/css("height:48px;display:flex;flex-direction:column;-webkit-box-pack:center;justify-content:center;animation:", animated ? /*#__PURE__*/css("800ms ", zoomIn, ";") : '', ";") : null;
|
|
29
|
+
}, ";");
|
|
30
|
+
const StyledBadge = /*#__PURE__*/_styled(Badge, {
|
|
31
|
+
target: "e1kzy2rr6"
|
|
32
|
+
})("margin-left:", _ref3 => {
|
|
33
|
+
let {
|
|
34
|
+
theme
|
|
35
|
+
} = _ref3;
|
|
36
|
+
return theme.space['1'];
|
|
37
|
+
}, ";align-self:center;");
|
|
38
|
+
const StyledText = /*#__PURE__*/_styled(Text, {
|
|
39
|
+
target: "e1kzy2rr5"
|
|
40
|
+
})("margin-left:", _ref4 => {
|
|
41
|
+
let {
|
|
42
|
+
theme
|
|
43
|
+
} = _ref4;
|
|
44
|
+
return theme.space['1'];
|
|
45
|
+
}, ";");
|
|
46
|
+
const MaxWidthText = /*#__PURE__*/_styled(Text, {
|
|
47
|
+
target: "e1kzy2rr4"
|
|
48
|
+
})(process.env.NODE_ENV === "production" ? {
|
|
49
|
+
name: "88bww",
|
|
50
|
+
styles: "max-width:75%"
|
|
51
|
+
} : {
|
|
52
|
+
name: "88bww",
|
|
53
|
+
styles: "max-width:75%",
|
|
54
|
+
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
|
|
55
|
+
});
|
|
56
|
+
const TextAlignRight = /*#__PURE__*/_styled(Text, {
|
|
57
|
+
target: "e1kzy2rr3"
|
|
58
|
+
})(process.env.NODE_ENV === "production" ? {
|
|
59
|
+
name: "2qga7i",
|
|
60
|
+
styles: "text-align:right"
|
|
61
|
+
} : {
|
|
62
|
+
name: "2qga7i",
|
|
63
|
+
styles: "text-align:right",
|
|
64
|
+
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
|
|
65
|
+
});
|
|
66
|
+
const StyledTooltip = /*#__PURE__*/_styled(Tooltip, {
|
|
67
|
+
target: "e1kzy2rr2"
|
|
68
|
+
})(process.env.NODE_ENV === "production" ? {
|
|
69
|
+
name: "uaxjgr",
|
|
70
|
+
styles: "vertical-align:text-top"
|
|
71
|
+
} : {
|
|
72
|
+
name: "uaxjgr",
|
|
73
|
+
styles: "vertical-align:text-top",
|
|
74
|
+
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
|
|
75
|
+
});
|
|
76
|
+
const StyledPriceCell = /*#__PURE__*/_styled(Cell, {
|
|
77
|
+
target: "e1kzy2rr1"
|
|
78
|
+
})(_ref5 => {
|
|
79
|
+
let {
|
|
80
|
+
theme
|
|
81
|
+
} = _ref5;
|
|
82
|
+
return PriceCell(theme);
|
|
83
|
+
}, ";");
|
|
84
|
+
const StyleNoPriceItem = /*#__PURE__*/_styled(Text, {
|
|
85
|
+
target: "e1kzy2rr0"
|
|
86
|
+
})(process.env.NODE_ENV === "production" ? {
|
|
87
|
+
name: "2qga7i",
|
|
88
|
+
styles: "text-align:right"
|
|
89
|
+
} : {
|
|
90
|
+
name: "2qga7i",
|
|
91
|
+
styles: "text-align:right",
|
|
92
|
+
toString: _EMOTION_STRINGIFIED_CSS_ERROR__
|
|
93
|
+
});
|
|
94
|
+
const Item = _ref6 => {
|
|
95
|
+
let {
|
|
96
|
+
discount = 0,
|
|
97
|
+
priceText,
|
|
98
|
+
discountText,
|
|
99
|
+
label,
|
|
100
|
+
tooltipInfo,
|
|
101
|
+
// Shows an icon with tooltip that contains this text
|
|
102
|
+
subLabel = '',
|
|
103
|
+
// Usually used for showing amount that is free
|
|
104
|
+
price: basePrice = 0,
|
|
105
|
+
// Hourly price for one unit
|
|
106
|
+
monthlyPrice = 0,
|
|
107
|
+
// Price per month
|
|
108
|
+
unit: baseUnit,
|
|
109
|
+
// Can be GB, MB, Node, Queries, etc.
|
|
110
|
+
amount: currentAmount = 1,
|
|
111
|
+
// Current number of items
|
|
112
|
+
onAmountChange,
|
|
113
|
+
amountFree = 0,
|
|
114
|
+
// Amount that is free - offered by company
|
|
115
|
+
maxAmount = 0,
|
|
116
|
+
// Max amount - used for kubernetes for example
|
|
117
|
+
longFractionDigits = false,
|
|
118
|
+
// In case price is really long 0.0000076 - up 7 fraction digits
|
|
119
|
+
noIteration = false,
|
|
120
|
+
// if item is not based on time (ex: download, upload, transfer)
|
|
121
|
+
noIterationText,
|
|
122
|
+
noBorder,
|
|
123
|
+
// remove the border bottom of the item
|
|
124
|
+
noPrice,
|
|
125
|
+
// remove the price on right side of the table
|
|
126
|
+
isDefined = true,
|
|
127
|
+
children = null,
|
|
128
|
+
isFirstElement = false,
|
|
129
|
+
isLastElement = false,
|
|
130
|
+
isPrimaryBackground = false,
|
|
131
|
+
productsCallback,
|
|
132
|
+
iteration: receivedIteration,
|
|
133
|
+
// Object from parent that contains time period (hours, days, months)
|
|
134
|
+
shouldBeHidden = false,
|
|
135
|
+
// Hide element from overlay if screen width is small
|
|
136
|
+
hideFromOverlay = false,
|
|
137
|
+
// Hide element from overlay in any case
|
|
138
|
+
textNotDefined,
|
|
139
|
+
// Text to display in case of not defined value
|
|
140
|
+
animated = false,
|
|
141
|
+
// if true, zoomIn animation is triggered
|
|
142
|
+
tabulation,
|
|
143
|
+
// Increase left padding of the item
|
|
144
|
+
labelTextVariant,
|
|
145
|
+
// To change left cell typography variant
|
|
146
|
+
labelTextProminence,
|
|
147
|
+
// To change left cell typography prominence
|
|
148
|
+
notice // To display a gray text below the label
|
|
149
|
+
} = _ref6;
|
|
150
|
+
const {
|
|
151
|
+
locales,
|
|
152
|
+
formatNumber
|
|
153
|
+
} = useEstimateCost();
|
|
154
|
+
let iteration;
|
|
155
|
+
if (noIteration) {
|
|
156
|
+
iteration = {
|
|
157
|
+
...(receivedIteration ?? {
|
|
158
|
+
value: 0
|
|
159
|
+
}),
|
|
160
|
+
unit: 'hours'
|
|
161
|
+
};
|
|
162
|
+
} else {
|
|
163
|
+
iteration = receivedIteration;
|
|
164
|
+
}
|
|
165
|
+
const price = useMemo(() => {
|
|
166
|
+
if (monthlyPrice > 0 && basePrice === 0) {
|
|
167
|
+
return monthlyPrice / multiplier.months;
|
|
168
|
+
}
|
|
169
|
+
return basePrice;
|
|
170
|
+
}, [basePrice, monthlyPrice]);
|
|
171
|
+
const unit = useMemo(() => {
|
|
172
|
+
if (!baseUnit) {
|
|
173
|
+
return locales['estimate.cost.units.gb.label'];
|
|
174
|
+
}
|
|
175
|
+
return baseUnit;
|
|
176
|
+
}, [baseUnit, locales]);
|
|
177
|
+
const {
|
|
178
|
+
isOverlay
|
|
179
|
+
} = useOverlay();
|
|
180
|
+
const Row = isOverlay ? OverlayRow : 'tr';
|
|
181
|
+
const Cell$1 = isOverlay ? Cell.withComponent('div', {
|
|
182
|
+
target: "e1kzy2rr8"
|
|
183
|
+
}) : Cell;
|
|
184
|
+
const LeftSide = isOverlay ? 'div' : StyledLeftSide;
|
|
185
|
+
const [amount, setAmount] = useState(currentAmount);
|
|
186
|
+
const [isVariant, setIsVariant] = useState(false);
|
|
187
|
+
useEffect(() => setAmount(currentAmount), [setAmount, currentAmount]);
|
|
188
|
+
useEffect(() => onAmountChange?.(amount), [onAmountChange, amount]);
|
|
189
|
+
const itemCallback = useCallback((localAmount, localIsVariant) => {
|
|
190
|
+
setAmount(localAmount);
|
|
191
|
+
setIsVariant(localIsVariant);
|
|
192
|
+
}, [setAmount, setIsVariant]);
|
|
193
|
+
const id = useId();
|
|
194
|
+
|
|
195
|
+
// We remove Item from object list when Iem component unmount to avoid duplicates
|
|
196
|
+
useEffect(() => () => productsCallback?.remove({
|
|
197
|
+
id
|
|
198
|
+
}), [id, productsCallback]);
|
|
199
|
+
useEffect(() => {
|
|
200
|
+
if (!isOverlay) {
|
|
201
|
+
productsCallback?.add({
|
|
202
|
+
id,
|
|
203
|
+
amount,
|
|
204
|
+
price,
|
|
205
|
+
amountFree,
|
|
206
|
+
isVariant,
|
|
207
|
+
maxAmount,
|
|
208
|
+
noIteration,
|
|
209
|
+
longFractionDigits,
|
|
210
|
+
discount
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}, [price, discount, amount, id, productsCallback, maxAmount, noIteration, isVariant, amountFree, isOverlay, longFractionDigits]);
|
|
214
|
+
const computedItemPrice = useMemo(() => calculatePrice({
|
|
215
|
+
price,
|
|
216
|
+
amount,
|
|
217
|
+
amountFree,
|
|
218
|
+
timeUnit: noIteration ? 'hours' : iteration?.unit ?? 'hours',
|
|
219
|
+
timeAmount: noIteration ? 1 : iteration?.value ?? 1,
|
|
220
|
+
discount
|
|
221
|
+
}), [price, amount, amountFree, iteration, noIteration, discount]);
|
|
222
|
+
const computedMaxItemPrice = useMemo(() => calculatePrice({
|
|
223
|
+
price,
|
|
224
|
+
amount: maxAmount,
|
|
225
|
+
amountFree,
|
|
226
|
+
timeUnit: noIteration ? 'hours' : iteration?.unit ?? 'hours',
|
|
227
|
+
timeAmount: noIteration ? 1 : iteration?.value ?? 1,
|
|
228
|
+
discount
|
|
229
|
+
}), [price, maxAmount, amountFree, iteration, noIteration, discount]);
|
|
230
|
+
const formatMaximumFractionDigits = useMemo(() => {
|
|
231
|
+
if (!iteration?.unit) {
|
|
232
|
+
return undefined;
|
|
233
|
+
}
|
|
234
|
+
return longFractionDigits ? maximumFractionDigitsLong[iteration?.unit] : maximumFractionDigits[iteration?.unit];
|
|
235
|
+
}, [iteration?.unit, longFractionDigits]);
|
|
236
|
+
return jsxs(Row, {
|
|
237
|
+
isFirstElement: isFirstElement,
|
|
238
|
+
shouldBeHidden: shouldBeHidden,
|
|
239
|
+
hideFromOverlay: hideFromOverlay,
|
|
240
|
+
children: [jsx(Cell$1, {
|
|
241
|
+
width: !isOverlay ? MAX_CELL_WIDTH : 'inherit',
|
|
242
|
+
hasBorder: !isLastElement && !noBorder && !isOverlay,
|
|
243
|
+
tabulation: tabulation,
|
|
244
|
+
children: jsxs(LeftSide, {
|
|
245
|
+
children: [jsxs(Stack, {
|
|
246
|
+
children: [jsxs(Stack, {
|
|
247
|
+
direction: "row",
|
|
248
|
+
children: [jsx(Text, {
|
|
249
|
+
as: "p",
|
|
250
|
+
variant: labelTextVariant ?? 'body',
|
|
251
|
+
prominence: labelTextProminence ?? 'default',
|
|
252
|
+
children: label
|
|
253
|
+
}), tooltipInfo ? jsx(StyledDiv, {
|
|
254
|
+
children: jsx(StyledTooltip, {
|
|
255
|
+
text: tooltipInfo,
|
|
256
|
+
children: jsx(Icon, {
|
|
257
|
+
name: "help-circle-outline",
|
|
258
|
+
size: 20
|
|
259
|
+
})
|
|
260
|
+
})
|
|
261
|
+
}) : null, subLabel && !isOverlay ? jsx(StyledText, {
|
|
262
|
+
as: "p",
|
|
263
|
+
variant: "body",
|
|
264
|
+
color: "primary",
|
|
265
|
+
italic: true,
|
|
266
|
+
children: subLabel
|
|
267
|
+
}) : null, discount > 0 && discountText ? jsx(StyledBadge, {
|
|
268
|
+
prominence: "strong",
|
|
269
|
+
size: "small",
|
|
270
|
+
sentiment: "warning",
|
|
271
|
+
children: discountText
|
|
272
|
+
}) : null]
|
|
273
|
+
}), notice ? jsx(MaxWidthText, {
|
|
274
|
+
as: "p",
|
|
275
|
+
variant: "caption",
|
|
276
|
+
prominence: "weak",
|
|
277
|
+
children: notice
|
|
278
|
+
}) : null]
|
|
279
|
+
}), jsx(StyledResourceName, {
|
|
280
|
+
isOverlay: isOverlay,
|
|
281
|
+
animated: animated,
|
|
282
|
+
children: isDefined ? Children.map(flattenChildren(children), child => /*#__PURE__*/isValidElement(child) ? /*#__PURE__*/cloneElement(child, {
|
|
283
|
+
itemCallback,
|
|
284
|
+
amount,
|
|
285
|
+
maxAmount,
|
|
286
|
+
unit
|
|
287
|
+
}) : null) : textNotDefined || locales['estimate.cost.notDefined']
|
|
288
|
+
})]
|
|
289
|
+
})
|
|
290
|
+
}), !isOverlay ? jsx(StyledPriceCell, {
|
|
291
|
+
hasBorder: !isLastElement && !noBorder,
|
|
292
|
+
primary: isPrimaryBackground,
|
|
293
|
+
children: !noPrice ? jsxs(Fragment, {
|
|
294
|
+
children: [jsxs(StyleNoPriceItem, {
|
|
295
|
+
as: "p",
|
|
296
|
+
variant: noIterationText ? 'headingSmall' : 'bodyStrong',
|
|
297
|
+
prominence: computedItemPrice === 0 && computedMaxItemPrice === 0 ? 'weak' : 'default',
|
|
298
|
+
color: computedItemPrice === 0 && computedMaxItemPrice === 0 ? 'neutral' : 'primary',
|
|
299
|
+
children: [priceText, !priceText ? formatNumber(computedItemPrice, {
|
|
300
|
+
maximumFractionDigits: formatMaximumFractionDigits
|
|
301
|
+
}) : null, noIterationText ? jsxs(Text, {
|
|
302
|
+
sentiment: "primary",
|
|
303
|
+
as: "span",
|
|
304
|
+
variant: "bodySmall",
|
|
305
|
+
children: ["/", noIterationText]
|
|
306
|
+
}) : null, !priceText && computedMaxItemPrice > 0 ? ` - ${formatNumber(computedMaxItemPrice, {
|
|
307
|
+
maximumFractionDigits: formatMaximumFractionDigits
|
|
308
|
+
})}` : null]
|
|
309
|
+
}), amount - amountFree !== 1 && computedItemPrice > 0 || maxAmount > 0 && computedMaxItemPrice > 0 ? jsxs(TextAlignRight, {
|
|
310
|
+
as: "p",
|
|
311
|
+
variant: "body",
|
|
312
|
+
children: [formatNumber(calculatePrice({
|
|
313
|
+
price,
|
|
314
|
+
amount: 1,
|
|
315
|
+
timeUnit: 'hours',
|
|
316
|
+
timeAmount: 1,
|
|
317
|
+
discount
|
|
318
|
+
}), {
|
|
319
|
+
maximumFractionDigits: longFractionDigits ? maximumFractionDigitsLong.hours : maximumFractionDigits.hours
|
|
320
|
+
}), TIME_RELATED_UNIT.includes(unit) ? locales[`estimate.cost.units.${unit}.label`].toLowerCase() : `/${unit}`, !noIteration ? `/${locales['estimate.cost.units.hours.label'].toLowerCase()}` : null]
|
|
321
|
+
}) : null]
|
|
322
|
+
}) : null
|
|
323
|
+
}) : null]
|
|
324
|
+
});
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
export { Item };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import _styled from '@emotion/styled/base';
|
|
2
|
+
import { css } from '@emotion/react';
|
|
3
|
+
|
|
4
|
+
const LineThrough = /*#__PURE__*/_styled('span', {
|
|
5
|
+
shouldForwardProp: prop => !['isActive'].includes(prop),
|
|
6
|
+
target: "e1d1k6i0"
|
|
7
|
+
})(_ref => {
|
|
8
|
+
let {
|
|
9
|
+
isActive,
|
|
10
|
+
theme
|
|
11
|
+
} = _ref;
|
|
12
|
+
return isActive ? /*#__PURE__*/css("text-decoration-line:line-through;text-decoration-color:", theme.colors.warning.border, ";") : null;
|
|
13
|
+
}, ";");
|
|
14
|
+
|
|
15
|
+
export { LineThrough };
|