Saltar al contenido principal

Definición de vista basada en modelo

Id del esquema: model-driven-view@2 Esquema legible por máquina: model-driven-view.schema.json

Versión reemplazada: model-driven-view@1 (model-driven-view-v1.schema.json) sigue publicada y registrada, de modo que una solución ya implementada con ella se sigue validando con el esquema para el que se creó. La versión 2 solo añade propiedades opcionales —la tabla Forma de más abajo es la lista actual—, así que toda definición v1 es también una definición v2 válida y no hay que reescribir nada.

La representación canónica de una vista de las aplicaciones basadas en modelo (sección 6.7): una lista tabular de registros con sus columnas, filtros y ordenaciones.

Forma​

CampoTipoObligatorioNotas
logicalNamestringsíCon el prefijo del editor, en snake_case en minúsculas.
displayNamestringsíNombre legible de la vista.
entitystringsíEl nombre lógico de la entidad propietaria.
descriptionstringnoLa línea que se muestra bajo el título en la barra de título de la vista.
iconstringnoEl icono que se muestra en la barra de título de la vista.
viewTypestringnoPara qué sirve la vista: Public (predeterminado), Lookup, QuickFind, Associated, QuickView, Card, SeedData.
seedDataKindstringen una vista SeedDataObligatorio en una vista SeedData y rechazado en cualquier otra: Configuration (filas que la solución necesita para funcionar; una importación siempre las trae, también a Producción) o Demonstration (filas de ejemplo; solo se importan cuando se marca Incluir datos de demostración, y nunca en Producción). Se incluye en el paquete como el kind del documento de datos iniciales.
columnsarraysíNombres lógicos de los campos que se muestran como columnas.
filtersarraynoCláusulas de filtro planas (combinadas con AND): field, operator y (para los operadores con valor) value.
filterGroupobjectnoUn árbol de filtros jerárquico AND/OR (al estilo de Búsqueda avanzada), combinado con filters mediante AND.
sortsarraynoCláusulas de ordenación: field, descending.
actionsarraynoAcciones diseñables de la barra de comandos.
hierarchyobjectnoPresente cuando la vista se representa como un árbol en lugar de una cuadrícula.
calendarobjectnoPresente cuando la vista se representa como un calendario en lugar de una cuadrícula. Nunca junto con hierarchy.
columnPropertiesarraynoCómo se presentan las columnas individuales: encabezado, ancho, formato, alineación, control. Disperso.
commandOverridesarraynoLo que esta vista cambia de los comandos que son propiedad de la plataforma.
commandOrderarraynoUna barra, un orden: comandos integrados y del creador intercalados, por id.
rowSelectionbooleannoIndica si las filas llevan una casilla de selección. true de forma predeterminada.

Operadores: Equals, NotEquals, Contains, GreaterThan, LessThan, IsNull, IsNotNull. Todos los campos a los que se hace referencia (columnas, filtros, condiciones de grupos de filtros, ordenaciones) deben existir en la entidad.

viewType​

El tipo de una vista indica qué superficie la lee. Una entidad puede tener a la vez una vista predeterminada de cada tipo, porque responden a preguntas distintas:

ValorPara qué sirve
PublicLa página de lista normal de la entidad. Es el valor predeterminado, y lo que es una definición sin viewType.
LookupLas columnas que se muestran dentro del panel de resultados de un control de búsqueda; normalmente de dos a cuatro.
QuickFindLas columnas de búsqueda: las columnas con las que se compara una búsqueda escrita. Sus columns son el conjunto en el que se busca; sus filtros y ordenaciones no se leen.
SeedDataLas filas y columnas que viajan con la solución (PF22). Nunca se muestra: una exportación de solución la ejecuta —sus filters deciden las filas y sus columns, los campos— y empaqueta el resultado como un documento seed-data@1, que una importación inserta o actualiza por id. Una tabla con varias usa la predeterminada o, si no la hay, la primera por nombre lógico.
AssociatedLa subcuadrícula de registros relacionados. Reservado: todavía no hay nada que la represente.

Un control de búsqueda que no nombra ninguna vista resuelve una automáticamente: la vista Lookup predeterminada de la entidad de destino; si no la hay, su vista Public predeterminada recortada a sus tres primeras columnas; y si tampoco, solo el campo principal de la entidad. Una búsqueda sin vista QuickFind compara únicamente con el campo principal. Las columnas de búsqueda deben ser campos de texto, ya que la comparación es un «contiene» que no distingue mayúsculas de minúsculas.

calendar (una vista que se representa como calendario)​

