Definición de aplicación basada en modelo
Id del esquema: model-driven-app@1
Esquema legible por máquina: model-driven-app.schema.json
La representación canónica de una aplicación basada en modelo (sección 6.7): una aplicación con nombre que agrupa un subconjunto seleccionado de las tablas, paneles e informes del entorno en una navegación (mapa del sitio) con una página de inicio, como hace una aplicación basada en modelo de Power Apps. Se valida de forma idéntica tanto si procede del diseñador como de una llamada a la API, de un asistente de IA o de una importación de solución.
Forma
| Campo | Tipo | Obligatorio | Notas |
|---|---|---|---|
logicalName | string | sí | Con el prefijo del editor, en snake_case en minúsculas (por ejemplo, par_sales_app). |
displayName | string | sí | Nombre legible de la aplicación que se muestra en el mosaico del iniciador. |
publisherPrefix | string | sí | El prefijo del editor propietario; el nombre lógico debe empezar por él. |
description | string | no | Descripción breve que se muestra en el mosaico del iniciador. |
icon | string | no | Clave del icono para el mosaico del iniciador y la cabecera del carril de la aplicación. |
supportsTasks | boolean | no | Indica si esta aplicación participa en procesos de negocio. Si está activado, el Shell ofrece la lista de tareas y el botón Decidir mientras la aplicación está abierta; si está desactivado, no muestra ninguno de los dos. Desactivado es el valor predeterminado, porque la mayoría de las aplicaciones no forman parte de un proceso, y una bandeja de entrada en una de ellas es un adorno que nunca tiene nada dentro. |
home | destino | sí | Lo que se abre en /apps/{id}; debe aparecer en navigation. Vea más abajo. |
navigation | array | sí | Uno o varios grupos de navegación (el mapa del sitio; vea más abajo). |
includes | array | no | Los componentes de la aplicación: cosas que puede abrir y que no están en su mapa del sitio. Vea más abajo. |
Destino
Un lugar al que puede ir la aplicación: una sola forma, que se usa para un elemento de
navegación y para home. Es deliberado y no casual: así, «la página de inicio debe ser un
lugar al que lleva la navegación» es una comparación de dos valores del mismo tipo, en lugar de
tres comprobaciones casi idénticas que podrían ir divergiendo tipo a tipo.
| Campo | Tipo | Obligatorio | Notas |
|---|---|---|---|
type | Entity | Dashboard | Report | sí | Las tres cosas que el reproductor puede poner en pantalla: una cuadrícula, un host de panel y un visor de informes. |
target | string | sí | El nombre lógico del destino. El almacén en el que debe existir lo decide type. |
Grupo de navegación
| Campo | Tipo | Obligatorio | Notas |
|---|---|---|---|
title | string | sí | Encabezado del grupo que se muestra en la navegación izquierda de la aplicación. |
items | array | sí | Uno o varios elementos de navegación (vea más abajo). |
Elemento de navegación
Un destino, más cómo quiere etiquetarlo esta aplicación. Las sustituciones de etiqueta e icono se aplican a todos los tipos: una aplicación que llama «Clientes» a la tabla Accounts tiene el mismo motivo para llamar «Hoy» a un panel.
| Campo | Tipo | Obligatorio | Notas |
|---|---|---|---|
type | Entity | Dashboard | Report | sí | Lo que abre este elemento. |
target | string | sí | Su nombre lógico (debe existir en el entorno, como ese tipo de cosa). |
displayName | string | no | Etiqueta que sustituye a la del componente en el carril de esta aplicación; si se omite, se usa el nombre para mostrar del propio componente. |
icon | string | no | Clave del icono para el elemento del carril. |
forms | array of string | no | Solo para elementos de entidad. Los formularios de esta tabla que ofrece esta aplicación, por nombre lógico. Vea más abajo. |
views | array of string | no | Solo para elementos de entidad. Las vistas de esta tabla que ofrece esta aplicación, por nombre lógico. |
Cada destino al que se hace referencia —en un elemento de navegación y en home— debe existir en
el entorno en el almacén que indica su propio tipo, y home debe coincidir con uno de los
elementos de navegación tanto por type como por target. Ambas reglas se aplican al guardar,
además de la validación del esquema (modelapps.app.unknown_entity,
modelapps.app.unknown_dashboard, modelapps.app.unknown_report,
modelapps.app.home_not_in_navigation).
forms y views en un elemento Dashboard o Report se rechazan, no se ignoran
(modelapps.app.component_selection_not_allowed): ninguno de los dos tiene formularios ni
vistas, así que una selección ahí es un error de creación que, de lo contrario, desaparecería en
silencio y haría creer a su autor que había restringido algo.
Quién puede abrirlo
Abrir un panel y ejecutar un informe son concesiones sobre ese componente: permisos llamados
<logicalName>.Open y <logicalName>.Run, que un rol de seguridad posee como cualquier otro, con
*.Open / *.Run como comodines que siguen cubriendo todo lo que se cree después. Colocar uno en
un mapa del sitio no lo concede. Lo que leen luego los widgets del panel y los conjuntos de datos
del informe se autoriza por sí mismo en cualquier caso, así que un usuario que llega a un panel
sin datos a los que tenga acceso ve widgets vacíos y no las cifras de otra persona.
Selección de componentes: forms y views
Una tabla va acumulando formularios y vistas a lo largo de su vida: un formulario de administración junto al que usa un comercial, una vista «Mis elementos abiertos» que solo le importa a un equipo. Que todas las aplicaciones muestren todos ellos es la forma en que una tabla limpia se convierte en una aplicación abarrotada, así que un elemento de navegación puede nombrar los que ofrece su aplicación.
La ausencia y una matriz vacía no son lo mismo, y tampoco equivalen a «todo marcado».
| Valor | Significado |
|---|---|
| clave ausente | Todos los formularios/vistas de la entidad, incluidos los que se añadan después. El valor predeterminado para una tabla recién colocada en una aplicación, y lo que significan todas las aplicaciones creadas antes de que esto existiera. |
| una lista | Una elección cerrada. Un formulario que se añada después a la entidad no aparece en esta aplicación hasta que se incluya en la lista. |
[] | No válido. No puede significar «todos» (eso lo significa la ausencia) ni debe significar «ninguno»: una tabla sin formulario no se puede abrir. |
Cada nombre de la lista debe ser un formulario o una vista de esa entidad, lo que se comprueba
al guardar (modelapps.app.unknown_component). Un nombre mal escrito merece un error en lugar de
ignorarse: de lo contrario, restringiría en silencio la aplicación a menos formularios de los que
eligió el autor, y la aplicación parecería correcta hasta que un usuario diera con una tabla que
no puede abrir.
La lista decide solo la pertenencia, nunca el orden: el entorno de ejecución conserva el orden propio de la entidad y su propio valor predeterminado, cuando ese valor sobrevive a la selección. Ordenar las vistas de una tabla dentro de una aplicación es una capacidad distinta, y no es esta.
Página incluida: includes
La navegación dice lo que una aplicación muestra; includes dice lo que contiene, y una
aplicación contiene más de lo que muestra. Un proceso abre un formulario de una tabla que nadie
recorre; un comando diseñado abre un panel que se ha mantenido fuera del carril a propósito; a un
informe se llega desde un registro y nunca desde la navegación. Sin esta lista, cada uno de esos
destinos sería inaccesible, o cada aplicación tendría que mostrar todo lo que pudiera llegar a
abrir.
| Campo | Tipo | Obligatorio | Notas |
|---|---|---|---|
type | Entity | Dashboard | Report | StudioApp | sí | Qué tipo de cosa es. |
target | string | sí | Su nombre lógico. |
forms | array | null | no | Solo para tablas. Los formularios de esta tabla que la aplicación puede abrir, por nombre lógico; la misma regla que en un elemento de navegación. |
views | array | null | no | Solo para tablas. Las vistas de esta tabla que la aplicación puede abrir. La misma regla que forms. |
forms y views siguen exactamente la regla de
Selección de componentes: la ausencia significa todos,
una lista es una elección cerrada y una matriz vacía no es válida.
Ejemplo
{
"logicalName": "par_sales_app",
"displayName": "Sales",
"publisherPrefix": "par",
"description": "Manage accounts and invoices",
"icon": "briefcase",
"home": { "type": "Dashboard", "target": "par_sales_overview" },
"navigation": [
{
"title": "Sales",
"items": [
{ "type": "Dashboard", "target": "par_sales_overview", "displayName": "Overview", "icon": "gauge" },
{ "type": "Entity", "target": "par_account", "displayName": "Accounts", "icon": "users" },
{
"type": "Entity",
"target": "par_invoice",
"forms": ["par_invoice_main"],
"views": ["par_invoice_active", "par_invoice_overdue"]
},
{ "type": "Entity", "target": "par_contact" },
{ "type": "Report", "target": "par_invoice_print", "displayName": "Print invoices" }
]
}
]
}
Esta aplicación se abre en su panel en lugar de en una cuadrícula de filas, que es para lo que
sirve un home que no es una tabla. par_invoice está seleccionada: la aplicación ofrece uno de
sus formularios y dos de sus vistas, y una vista que se añada mañana a la tabla no aparecerá
aquí. par_account y par_contact no indican ninguna selección, así que la aplicación ofrece
todo lo que tienen esas tablas, ahora y en adelante.