various visual changes

This commit is contained in:
miloschwartz
2026-06-08 22:07:44 -07:00
parent f28571629f
commit 407ba567a0
8 changed files with 73 additions and 129 deletions
@@ -41,6 +41,7 @@ import {
FormMessage FormMessage
} from "@app/components/ui/form"; } from "@app/components/ui/form";
import { Input } from "@app/components/ui/input"; import { Input } from "@app/components/ui/input";
import { Label } from "@app/components/ui/label";
import { import {
Popover, Popover,
PopoverContent, PopoverContent,
@@ -1172,52 +1173,55 @@ export default function Page() {
{isNative ? ( {isNative ? (
<SettingsFormCell span="half"> <SettingsFormCell span="half">
<Popover <div className="grid gap-2">
open={ <Label>{t("sites")}</Label>
nativeSiteOpen <Popover
} open={
onOpenChange={ nativeSiteOpen
setNativeSiteOpen }
} onOpenChange={
> setNativeSiteOpen
<PopoverTrigger }
asChild
> >
<Button <PopoverTrigger
variant="outline" asChild
role="combobox"
className="w-full justify-between font-normal"
> >
<span className="truncate"> <Button
{nativeSelectedSite?.name ?? variant="outline"
t( role="combobox"
"siteSelect" className="w-full justify-between font-normal"
)} >
</span> <span className="truncate">
<ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" /> {nativeSelectedSite?.name ??
</Button> t(
</PopoverTrigger> "siteSelect"
<PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0"> )}
<SitesSelector </span>
orgId={ <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
orgId as string </Button>
} </PopoverTrigger>
selectedSite={ <PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0">
nativeSelectedSite <SitesSelector
} orgId={
onSelectSite={( orgId as string
site }
) => { selectedSite={
setNativeSelectedSite( nativeSelectedSite
}
onSelectSite={(
site site
); ) => {
setNativeSiteOpen( setNativeSelectedSite(
false site
); );
}} setNativeSiteOpen(
/> false
</PopoverContent> );
</Popover> }}
/>
</PopoverContent>
</Popover>
</div>
</SettingsFormCell> </SettingsFormCell>
) : standardDaemonLocation !== ) : standardDaemonLocation !==
"site" || "site" ||
+1 -1
View File
@@ -91,7 +91,7 @@ export default function AuthPageBrandingForm({
orgSubtitle: branding?.orgSubtitle ?? `Log in to {{orgName}}`, orgSubtitle: branding?.orgSubtitle ?? `Log in to {{orgName}}`,
resourceTitle: resourceTitle:
branding?.resourceTitle ?? branding?.resourceTitle ??
`Authenticate to access {{resourceName}}`, `Authenticate to Access {{resourceName}}`,
resourceSubtitle: resourceSubtitle:
branding?.resourceSubtitle ?? branding?.resourceSubtitle ??
`Choose your preferred authentication method for {{resourceName}}`, `Choose your preferred authentication method for {{resourceName}}`,
@@ -12,11 +12,9 @@ import {
import { useEnvContext } from "@app/hooks/useEnvContext"; import { useEnvContext } from "@app/hooks/useEnvContext";
import { useOrgContext } from "@app/hooks/useOrgContext"; import { useOrgContext } from "@app/hooks/useOrgContext";
import { usePaidStatus } from "@app/hooks/usePaidStatus"; import { usePaidStatus } from "@app/hooks/usePaidStatus";
import { getUserDisplayName } from "@app/lib/getUserDisplayName";
import { orgQueries } from "@app/lib/queries"; import { orgQueries } from "@app/lib/queries";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { build } from "@server/build"; import { build } from "@server/build";
import { UserType } from "@server/types/UserTypes";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import { import {
@@ -67,12 +65,6 @@ export function CreatePolicyForm({}: CreatePolicyFormProps) {
env.server.maxmind_asn_path && env.server.maxmind_asn_path.length > 0 env.server.maxmind_asn_path && env.server.maxmind_asn_path.length > 0
); );
const { data: orgRoles = [], isLoading: isLoadingOrgRoles } = useQuery(
orgQueries.roles({ orgId: org.org.orgId })
);
const { data: orgUsers = [], isLoading: isLoadingOrgUsers } = useQuery(
orgQueries.users({ orgId: org.org.orgId })
);
const { data: orgIdps = [], isLoading: isLoadingOrgIdps } = useQuery( const { data: orgIdps = [], isLoading: isLoadingOrgIdps } = useQuery(
orgQueries.identityProviders({ orgQueries.identityProviders({
orgId: org.org.orgId, orgId: org.org.orgId,
@@ -163,26 +155,6 @@ export function CreatePolicyForm({}: CreatePolicyFormProps) {
} }
} }
const allRoles = useMemo(
() =>
orgRoles
.map((role) => ({
id: role.roleId.toString(),
text: role.name
}))
.filter((role) => role.text !== "Admin"),
[orgRoles]
);
const allUsers = useMemo(
() =>
orgUsers.map((user) => ({
id: user.id.toString(),
text: `${getUserDisplayName({ email: user.email, username: user.username })}${user.type !== UserType.Internal ? ` (${user.idpName})` : ""}`
})),
[orgUsers]
);
const allIdps = useMemo(() => { const allIdps = useMemo(() => {
if (build === "saas") { if (build === "saas") {
if (isPaidUser(tierMatrix.orgOidc)) { if (isPaidUser(tierMatrix.orgOidc)) {
@@ -197,7 +169,7 @@ export function CreatePolicyForm({}: CreatePolicyFormProps) {
return []; return [];
}, [orgIdps, isPaidUser]); }, [orgIdps, isPaidUser]);
if (isLoadingOrgRoles || isLoadingOrgUsers || isLoadingOrgIdps) { if (isLoadingOrgIdps) {
return <></>; return <></>;
} }
@@ -252,8 +224,6 @@ export function CreatePolicyForm({}: CreatePolicyFormProps) {
form={form} form={form}
orgId={org.org.orgId} orgId={org.org.orgId}
allIdps={allIdps} allIdps={allIdps}
allRoles={allRoles}
allUsers={allUsers}
emailEnabled={env.email.emailEnabled} emailEnabled={env.email.emailEnabled}
/> />
<PolicyAccessRulesSection <PolicyAccessRulesSection
@@ -19,8 +19,6 @@ type PolicyAuthStackSectionCreateProps = {
form: UseFormReturn<PolicyFormValues, any, any>; form: UseFormReturn<PolicyFormValues, any, any>;
orgId: string; orgId: string;
allIdps: { id: number; text: string }[]; allIdps: { id: number; text: string }[];
allRoles: { id: string; text: string }[];
allUsers: { id: string; text: string }[];
emailEnabled: boolean; emailEnabled: boolean;
}; };
@@ -12,7 +12,8 @@ import {
SettingsSubsectionTitle, SettingsSubsectionTitle,
SettingsSectionTitle SettingsSectionTitle
} from "@app/components/Settings"; } from "@app/components/Settings";
import { TagInput } from "@app/components/tags/tag-input"; import { RolesSelector } from "@app/components/roles-selector";
import { UsersSelector } from "@app/components/users-selector";
import { FormField } from "@app/components/ui/form"; import { FormField } from "@app/components/ui/form";
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import { useState } from "react"; import { useState } from "react";
@@ -38,27 +39,18 @@ export type PolicyAuthStackSectionCreateProps = {
form: UseFormReturn<PolicyFormValues, any, any>; form: UseFormReturn<PolicyFormValues, any, any>;
orgId: string; orgId: string;
allIdps: { id: number; text: string }[]; allIdps: { id: number; text: string }[];
allRoles: { id: string; text: string }[];
allUsers: { id: string; text: string }[];
emailEnabled: boolean; emailEnabled: boolean;
}; };
export function PolicyAuthStackSectionCreate({ export function PolicyAuthStackSectionCreate({
form: parentForm, form: parentForm,
orgId,
allIdps, allIdps,
allRoles,
allUsers,
emailEnabled emailEnabled
}: PolicyAuthStackSectionCreateProps) { }: PolicyAuthStackSectionCreateProps) {
const t = useTranslations(); const t = useTranslations();
const [editingMethod, setEditingMethod] = const [editingMethod, setEditingMethod] =
useState<PolicyAuthMethodId | null>(null); useState<PolicyAuthMethodId | null>(null);
const [activeRolesTagIndex, setActiveRolesTagIndex] = useState<
number | null
>(null);
const [activeUsersTagIndex, setActiveUsersTagIndex] = useState<
number | null
>(null);
const sso = useWatch({ control: parentForm.control, name: "sso" }); const sso = useWatch({ control: parentForm.control, name: "sso" });
const skipToIdpId = useWatch({ const skipToIdpId = useWatch({
@@ -126,47 +118,38 @@ export function PolicyAuthStackSectionCreate({
} }
allIdps={allIdps} allIdps={allIdps}
rolesEditor={ rolesEditor={
<FormField<PolicyFormValues, "roles"> <FormField
control={parentForm.control} control={parentForm.control}
name="roles" name="roles"
render={({ field }) => ( render={({ field }) => (
<TagInput <RolesSelector
{...field} orgId={orgId}
activeTagIndex={activeRolesTagIndex} selectedRoles={field.value}
setActiveTagIndex={ onSelectRoles={(selected) =>
setActiveRolesTagIndex parentForm.setValue(
"roles",
selected
)
} }
placeholder={t("accessRoleSelect2")} restrictAdminRole
tags={field.value ?? []}
setTags={(newRoles) =>
field.onChange(newRoles)
}
autocompleteOptions={allRoles}
allowDuplicates={false}
size="sm"
/> />
)} )}
/> />
} }
usersEditor={ usersEditor={
<FormField<PolicyFormValues, "users"> <FormField
control={parentForm.control} control={parentForm.control}
name="users" name="users"
render={({ field }) => ( render={({ field }) => (
<TagInput <UsersSelector
{...field} orgId={orgId}
activeTagIndex={activeUsersTagIndex} selectedUsers={field.value}
setActiveTagIndex={ onSelectUsers={(selected) =>
setActiveUsersTagIndex parentForm.setValue(
"users",
selected
)
} }
placeholder={t("accessUserSelect")}
tags={field.value ?? []}
setTags={(newUsers) =>
field.onChange(newUsers)
}
autocompleteOptions={allUsers}
allowDuplicates={false}
size="sm"
/> />
)} )}
/> />
+1 -1
View File
@@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@app/lib/cn"; import { cn } from "@app/lib/cn";
const buttonVariants = cva( const buttonVariants = cva(
"cursor-pointer inline-flex items-center justify-center whitespace-nowrap text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-50", "cursor-pointer inline-flex items-center justify-center whitespace-nowrap text-sm font-normal ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-0 disabled:pointer-events-none disabled:opacity-50",
{ {
variants: { variants: {
variant: { variant: {
@@ -351,10 +351,6 @@ export function ControlledDataTable<TData, TValue>({
dataTableFilterDropdownContentClassName dataTableFilterDropdownContentClassName
} }
> >
<DropdownMenuLabel>
{filter.label}
</DropdownMenuLabel>
<DropdownMenuSeparator />
{filter.options.map( {filter.options.map(
(option) => { (option) => {
const isChecked = const isChecked =
@@ -484,13 +480,6 @@ export function ControlledDataTable<TData, TValue>({
align="end" align="end"
className="w-48" className="w-48"
> >
<DropdownMenuLabel>
{t(
"toggleColumns"
) ||
"Toggle columns"}
</DropdownMenuLabel>
<DropdownMenuSeparator />
{table {table
.getAllColumns() .getAllColumns()
.filter( .filter(
+1 -1
View File
@@ -91,7 +91,7 @@ const TableHead = React.forwardRef<
<th <th
ref={ref} ref={ref}
className={cn( className={cn(
"h-10 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0", "h-10 text-left align-middle font-medium text-muted-foreground [&_button]:font-medium [&:has([role=checkbox])]:pr-0",
className className
)} )}
{...props} {...props}