feat(10-02): backend strings, controller messages and declarative toolbar
- phrasebook ships the backend::lang admin strings (pl, en) with CLDR plural maps, loads them as namespace backend, applies pact.HasLangOverrides trees (lang/<locale>/<namespace>/<group>.yaml) after every namespace, and fails activation when a backend key cannot convert to plural forms - Translator.Forms, Bundle, Resolved and Has serve keys as CLDR form maps - Public GET /lang returns every backend::lang key for the request locale over the fallback locale, Cache-Control no-cache - config_list, config_form and config_relation accept a strict messages block; omitted keys take framework defaults, schemas serve every message as CLDR forms, and activation fails on a missing phrase key - toolbar.buttons is an ordered [create, delete] list; the Winter string form, duplicates, unknown actions and delete without showCheckboxes fail at boot, and create is dropped when the controller has no form - Form schema serves the raw Winter redirects; scaffold emits the list syntax; form and relation schema routes are typed in the admin OpenAPI
This commit is contained in:
@@ -154,6 +154,36 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.Envelope-cabana_FormView": {
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/cabana.FormView"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/cabana.SuccessMeta"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data",
|
||||
"meta"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.Envelope-cabana_LangBundle": {
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/cabana.LangBundle"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/cabana.SuccessMeta"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data",
|
||||
"meta"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.Envelope-cabana_ListSchema": {
|
||||
"properties": {
|
||||
"data": {
|
||||
@@ -169,6 +199,21 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.Envelope-cabana_RelationSchema": {
|
||||
"properties": {
|
||||
"data": {
|
||||
"$ref": "#/components/schemas/cabana.RelationSchema"
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/cabana.SuccessMeta"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"data",
|
||||
"meta"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.ErrorBody": {
|
||||
"properties": {
|
||||
"code": {
|
||||
@@ -200,6 +245,99 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.FormField": {
|
||||
"properties": {
|
||||
"attributes": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/components/schemas/cabana.jsonScalar"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"comment": {
|
||||
"type": "string"
|
||||
},
|
||||
"context": {
|
||||
"$ref": "#/components/schemas/cabana.fieldContext"
|
||||
},
|
||||
"default": {
|
||||
"$ref": "#/components/schemas/cabana.jsonScalar"
|
||||
},
|
||||
"emptyOption": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"multiple": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"nameFrom": {
|
||||
"type": "string"
|
||||
},
|
||||
"options": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/cabana.FormOption"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"readOnly": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"relation": {
|
||||
"type": "string"
|
||||
},
|
||||
"required": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"size": {
|
||||
"type": "string"
|
||||
},
|
||||
"span": {
|
||||
"type": "string"
|
||||
},
|
||||
"tab": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.FormMessages": {
|
||||
"properties": {
|
||||
"create": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"deleteConfirm": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"deleted": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"saved": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"update": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"create",
|
||||
"deleteConfirm",
|
||||
"deleted",
|
||||
"saved",
|
||||
"update"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.FormMeta": {
|
||||
"properties": {
|
||||
"locale": {
|
||||
@@ -226,6 +364,88 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.FormRedirect": {
|
||||
"properties": {
|
||||
"redirect": {
|
||||
"type": "string"
|
||||
},
|
||||
"redirectClose": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"redirect",
|
||||
"redirectClose"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.FormRedirects": {
|
||||
"properties": {
|
||||
"create": {
|
||||
"$ref": "#/components/schemas/cabana.FormRedirect"
|
||||
},
|
||||
"default": {
|
||||
"type": "string"
|
||||
},
|
||||
"update": {
|
||||
"$ref": "#/components/schemas/cabana.FormRedirect"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"create",
|
||||
"default",
|
||||
"update"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.FormView": {
|
||||
"properties": {
|
||||
"fields": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/cabana.FormField"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"messages": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/cabana.FormMessages"
|
||||
}
|
||||
],
|
||||
"description": "Messages is the form's copy resolved in the request locale (D-13)."
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/cabana.FormMeta"
|
||||
},
|
||||
"modelClass": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"redirects": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/cabana.FormRedirects"
|
||||
}
|
||||
],
|
||||
"description": "Redirects are the raw Winter config_form.yaml targets; the SPA maps\nthem onto its routes."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"fields",
|
||||
"messages",
|
||||
"meta",
|
||||
"redirects"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.LangBundle": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.ListColumn": {
|
||||
"properties": {
|
||||
"key": {
|
||||
@@ -337,6 +557,53 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.ListMessages": {
|
||||
"properties": {
|
||||
"create": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"deleteConfirm": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"deleteSelected": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"deleted": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"empty": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"emptySearch": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"emptySearchHint": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"recordCount": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"searchPrompt": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"selected": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"create",
|
||||
"deleteConfirm",
|
||||
"deleteSelected",
|
||||
"deleted",
|
||||
"empty",
|
||||
"emptySearch",
|
||||
"emptySearchHint",
|
||||
"recordCount",
|
||||
"searchPrompt",
|
||||
"selected"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.ListMeta": {
|
||||
"properties": {
|
||||
"last_page": {
|
||||
@@ -383,6 +650,14 @@
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"messages": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/cabana.ListMessages"
|
||||
}
|
||||
],
|
||||
"description": "Messages is the list's copy (D-13). The cached schema carries each\nphrase key as its own form; a response resolves them in its locale."
|
||||
},
|
||||
"meta": {
|
||||
"$ref": "#/components/schemas/cabana.FormMeta"
|
||||
},
|
||||
@@ -442,6 +717,7 @@
|
||||
"bulkActions",
|
||||
"columns",
|
||||
"filters",
|
||||
"messages",
|
||||
"perPageOptions",
|
||||
"recordsPerPage",
|
||||
"rowActions",
|
||||
@@ -469,6 +745,12 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.MessageForms": {
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.NavigationEntry": {
|
||||
"properties": {
|
||||
"code": {
|
||||
@@ -535,6 +817,82 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.RelationColumn": {
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"searchable": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"sortable": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"key",
|
||||
"label",
|
||||
"searchable",
|
||||
"sortable"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.RelationList": {
|
||||
"properties": {
|
||||
"columns": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/cabana.RelationColumn"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"columns"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.RelationMessages": {
|
||||
"properties": {
|
||||
"candidateSearch": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"empty": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"link": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"linkHint": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"linked": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"unlinkConfirm": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"unlinkSelected": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
},
|
||||
"unlinked": {
|
||||
"$ref": "#/components/schemas/cabana.MessageForms"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"candidateSearch",
|
||||
"empty",
|
||||
"link",
|
||||
"linkHint",
|
||||
"linked",
|
||||
"unlinkConfirm",
|
||||
"unlinkSelected",
|
||||
"unlinked"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.RelationOption": {
|
||||
"properties": {
|
||||
"label": {
|
||||
@@ -550,6 +908,60 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.RelationPanel": {
|
||||
"properties": {
|
||||
"list": {
|
||||
"$ref": "#/components/schemas/cabana.RelationList"
|
||||
},
|
||||
"showSearch": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"toolbarButtons": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"list",
|
||||
"showSearch",
|
||||
"toolbarButtons"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.RelationSchema": {
|
||||
"properties": {
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"manage": {
|
||||
"$ref": "#/components/schemas/cabana.RelationPanel"
|
||||
},
|
||||
"messages": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/cabana.RelationMessages"
|
||||
}
|
||||
],
|
||||
"description": "Messages is the relation manager's copy (D-13); the cached schema\ncarries each phrase key as its own form."
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"view": {
|
||||
"$ref": "#/components/schemas/cabana.RelationPanel"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"label",
|
||||
"manage",
|
||||
"messages",
|
||||
"name",
|
||||
"view"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.RowAction": {
|
||||
"properties": {
|
||||
"label": {
|
||||
@@ -600,6 +1012,19 @@
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"cabana.fieldContext": {
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
]
|
||||
},
|
||||
"cabana.jsonScalar": {
|
||||
"nullable": true,
|
||||
"oneOf": [
|
||||
@@ -803,6 +1228,27 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/lang": {
|
||||
"get": {
|
||||
"description": "Every backend::lang key as CLDR plural forms for the Accept-Language locale, over the fallback locale's keys. Public: the login screen loads it before signing in. meta.locale is the locale the bundle resolved to.",
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/cabana.Envelope-cabana_LangBundle"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "OK"
|
||||
}
|
||||
},
|
||||
"summary": "Admin UI strings",
|
||||
"tags": [
|
||||
"admin"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/navigation": {
|
||||
"get": {
|
||||
"responses": {
|
||||
@@ -1544,7 +1990,7 @@
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
|
||||
"$ref": "#/components/schemas/cabana.Envelope-cabana_FormView"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1721,7 +2167,7 @@
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/cabana.SuccessEnvelope"
|
||||
"$ref": "#/components/schemas/cabana.Envelope-cabana_RelationSchema"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user