Una vista con un bloque calendar dibuja sus registros colocados en una hoja de día, semana o mes —según dos de sus propios campos de fecha— en lugar de como una cuadrícula. Si falta, es la cuadrícula, exactamente igual que con hierarchy, así que todas las vistas almacenadas siguen siendo válidas. Una vista que incluye ambos bloques se rechaza: una vista se dibuja de una sola manera.

Es una asignación, no un modelo de datos. No hay tabla de reservas ni tipo de cita: cualquier tabla que tenga una fecha puede disponerse en un calendario, y cuál de sus fechas significa «empieza» lo decide el creador.

CampoTipoObligatorioNotas
startstringsíEl campo de fecha y hora en el que se coloca un bloque. El único rol obligatorio: un registro sin inicio no puede colocarse en una hoja, así que no hay nada a lo que recurrir. Se admite un campo del sistema: created_at_utc dispone los registros según cuándo llegaron.
endstringnoEl campo de fecha y hora en el que termina un bloque. La ausencia sirve para una tabla que registra un momento en lugar de un intervalo, y hace que cada bloque dure defaultDurationMinutes; no cero, porque en un bloque sin altura no se puede hacer clic.
titlestringnoEl campo del que se lee la primera línea del bloque. Si falta, es el campo principal de la tabla, que es lo que ya muestran una cuadrícula, un panel de búsqueda y una ruta de navegación.
categorystringnoUn campo de elección, estado o motivo cuyas opciones colorean los bloques y rellenan la leyenda.
bookedForstringnoEl campo que indica para quién es la franja, que se muestra de forma discreta bajo el título. De cualquier tipo: una búsqueda se resuelve en el nombre del registro de destino.
notestringnoEl campo que se muestra en un bloque lo bastante alto para una tercera línea y, si no, en su información sobre herramientas.
defaultScalestringnoEn qué hoja se abre la vista: Day, Week (predeterminado) o Month.
startHourintegernoLa primera hora que muestran las hojas de día y de semana, 0–23. 0 de forma predeterminada.
endHourintegernoLa hora en la que terminan esas hojas, 1–24, y mayor que startHour. 24 de forma predeterminada.
defaultDurationMinutesintegernoCuánto dura una franja cuando el lector hace clic en una vacía —la duración con la que llega el nuevo registro— y la altura de cada bloque en una vista que no asigna end. Al menos 1; 60 de forma predeterminada.

🔴 start y end deben ser campos de fecha y hora, y category debe tener colores. Ambas cosas se rechazan al guardar, porque ambas fallan en silencio en pantalla: un start que es una columna de texto dibuja una hoja vacía, que se lee como «no hay nada reservado esta semana», justo la conclusión sobre la que un lector actuará y que no puede comprobar. El color reside en las propias opciones de la elección, y eso es lo que permite decir una sola vez «Examen es ámbar» y que lo lean por igual el calendario, una celda de cuadrícula y un gráfico.

startHour y endHour marcan la diferencia entre una hoja de reservas útil y una que se abre con dos tercios vacíos: una clínica que trabaja de 8 a 19 no quiere dieciséis filas de medianoche. Indican dónde se abre la hoja: el lector sigue pudiendo cambiar de escala y acotar las horas desde el propio encabezado de la hoja, porque la ventana es suya y no del creador.

No hay, a propósito, ningún rol resource. Las hojas muestran los días a lo ancho, así que un campo que nombrara la columna a la que pertenece un bloque sería una asignación que un creador podría hacer y luego ver que no hace nada. Llegará con el eje que la dibuje.

hierarchy (una vista que se representa como árbol)​

Una vista con un bloque hierarchy dibuja sus registros anidados mediante una búsqueda —un organigrama con las personas de cada unidad, un árbol de categorías, una lista de materiales— en lugar de como una cuadrícula. Si falta, es la cuadrícula que siempre ha sido cada vista, y por eso todas las vistas almacenadas siguen siendo válidas.

Un árbol sirve para navegar: las filas se obtienen por ventanas, de modo que un organigrama de cincuenta mil personas se abre sin cargar ninguna de ellas.

CampoTipoObligatorioNotas
nodeTypesarraysíTodos los tipos de nodo que puede dibujar el árbol. Al menos uno.
orderarraynoEl orden en que se dibujan los segmentos bajo un nodo, por id de tipo de nodo. Si falta, es el orden de declaración.
rootPickerbooleannoIndica si un lector puede centrar el árbol en un nodo: abrirlo en una ciudad en lugar de en toda la organización.
expandRootsbooleannoIndica si el primer nivel se abre al cargar. true de forma predeterminada.

