Merge branch 'fix/schema-editor-approval-aware' into 'main'
fix(ui): DictionaryEditorDialog disables Save when draft workflow needed See merge request 2-6/2-6-4/terravault/ordinis!183
This commit is contained in:
@@ -138,6 +138,24 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
|
|||||||
[isEdit, initial, changes, schemaVersion],
|
[isEdit, initial, changes, schemaVersion],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Approval-aware Save: when editing an approval-required dict, any schema
|
||||||
|
// change OR toggling approvalRequired off OR changing approvalMinRole has
|
||||||
|
// to route through the schema-draft workflow. The backend will reject with
|
||||||
|
// 422 approval_required, but it's much better UX to disable Save up front
|
||||||
|
// and tell the user to open a draft instead. Mirror the three backend
|
||||||
|
// gate clauses exactly so the UX matches the server contract.
|
||||||
|
const wasApprovalRequired =
|
||||||
|
Boolean((initial as { approvalRequired?: boolean } | null)?.approvalRequired)
|
||||||
|
const initialMinRole =
|
||||||
|
((initial as { approvalMinRole?: string } | null)?.approvalMinRole ?? '') || null
|
||||||
|
const currentMinRole = approvalMinRole.trim() === '' ? null : approvalMinRole.trim()
|
||||||
|
const schemaChangedFromInitial = isEdit && changes.length > 0
|
||||||
|
const approvalToggledOff = isEdit && wasApprovalRequired && !approvalRequired
|
||||||
|
const minRoleChanged = isEdit && wasApprovalRequired && initialMinRole !== currentMinRole
|
||||||
|
const requiresDraftFlow =
|
||||||
|
isEdit && wasApprovalRequired
|
||||||
|
&& (schemaChangedFromInitial || approvalToggledOff || minRoleChanged)
|
||||||
|
|
||||||
const activeMutation = isEdit ? updateMut : createMut
|
const activeMutation = isEdit ? updateMut : createMut
|
||||||
const serverError = serverErrorMessage(activeMutation.error)
|
const serverError = serverErrorMessage(activeMutation.error)
|
||||||
|
|
||||||
@@ -412,6 +430,17 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
|
|||||||
|
|
||||||
{serverError && <Alert variant="error">{serverError}</Alert>}
|
{serverError && <Alert variant="error">{serverError}</Alert>}
|
||||||
|
|
||||||
|
{requiresDraftFlow && (
|
||||||
|
<Alert variant="warning">
|
||||||
|
{t('schema.approvalRequired.editorBlock', {
|
||||||
|
defaultValue:
|
||||||
|
'Этот словарь требует ревью изменений. Закройте редактор и нажмите ' +
|
||||||
|
'«Создать черновик схемы» на странице справочника — там вы сможете ' +
|
||||||
|
'отправить эти изменения на согласование.',
|
||||||
|
})}
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
|
||||||
<FormActions align="end">
|
<FormActions align="end">
|
||||||
<Button type="button" variant="ghost" onClick={onClose} disabled={activeMutation.isPending}>
|
<Button type="button" variant="ghost" onClick={onClose} disabled={activeMutation.isPending}>
|
||||||
{t('form.cancel')}
|
{t('form.cancel')}
|
||||||
@@ -420,7 +449,7 @@ export const DictionaryEditorDialog = ({ open, mode, onClose, onSuccess }: Props
|
|||||||
type="button"
|
type="button"
|
||||||
variant="primary"
|
variant="primary"
|
||||||
loading={activeMutation.isPending}
|
loading={activeMutation.isPending}
|
||||||
disabled={isEdit && breaking}
|
disabled={(isEdit && breaking) || requiresDraftFlow}
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}
|
||||||
>
|
>
|
||||||
{activeMutation.isPending ? t('form.saving') : t('form.save')}
|
{activeMutation.isPending ? t('form.saving') : t('form.save')}
|
||||||
|
|||||||
Reference in New Issue
Block a user