mirror of
https://github.com/docmost/docmost.git
synced 2025-11-10 09:02:10 +10:00
UI fixes
This commit is contained in:
47
apps/client/src/components/ui/responsive-settings-row.tsx
Normal file
47
apps/client/src/components/ui/responsive-settings-row.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import { Box } from "@mantine/core";
|
||||
import React from "react";
|
||||
|
||||
interface ResponsiveSettingsRowProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function ResponsiveSettingsRow({ children }: ResponsiveSettingsRowProps) {
|
||||
return (
|
||||
<Box
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
gap: "1rem",
|
||||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
interface ResponsiveSettingsContentProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function ResponsiveSettingsContent({ children }: ResponsiveSettingsContentProps) {
|
||||
return (
|
||||
<Box style={{ flex: "1 1 300px", minWidth: 0 }}>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
interface ResponsiveSettingsControlProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export function ResponsiveSettingsControl({ children }: ResponsiveSettingsControlProps) {
|
||||
return (
|
||||
<Box style={{ flex: "0 0 auto" }}>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@ -9,6 +9,7 @@ import { MfaDisableModal } from "@/ee/mfa";
|
||||
import { MfaBackupCodesModal } from "@/ee/mfa";
|
||||
import { isCloud } from "@/lib/config.ts";
|
||||
import useLicense from "@/ee/hooks/use-license.tsx";
|
||||
import { ResponsiveSettingsRow, ResponsiveSettingsContent, ResponsiveSettingsControl } from "@/components/ui/responsive-settings-row";
|
||||
|
||||
export function MfaSettings() {
|
||||
const { t } = useTranslation();
|
||||
@ -53,8 +54,8 @@ export function MfaSettings() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Group justify="space-between" wrap="nowrap" gap="xl">
|
||||
<div style={{ minWidth: 0, flex: 1 }}>
|
||||
<ResponsiveSettingsRow>
|
||||
<ResponsiveSettingsContent>
|
||||
<Text size="md">{t("2-step verification")}</Text>
|
||||
<Text size="sm" c="dimmed">
|
||||
{!isMfaEnabled
|
||||
@ -63,44 +64,46 @@ export function MfaSettings() {
|
||||
)
|
||||
: t("Two-factor authentication is active on your account.")}
|
||||
</Text>
|
||||
</div>
|
||||
</ResponsiveSettingsContent>
|
||||
|
||||
{!isMfaEnabled ? (
|
||||
<Tooltip
|
||||
label={t("Available in enterprise edition")}
|
||||
disabled={canUseMfa}
|
||||
>
|
||||
<Button
|
||||
disabled={!canUseMfa}
|
||||
variant="default"
|
||||
onClick={() => setSetupModalOpen(true)}
|
||||
style={{ whiteSpace: "nowrap" }}
|
||||
<ResponsiveSettingsControl>
|
||||
{!isMfaEnabled ? (
|
||||
<Tooltip
|
||||
label={t("Available in enterprise edition")}
|
||||
disabled={canUseMfa}
|
||||
>
|
||||
{t("Add 2FA method")}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Group gap="sm" wrap="nowrap">
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
onClick={() => setBackupCodesModalOpen(true)}
|
||||
style={{ whiteSpace: "nowrap" }}
|
||||
>
|
||||
{t("Backup codes")} ({mfaStatus?.backupCodesCount || 0})
|
||||
</Button>
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
color="red"
|
||||
onClick={() => setDisableModalOpen(true)}
|
||||
style={{ whiteSpace: "nowrap" }}
|
||||
>
|
||||
{t("Disable")}
|
||||
</Button>
|
||||
</Group>
|
||||
)}
|
||||
</Group>
|
||||
<Button
|
||||
disabled={!canUseMfa}
|
||||
variant="default"
|
||||
onClick={() => setSetupModalOpen(true)}
|
||||
style={{ whiteSpace: "nowrap" }}
|
||||
>
|
||||
{t("Add 2FA method")}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Group gap="sm" wrap="nowrap">
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
onClick={() => setBackupCodesModalOpen(true)}
|
||||
style={{ whiteSpace: "nowrap" }}
|
||||
>
|
||||
{t("Backup codes")} ({mfaStatus?.backupCodesCount || 0})
|
||||
</Button>
|
||||
<Button
|
||||
variant="default"
|
||||
size="sm"
|
||||
color="red"
|
||||
onClick={() => setDisableModalOpen(true)}
|
||||
style={{ whiteSpace: "nowrap" }}
|
||||
>
|
||||
{t("Disable")}
|
||||
</Button>
|
||||
</Group>
|
||||
)}
|
||||
</ResponsiveSettingsControl>
|
||||
</ResponsiveSettingsRow>
|
||||
|
||||
<MfaSetupModal
|
||||
opened={setupModalOpen}
|
||||
|
||||
@ -69,7 +69,7 @@ export default function SsoProviderList() {
|
||||
return (
|
||||
<>
|
||||
<Card shadow="sm" radius="sm">
|
||||
<Table.ScrollContainer minWidth={500}>
|
||||
<Table.ScrollContainer minWidth={600}>
|
||||
<Table verticalSpacing="sm">
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
@ -104,7 +104,7 @@ export default function SsoProviderList() {
|
||||
</Group>
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Badge color={"gray"} variant="light">
|
||||
<Badge color={"gray"} variant="light" style={{ whiteSpace: "nowrap" }}>
|
||||
{provider.type.toUpperCase()}
|
||||
</Badge>
|
||||
</Table.Td>
|
||||
@ -133,6 +133,7 @@ export default function SsoProviderList() {
|
||||
)}
|
||||
</Table.Td>
|
||||
<Table.Td>
|
||||
<Group gap="xs" wrap="nowrap">
|
||||
<ActionIcon
|
||||
variant="subtle"
|
||||
color="gray"
|
||||
@ -168,6 +169,7 @@ export default function SsoProviderList() {
|
||||
</Menu.Item>
|
||||
</Menu.Dropdown>
|
||||
</Menu>
|
||||
</Group>
|
||||
</Table.Td>
|
||||
</Table.Tr>
|
||||
))}
|
||||
|
||||
@ -1,25 +1,28 @@
|
||||
import { Group, Text, MantineSize, SegmentedControl } from "@mantine/core";
|
||||
import { Text, MantineSize, SegmentedControl } from "@mantine/core";
|
||||
import { useAtom } from "jotai";
|
||||
import { userAtom } from "@/features/user/atoms/current-user-atom.ts";
|
||||
import { updateUser } from "@/features/user/services/user-service.ts";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { PageEditMode } from "@/features/user/types/user.types.ts";
|
||||
import { ResponsiveSettingsRow, ResponsiveSettingsContent, ResponsiveSettingsControl } from "@/components/ui/responsive-settings-row";
|
||||
|
||||
export default function PageStatePref() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Group justify="space-between" wrap="nowrap" gap="xl">
|
||||
<div>
|
||||
<ResponsiveSettingsRow>
|
||||
<ResponsiveSettingsContent>
|
||||
<Text size="md">{t("Default page edit mode")}</Text>
|
||||
<Text size="sm" c="dimmed">
|
||||
{t("Choose your preferred page edit mode. Avoid accidental edits.")}
|
||||
</Text>
|
||||
</div>
|
||||
</ResponsiveSettingsContent>
|
||||
|
||||
<PageStateSegmentedControl />
|
||||
</Group>
|
||||
<ResponsiveSettingsControl>
|
||||
<PageStateSegmentedControl />
|
||||
</ResponsiveSettingsControl>
|
||||
</ResponsiveSettingsRow>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -1,24 +1,27 @@
|
||||
import { userAtom } from "@/features/user/atoms/current-user-atom.ts";
|
||||
import { updateUser } from "@/features/user/services/user-service.ts";
|
||||
import { Group, MantineSize, Switch, Text } from "@mantine/core";
|
||||
import { MantineSize, Switch, Text } from "@mantine/core";
|
||||
import { useAtom } from "jotai/index";
|
||||
import React, { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ResponsiveSettingsRow, ResponsiveSettingsContent, ResponsiveSettingsControl } from "@/components/ui/responsive-settings-row";
|
||||
|
||||
export default function PageWidthPref() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Group justify="space-between" wrap="nowrap" gap="xl">
|
||||
<div>
|
||||
<ResponsiveSettingsRow>
|
||||
<ResponsiveSettingsContent>
|
||||
<Text size="md">{t("Full page width")}</Text>
|
||||
<Text size="sm" c="dimmed">
|
||||
{t("Choose your preferred page width.")}
|
||||
</Text>
|
||||
</div>
|
||||
</ResponsiveSettingsContent>
|
||||
|
||||
<PageWidthToggle />
|
||||
</Group>
|
||||
<ResponsiveSettingsControl>
|
||||
<PageWidthToggle />
|
||||
</ResponsiveSettingsControl>
|
||||
</ResponsiveSettingsRow>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ export default function WorkspaceInvitesTable() {
|
||||
)}
|
||||
</Alert>
|
||||
|
||||
<Table.ScrollContainer minWidth={500}>
|
||||
<Table.ScrollContainer minWidth={600}>
|
||||
<Table highlightOnHover verticalSpacing="sm">
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
|
||||
@ -4,7 +4,7 @@ import {
|
||||
useWorkspaceMembersQuery,
|
||||
} from "@/features/workspace/queries/workspace-query.ts";
|
||||
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
|
||||
import React, { useCallback, useRef, useState } from "react";
|
||||
import React from "react";
|
||||
import RoleSelectMenu from "@/components/ui/role-select-menu.tsx";
|
||||
import {
|
||||
getUserRoleLabel,
|
||||
@ -54,7 +54,7 @@ export default function WorkspaceMembersTable() {
|
||||
return (
|
||||
<>
|
||||
<SearchInput onSearch={handleSearch} />
|
||||
<Table.ScrollContainer minWidth={500}>
|
||||
<Table.ScrollContainer minWidth={600}>
|
||||
<Table highlightOnHover verticalSpacing="sm">
|
||||
<Table.Thead>
|
||||
<Table.Tr>
|
||||
|
||||
Reference in New Issue
Block a user