Cada entrada de nodeTypes:

CampoTipoObligatorioNotas
idstringsíCómo se llama este tipo dentro del bloque: unit, person. Único aquí, y aquello a lo que hacen referencia order y cada childOf.of. La misma tabla puede aparecer dos veces en un organigrama, y por eso es una palabra del propio creador y no un nombre de tabla.
entitystringsíLa tabla de la que son registros estos nodos.
childOfobjectsíCómo cuelga este tipo de su padre; vea más abajo.
labelstringnoEl campo cuyo valor es la línea del nodo. Si falta, es el campo principal de la tabla.
secondarystringnoEl campo que se muestra de forma discreta tras la etiqueta. Si falta, es el propio campo secundario de la tabla; una cadena vacía significa ninguno: en una unidad, el nombre del padre es la fila justo encima, así que un organigrama es un sitio en el que la segunda línea predeterminada de una tabla no sirve.
iconstringnoEl glifo de la fila. Si falta, es el propio icono de la tabla.
imagebooleannoIndica si la fila lleva la imagen del registro.
detailobjectnoLo que llena el panel junto al organigrama cuando se selecciona uno. Si falta, es el formulario principal de la tabla.

childOf recibe un field —la búsqueda de la tabla de este tipo que contiene el registro padre— y un of opcional, el tipo de nodo del que cuelga, por id.

🔴 Exactamente un tipo de nodo omite of. Ese es la propia tabla del árbol anidada bajo sí misma, y sus registros con el padre vacío son el nivel superior del organigrama; todos los demás tipos nombran aquello de lo que cuelgan. Los nodos heterogéneos son el caso general y no un añadido: unidades y luego las personas que hay en ellas es el mismo mecanismo que provincia → ciudad → sucursal modelado como tres tablas.

La búsqueda que nombra childOf.field debe apuntar a la tabla del tipo padre (a la suya propia, en el tipo raíz). Una que apunte a cualquier otro sitio no describe un anidamiento, y se rechaza al guardar en lugar de mostrar un nivel sin nada debajo.

detail recibe un kind de Form (el propio formulario de la tabla, guardado mediante la ruta de escritura del formulario de registro), Card (una vista de tarjeta pensada para leerse y no para escribir en ella, que suele ser lo que se quiere para una persona bajo una unidad) o None (para un tipo que solo es estructura), más un name opcional que indica qué formulario o vista de tarjeta.

columnProperties (cómo se presenta una columna)​

Una lista dispersa: solo aparecen las columnas que ha configurado un creador, y una columna sin entrada se representa solo a partir de los metadatos de su campo. Se sitúa junto a columns en lugar de convertirla en una lista de objetos, de modo que todas las definiciones v1 siguen siendo válidas y no se toca ningún lector que solo necesite saber qué columnas tiene una vista.

CampoTipoObligatorioNotas
fieldstringsíLa columna que configura. Debe ser una de las columns de la vista.
labelstring | nullnoSustitución del encabezado. Si falta, se usa el nombre para mostrar del campo.
widthinteger | nullnoAncho en píxeles, 40–1200. Si falta, la columna ajusta su propio tamaño.
formatstring | nullnoFormato del valor. Para una columna DateTime, el mismo conjunto de tokens que aceptan los controles de fecha del formulario (yyyy, yy, MM, dd, HH, mm, ss): un único vocabulario de formato en todo el producto.
alignstring | nullnostart, center o end. Lógico, no izquierda/derecha, de modo que sigue la dirección de lectura (§6.13.6).
controlTypestring | nullnoEl control con el que se representa la columna: un glifo de interruptor para un booleano, una fecha persa para una fecha.

controlType admite Text, TextArea, Check, Toggle, Date, DateTime, Time, PersianDate, PersianDateTime, PersianTime, Lookup, PolymorphicLookup, Dropdown o Label. Si falta, hereda el valor predeterminado del propio campo y, después, el del tipo de datos.

🔴 Siempre se representa como de solo lectura. Una cuadrícula no tiene edición en línea, así que un interruptor aquí muestra el estado en lugar de aceptar un clic. También es la única forma de que una columna muestre el calendario jalalí en un inquilino gregoriano, ya que format es un patrón sin calendario asociado.

commandOverrides (cambiar un comando propiedad de la plataforma)​

Lo que esta vista cambia de los comandos integrados: Nuevo, Editar, Eliminar, Actualizar, Guardar, Guardar y cerrar, Anclar. Si falta, no cambia nada, que es lo que significa toda vista creada antes de que esto existiera.

