diff --git a/.env b/.env index b165595..9dd9939 100644 --- a/.env +++ b/.env @@ -1,2 +1,5 @@ VITE_API_BASE_URL=http://127.0.0.1:3000/v1 -VITE_DEV_BASE_URL=http://127.0.0.1:3002/api \ No newline at end of file +VITE_DEV_BASE_URL=http://127.0.0.1:3002/api + +## enables choosing units and lisenced account call limits +# VITE_APP_ENABLE_ACCOUNT_LIMITS_ALL=true \ No newline at end of file diff --git a/src/api/constants.ts b/src/api/constants.ts index 53c67c5..f962de5 100644 --- a/src/api/constants.ts +++ b/src/api/constants.ts @@ -1,5 +1,6 @@ import type { LimitField, + LimitUnitOption, PasswordSettings, SipGateway, SmppGateway, @@ -123,10 +124,9 @@ export const WEBHOOK_METHODS: WebhookOption[] = [ ]; /** Various system limits */ -/** For now we are only supporting `voice_call_session` */ export const LIMITS: LimitField[] = [ { - label: "Max concurrent calls (0=unlimited)", + label: "Max calls", category: "voice_call_session", }, // { @@ -137,6 +137,32 @@ export const LIMITS: LimitField[] = [ // label: "Max api calls per minute (0=unlimited)", // category: "api_rate", // }, + { + label: "Licensed calls", + category: "voice_call_session_license", + }, + { + label: "Max minutes", + category: "voice_call_minutes", + }, + { + label: "Licensed minutes", + category: "voice_call_minutes_license", + }, +]; + +export const LIMIT_MINS = "minutes"; +export const LIMIT_SESS = "sessions"; + +export const LIMIT_UNITS: LimitUnitOption[] = [ + { + name: "Sessions", + value: LIMIT_SESS, + }, + { + name: "Minutes", + value: LIMIT_MINS, + }, ]; export const DEFAULT_PSWD_SETTINGS: PasswordSettings = { diff --git a/src/api/types.ts b/src/api/types.ts index dc424cf..623ad1b 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -8,10 +8,22 @@ export type CredentialStatus = "ok" | "fail" | "not tested"; export type IpType = "ip" | "fqdn" | "fqdn-top-level" | "invalid"; -export type LimitCategories = "api_rate" | "voice_call_session" | "device"; +export type LimitCategories = + | "api_rate" + | "voice_call_session" + | "device" + | "voice_call_minutes_license" + | "voice_call_minutes" + | "voice_call_session_license"; + +export type LimitUnit = "Sessions" | "Minutes"; + +export interface LimitUnitOption { + name: LimitUnit; + value: Lowercase; +} /** User roles / permissions */ - export type UserScopes = "admin" | "service_provider" | "account"; export type UserPermissions = diff --git a/src/components/forms/local-limits.tsx b/src/components/forms/local-limits.tsx index 624d428..21cae23 100644 --- a/src/components/forms/local-limits.tsx +++ b/src/components/forms/local-limits.tsx @@ -1,9 +1,10 @@ -import React, { useEffect, useRef } from "react"; +import React, { useEffect, useRef, useState } from "react"; -import { LIMITS } from "src/api/constants"; +import { LIMITS, LIMIT_MINS, LIMIT_SESS, LIMIT_UNITS } from "src/api/constants"; import { hasLength } from "src/utils"; -import type { Limit, LimitCategories } from "src/api/types"; +import type { Limit, LimitCategories, LimitUnit } from "src/api/types"; +import { Selector } from "./selector"; type LocalLimitRef = { [key in LimitCategories]?: HTMLInputElement; @@ -25,6 +26,8 @@ export const LocalLimits = ({ limits: [localLimits, setLocalLimits], inputRef, }: LocalLimitsProps) => { + const [unit, setUnit] = useState>(LIMIT_SESS); + const updateLimitValue = (category: string) => { if (hasLength(localLimits)) { const limit = localLimits.find((l) => l.category === category); @@ -35,6 +38,18 @@ export const LocalLimits = ({ return ""; }; + const filteredLimits = import.meta.env.VITE_APP_ENABLE_ACCOUNT_LIMITS_ALL + ? LIMITS.filter((limit) => + unit === LIMIT_SESS + ? !limit.category.includes(LIMIT_MINS) + : limit.category.includes(LIMIT_MINS) + ) + : LIMITS.filter( + (limit) => + !limit.category.includes("license") && + !limit.category.includes(LIMIT_MINS) + ); + useEffect(() => { if (hasLength(data)) { setLocalLimits(data); @@ -45,7 +60,19 @@ export const LocalLimits = ({ return ( <> - {LIMITS.map(({ category, label }) => { + {import.meta.env.VITE_APP_ENABLE_ACCOUNT_LIMITS_ALL && ( + <> + + setUnit(e.target.value as Lowercase)} + /> + + )} + {filteredLimits.map(({ category, label }) => { return (