mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 19:33:11 +02:00
Alpha flag for file storage settings (#6044)
## Summary - Added "Alpha" badge to the File Storage & Sharing nav item in the settings sidebar - Added "Alpha" badge to the File Storage & Sharing page title - Removed the old inline "(Alpha)" text from the Enable Group Signing label - Restructured all toggle cards so the switch is anchored to the right of each row - Tightened spacing between cards for a more compact layout - Extended `ConfigNavItem` interface with optional `badge` and `badgeColor` fields for reuse elsewhere <img width="1696" height="1057" alt="image" src="https://github.com/user-attachments/assets/77ac8276-ed65-4cae-8470-65de8f56dd74" />
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import React, { useMemo, useState, useEffect, useCallback, useRef } from 'react';
|
import React, { useMemo, useState, useEffect, useCallback, useRef } from 'react';
|
||||||
import { Modal, Text, ActionIcon, Tooltip, Group } from '@mantine/core';
|
import { Badge, Modal, Text, ActionIcon, Tooltip, Group } from '@mantine/core';
|
||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
import LocalIcon from '@app/components/shared/LocalIcon';
|
import LocalIcon from '@app/components/shared/LocalIcon';
|
||||||
import { useConfigNavSections } from '@app/components/shared/config/configNavSections';
|
import { useConfigNavSections } from '@app/components/shared/config/configNavSections';
|
||||||
@@ -186,6 +186,11 @@ const AppConfigModalInner: React.FC<AppConfigModalProps> = ({ opened, onClose })
|
|||||||
<Text size="sm" fw={500} style={{ color }}>
|
<Text size="sm" fw={500} style={{ color }}>
|
||||||
{item.label}
|
{item.label}
|
||||||
</Text>
|
</Text>
|
||||||
|
{item.badge && (
|
||||||
|
<Badge size="xs" variant="light" color={item.badgeColor ?? 'orange'} style={{ flexShrink: 0 }}>
|
||||||
|
{item.badge}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
{showPlanWarning && (
|
{showPlanWarning && (
|
||||||
<LocalIcon
|
<LocalIcon
|
||||||
icon="warning-rounded"
|
icon="warning-rounded"
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ export interface ConfigNavItem {
|
|||||||
component: React.ReactNode;
|
component: React.ReactNode;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
disabledTooltip?: string;
|
disabledTooltip?: string;
|
||||||
|
badge?: string;
|
||||||
|
badgeColor?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConfigNavSection {
|
export interface ConfigNavSection {
|
||||||
|
|||||||
@@ -105,7 +105,9 @@ export const useConfigNavSections = (
|
|||||||
icon: 'storage-rounded',
|
icon: 'storage-rounded',
|
||||||
component: <AdminStorageSharingSection />,
|
component: <AdminStorageSharingSection />,
|
||||||
disabled: requiresLogin,
|
disabled: requiresLogin,
|
||||||
disabledTooltip: requiresLogin ? enableLoginTooltip : undefined
|
disabledTooltip: requiresLogin ? enableLoginTooltip : undefined,
|
||||||
|
badge: t('toolPanel.alpha', 'Alpha'),
|
||||||
|
badgeColor: 'orange',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'adminEndpoints',
|
key: 'adminEndpoints',
|
||||||
|
|||||||
+41
-23
@@ -1,6 +1,6 @@
|
|||||||
import { useCallback, useEffect } from 'react';
|
import { useCallback, useEffect } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Anchor, Group, Loader, Paper, Stack, Switch, Text } from '@mantine/core';
|
import { Anchor, Badge, Group, Loader, Paper, Stack, Switch, Text } from '@mantine/core';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { alert } from '@app/components/toast';
|
import { alert } from '@app/components/toast';
|
||||||
import RestartConfirmationModal from '@app/components/shared/config/RestartConfirmationModal';
|
import RestartConfirmationModal from '@app/components/shared/config/RestartConfirmationModal';
|
||||||
@@ -124,42 +124,50 @@ export default function AdminStorageSharingSection() {
|
|||||||
return (
|
return (
|
||||||
<div className="settings-section-container">
|
<div className="settings-section-container">
|
||||||
<div className="settings-section-content">
|
<div className="settings-section-content">
|
||||||
<Stack gap="lg">
|
<Stack gap="sm">
|
||||||
<LoginRequiredBanner show={!loginEnabled} />
|
<LoginRequiredBanner show={!loginEnabled} />
|
||||||
<div>
|
<div>
|
||||||
|
<Group gap="xs" align="center">
|
||||||
<Text fw={600} size="lg">{t('admin.settings.storage.title', 'File Storage & Sharing')}</Text>
|
<Text fw={600} size="lg">{t('admin.settings.storage.title', 'File Storage & Sharing')}</Text>
|
||||||
|
<Badge size="sm" variant="light" color="orange">{t('toolPanel.alpha', 'Alpha')}</Badge>
|
||||||
|
</Group>
|
||||||
<Text size="sm" c="dimmed">
|
<Text size="sm" c="dimmed">
|
||||||
{t('admin.settings.storage.description', 'Control server storage and sharing options.')}
|
{t('admin.settings.storage.description', 'Control server storage and sharing options.')}
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Paper withBorder p="md" radius="md">
|
<Paper withBorder p="sm" radius="md">
|
||||||
<Stack gap="md">
|
<Group justify="space-between" align="flex-start" wrap="nowrap">
|
||||||
<Group justify="space-between" align="center">
|
<div>
|
||||||
|
<Group gap="xs" align="center">
|
||||||
<Text fw={600} size="sm">{t('admin.settings.storage.enabled.label', 'Enable Server File Storage')}</Text>
|
<Text fw={600} size="sm">{t('admin.settings.storage.enabled.label', 'Enable Server File Storage')}</Text>
|
||||||
{isFieldPending('enabled') && <PendingBadge show={true} />}
|
{isFieldPending('enabled') && <PendingBadge show={true} />}
|
||||||
</Group>
|
</Group>
|
||||||
<Text size="xs" c="dimmed">
|
<Text size="xs" c="dimmed">
|
||||||
{t('admin.settings.storage.enabled.description', 'Allow users to store files on the server.')}
|
{t('admin.settings.storage.enabled.description', 'Allow users to store files on the server.')}
|
||||||
</Text>
|
</Text>
|
||||||
|
</div>
|
||||||
<Switch
|
<Switch
|
||||||
checked={storageEnabled}
|
checked={storageEnabled}
|
||||||
onChange={(e) => setSettings({ ...settings, enabled: e.currentTarget.checked })}
|
onChange={(e) => setSettings({ ...settings, enabled: e.currentTarget.checked })}
|
||||||
disabled={!loginEnabled}
|
disabled={!loginEnabled}
|
||||||
styles={getDisabledStyles()}
|
styles={getDisabledStyles()}
|
||||||
|
style={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Group>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
<Paper withBorder p="md" radius="md">
|
<Paper withBorder p="sm" radius="md">
|
||||||
<Stack gap="md">
|
<Group justify="space-between" align="flex-start" wrap="nowrap">
|
||||||
<Group justify="space-between" align="center">
|
<div>
|
||||||
|
<Group gap="xs" align="center">
|
||||||
<Text fw={600} size="sm">{t('admin.settings.storage.sharing.enabled.label', 'Enable Sharing')}</Text>
|
<Text fw={600} size="sm">{t('admin.settings.storage.sharing.enabled.label', 'Enable Sharing')}</Text>
|
||||||
{isFieldPending('sharing.enabled') && <PendingBadge show={true} />}
|
{isFieldPending('sharing.enabled') && <PendingBadge show={true} />}
|
||||||
</Group>
|
</Group>
|
||||||
<Text size="xs" c="dimmed">
|
<Text size="xs" c="dimmed">
|
||||||
{t('admin.settings.storage.sharing.enabled.description', 'Allow users to share stored files.')}
|
{t('admin.settings.storage.sharing.enabled.description', 'Allow users to share stored files.')}
|
||||||
</Text>
|
</Text>
|
||||||
|
</div>
|
||||||
<Switch
|
<Switch
|
||||||
checked={settings.sharing?.enabled ?? false}
|
checked={settings.sharing?.enabled ?? false}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
@@ -170,13 +178,15 @@ export default function AdminStorageSharingSection() {
|
|||||||
}
|
}
|
||||||
disabled={!loginEnabled || !storageEnabled}
|
disabled={!loginEnabled || !storageEnabled}
|
||||||
styles={getDisabledStyles()}
|
styles={getDisabledStyles()}
|
||||||
|
style={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Group>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
<Paper withBorder p="md" radius="md">
|
<Paper withBorder p="sm" radius="md">
|
||||||
<Stack gap="md">
|
<Group justify="space-between" align="flex-start" wrap="nowrap">
|
||||||
<Group justify="space-between" align="center">
|
<div>
|
||||||
|
<Group gap="xs" align="center">
|
||||||
<Text fw={600} size="sm">{t('admin.settings.storage.sharing.links.label', 'Enable Share Links')}</Text>
|
<Text fw={600} size="sm">{t('admin.settings.storage.sharing.links.label', 'Enable Share Links')}</Text>
|
||||||
{isFieldPending('sharing.linkEnabled') && <PendingBadge show={true} />}
|
{isFieldPending('sharing.linkEnabled') && <PendingBadge show={true} />}
|
||||||
</Group>
|
</Group>
|
||||||
@@ -199,6 +209,7 @@ export default function AdminStorageSharingSection() {
|
|||||||
</Anchor>
|
</Anchor>
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
<Switch
|
<Switch
|
||||||
checked={settings.sharing?.linkEnabled ?? false}
|
checked={settings.sharing?.linkEnabled ?? false}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
@@ -209,13 +220,15 @@ export default function AdminStorageSharingSection() {
|
|||||||
}
|
}
|
||||||
disabled={!loginEnabled || !sharingEnabled || !frontendUrlConfigured}
|
disabled={!loginEnabled || !sharingEnabled || !frontendUrlConfigured}
|
||||||
styles={getDisabledStyles()}
|
styles={getDisabledStyles()}
|
||||||
|
style={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Group>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
<Paper withBorder p="md" radius="md">
|
<Paper withBorder p="sm" radius="md">
|
||||||
<Stack gap="md">
|
<Group justify="space-between" align="flex-start" wrap="nowrap">
|
||||||
<Group justify="space-between" align="center">
|
<div>
|
||||||
|
<Group gap="xs" align="center">
|
||||||
<Text fw={600} size="sm">{t('admin.settings.storage.sharing.email.label', 'Enable Email Sharing')}</Text>
|
<Text fw={600} size="sm">{t('admin.settings.storage.sharing.email.label', 'Enable Email Sharing')}</Text>
|
||||||
{isFieldPending('sharing.emailEnabled') && <PendingBadge show={true} />}
|
{isFieldPending('sharing.emailEnabled') && <PendingBadge show={true} />}
|
||||||
</Group>
|
</Group>
|
||||||
@@ -238,6 +251,7 @@ export default function AdminStorageSharingSection() {
|
|||||||
</Anchor>
|
</Anchor>
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
<Switch
|
<Switch
|
||||||
checked={settings.sharing?.emailEnabled ?? false}
|
checked={settings.sharing?.emailEnabled ?? false}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
@@ -248,19 +262,22 @@ export default function AdminStorageSharingSection() {
|
|||||||
}
|
}
|
||||||
disabled={!loginEnabled || !sharingEnabled || !mailEnabled}
|
disabled={!loginEnabled || !sharingEnabled || !mailEnabled}
|
||||||
styles={getDisabledStyles()}
|
styles={getDisabledStyles()}
|
||||||
|
style={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Group>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
<Paper withBorder p="md" radius="md">
|
<Paper withBorder p="sm" radius="md">
|
||||||
<Stack gap="md">
|
<Group justify="space-between" align="flex-start" wrap="nowrap">
|
||||||
<Group justify="space-between" align="center">
|
<div>
|
||||||
<Text fw={600} size="sm">{t('admin.settings.storage.signing.enabled.label', 'Enable Group Signing (Alpha)')}</Text>
|
<Group gap="xs" align="center">
|
||||||
|
<Text fw={600} size="sm">{t('admin.settings.storage.signing.enabled.label', 'Enable Group Signing')}</Text>
|
||||||
{isFieldPending('signing.enabled') && <PendingBadge show={true} />}
|
{isFieldPending('signing.enabled') && <PendingBadge show={true} />}
|
||||||
</Group>
|
</Group>
|
||||||
<Text size="xs" c="dimmed">
|
<Text size="xs" c="dimmed">
|
||||||
{t('admin.settings.storage.signing.enabled.description', 'Allow users to create multi-participant document signing sessions. Requires server file storage to be enabled.')}
|
{t('admin.settings.storage.signing.enabled.description', 'Allow users to create multi-participant document signing sessions. Requires server file storage to be enabled.')}
|
||||||
</Text>
|
</Text>
|
||||||
|
</div>
|
||||||
<Switch
|
<Switch
|
||||||
checked={settings.signing?.enabled ?? false}
|
checked={settings.signing?.enabled ?? false}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
@@ -271,8 +288,9 @@ export default function AdminStorageSharingSection() {
|
|||||||
}
|
}
|
||||||
disabled={!loginEnabled || !storageEnabled}
|
disabled={!loginEnabled || !storageEnabled}
|
||||||
styles={getDisabledStyles()}
|
styles={getDisabledStyles()}
|
||||||
|
style={{ flexShrink: 0 }}
|
||||||
/>
|
/>
|
||||||
</Stack>
|
</Group>
|
||||||
</Paper>
|
</Paper>
|
||||||
|
|
||||||
<RestartConfirmationModal
|
<RestartConfirmationModal
|
||||||
|
|||||||
Reference in New Issue
Block a user