Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const SelectItem = React.forwardRef<
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<div className="flex items-center gap-3">
<div className="flex items-center gap-2">
<span className="flex-shrink-0">{icon}</span>
<div className="flex flex-col">
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
Expand Down
29 changes: 22 additions & 7 deletions src/components/select/SelectDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ interface SelectDropdownProps {
children?: React.ReactNode;
maxHeight?: number;
triggerClassName?: string;
iconSize?: number;
truncate?: boolean;
}

export function SelectDropdown({
Expand All @@ -68,6 +70,8 @@ export function SelectDropdown({
children,
maxHeight,
triggerClassName,
iconSize = 14,
truncate = false,
}: Readonly<SelectDropdownProps>) {
const [inputRef, { width }] = useElementSize<HTMLButtonElement>();

Expand Down Expand Up @@ -107,15 +111,18 @@ export function SelectDropdown({

const SelectedItem = () => {
return (
<div className={"flex items-center gap-2.5"}>
{selected?.icon && <selected.icon size={14} width={14} />}
<div className={cn("flex items-center gap-2.5", truncate && "min-w-0")}>
{selected?.icon && <selected.icon size={iconSize} width={iconSize} />}
<div
className={cn(
"flex flex-col text-sm font-medium",
size === "xs" && "text-xs",
truncate && "min-w-0",
)}
>
<span className={"text-nb-gray-200"}>{selected?.label}</span>
<span className={cn("text-nb-gray-200", truncate && "truncate")}>
{selected?.label}
</span>
</div>
</div>
);
Expand Down Expand Up @@ -216,20 +223,21 @@ export function SelectDropdown({

<ScrollArea
className={cn(
"overflow-y-auto flex flex-col gap-1 pl-2 pr-3",
!showSearch && "pt-2",
"overflow-y-auto flex flex-col gap-1 pl-1 pr-1",
!showSearch && "pt-1",
)}
style={{
maxHeight: maxHeight ?? 380,
}}
>
<CommandGroup>
<div className={"grid grid-cols-1 gap-1 pb-2 w-full"}>
<div className={"grid grid-cols-1 gap-1 pb-1 w-full"}>
{filteredItems.map((option) => (
<SelectDropdownItem
option={option}
toggle={toggle}
key={option.value}
iconSize={iconSize}
showValue={showValues}
size={size}
/>
Expand All @@ -249,11 +257,13 @@ const SelectDropdownItem = ({
toggle,
showValue = false,
size = "sm",
iconSize = 14,
}: {
option: SelectOption;
toggle: (value: string) => void;
showValue?: boolean;
size: "xs" | "sm";
iconSize?: number;
}) => {
const value = option.value || "" + option.label || "";
const elementRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -285,7 +295,12 @@ const SelectDropdownItem = ({
option?.disabled && "cursor-not-allowed",
)}
>
{option.icon && <option.icon size={14} width={14} />}
{option.icon && (
<div className={"shrink-0"}>
<option.icon size={iconSize} width={iconSize} />
</div>
)}

{option?.renderItem && option.renderItem()}
{!option?.renderItem && (
<div
Expand Down
10 changes: 8 additions & 2 deletions src/components/ui/CountrySelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import { useCountries } from "@/contexts/CountryProvider";
type Props = {
value: string;
onChange: (value: string) => void;
iconSize?: number;
popoverWidth?: "auto" | "content" | number;
truncate?: boolean;
};
export const CountrySelector = ({ value, onChange }: Props) => {
export const CountrySelector = ({ value, onChange, iconSize = 20, popoverWidth, truncate }: Props) => {
const { countries, isLoading } = useCountries();

const countryList = useMemo(() => {
Expand All @@ -22,7 +25,7 @@ export const CountrySelector = ({ value, onChange }: Props) => {
}) =>
createElement(RoundedFlag, {
country: country.country_code,
size: 20,
size: iconSize,
...props,
});
return {
Expand All @@ -42,7 +45,10 @@ export const CountrySelector = ({ value, onChange }: Props) => {
searchPlaceholder={"Search country..."}
value={value}
onChange={onChange}
iconSize={iconSize}
options={countryList || []}
popoverWidth={popoverWidth}
truncate={truncate}
/>
</div>
);
Expand Down
20 changes: 15 additions & 5 deletions src/contexts/CountryProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,23 @@ const CountryContext = React.createContext(
countries: Country[] | undefined;
isLoading: boolean;
getRegionByPeer: (peer: Peer) => string;
getRegionText: (country_code: string, city_name: string) => string;
getRegionText: (
country_code: string,
city_name: string,
subdivision_code?: string,
) => string;
},
);

export default function CountryProvider({ children }: Props) {
const { isRestricted } = usePermissions();

const getRegionByPeer = (peer: Peer) => "Unknown";
const getRegionText = (country_code: string, city_name: string) => "Unknown";
const getRegionText = (
country_code: string,
city_name: string,
subdivision_code?: string,
) => "Unknown";

return isRestricted ? (
<CountryContext.Provider
Expand All @@ -47,12 +55,14 @@ function CountryProviderContent({ children }: Props) {
);

const getRegionText = useCallback(
(country_code: string, city_name: string) => {
(country_code: string, city_name: string, subdivision_code?: string) => {
if (!countries) return "Unknown";
const country = countries.find((c) => c.country_code === country_code);
if (!country) return "Unknown";
if (!city_name) return country.country_name;
return `${country.country_name}, ${city_name}`;
const parts = [country.country_name];
if (subdivision_code) parts.push(subdivision_code);
if (city_name) parts.push(city_name);
return parts.join(", ");
},
[countries],
);
Expand Down
19 changes: 19 additions & 0 deletions src/interfaces/ReverseProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,17 @@ export interface ReverseProxy {
pass_host_header?: boolean;
rewrite_redirects?: boolean;
auth?: ReverseProxyAuth;
access_restrictions?: AccessRestrictions;
meta?: ReverseProxyMeta;
}

export interface AccessRestrictions {
allowed_cidrs?: string[];
blocked_cidrs?: string[];
allowed_countries?: string[];
blocked_countries?: string[];
}

export interface ReverseProxyMeta {
created_at: string;
status: ReverseProxyStatus;
Expand Down Expand Up @@ -77,6 +85,13 @@ export interface ReverseProxyAuth {
link_auth?: {
enabled: boolean;
};
header_auths?: HeaderAuthConfig[];
}

export interface HeaderAuthConfig {
enabled: boolean;
header: string;
value: string;
}

export interface ReverseProxyDomain {
Expand Down Expand Up @@ -129,6 +144,7 @@ export interface ReverseProxyEvent {
auth_method_used?: string;
country_code?: string;
city_name?: string;
subdivision_code?: string;
bytes_upload: number;
bytes_download: number;
protocol?: EventProtocol;
Expand Down Expand Up @@ -181,5 +197,8 @@ export const REVERSE_PROXY_DOMAIN_VERIFICATION_LINK =
export const REVERSE_PROXY_EVENTS_DOCS_LINK =
"https://docs.netbird.io/manage/reverse-proxy/access-logs";

export const REVERSE_PROXY_ACCESS_CONTROL_DOCS_LINK =
"https://docs.netbird.io/manage/reverse-proxy";

export const REVERSE_PROXY_TROUBLESHOOTING_DOCS_LINK =
"https://docs.netbird.io/manage/reverse-proxy#troubleshooting";
Loading
Loading