Auto-open modals from global quick actions

This commit is contained in:
Esdras Renan 2025-11-13 21:43:36 -03:00
parent 59a94744b3
commit abb29d9116
7 changed files with 70 additions and 11 deletions

View file

@ -95,6 +95,7 @@ type LastAlertInfo = { createdAt: number; usagePct: number; threshold: number }
type Props = {
initialCompanies: NormalizedCompany[]
tenantId?: string | null
autoOpenCreate?: boolean
}
type ViewMode = "table" | "board"
@ -291,7 +292,7 @@ function FieldError({ error }: { error?: string }) {
return <p className="text-xs font-medium text-destructive">{error}</p>
}
export function AdminCompaniesManager({ initialCompanies, tenantId }: Props) {
export function AdminCompaniesManager({ initialCompanies, tenantId, autoOpenCreate = false }: Props) {
const [companies, setCompanies] = useState<NormalizedCompany[]>(() => initialCompanies)
const [view, setView] = useState<ViewMode>("table")
const [search, setSearch] = useState("")
@ -429,6 +430,12 @@ export function AdminCompaniesManager({ initialCompanies, tenantId }: Props) {
const cancelDelete = useCallback(() => setIsDeleting(null), [])
useEffect(() => {
if (autoOpenCreate) {
openCreate()
}
}, [autoOpenCreate, openCreate])
const handleDelete = useCallback(async () => {
if (!isDeleting) return
try {

View file

@ -1268,7 +1268,15 @@ function OsIcon({ osName }: { osName?: string | null }) {
return <Monitor className="size-4 text-black" />
}
export function AdminDevicesOverview({ tenantId, initialCompanyFilterSlug = "all" }: { tenantId: string; initialCompanyFilterSlug?: string }) {
export function AdminDevicesOverview({
tenantId,
initialCompanyFilterSlug = "all",
autoOpenCreateDevice = false,
}: {
tenantId: string
initialCompanyFilterSlug?: string
autoOpenCreateDevice?: boolean
}) {
const { devices, isLoading } = useDevicesQuery(tenantId)
const [q, setQ] = useState("")
const [statusFilter, setStatusFilter] = useState<string>("all")
@ -1555,6 +1563,12 @@ export function AdminDevicesOverview({ tenantId, initialCompanyFilterSlug = "all
setIsCreateDeviceOpen(true)
}, [selectedCompany, companyFilterSlug])
useEffect(() => {
if (autoOpenCreateDevice) {
handleOpenCreateDevice()
}
}, [autoOpenCreateDevice, handleOpenCreateDevice])
const handleCreateDevice = useCallback(async () => {
if (!convexUserId) {
toast.error("Sincronize a sessão antes de criar dispositivos.")

View file

@ -95,6 +95,7 @@ type Props = {
initialAccounts: AdminAccount[]
companies: NormalizedCompany[]
tenantId: string
autoOpenCreate?: boolean
}
type SectionEditorState =
@ -164,7 +165,7 @@ function FieldError({ message }: { message?: string }) {
return <p className="text-xs font-medium text-destructive">{message}</p>
}
export function AdminUsersWorkspace({ initialAccounts, companies, tenantId }: Props) {
export function AdminUsersWorkspace({ initialAccounts, companies, tenantId, autoOpenCreate = false }: Props) {
const [tab, setTab] = useState<"accounts" | "structure">("accounts")
return (
<Tabs value={tab} onValueChange={(value) => setTab(value as typeof tab)}>
@ -173,7 +174,12 @@ export function AdminUsersWorkspace({ initialAccounts, companies, tenantId }: Pr
<TabsTrigger value="structure">Estrutura das empresas</TabsTrigger>
</TabsList>
<TabsContent value="accounts">
<AccountsTable initialAccounts={initialAccounts} companies={companies} tenantId={tenantId} />
<AccountsTable
initialAccounts={initialAccounts}
companies={companies}
tenantId={tenantId}
autoOpenCreate={autoOpenCreate}
/>
</TabsContent>
<TabsContent value="structure">
<CompanyStructurePanel initialCompanies={companies} />
@ -186,10 +192,12 @@ function AccountsTable({
initialAccounts,
companies,
tenantId,
autoOpenCreate,
}: {
initialAccounts: AdminAccount[]
companies: NormalizedCompany[]
tenantId: string
autoOpenCreate?: boolean
}) {
const [accounts, setAccounts] = useState(initialAccounts)
const [search, setSearch] = useState("")
@ -212,6 +220,7 @@ function AccountsTable({
const [isResettingPassword, setIsResettingPassword] = useState(false)
const [passwordPreview, setPasswordPreview] = useState<string | null>(null)
const [createDialogOpen, setCreateDialogOpen] = useState(false)
const autoOpenHandledRef = useRef(false)
const [isCreatingAccount, setIsCreatingAccount] = useState(false)
const [createForm, setCreateForm] = useState<CreateAccountFormState>(() => createDefaultAccountForm())
@ -400,6 +409,13 @@ function AccountsTable({
setCreateForm(createDefaultAccountForm())
}, [])
useEffect(() => {
if (!autoOpenCreate || autoOpenHandledRef.current) return
autoOpenHandledRef.current = true
setCreateForm(createDefaultAccountForm())
setCreateDialogOpen(true)
}, [autoOpenCreate])
useEffect(() => {
if (editAccount) {
setEditForm({

View file

@ -39,7 +39,7 @@ export function GlobalQuickActions() {
label: "Adicionar empresa",
description: "Cadastrar novo cliente",
icon: Building,
href: "/admin/companies",
href: "/admin/companies?quick=new-company",
visible: Boolean(isAdmin),
},
{
@ -47,7 +47,7 @@ export function GlobalQuickActions() {
label: "Novo usuário",
description: "Gestores / colaboradores",
icon: UserPlus,
href: "/admin/users",
href: "/admin/users?quick=new-user",
visible: Boolean(isAdmin),
},
]