mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-11-16 01:21:16 +01:00
Add first run UI and fix errors
This commit is contained in:
parent
fb704cc901
commit
17e038e206
@ -5281,5 +5281,139 @@
|
||||
"offline": "Backend Offline",
|
||||
"starting": "Backend starting up...",
|
||||
"wait": "Please wait for the backend to finish launching and try again."
|
||||
},
|
||||
"setup": {
|
||||
"welcome": "Welcome to Stirling PDF",
|
||||
"description": "Get started by choosing how you want to use Stirling PDF",
|
||||
"step1": {
|
||||
"label": "Choose Mode",
|
||||
"description": "Offline or Server"
|
||||
},
|
||||
"step2": {
|
||||
"label": "Select Server",
|
||||
"description": "SaaS or Self-hosted"
|
||||
},
|
||||
"step3": {
|
||||
"label": "Login",
|
||||
"description": "Enter credentials"
|
||||
},
|
||||
"mode": {
|
||||
"offline": {
|
||||
"title": "Use Offline",
|
||||
"description": "Run locally without an internet connection"
|
||||
},
|
||||
"server": {
|
||||
"title": "Connect to Server",
|
||||
"description": "Connect to a remote Stirling PDF server"
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
"type": {
|
||||
"saas": "Stirling PDF SaaS (stirling.com/app)",
|
||||
"selfhosted": "Self-hosted server"
|
||||
},
|
||||
"url": {
|
||||
"label": "Server URL",
|
||||
"description": "Enter the full URL of your self-hosted Stirling PDF server"
|
||||
},
|
||||
"error": {
|
||||
"emptyUrl": "Please enter a server URL",
|
||||
"unreachable": "Could not connect to server",
|
||||
"testFailed": "Connection test failed"
|
||||
},
|
||||
"testing": "Testing connection..."
|
||||
},
|
||||
"login": {
|
||||
"connectingTo": "Connecting to:",
|
||||
"username": {
|
||||
"label": "Username",
|
||||
"placeholder": "Enter your username"
|
||||
},
|
||||
"password": {
|
||||
"label": "Password",
|
||||
"placeholder": "Enter your password"
|
||||
},
|
||||
"error": {
|
||||
"emptyUsername": "Please enter your username",
|
||||
"emptyPassword": "Please enter your password"
|
||||
},
|
||||
"submit": "Login"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"connection": {
|
||||
"title": "Connection Mode",
|
||||
"mode": {
|
||||
"offline": "Offline",
|
||||
"server": "Server"
|
||||
},
|
||||
"server": "Server",
|
||||
"user": "Logged in as",
|
||||
"switchToServer": "Connect to Server",
|
||||
"switchToOffline": "Switch to Offline",
|
||||
"logout": "Logout",
|
||||
"selectServer": "Select Server",
|
||||
"login": "Login"
|
||||
},
|
||||
"general": {
|
||||
"title": "General",
|
||||
"description": "Configure general application preferences.",
|
||||
"user": "User",
|
||||
"logout": "Log out",
|
||||
"enableFeatures": {
|
||||
"dismiss": "Dismiss",
|
||||
"title": "For System Administrators",
|
||||
"intro": "Enable user authentication, team management, and workspace features for your organisation.",
|
||||
"action": "Configure",
|
||||
"and": "and",
|
||||
"benefit": "Enables user roles, team collaboration, admin controls, and enterprise features.",
|
||||
"learnMore": "Learn more in documentation"
|
||||
},
|
||||
"defaultToolPickerMode": "Default tool picker mode",
|
||||
"defaultToolPickerModeDescription": "Choose whether the tool picker opens in fullscreen or sidebar by default",
|
||||
"mode": {
|
||||
"sidebar": "Sidebar",
|
||||
"fullscreen": "Fullscreen"
|
||||
},
|
||||
"autoUnzipTooltip": "Automatically extract ZIP files returned from API operations. Disable to keep ZIP files intact. This does not affect automation workflows.",
|
||||
"autoUnzip": "Auto-unzip API responses",
|
||||
"autoUnzipDescription": "Automatically extract files from ZIP responses",
|
||||
"autoUnzipFileLimitTooltip": "Only unzip if the ZIP contains this many files or fewer. Set higher to extract larger ZIPs.",
|
||||
"autoUnzipFileLimit": "Auto-unzip file limit",
|
||||
"autoUnzipFileLimitDescription": "Maximum number of files to extract from ZIP"
|
||||
},
|
||||
"hotkeys": {
|
||||
"errorConflict": "Shortcut already used by {{tool}}.",
|
||||
"searchPlaceholder": "Search tools...",
|
||||
"none": "Not assigned",
|
||||
"customBadge": "Custom",
|
||||
"defaultLabel": "Default: {{shortcut}}",
|
||||
"capturing": "Press keys… (Esc to cancel)",
|
||||
"change": "Change shortcut",
|
||||
"reset": "Reset",
|
||||
"shortcut": "Shortcut",
|
||||
"noShortcut": "No shortcut set"
|
||||
}
|
||||
},
|
||||
"auth": {
|
||||
"sessionExpired": "Session Expired",
|
||||
"pleaseLoginAgain": "Please login again.",
|
||||
"accessDenied": "Access Denied",
|
||||
"insufficientPermissions": "You do not have permission to perform this action."
|
||||
},
|
||||
"common": {
|
||||
"loading": "Loading...",
|
||||
"back": "Back",
|
||||
"continue": "Continue",
|
||||
"preview": "Preview",
|
||||
"previous": "Previous",
|
||||
"next": "Next",
|
||||
"copied": "Copied!",
|
||||
"copy": "Copy",
|
||||
"expand": "Expand",
|
||||
"collapse": "Collapse",
|
||||
"retry": "Retry",
|
||||
"refresh": "Refresh",
|
||||
"cancel": "Cancel"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,44 @@
|
||||
import { ReactNode } from "react";
|
||||
import { AppProviders as ProprietaryAppProviders } from "@proprietary/components/AppProviders";
|
||||
import { DesktopConfigSync } from '@app/components/DesktopConfigSync';
|
||||
import { SetupWizard } from '@app/components/SetupWizard';
|
||||
import { useAppInitialization } from '@app/hooks/useAppInitialization';
|
||||
import { DESKTOP_DEFAULT_APP_CONFIG } from '@app/config/defaultAppConfig';
|
||||
|
||||
/**
|
||||
* Desktop application providers
|
||||
* Wraps proprietary providers and adds desktop-specific configuration
|
||||
* - Enables retry logic for app config (needed for Tauri mode when backend is starting)
|
||||
* - Shows setup wizard on first launch
|
||||
*/
|
||||
export function AppProviders({ children }: { children: ReactNode }) {
|
||||
const { isFirstLaunch, setupComplete } = useAppInitialization();
|
||||
|
||||
// Show setup wizard on first launch
|
||||
if (isFirstLaunch && !setupComplete) {
|
||||
return (
|
||||
<ProprietaryAppProviders
|
||||
appConfigRetryOptions={{
|
||||
maxRetries: 5,
|
||||
initialDelay: 1000,
|
||||
}}
|
||||
appConfigProviderProps={{
|
||||
initialConfig: DESKTOP_DEFAULT_APP_CONFIG,
|
||||
bootstrapMode: 'non-blocking',
|
||||
autoFetch: false,
|
||||
}}
|
||||
>
|
||||
<SetupWizard
|
||||
onComplete={() => {
|
||||
// Reload the page to reinitialize with new connection config
|
||||
window.location.reload();
|
||||
}}
|
||||
/>
|
||||
</ProprietaryAppProviders>
|
||||
);
|
||||
}
|
||||
|
||||
// Normal app flow
|
||||
return (
|
||||
<ProprietaryAppProviders
|
||||
appConfigRetryOptions={{
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import React from 'react';
|
||||
import { Stack, Button, Text } from '@mantine/core';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IconCloud, IconDeviceDesktop } from '@tabler/icons-react';
|
||||
import CloudIcon from '@mui/icons-material/Cloud';
|
||||
import ComputerIcon from '@mui/icons-material/Computer';
|
||||
|
||||
interface ModeSelectionProps {
|
||||
onSelect: (mode: 'offline' | 'server') => void;
|
||||
@ -18,7 +19,7 @@ export const ModeSelection: React.FC<ModeSelectionProps> = ({ onSelect, loading
|
||||
variant="light"
|
||||
onClick={() => onSelect('offline')}
|
||||
disabled={loading}
|
||||
leftSection={<IconDeviceDesktop size={24} />}
|
||||
leftSection={<ComputerIcon />}
|
||||
>
|
||||
<div style={{ textAlign: 'left', flex: 1 }}>
|
||||
<Text fw={600}>{t('setup.mode.offline.title', 'Use Offline')}</Text>
|
||||
@ -33,7 +34,7 @@ export const ModeSelection: React.FC<ModeSelectionProps> = ({ onSelect, loading
|
||||
variant="light"
|
||||
onClick={() => onSelect('server')}
|
||||
disabled={loading}
|
||||
leftSection={<IconCloud size={24} />}
|
||||
leftSection={<CloudIcon />}
|
||||
>
|
||||
<div style={{ textAlign: 'left', flex: 1 }}>
|
||||
<Text fw={600}>{t('setup.mode.server.title', 'Connect to Server')}</Text>
|
||||
|
||||
@ -117,7 +117,7 @@ export const SetupWizard: React.FC<SetupWizardProps> = ({ onComplete }) => {
|
||||
{t('setup.description', 'Get started by choosing how you want to use Stirling PDF')}
|
||||
</Text>
|
||||
|
||||
<Stepper active={activeStep} breakpoint="sm">
|
||||
<Stepper active={activeStep}>
|
||||
<Stepper.Step
|
||||
label={t('setup.step1.label', 'Choose Mode')}
|
||||
description={t('setup.step1.description', 'Offline or Server')}
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
import { createConfigNavSections as createProprietaryConfigNavSections } from '@proprietary/components/shared/config/configNavSections';
|
||||
import { ConfigNavSection } from '@core/components/shared/config/configNavSections';
|
||||
import { ConnectionSettings } from '@app/components/ConnectionSettings';
|
||||
|
||||
/**
|
||||
* Desktop extension of createConfigNavSections that adds connection settings
|
||||
*/
|
||||
export const createConfigNavSections = (
|
||||
isAdmin: boolean = false,
|
||||
runningEE: boolean = false,
|
||||
loginEnabled: boolean = false
|
||||
): ConfigNavSection[] => {
|
||||
// Get the proprietary sections (includes core Preferences + admin sections)
|
||||
const sections = createProprietaryConfigNavSections(isAdmin, runningEE, loginEnabled);
|
||||
|
||||
// Add Connection section at the beginning (after Preferences)
|
||||
sections.splice(1, 0, {
|
||||
title: 'Connection',
|
||||
items: [
|
||||
{
|
||||
key: 'connectionMode',
|
||||
label: 'Connection Mode',
|
||||
icon: 'cloud-rounded',
|
||||
component: <ConnectionSettings />,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
return sections;
|
||||
};
|
||||
8
frontend/src/desktop/components/shared/config/types.ts
Normal file
8
frontend/src/desktop/components/shared/config/types.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { VALID_NAV_KEYS as CORE_NAV_KEYS } from '@core/components/shared/config/types';
|
||||
|
||||
export const VALID_NAV_KEYS = [
|
||||
...CORE_NAV_KEYS,
|
||||
'connectionMode',
|
||||
]
|
||||
|
||||
export type NavKey = typeof VALID_NAV_KEYS[number];
|
||||
Loading…
Reference in New Issue
Block a user