mirror of
https://github.com/Tria-plc/emaui.git
synced 2026-09-06 12:25:03 +00:00
feat: add non-expiring license support to backoffice and portal UI with updated i18n and selective form patching
This commit is contained in:
@@ -84,9 +84,11 @@ export function DesignerToolbar({
|
||||
<Text size="sm" fw={600}>
|
||||
{validityDays != null
|
||||
? t('designer.validityDays', '{{count}} days', { count: validityDays })
|
||||
: t('designer.validityMonths', '{{count}} months', {
|
||||
count: validityMonths,
|
||||
})}
|
||||
: validityMonths
|
||||
? t('designer.validityMonths', '{{count}} months', {
|
||||
count: validityMonths,
|
||||
})
|
||||
: t('designer.validityNone', 'Does not expire')}
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed">
|
||||
{t('designer.validityEditedOn', '— set on Certificate Requirements → Behaviour')}
|
||||
|
||||
@@ -72,9 +72,13 @@ function toDraft(licenseType: LicenseType): Draft {
|
||||
licenseType.capitalThreshold == null
|
||||
? null
|
||||
: Number(licenseType.capitalThreshold),
|
||||
// Zero is a real stored state for `validityMonths` (a type that issues
|
||||
// nothing with an expiry) and is kept. Zero in the other two is not a
|
||||
// policy anyone set — it is an unfilled column — and seeding a box with a
|
||||
// value below its own floor only produces a save the server rejects.
|
||||
validityMonths: licenseType.validityMonths ?? 12,
|
||||
validityDays: licenseType.validityDays ?? null,
|
||||
renewalWindowDays: licenseType.renewalWindowDays ?? 60,
|
||||
validityDays: licenseType.validityDays || null,
|
||||
renewalWindowDays: licenseType.renewalWindowDays || 60,
|
||||
expiryReminderDays: licenseType.expiryReminderDays ?? [60, 30, 7],
|
||||
requiresOperatorMode: licenseType.requiresOperatorMode ?? true,
|
||||
allowMultipleOpenDrafts: licenseType.allowMultipleOpenDrafts ?? false,
|
||||
@@ -128,9 +132,38 @@ export function BehaviorTab({ licenseType }: { licenseType: LicenseType }) {
|
||||
// against an expiry that never arrives, so none of them are asked for.
|
||||
const expires = draft.validityDays !== null || draft.validityMonths > 0;
|
||||
|
||||
// The server's floor for a stated term is 6 months, so no-expiry is a state
|
||||
// this form can hold and edit around but cannot switch a type into. Offered
|
||||
// only where it is already what the type is, rather than as an option whose
|
||||
// save would be refused.
|
||||
const noExpiryAvailable =
|
||||
(licenseType.validityMonths ?? 12) === 0 && !licenseType.validityDays;
|
||||
|
||||
async function onSave() {
|
||||
// Only the settings this form actually asked for. The endpoint patches, so
|
||||
// an omitted field keeps its stored value — and the fields hidden above are
|
||||
// hidden precisely because the type has no such policy, which the server
|
||||
// stores as a zero its own validators then refuse (`validityMonths` has a
|
||||
// floor of 6, `renewalWindowDays` of 1). Echoing those back is what made
|
||||
// saving an ownership transfer fail outright.
|
||||
const {
|
||||
validityMonths,
|
||||
validityDays,
|
||||
renewalWindowDays,
|
||||
expiryReminderDays,
|
||||
...rest
|
||||
} = draft;
|
||||
|
||||
const ok = await run(
|
||||
() => save({ id: licenseType.id, ...draft }).unwrap(),
|
||||
() =>
|
||||
save({
|
||||
id: licenseType.id,
|
||||
...rest,
|
||||
...(expires ? { validityMonths, validityDays } : {}),
|
||||
...(expires && draft.renewalEnabled
|
||||
? { renewalWindowDays, expiryReminderDays }
|
||||
: {}),
|
||||
}).unwrap(),
|
||||
t('certReq.behavior.saved', 'Configuration saved.'),
|
||||
);
|
||||
if (ok) setDirty(false);
|
||||
@@ -334,7 +367,14 @@ export function BehaviorTab({ licenseType }: { licenseType: LicenseType }) {
|
||||
data={[
|
||||
{ value: 'MONTHS', label: t('certReq.behavior.unitMonths', 'Months') },
|
||||
{ value: 'DAYS', label: t('certReq.behavior.unitDays', 'Days') },
|
||||
{ value: 'NONE', label: t('certReq.behavior.unitNone', 'Does not expire') },
|
||||
...(noExpiryAvailable
|
||||
? [
|
||||
{
|
||||
value: 'NONE',
|
||||
label: t('certReq.behavior.unitNone', 'Does not expire'),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
]}
|
||||
value={
|
||||
draft.validityDays !== null
|
||||
|
||||
@@ -1253,6 +1253,7 @@ export const am: Translations = {
|
||||
validityMonths_other: "{{count}} ወራት",
|
||||
validityDays_one: "{{count}} ቀን",
|
||||
validityDays_other: "{{count}} ቀናት",
|
||||
validityNone: "ጊዜው አያልፍም",
|
||||
validityEditedOn: "— በምስክር ወረቀት መስፈርቶች → ባህሪ ውስጥ ይዘጋጃል",
|
||||
newVersion: "አዲስ ስሪት",
|
||||
versions: "ስሪቶች",
|
||||
|
||||
@@ -1260,6 +1260,7 @@ export const en = {
|
||||
validityMonths_other: '{{count}} months',
|
||||
validityDays_one: '{{count}} day',
|
||||
validityDays_other: '{{count}} days',
|
||||
validityNone: 'Does not expire',
|
||||
validityEditedOn: '— set on Certificate Requirements → Behaviour',
|
||||
newVersion: 'New version',
|
||||
versions: 'Versions',
|
||||
|
||||
Reference in New Issue
Block a user