CampoTipoObligatorioNotas
commandstringsíEl id estable del comando que se sustituye.
labelstringnoSustituye la etiqueta de la plataforma. Si falta, se conserva, incluidas sus traducciones, que una sustitución escrita pierde necesariamente.
iconstringnoSustituye el glifo de la plataforma.
initiallyHiddenbooleannoIndica si el comando empieza oculto.
initiallyDisabledbooleannoIndica si el comando empieza deshabilitado.

🔴 Se identifica por un id de comando estable, nunca por etiqueta ni posición. El id es el nombre propio de la plataforma y no cambia cuando cambia la etiqueta, así que una sustitución no puede desvincularse de lo que sustituye en cuanto alguien la edita; y un comando integrado puede renombrarse o retirarse más adelante sin que haya que conciliar cada documento almacenado, ya que una sustitución que nombra un comando que ya no existe simplemente se ignora.

🔴 Un creador puede ocultar y deshabilitar, nunca mostrar ni habilitar. El reproductor oculta Nuevo a quien no puede crear y deshabilita Eliminar cuando no hay nada seleccionado; una sustitución capaz de deshacer eso construiría una barra que ofrece lo que el servidor rechazará.

«Inicialmente» es todo el significado de la palabra. Es el estado en el que se abre la barra, no una condición permanente: una regla de negocio o el propio script del comando pueden mostrarlo después. Un comando que nunca debe aparecer para alguien no es esto; eso es un permiso, que se decide en el servidor, donde un navegador no puede rebatirlo.

commandOrder (una barra, un orden)​

Los comandos integrados y los del propio creador, intercalados tal como los dispuso el creador, por id.

Una lista explícita en lugar de un rango en cada comando, porque un rango hay que reescribirlo en todos los comandos cada vez que uno se mueve, y dos comandos pueden tener el mismo: un empate que el renderizador resolvería de forma distinta a como lo resolvió el diseñador.

🔴 Todo lo que esta lista no menciona conserva su lugar natural, al final. Eso es lo que hace que la regla resista el paso del tiempo: un comando integrado que se añada a la plataforma el año que viene, o un comando que añada una actualización, aparece en lugar de desaparecer porque un orden almacenado es anterior a él. Un id que nombra algo que ya no existe se omite.

rowSelection (si las filas llevan una casilla)​

true de forma predeterminada, y lo que significa toda vista creada antes de que esto existiera: la cuadrícula tiene su encabezado de seleccionar todo y una casilla por fila, que es sobre lo que actúa la barra de comandos.

false es para una vista que solo se lee —una lista desde la que nadie elimina ni reasigna—, donde una casilla ofrece una selección múltiple que la superficie no necesita y cuesta una columna de ancho.

filterGroup (AND/OR jerárquico)​

Un filterGroup es un nodo recursivo que combina sus miembros con un connector:

CampoTipoObligatorioNotas
connectorstringsíAnd (coinciden todos los miembros) u Or (coincide cualquier miembro).
conditionsarraynoCondiciones hoja (field, operator, value) de este grupo.
groupsarraynoSubgrupos anidados (con la misma forma), para un anidamiento AND/OR arbitrario.

Ejemplo​

{
"logicalName": "par_invoice_active",
"displayName": "Active Invoices",
"entity": "par_invoice",
"viewType": "Public",
"columns": ["par_name", "par_total"],
"filters": [ { "field": "par_total", "operator": "GreaterThan", "value": 0 } ],
"filterGroup": {
"connector": "And",
"conditions": [ { "field": "par_name", "operator": "Contains", "value": "INV" } ],
"groups": [
{
"connector": "Or",
"conditions": [
{ "field": "par_total", "operator": "GreaterThan", "value": 1000 },
{ "field": "par_total", "operator": "IsNull" }
]
}
]
},
"sorts": [ { "field": "par_name", "descending": false } ]
}

Ejemplo: una vista de búsqueda​

{
"logicalName": "par_contact_pick",
"displayName": "Contact Lookup",
"entity": "par_contact",
"viewType": "Lookup",
"columns": ["par_name", "par_email", "par_city"],
"sorts": [ { "field": "par_name", "descending": false } ]
}

Ejemplo: una vista de búsqueda rápida​

Solo se lee columns: son las columnas con las que se compara una búsqueda escrita.

{
"logicalName": "par_contact_find",
"displayName": "Contact Quick Find",
"entity": "par_contact",
"viewType": "QuickFind",
"columns": ["par_name", "par_email", "par_accountnumber"]
}