Add the ERPNext settings UI, History and detail controls, and voiced.invoice.v1 export (Phase F3)
- Settings gets an Integrations tab: connection fields with a write-only API secret, a CA PEM option, Test connection with versions and warnings, live mapping lists loaded after a test, naming mode, toggles and its own Save. - Pushing for a GST-registered vendor is refused until a connection test result is stored. The UI shows the reason and disables Send. - History shows an ERPNext status column from one bulk call, a row Send and Open in ERPNext, and a bulk Send selected with a draft-or-submit confirm step and per-row results that never abort the batch. The detail view gets an ERPNext panel and per-payment send. All of it is hidden or disabled when the integration is not configured. - Optional auto-push after issue runs in the background and never blocks or fails the issue. - Generic export: a deterministic voiced.invoice.v1 JSON (and CSV line items) for selected invoices, documented in docs/voiced-invoice-v1.md with a golden test. Money is integer paise plus a decimal string. The new screens have not been run in a webview yet. The ERPNext Payment Entry deduction fields still need a live check.
This commit is contained in:
@@ -41,6 +41,7 @@ import { ImagePicker } from "../components/ImagePicker";
|
||||
import { LogoBranding } from "../components/LogoBranding";
|
||||
import DataBackupPanel from "../components/DataBackupPanel";
|
||||
import DiagnosticsPanel from "../components/DiagnosticsPanel";
|
||||
import ErpnextSettingsPanel from "../components/ErpnextSettingsPanel";
|
||||
import { FontOverrideTable } from "../components/FontOverrideTable";
|
||||
import { useToast } from "../components/ToastProvider";
|
||||
import { SETTINGS_TABS, loadSettingsTab, saveSettingsTab } from "../lib/settingsTab";
|
||||
@@ -159,7 +160,7 @@ export default function AppSettings({
|
||||
return (
|
||||
<div className="voiced-page">
|
||||
<h1 className="voiced-page__title">Settings</h1>
|
||||
<p className="voiced-page__subtitle">Business details, branding, defaults and bank accounts.</p>
|
||||
<p className="voiced-page__subtitle">Business details, branding, defaults, bank accounts and integrations.</p>
|
||||
|
||||
<Tabs selectedIndex={tab} onChange={({ selectedIndex }) => selectTab(selectedIndex)}>
|
||||
<TabList aria-label="Settings sections" contained scrollIntoView>
|
||||
@@ -171,6 +172,7 @@ export default function AppSettings({
|
||||
<Tab>Templates & export</Tab>
|
||||
<Tab>Fonts</Tab>
|
||||
<Tab>Data</Tab>
|
||||
<Tab>Integrations</Tab>
|
||||
</TabList>
|
||||
<TabPanels>
|
||||
<TabPanel>
|
||||
@@ -516,6 +518,9 @@ export default function AppSettings({
|
||||
<TabPanel>
|
||||
<DataBackupPanel />
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<ErpnextSettingsPanel active={tab === SETTINGS_TABS.findIndex((t) => t.id === "integrations")} />
|
||||
</TabPanel>
|
||||
</TabPanels>
|
||||
</Tabs>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user