1 import { c } from 'ttag';
3 import { SERVER_FEATURES } from '@proton/shared/lib/constants';
5 import { type CountryOptions, getLocalizedCountryByAbbr } from '../../../helpers/countries';
6 import type { GatewayDto } from './GatewayDto';
7 import type { GatewayLocation } from './GatewayLocation';
8 import type { GatewayLogical } from './GatewayLogical';
9 import type { GatewayServer } from './GatewayServer';
10 import type { GatewayUser } from './GatewayUser';
12 export const getSuffix = (name: string | undefined) => name?.match(/#\d+$/)?.[0] || '';
14 const locations: Record<string, GatewayLocation> = {};
16 const getAverageLoad = (servers: GatewayServer[]) =>
17 servers.reduce((load, server) => load + server.Load, 0) / servers.length;
19 const getColorForLoad = (load: number): string => {
31 export const getFormattedLoad = (servers: GatewayServer[]) => {
32 const load = Math.max(0, Math.min(100, Math.round(getAverageLoad(servers))));
34 return <span className={'color-' + getColorForLoad(load)}>{load}%</span>;
37 export const getTotalAdded = (quantities: Record<string, number> | null | undefined): number =>
38 Object.values(quantities || {}).reduce((total, quantity) => total + quantity, 0);
40 const getUsersList = (userIds: readonly string[], users: readonly GatewayUser[], key = '') =>
42 ? userIds.map((id) => {
43 const user = users?.find((user) => user.ID === id);
45 return <div key={'logical-users-' + key + '-' + id}>{user?.Name || user?.Email}</div>;
49 export const getMembers = (users: readonly GatewayUser[], logical: GatewayLogical) =>
50 logical.Features & SERVER_FEATURES.DOUBLE_RESTRICTION
51 ? getUsersList(logical.Users, users, logical.ID)
52 : /* translator: The whole organization has access to the gateway */ c('Info').t`Whole organization`;
54 export const getLocationId = (location: GatewayLocation): string => {
55 const id = btoa(location.Country + '\n' + (location.City || ''));
57 if (!(id in locations)) {
58 locations[id] = location;
64 export const getLocationDisplayName = (location: GatewayLocation, countryOptions: CountryOptions): string => {
65 const country = getLocalizedCountryByAbbr(location.Country, countryOptions) || location.Country;
66 return country + (location.TranslatedCity ? ' - ' + location.TranslatedCity : '');
69 export const getLocationFromId = (locationId: string): GatewayLocation => {
70 return locations[locationId];
73 const getInitialQuantities = (locations: readonly GatewayLocation[]) => {
74 const quantities: Record<string, 1> = {};
76 // Add 1 by default in first location
77 for (let i = 0; i < 0 && locations[i]; i++) {
78 quantities[getLocationId(locations[i])] = 1;
84 export const getInitialModel = (locations: readonly GatewayLocation[]): GatewayDto => ({
85 location: locations[0],
89 quantities: getInitialQuantities(locations),
90 unassignedIpQuantities: {},