diff --git a/frontend/src/container/IngestionSettings/IngestionSettings.styles.scss b/frontend/src/container/IngestionSettings/IngestionSettings.styles.scss index c98c6884fd..acf7b238f4 100644 --- a/frontend/src/container/IngestionSettings/IngestionSettings.styles.scss +++ b/frontend/src/container/IngestionSettings/IngestionSettings.styles.scss @@ -18,8 +18,13 @@ font-style: normal; font-weight: var(--font-weight-normal); line-height: 28px; - /* 155.556% */ letter-spacing: -0.09px; + + width: 72%; // arbitrary number to match input width + display: flex; + align-items: center; + gap: 8px; + justify-content: space-between; } .subtitle { @@ -356,6 +361,8 @@ flex: 1; .heading { + margin-bottom: 8px; + .title { font-size: 12px; } @@ -370,6 +377,18 @@ .ant-input-number { width: 80%; } + + .no-limit { + display: flex; + align-items: center; + gap: 8px; + + margin-bottom: 24px; + + font-weight: 700; + font-size: 12px; + color: var(--bg-forest-400); + } } .signal-limit-view-mode { diff --git a/frontend/src/container/IngestionSettings/MultiIngestionSettings.tsx b/frontend/src/container/IngestionSettings/MultiIngestionSettings.tsx index 0355d069fb..b6e744ccaf 100644 --- a/frontend/src/container/IngestionSettings/MultiIngestionSettings.tsx +++ b/frontend/src/container/IngestionSettings/MultiIngestionSettings.tsx @@ -12,6 +12,7 @@ import { Modal, Row, Select, + Switch, Table, TablePaginationConfig, TableProps as AntDTableProps, @@ -34,7 +35,7 @@ import dayjs, { Dayjs } from 'dayjs'; import { useGetAllIngestionsKeys } from 'hooks/IngestionKeys/useGetAllIngestionKeys'; import useDebouncedFn from 'hooks/useDebouncedFunction'; import { useNotifications } from 'hooks/useNotifications'; -import { isNil } from 'lodash-es'; +import { isNil, isUndefined } from 'lodash-es'; import { ArrowUpRight, CalendarClock, @@ -395,84 +396,6 @@ function MultiIngestionSettings(): JSX.Element { const getFormattedTime = (date: string): string => dayjs(date).format('MMM DD,YYYY, hh:mm a'); - const handleAddLimit = ( - APIKey: IngestionKeyProps, - signalName: string, - ): void => { - setActiveSignal({ - id: signalName, - signal: signalName, - config: {}, - }); - - const { dailyLimit, secondsLimit } = addEditLimitForm.getFieldsValue(); - - const payload = { - keyID: APIKey.id, - signal: signalName, - config: { - day: { - size: gbToBytes(dailyLimit), - }, - second: { - size: gbToBytes(secondsLimit), - }, - }, - }; - - createLimitForIngestionKey(payload); - }; - - const handleUpdateLimit = ( - APIKey: IngestionKeyProps, - signal: LimitProps, - ): void => { - setActiveSignal(signal); - const { dailyLimit, secondsLimit } = addEditLimitForm.getFieldsValue(); - const payload = { - limitID: signal.id, - signal: signal.signal, - config: { - day: { - size: gbToBytes(dailyLimit), - }, - second: { - size: gbToBytes(secondsLimit), - }, - }, - }; - updateLimitForIngestionKey(payload); - }; - - const bytesToGb = (size: number | undefined): number => { - if (!size) { - return 0; - } - - return size / BYTES; - }; - - const enableEditLimitMode = ( - APIKey: IngestionKeyProps, - signal: LimitProps, - ): void => { - setActiveAPIKey(APIKey); - setActiveSignal(signal); - - addEditLimitForm.setFieldsValue({ - dailyLimit: bytesToGb(signal?.config?.day?.size || 0), - secondsLimit: bytesToGb(signal?.config?.second?.size || 0), - }); - - setIsEditAddLimitOpen(true); - }; - - const onDeleteLimitHandler = (): void => { - if (activeSignal && activeSignal?.id) { - deleteLimitForKey(activeSignal.id); - } - }; - const showDeleteLimitModal = ( APIKey: IngestionKeyProps, limit: LimitProps, @@ -496,6 +419,131 @@ function MultiIngestionSettings(): JSX.Element { addEditLimitForm.resetFields(); }; + const handleAddLimit = ( + APIKey: IngestionKeyProps, + signalName: string, + ): void => { + const { dailyLimit, secondsLimit } = addEditLimitForm.getFieldsValue(); + + const payload = { + keyID: APIKey.id, + signal: signalName, + config: {}, + }; + + if (!isUndefined(dailyLimit)) { + payload.config = { + day: { + size: gbToBytes(dailyLimit), + }, + }; + } + + if (!isUndefined(secondsLimit)) { + payload.config = { + ...payload.config, + second: { + size: gbToBytes(secondsLimit), + }, + }; + } + + if (isUndefined(dailyLimit) && isUndefined(secondsLimit)) { + // No need to save as no limit is provided, close the edit view and reset active signal and api key + setActiveSignal(null); + setActiveAPIKey(null); + setIsEditAddLimitOpen(false); + setUpdatedTags([]); + hideAddViewModal(); + setHasCreateLimitForIngestionKeyError(false); + + return; + } + + createLimitForIngestionKey(payload); + }; + + const handleUpdateLimit = ( + APIKey: IngestionKeyProps, + signal: LimitProps, + ): void => { + const { dailyLimit, secondsLimit } = addEditLimitForm.getFieldsValue(); + const payload = { + limitID: signal.id, + signal: signal.signal, + config: {}, + }; + + if (isUndefined(dailyLimit) && isUndefined(secondsLimit)) { + showDeleteLimitModal(APIKey, signal); + + return; + } + + if (!isUndefined(dailyLimit)) { + payload.config = { + day: { + size: gbToBytes(dailyLimit), + }, + }; + } + + if (!isUndefined(secondsLimit)) { + payload.config = { + ...payload.config, + second: { + size: gbToBytes(secondsLimit), + }, + }; + } + + updateLimitForIngestionKey(payload); + }; + + const bytesToGb = (size: number | undefined): number => { + if (!size) { + return 0; + } + + return size / BYTES; + }; + + const enableEditLimitMode = ( + APIKey: IngestionKeyProps, + signal: LimitProps, + ): void => { + setActiveAPIKey(APIKey); + setActiveSignal({ + ...signal, + config: { + ...signal.config, + day: { + ...signal.config?.day, + enabled: !isNil(signal?.config?.day?.size), + }, + second: { + ...signal.config?.second, + enabled: !isNil(signal?.config?.second?.size), + }, + }, + }); + + addEditLimitForm.setFieldsValue({ + dailyLimit: bytesToGb(signal?.config?.day?.size || 0), + secondsLimit: bytesToGb(signal?.config?.second?.size || 0), + enableDailyLimit: !isNil(signal?.config?.day?.size), + enableSecondLimit: !isNil(signal?.config?.second?.size), + }); + + setIsEditAddLimitOpen(true); + }; + + const onDeleteLimitHandler = (): void => { + if (activeSignal && activeSignal?.id) { + deleteLimitForKey(activeSignal.id); + } + }; + const columns: AntDTableProps['columns'] = [ { title: 'Ingestion Key', @@ -684,50 +732,108 @@ function MultiIngestionSettings(): JSX.Element {
-
Daily limit
+
+ Daily limit +
+ + { + setActiveSignal({ + ...activeSignal, + config: { + ...activeSignal.config, + day: { + ...activeSignal.config?.day, + enabled: value, + }, + }, + }); + }} + /> + +
+
- Add a limit for data ingested daily{' '} + Add a limit for data ingested daily
-
- - - - - - - - } - /> - + {activeSignal?.config?.day?.enabled ? ( + + + + + + + + } + /> + + ) : ( +
+ NO LIMIT +
+ )}
-
Per Second limit
+
+ Per Second limit{' '} +
+ + { + setActiveSignal({ + ...activeSignal, + config: { + ...activeSignal.config, + second: { + ...activeSignal.config?.second, + enabled: value, + }, + }, + }); + }} + /> + +
+
- {' '} - Add a limit for data ingested every second{' '} + Add a limit for data ingested every second
- - - - - - - - } - /> - + {activeSignal?.config?.second?.enabled ? ( + + + + + + + + } + /> + + ) : ( +
+ NO LIMIT +
+ )}
diff --git a/frontend/src/types/api/ingestionKeys/limits/types.ts b/frontend/src/types/api/ingestionKeys/limits/types.ts index 279ec157d5..697fb7ebf2 100644 --- a/frontend/src/types/api/ingestionKeys/limits/types.ts +++ b/frontend/src/types/api/ingestionKeys/limits/types.ts @@ -8,17 +8,21 @@ export interface LimitProps { config?: { day?: { size?: number; + enabled?: boolean; }; second?: { size?: number; + enabled?: boolean; }; }; metric?: { day?: { size?: number; + enabled?: boolean; }; second?: { size?: number; + enabled?: boolean; }; }; } @@ -27,11 +31,13 @@ export interface AddLimitProps { keyID: string; signal: string; config: { - day: { - size: number; + day?: { + size?: number; + enabled?: boolean; }; - second: { - size: number; + second?: { + size?: number; + enabled?: boolean; }; }; } @@ -40,11 +46,13 @@ export interface UpdateLimitProps { limitID: string; signal: string; config: { - day: { - size: number; + day?: { + size?: number; + enabled?: boolean; }; - second: { - size: number; + second?: { + size?: number; + enabled?: boolean; }; }; }