Definitie van een modelgestuurde app
Schema-id: model-driven-app@1
Machineleesbaar schema: model-driven-app.schema.json
De canonieke weergave van een modelgestuurde app (sectie 6.7) — een app met een naam die een zorgvuldig gekozen deel van de tabellen, dashboards en rapporten van de omgeving groepeert in een navigatie (siteoverzicht) met een startpagina, zoals een modelgestuurde app in Power Apps dat doet. Wordt op dezelfde manier gevalideerd, of hij nu uit de ontwerper komt, uit een API-aanroep, van een AI-assistent of uit een oplossingsimport.
Structuur
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
logicalName | tekenreeks | ja | Met uitgeversvoorvoegsel, in kleine letters snake_case (bijvoorbeeld par_sales_app). |
displayName | tekenreeks | ja | Leesbare naam van de app, getoond op de tegel in het startscherm. |
publisherPrefix | tekenreeks | ja | Het voorvoegsel van de eigenaar-uitgever; de logische naam moet ermee beginnen. |
description | tekenreeks | nee | Korte beschrijving, getoond op de tegel in het startscherm. |
icon | tekenreeks | nee | Pictogramsleutel voor de tegel en de kop van de navigatiebalk van de app. |
supportsTasks | booleaans | nee | Of deze app meedoet aan bedrijfsprocessen. Staat het aan, dan biedt de shell de takenlijst en de knop Beslissen aan zolang de app open is; staat het uit, dan tekent hij geen van beide. Uit is de standaard, omdat de meeste apps geen deel uitmaken van een proces en een inbox in zo'n app omlijsting is waar nooit iets in staat. |
home | bestemming | ja | Wat er opent op /apps/{id}; moet in navigation voorkomen. Zie hieronder. |
navigation | array | ja | Een of meer navigatiegroepen (het siteoverzicht; zie hieronder). |
includes | array | nee | De componenten van de app: dingen die hij kan openen maar die niet in zijn siteoverzicht staan. Zie hieronder. |
Bestemming
Een plek waar de app naartoe kan — één vorm, gebruikt voor een navigatie-item en voor
home. Dat is een bewuste keuze en geen toeval: "home moet een plek zijn waar de
navigatie naartoe gaat" wordt dan een vergelijking van twee waarden van hetzelfde type, in
plaats van drie bijna identieke controles die per soort uit elkaar kunnen groeien.
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
type | Entity | Dashboard | Report | ja | De drie dingen die de Player op een scherm kan zetten: een raster, een dashboardhost, een rapportviewer. |
target | tekenreeks | ja | De logische naam van de bestemming. In welke opslag die moet bestaan, bepaalt type. |
Navigatiegroep
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
title | tekenreeks | ja | Groepskop in de linkernavigatie van de app. |
items | array | ja | Een of meer navigatie-items (zie hieronder). |
Navigatie-item
Een bestemming, plus hoe deze app die wil laten benoemen. Het overschrijven van label en pictogram geldt voor elke soort — een app die de tabel Accounts "Klanten" noemt, heeft dezelfde reden om een dashboard "Vandaag" te noemen.
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
type | Entity | Dashboard | Report | ja | Wat dit item opent. |
target | tekenreeks | ja | De logische naam ervan (moet in de omgeving bestaan, als dat soort ding). |
displayName | tekenreeks | nee | Label dat het label in de navigatiebalk van deze app overschrijft; zonder dit wordt de eigen weergavenaam van de component gebruikt. |
icon | tekenreeks | nee | Pictogramsleutel voor het item in de navigatiebalk. |
forms | array van tekenreeksen | nee | Alleen voor Entity-items. De formulieren van deze tabel die deze app aanbiedt, op logische naam. Zie hieronder. |
views | array van tekenreeksen | nee | Alleen voor Entity-items. De weergaven van deze tabel die deze app aanbiedt, op logische naam. |
Elke bestemming waarnaar wordt verwezen — in een navigatie-item en in home — moet in de
omgeving bestaan in de opslag die haar eigen soort noemt, en home moet met een van de
navigatie-items overeenkomen op zowel type als target. Beide worden bij het opslaan
afgedwongen, naast de schemavalidatie (modelapps.app.unknown_entity,
modelapps.app.unknown_dashboard, modelapps.app.unknown_report,
modelapps.app.home_not_in_navigation).
forms en views op een item van het type Dashboard of Report worden geweigerd,
niet genegeerd (modelapps.app.component_selection_not_allowed): geen van beide heeft
formulieren of weergaven, dus een selectie daar is een fout van de auteur die anders
ongemerkt zou verdwijnen en de auteur in de veronderstelling zou laten dat hij iets had
ingeperkt.
Wie er een mag openen
Een dashboard openen en een rapport uitvoeren zijn rechten op die component — rechten
met de naam <logicalName>.Open en <logicalName>.Run, toegekend via een beveiligingsrol
zoals elk ander recht, met *.Open / *.Run als jokers die alles blijven dekken wat
hierna wordt gebouwd. Er een in een siteoverzicht plaatsen, kent het recht niet toe. Wat de
widgets van het dashboard en de datasets van het rapport vervolgens lezen, wordt hoe dan ook
zelfstandig geautoriseerd, dus een gebruiker die een dashboard bereikt waarvoor hij geen
gegevens heeft, ziet lege widgets in plaats van de cijfers van iemand anders.
Componentselectie — forms en views
Een tabel verzamelt in de loop van zijn leven formulieren en weergaven: een beheerdersformulier naast het formulier dat een verkoper gebruikt, een weergave "Mijn open items" die voor één team belangrijk is. Als elke app ze allemaal toont, wordt een nette tabel een rommelige app, dus een navigatie-item mag noemen welke zijn app aanbiedt.
Afwezigheid en een lege array zijn niet hetzelfde, en "alles aangevinkt" is ook iets anders.
| Waarde | Betekenis |
|---|---|
| sleutel afwezig | Elk formulier/elke weergave van de tabel, inclusief die later worden toegevoegd. De standaard voor een tabel die net in een app is geplaatst, en wat elke app betekent die is gemaakt voordat dit bestond. |
| een lijst | Een gesloten keuze. Een formulier dat later aan de tabel wordt toegevoegd, verschijnt niet in deze app totdat het in de lijst staat. |
[] | Ongeldig. Het kan niet "alles" betekenen (dat doet afwezigheid) en mag niet "niets" betekenen — een tabel zonder formulier kan niet worden geopend. |
Elke genoemde naam moet een formulier/weergave van die tabel zijn; dat wordt bij het
opslaan gecontroleerd (modelapps.app.unknown_component). Een verkeerd getypte naam is het
waard om op te falen in plaats van hem te negeren: anders zou hij de app ongemerkt beperken
tot minder formulieren dan de auteur koos, en zou de app er correct uitzien totdat een
gebruiker een tabel tegenkwam die hij niet kon openen.
De lijst bepaalt alleen het lidmaatschap, nooit de volgorde — de runtime behoudt de eigen volgorde van de tabel en haar eigen standaard, voor zover die standaard de selectie overleeft. De weergaven van een tabel binnen een app ordenen is een aparte mogelijkheid, en dit is die niet.
Opgenomen pagina — includes
De navigatie zegt wat een app toont; includes zegt wat hij bevat, en een app bevat
meer dan hij toont. Een proces opent een formulier van een tabel waar niemand doorheen
bladert; een ontworpen opdracht opent een dashboard dat bewust uit de navigatiebalk is
gehouden; een rapport wordt bereikt vanuit een record en nooit vanuit de navigatie. Zonder
deze lijst zou elke zulke bestemming onbereikbaar zijn, of zou elke app alles moeten tonen
wat hij ooit zou kunnen openen.
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
type | Entity | Dashboard | Report | StudioApp | ja | Wat voor soort ding dit is. |
target | tekenreeks | ja | De logische naam ervan. |
forms | array | null | nee | Alleen voor tabellen. De formulieren van deze tabel die de app mag openen, op logische naam — dezelfde regel als bij een navigatie-item. |
views | array | null | nee | Alleen voor tabellen. De weergaven van deze tabel die de app mag openen. Dezelfde regel als bij forms. |
forms en views volgen precies de regel in
Componentselectie: afwezig betekent allemaal, een
lijst is een gesloten keuze, en een lege array is ongeldig.
Voorbeeld
{
"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" }
]
}
]
}
Deze app opent op zijn dashboard in plaats van op een raster met rijen, en daar is een
home die geen tabel is voor bedoeld. par_invoice is een zorgvuldige selectie — de app
biedt een van de formulieren en twee van de weergaven aan, en een weergave die morgen aan de
tabel wordt toegevoegd, verschijnt hier niet. par_account en par_contact noemen geen
selectie, dus de app biedt alles aan wat die tabellen hebben, nu en later.