@open-mercato/enterprise 0.6.8-develop.7101.1.bd9356828a → 0.7.1-develop.7102.1.b41f7e3e51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -136,7 +136,7 @@ function RecordLockingSettingsPage() {
136
136
  }
137
137
  ),
138
138
  /* @__PURE__ */ jsx(Alert, { status: "information", children: /* @__PURE__ */ jsxs(AlertDescription, { children: [
139
- /* @__PURE__ */ jsxs("p", { children: [
139
+ /* @__PURE__ */ jsxs("span", { className: "block", children: [
140
140
  /* @__PURE__ */ jsxs("strong", { children: [
141
141
  t("record_locks.settings.strategy_optimistic", "Optimistic"),
142
142
  ":"
@@ -147,7 +147,7 @@ function RecordLockingSettingsPage() {
147
147
  "Multiple users can edit at the same time; conflicts are checked on save."
148
148
  )
149
149
  ] }),
150
- /* @__PURE__ */ jsxs("p", { className: "mt-1", children: [
150
+ /* @__PURE__ */ jsxs("span", { className: "mt-1 block", children: [
151
151
  /* @__PURE__ */ jsxs("strong", { children: [
152
152
  t("record_locks.settings.strategy_pessimistic", "Pessimistic"),
153
153
  ":"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/record_locks/backend/settings/record-locks/page.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { apiCall, apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { TagsInput } from '@open-mercato/ui/backend/inputs'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Switch } from '@open-mercato/ui/primitives/switch'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { E } from '@open-mercato/core/generated-shims/entities.ids.generated'\nimport { DEFAULT_RECORD_LOCK_SETTINGS } from '../../../lib/config'\n\ntype RecordLockSettings = {\n enabled: boolean\n strategy: 'optimistic' | 'pessimistic'\n timeoutSeconds: number\n heartbeatSeconds: number\n enabledResources: string[]\n allowForceUnlock: boolean\n allowIncomingOverride: boolean\n notifyOnConflict: boolean\n}\n\nconst DEFAULT_SETTINGS: RecordLockSettings = {\n ...DEFAULT_RECORD_LOCK_SETTINGS,\n}\n\nconst RECORD_LOCK_RESOURCE_ALIASES = [\n 'customers.person',\n 'customers.company',\n 'customers.deal',\n 'sales.quote',\n 'sales.order',\n]\n\nconst RECORD_LOCK_RESOURCE_SUGGESTIONS = Array.from(\n new Set([\n ...Object.values(E).flatMap((moduleEntities) =>\n Object.values(moduleEntities).flatMap((entityId) => {\n if (typeof entityId !== 'string' || !entityId.includes(':')) return []\n return [entityId.replace(':', '.')]\n })\n ),\n ...RECORD_LOCK_RESOURCE_ALIASES,\n ]),\n).sort((left, right) => left.localeCompare(right))\n\nexport default function RecordLockingSettingsPage() {\n const t = useT()\n const [settings, setSettings] = React.useState<RecordLockSettings>(DEFAULT_SETTINGS)\n const [loading, setLoading] = React.useState(true)\n const [saving, setSaving] = React.useState(false)\n\n const normalizeResources = React.useCallback((input: string[]): string[] => {\n const seen = new Set<string>()\n const out: string[] = []\n for (const raw of input) {\n const resource = typeof raw === 'string' ? raw.trim() : ''\n if (!resource || seen.has(resource)) continue\n seen.add(resource)\n out.push(resource)\n }\n return out\n }, [])\n\n const load = React.useCallback(async () => {\n setLoading(true)\n try {\n const call = await apiCall<{ settings?: RecordLockSettings }>('/api/record_locks/settings')\n const next = call.result?.settings ?? DEFAULT_SETTINGS\n setSettings({\n ...next,\n enabledResources: normalizeResources(next.enabledResources ?? []),\n })\n } catch {\n flash(t('record_locks.settings.save_error', 'Failed to load settings'), 'error')\n } finally {\n setLoading(false)\n }\n }, [normalizeResources, t])\n\n React.useEffect(() => {\n void load()\n }, [load])\n\n const onSave = React.useCallback(async () => {\n setSaving(true)\n try {\n const payload: RecordLockSettings = {\n ...settings,\n enabledResources: normalizeResources(settings.enabledResources ?? []),\n }\n const call = await apiCallOrThrow<{ settings?: RecordLockSettings }>(\n '/api/record_locks/settings',\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n },\n { errorMessage: t('record_locks.settings.save_error', 'Failed to save settings') },\n )\n\n const next = call.result?.settings ?? payload\n setSettings({\n ...next,\n enabledResources: normalizeResources(next.enabledResources ?? []),\n })\n flash(t('record_locks.settings.saved', 'Settings saved'), 'success')\n } catch {\n flash(t('record_locks.settings.save_error', 'Failed to save settings'), 'error')\n } finally {\n setSaving(false)\n }\n }, [normalizeResources, settings, t])\n\n if (loading) {\n return (\n <div className=\"p-6\">\n <Spinner />\n </div>\n )\n }\n\n return (\n <div className=\"max-w-2xl space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">{t('record_locks.settings.title', 'Record locking')}</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {t('record_locks.settings.description', 'Configure optimistic/pessimistic locking and conflict handling.')}\n </p>\n </div>\n\n <div className=\"space-y-5 rounded-lg border p-4\">\n <div className=\"flex items-center justify-between gap-4\">\n <Label htmlFor=\"record-lock-enabled\">{t('record_locks.settings.enabled', 'Enable record locking')}</Label>\n <Switch\n id=\"record-lock-enabled\"\n checked={settings.enabled}\n onCheckedChange={(checked) => setSettings((prev) => ({ ...prev, enabled: checked }))}\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"record-lock-strategy\">{t('record_locks.settings.strategy', 'Strategy')}</Label>\n <select\n id=\"record-lock-strategy\"\n className=\"h-10 w-full rounded-md border bg-background px-3 text-sm\"\n value={settings.strategy}\n onChange={(event) => setSettings((prev) => ({\n ...prev,\n strategy: event.target.value === 'pessimistic' ? 'pessimistic' : 'optimistic',\n }))}\n >\n <option value=\"optimistic\">{t('record_locks.settings.strategy_optimistic', 'Optimistic')}</option>\n <option value=\"pessimistic\">{t('record_locks.settings.strategy_pessimistic', 'Pessimistic')}</option>\n </select>\n <Alert status=\"information\">\n <AlertDescription>\n <p>\n <strong>{t('record_locks.settings.strategy_optimistic', 'Optimistic')}:</strong>{' '}\n {t(\n 'record_locks.settings.strategy_help_optimistic',\n 'Multiple users can edit at the same time; conflicts are checked on save.',\n )}\n </p>\n <p className=\"mt-1\">\n <strong>{t('record_locks.settings.strategy_pessimistic', 'Pessimistic')}:</strong>{' '}\n {t(\n 'record_locks.settings.strategy_help_pessimistic',\n 'First editor acquires the lock and blocks concurrent edits until release.',\n )}\n </p>\n </AlertDescription>\n </Alert>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"record-lock-timeout\">{t('record_locks.settings.timeout_seconds', 'Lock timeout (seconds)')}</Label>\n <Input\n id=\"record-lock-timeout\"\n type=\"number\"\n min={30}\n max={3600}\n value={settings.timeoutSeconds}\n onChange={(event) => setSettings((prev) => ({\n ...prev,\n timeoutSeconds: Math.max(30, Math.min(3600, Number(event.target.value) || 30)),\n }))}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"record-lock-heartbeat\">{t('record_locks.settings.heartbeat_seconds', 'Heartbeat interval (seconds)')}</Label>\n <Input\n id=\"record-lock-heartbeat\"\n type=\"number\"\n min={5}\n max={300}\n value={settings.heartbeatSeconds}\n onChange={(event) => setSettings((prev) => ({\n ...prev,\n heartbeatSeconds: Math.max(5, Math.min(300, Number(event.target.value) || 5)),\n }))}\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label>{t('record_locks.settings.enabled_resources', 'Enabled resources')}</Label>\n <TagsInput\n value={settings.enabledResources}\n onChange={(next) => setSettings((prev) => ({ ...prev, enabledResources: normalizeResources(next) }))}\n suggestions={RECORD_LOCK_RESOURCE_SUGGESTIONS}\n allowCustomValues\n disabled={saving}\n placeholder={t(\n 'record_locks.settings.enabled_resources_placeholder',\n 'Add resource kind and press Enter',\n )}\n />\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'record_locks.settings.enabled_resources_hint',\n 'Pick from suggestions or type a custom resource kind.',\n )}\n </p>\n </div>\n\n <div className=\"flex items-center justify-between gap-4\">\n <Label htmlFor=\"record-lock-force-unlock\">{t('record_locks.settings.allow_force_unlock', 'Allow force unlock')}</Label>\n <Switch\n id=\"record-lock-force-unlock\"\n checked={settings.allowForceUnlock}\n onCheckedChange={(checked) => setSettings((prev) => ({ ...prev, allowForceUnlock: checked }))}\n />\n </div>\n\n <div className=\"flex items-center justify-between gap-4\">\n <Label htmlFor=\"record-lock-allow-incoming-override\">\n {t('record_locks.settings.allow_incoming_override', 'Allow overriding incoming changes')}\n </Label>\n <Switch\n id=\"record-lock-allow-incoming-override\"\n checked={settings.allowIncomingOverride}\n onCheckedChange={(checked) => setSettings((prev) => ({ ...prev, allowIncomingOverride: checked }))}\n />\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'record_locks.settings.allow_incoming_override_hint',\n 'Users still need the record_locks.override_incoming feature in their role or user ACL to keep their version during conflicts.'\n )}{' '}\n <Link href=\"/backend/users\" className=\"underline underline-offset-2 hover:text-foreground\">\n {t('record_locks.settings.allow_incoming_override_permissions_link', 'Check permissions')}\n </Link>\n </p>\n\n <div className=\"flex items-center justify-between gap-4\">\n <Label htmlFor=\"record-lock-notify-conflict\">{t('record_locks.settings.notify_on_conflict', 'Notify on conflict')}</Label>\n <Switch\n id=\"record-lock-notify-conflict\"\n checked={settings.notifyOnConflict}\n onCheckedChange={(checked) => setSettings((prev) => ({ ...prev, notifyOnConflict: checked }))}\n />\n </div>\n\n <div className=\"pt-2\">\n <Button onClick={() => void onSave()} disabled={saving}>\n {saving ? t('ui.forms.status.saving', 'Saving...') : t('record_locks.settings.save', 'Save settings')}\n </Button>\n </div>\n </div>\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { apiCall, apiCallOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { TagsInput } from '@open-mercato/ui/backend/inputs'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Switch } from '@open-mercato/ui/primitives/switch'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { E } from '@open-mercato/core/generated-shims/entities.ids.generated'\nimport { DEFAULT_RECORD_LOCK_SETTINGS } from '../../../lib/config'\n\ntype RecordLockSettings = {\n enabled: boolean\n strategy: 'optimistic' | 'pessimistic'\n timeoutSeconds: number\n heartbeatSeconds: number\n enabledResources: string[]\n allowForceUnlock: boolean\n allowIncomingOverride: boolean\n notifyOnConflict: boolean\n}\n\nconst DEFAULT_SETTINGS: RecordLockSettings = {\n ...DEFAULT_RECORD_LOCK_SETTINGS,\n}\n\nconst RECORD_LOCK_RESOURCE_ALIASES = [\n 'customers.person',\n 'customers.company',\n 'customers.deal',\n 'sales.quote',\n 'sales.order',\n]\n\nconst RECORD_LOCK_RESOURCE_SUGGESTIONS = Array.from(\n new Set([\n ...Object.values(E).flatMap((moduleEntities) =>\n Object.values(moduleEntities).flatMap((entityId) => {\n if (typeof entityId !== 'string' || !entityId.includes(':')) return []\n return [entityId.replace(':', '.')]\n })\n ),\n ...RECORD_LOCK_RESOURCE_ALIASES,\n ]),\n).sort((left, right) => left.localeCompare(right))\n\nexport default function RecordLockingSettingsPage() {\n const t = useT()\n const [settings, setSettings] = React.useState<RecordLockSettings>(DEFAULT_SETTINGS)\n const [loading, setLoading] = React.useState(true)\n const [saving, setSaving] = React.useState(false)\n\n const normalizeResources = React.useCallback((input: string[]): string[] => {\n const seen = new Set<string>()\n const out: string[] = []\n for (const raw of input) {\n const resource = typeof raw === 'string' ? raw.trim() : ''\n if (!resource || seen.has(resource)) continue\n seen.add(resource)\n out.push(resource)\n }\n return out\n }, [])\n\n const load = React.useCallback(async () => {\n setLoading(true)\n try {\n const call = await apiCall<{ settings?: RecordLockSettings }>('/api/record_locks/settings')\n const next = call.result?.settings ?? DEFAULT_SETTINGS\n setSettings({\n ...next,\n enabledResources: normalizeResources(next.enabledResources ?? []),\n })\n } catch {\n flash(t('record_locks.settings.save_error', 'Failed to load settings'), 'error')\n } finally {\n setLoading(false)\n }\n }, [normalizeResources, t])\n\n React.useEffect(() => {\n void load()\n }, [load])\n\n const onSave = React.useCallback(async () => {\n setSaving(true)\n try {\n const payload: RecordLockSettings = {\n ...settings,\n enabledResources: normalizeResources(settings.enabledResources ?? []),\n }\n const call = await apiCallOrThrow<{ settings?: RecordLockSettings }>(\n '/api/record_locks/settings',\n {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n },\n { errorMessage: t('record_locks.settings.save_error', 'Failed to save settings') },\n )\n\n const next = call.result?.settings ?? payload\n setSettings({\n ...next,\n enabledResources: normalizeResources(next.enabledResources ?? []),\n })\n flash(t('record_locks.settings.saved', 'Settings saved'), 'success')\n } catch {\n flash(t('record_locks.settings.save_error', 'Failed to save settings'), 'error')\n } finally {\n setSaving(false)\n }\n }, [normalizeResources, settings, t])\n\n if (loading) {\n return (\n <div className=\"p-6\">\n <Spinner />\n </div>\n )\n }\n\n return (\n <div className=\"max-w-2xl space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold\">{t('record_locks.settings.title', 'Record locking')}</h1>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {t('record_locks.settings.description', 'Configure optimistic/pessimistic locking and conflict handling.')}\n </p>\n </div>\n\n <div className=\"space-y-5 rounded-lg border p-4\">\n <div className=\"flex items-center justify-between gap-4\">\n <Label htmlFor=\"record-lock-enabled\">{t('record_locks.settings.enabled', 'Enable record locking')}</Label>\n <Switch\n id=\"record-lock-enabled\"\n checked={settings.enabled}\n onCheckedChange={(checked) => setSettings((prev) => ({ ...prev, enabled: checked }))}\n />\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"record-lock-strategy\">{t('record_locks.settings.strategy', 'Strategy')}</Label>\n <select\n id=\"record-lock-strategy\"\n className=\"h-10 w-full rounded-md border bg-background px-3 text-sm\"\n value={settings.strategy}\n onChange={(event) => setSettings((prev) => ({\n ...prev,\n strategy: event.target.value === 'pessimistic' ? 'pessimistic' : 'optimistic',\n }))}\n >\n <option value=\"optimistic\">{t('record_locks.settings.strategy_optimistic', 'Optimistic')}</option>\n <option value=\"pessimistic\">{t('record_locks.settings.strategy_pessimistic', 'Pessimistic')}</option>\n </select>\n <Alert status=\"information\">\n <AlertDescription>\n <span className=\"block\">\n <strong>{t('record_locks.settings.strategy_optimistic', 'Optimistic')}:</strong>{' '}\n {t(\n 'record_locks.settings.strategy_help_optimistic',\n 'Multiple users can edit at the same time; conflicts are checked on save.',\n )}\n </span>\n <span className=\"mt-1 block\">\n <strong>{t('record_locks.settings.strategy_pessimistic', 'Pessimistic')}:</strong>{' '}\n {t(\n 'record_locks.settings.strategy_help_pessimistic',\n 'First editor acquires the lock and blocks concurrent edits until release.',\n )}\n </span>\n </AlertDescription>\n </Alert>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"record-lock-timeout\">{t('record_locks.settings.timeout_seconds', 'Lock timeout (seconds)')}</Label>\n <Input\n id=\"record-lock-timeout\"\n type=\"number\"\n min={30}\n max={3600}\n value={settings.timeoutSeconds}\n onChange={(event) => setSettings((prev) => ({\n ...prev,\n timeoutSeconds: Math.max(30, Math.min(3600, Number(event.target.value) || 30)),\n }))}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"record-lock-heartbeat\">{t('record_locks.settings.heartbeat_seconds', 'Heartbeat interval (seconds)')}</Label>\n <Input\n id=\"record-lock-heartbeat\"\n type=\"number\"\n min={5}\n max={300}\n value={settings.heartbeatSeconds}\n onChange={(event) => setSettings((prev) => ({\n ...prev,\n heartbeatSeconds: Math.max(5, Math.min(300, Number(event.target.value) || 5)),\n }))}\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label>{t('record_locks.settings.enabled_resources', 'Enabled resources')}</Label>\n <TagsInput\n value={settings.enabledResources}\n onChange={(next) => setSettings((prev) => ({ ...prev, enabledResources: normalizeResources(next) }))}\n suggestions={RECORD_LOCK_RESOURCE_SUGGESTIONS}\n allowCustomValues\n disabled={saving}\n placeholder={t(\n 'record_locks.settings.enabled_resources_placeholder',\n 'Add resource kind and press Enter',\n )}\n />\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'record_locks.settings.enabled_resources_hint',\n 'Pick from suggestions or type a custom resource kind.',\n )}\n </p>\n </div>\n\n <div className=\"flex items-center justify-between gap-4\">\n <Label htmlFor=\"record-lock-force-unlock\">{t('record_locks.settings.allow_force_unlock', 'Allow force unlock')}</Label>\n <Switch\n id=\"record-lock-force-unlock\"\n checked={settings.allowForceUnlock}\n onCheckedChange={(checked) => setSettings((prev) => ({ ...prev, allowForceUnlock: checked }))}\n />\n </div>\n\n <div className=\"flex items-center justify-between gap-4\">\n <Label htmlFor=\"record-lock-allow-incoming-override\">\n {t('record_locks.settings.allow_incoming_override', 'Allow overriding incoming changes')}\n </Label>\n <Switch\n id=\"record-lock-allow-incoming-override\"\n checked={settings.allowIncomingOverride}\n onCheckedChange={(checked) => setSettings((prev) => ({ ...prev, allowIncomingOverride: checked }))}\n />\n </div>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'record_locks.settings.allow_incoming_override_hint',\n 'Users still need the record_locks.override_incoming feature in their role or user ACL to keep their version during conflicts.'\n )}{' '}\n <Link href=\"/backend/users\" className=\"underline underline-offset-2 hover:text-foreground\">\n {t('record_locks.settings.allow_incoming_override_permissions_link', 'Check permissions')}\n </Link>\n </p>\n\n <div className=\"flex items-center justify-between gap-4\">\n <Label htmlFor=\"record-lock-notify-conflict\">{t('record_locks.settings.notify_on_conflict', 'Notify on conflict')}</Label>\n <Switch\n id=\"record-lock-notify-conflict\"\n checked={settings.notifyOnConflict}\n onCheckedChange={(checked) => setSettings((prev) => ({ ...prev, notifyOnConflict: checked }))}\n />\n </div>\n\n <div className=\"pt-2\">\n <Button onClick={() => void onSave()} disabled={saving}>\n {saving ? t('ui.forms.status.saving', 'Saving...') : t('record_locks.settings.save', 'Save settings')}\n </Button>\n </div>\n </div>\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/enterprise",
3
- "version": "0.6.8-develop.7101.1.bd9356828a",
3
+ "version": "0.7.1-develop.7102.1.b41f7e3e51",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -65,8 +65,8 @@
65
65
  }
66
66
  },
67
67
  "dependencies": {
68
- "@open-mercato/core": "0.6.8-develop.7101.1.bd9356828a",
69
- "@open-mercato/ui": "0.6.8-develop.7101.1.bd9356828a",
68
+ "@open-mercato/core": "0.7.1-develop.7102.1.b41f7e3e51",
69
+ "@open-mercato/ui": "0.7.1-develop.7102.1.b41f7e3e51",
70
70
  "@simplewebauthn/browser": "^13.3.0",
71
71
  "@simplewebauthn/server": "^13.3.2",
72
72
  "@simplewebauthn/types": "^12.0.0",
@@ -76,12 +76,12 @@
76
76
  "qrcode": "^1.5.4"
77
77
  },
78
78
  "peerDependencies": {
79
- "@open-mercato/shared": "0.6.8-develop.7101.1.bd9356828a",
79
+ "@open-mercato/shared": "0.7.1-develop.7102.1.b41f7e3e51",
80
80
  "react": "^19.0.0",
81
81
  "react-dom": "^19.0.0"
82
82
  },
83
83
  "devDependencies": {
84
- "@open-mercato/shared": "0.6.8-develop.7101.1.bd9356828a",
84
+ "@open-mercato/shared": "0.7.1-develop.7102.1.b41f7e3e51",
85
85
  "@types/jest": "^30.0.0",
86
86
  "@types/react": "^19.2.17",
87
87
  "@types/react-dom": "^19.2.3",
@@ -99,5 +99,5 @@
99
99
  "url": "https://github.com/open-mercato/open-mercato",
100
100
  "directory": "packages/enterprise"
101
101
  },
102
- "stableVersion": "0.6.7"
102
+ "stableVersion": "0.7.0"
103
103
  }
@@ -161,20 +161,20 @@ export default function RecordLockingSettingsPage() {
161
161
  </select>
162
162
  <Alert status="information">
163
163
  <AlertDescription>
164
- <p>
164
+ <span className="block">
165
165
  <strong>{t('record_locks.settings.strategy_optimistic', 'Optimistic')}:</strong>{' '}
166
166
  {t(
167
167
  'record_locks.settings.strategy_help_optimistic',
168
168
  'Multiple users can edit at the same time; conflicts are checked on save.',
169
169
  )}
170
- </p>
171
- <p className="mt-1">
170
+ </span>
171
+ <span className="mt-1 block">
172
172
  <strong>{t('record_locks.settings.strategy_pessimistic', 'Pessimistic')}:</strong>{' '}
173
173
  {t(
174
174
  'record_locks.settings.strategy_help_pessimistic',
175
175
  'First editor acquires the lock and blocks concurrent edits until release.',
176
176
  )}
177
- </p>
177
+ </span>
178
178
  </AlertDescription>
179
179
  </Alert>
180
180
  </div>