KEPLIN Docs

Gebeurtenissen en de SDK

De gebeurtenissen van de widgets en van het scherm, de code-editor, de vooraf bepaalde acties en de keplin-SDK in TypeScript — gegevens, widgets, navigatie, sessie, modale vensters en workflows.

Er is heel wat scherm dat u maakt zonder één regel te schrijven: een datastore koppelen, widgets slepen, een knop op een ander scherm richten. Maar vroeg of laat verschijnt het "wanneer dit gebeurt, doe dan dat" — opslaan en teruggaan, een tabel opnieuw laden na een filter, bevestigen voor het verwijderen, een modaal venster openen en gebruiken wat het teruggaf.

Daar dienen de gebeurtenissen voor: punten op het scherm waar uw eigen code draait, geschreven in TypeScript, met een SDK — het object keplin — die toegang geeft tot alles wat het scherm heeft.

Waar de gebeurtenissen staan

In de inspector heet de laatste categorie van een widget (en van het scherm zelf) Gebeurtenissen. Zij heeft één regel per beschikbare gebeurtenis, en op elke regel:

  • een stip links: gevuld wanneer die gebeurtenis al code heeft, leeg wanneer niet;
  • een knop rechts, die de editor opent.

De categorie Gebeurtenissen van een Knop: een gevulde stip markeert de gebeurtenissen die al code hebben; de … opent de editor.
De categorie Gebeurtenissen van een Knop: een gevulde stip markeert de gebeurtenissen die al code hebben; de … opent de editor.

De namen van de gebeurtenissen worden niet vertaald — zij zijn in elke taal dezelfde (onClick, onRowClick, onLoad), omdat het ook de namen zijn die in de code en in de registraties van Radar verschijnen.

De gebeurtenissen van het scherm

Klik op een lege zone van het canvas zodat de inspector het scherm toont. De categorie Gebeurtenissen heeft er drie:

Gebeurtenis Wanneer die afgaat Waarvoor
onLoad Eén keer, wanneer het scherm opent. State klaarzetten, dingen laden die de datastores niet laden, welkom heten.
onParamsChange Telkens wanneer de routeparameters wijzigen — en niet bij het eerste openen. Reageren op een wisseling van record zonder het scherm opnieuw te openen.
onUnload Wanneer het scherm afsluit. State opruimen, concepten bewaren.

De gebeurtenissen van het scherm zelf — onLoad, onParamsChange en onUnload — in de inspector zonder selectie.
De gebeurtenissen van het scherm zelf — onLoad, onParamsChange en onUnload — in de inspector zonder selectie.

De gebeurtenissen van elke widget

Elk type widget declareert de zijne. Naast de naam telt de payload — de gegevens die de gebeurtenis meebrengt, en die de code leest in keplin.event.

Formuliervelden

Widget Gebeurtenissen keplin.event
Tekstvak, Tekstgebied, Getal, Ja/Nee, Keuzelijst, Datum, Kleur onChange { value }
Bestand onChange, onUpload onUpload: { file, name }

Acties en navigatie

Widget Gebeurtenissen keplin.event
Knop onClick {}
Knop met menu onClick, onMenuItem onMenuItem: { id, label }
Link onClick {}
Exporteren onExport, onDataLoaded onExport: { rows, filename }

Structuur en inhoud

Widget Gebeurtenissen keplin.event
Tabbladen onTabChange { tab }
Rapport onLoad { report }

Gegevenswidgets

Widget Gebeurtenissen keplin.event
Tabel onRowClick, onRowDoubleClick, onSelectionChange, onDataLoaded { row, index } · onSelectionChange: { row, rows }
Lijst, Kaarten onRowClick, onDataLoaded { row, index }
Grafiek onClick { name, seriesName, value, dataIndex }
KPI onClick, onDataLoaded { value, indicatorId }

Borden en planning

Widget Gebeurtenissen keplin.event
Kanban onCardClick, onCardCreate, onCardMoved, onDataLoaded { row } · { column } · { row, from, to, index }
Kalender onEventClick, onDayClick, onRangeSelect, onRangeChange, onDataLoaded { row } · { date } · { start, end } · { start, end, view }
Gantt onBarClick, onEmptyClick, onDataLoaded { row } · { date }

Processen

Widget Gebeurtenissen keplin.event
Status van het proces onDecide { task, outcome }
Mijn taken onOpen, onDecide { task, screenId }

Nota

Widgets die u zelf hebt geprogrammeerd (die op het palet onder Aangepast verschijnen) declareren hun eigen gebeurtenissen, en die verschijnen hier als alle andere.

De code-editor

De knop van een gebeurtenis opent de editor in een modaal venster. De titel zegt waar u bent: het id van de widget (of de naam van het scherm) en de naam van de gebeurtenis — w_fic_sav1 · onClick.

De editor van de gebeurtenis onClick van de knop Opslaan: de code slaat de datastore op en, als dat goed ging, meldt zij het en gaat terug naar de lijst.
De editor van de gebeurtenis onClick van de knop Opslaan: de code slaat de datastore op en, als dat goed ging, meldt zij het en gaat terug naar de lijst.

Knop Wat die doet
Actie invoegen Schrijft voor u de code van een veelvoorkomende taak (hierna).
Handler verwijderen Wist de code van deze gebeurtenis. De stip wordt weer leeg.
Annuleren Sluit zonder op te slaan.
Opslaan Controleert en slaat op.

De editor heeft suggesties tijdens het typen (Ctrl+Spatie): de hele keplin is gedeclareerd, met de juiste types — en, nog beter, de id's van de widgets van dit scherm zitten erin. keplin.widgets.get(" typen toont de lijst met widgets van het scherm, en een id dat niet bestaat wordt als fout aangewezen voordat u opslaat.

Atenção

Bij het opslaan wordt de code gecompileerd. Is zij niet uitvoerbaar, dan weigert het platform haar — De gebeurtenis is niet opgeslagen: de code is niet uitvoerbaar — en blijft het venster open zodat u kunt herstellen. Een scherm blijft nooit met kapotte code achter.

De vooraf bepaalde acties

Actie invoegen opent een lijst met de meest voorkomende taken. U kiest er een en de code wordt achter het bestaande aan geschreven, meteen met de echte namen van uw scherm — de eerste record-datastore, de eerste tabel, het eerste tekstvak.

Actie invoegen — de vooraf bepaalde acties die de code voor u schrijven, van de datastores tot de workflows.
Actie invoegen — de vooraf bepaalde acties die de code voor u schrijven, van de datastores tot de workflows.

Actie Wat die schrijft
Datastore opslaan Valideert en slaat het record op, met een melding bij succes.
Datastore opnieuw laden Leest de gegevens van een datastore opnieuw.
Datastore filteren (op tekst) Leest de tekst uit een tekstvak en past die als filter toe.
Naar een scherm navigeren Springt naar een andere route van de app.
Een tabel opnieuw laden Vernieuwt de gegevens van een tabelwidget.
Tabel filteren op de tekst van een veld Het klassieke interactieve filter.
Een widget tonen/verbergen Wisselt de zichtbaarheid van een widget.
Bevestigen en een toast tonen Vraagt voordat er gehandeld wordt en meldt het aan het eind.
Een workflow starten Zet een proces in gang op het huidige record.
Taken bekijken en voltooien Somt de taken op van wie de app gebruikt en beslist er een.
Een signaal naar een workflow sturen Wekt processen die stonden te wachten.
Afmelden Verlaat de app.

De ingevoegde code is een vertrekpunt: hij is van u, en is bedoeld om te bewerken. Hij wordt niet opnieuw gegenereerd.

Hoe de code draait

Elke gebeurtenis is een asynchrone functie die maar één ding ontvangt: de keplin. Daaruit volgen drie praktische gevolgen:

  • await werkt op het hoogste niveau van de code. U hoeft niets in te pakken.
  • return verlaat de gebeurtenis. Dat is de normale manier om halverwege af te haken (bijvoorbeeld wanneer een bevestiging geweigerd is).
  • Er zijn geen parameters. De context zit in keplin zelf: keplin.event brengt de payload mee en keplin.ctx zegt waar u bent (ctx.widget is de widget die afging — null bij gebeurtenissen van het scherm —, ctx.event is de naam van de gebeurtenis en ctx.screen het scherm).

Zolang de code van een knop niet klaar is, toont de knop drie geanimeerde stippen: wie de app gebruikt merkt dat er gewerkt wordt. Klapt de code, dan breekt het scherm niet: er verschijnt een melding en de fout wordt in Radar vastgelegd, met het scherm, de widget en de gebeurtenis waar het gebeurde.

De SDK keplin

Alles wat de code kan doen zit onder keplin. Dit zijn de gebieden:

Gebied Waarvoor
keplin.event / keplin.ctx De payload van de gebeurtenis en de context waarin zij draait.
keplin.widgets Praten met de widgets van het scherm.
keplin.data De datastores: lezen, schrijven, filteren, opslaan.
keplin.nav Navigeren en de routeparameters lezen.
keplin.ui Meldingen, bevestigingen en modale vensters.
keplin.state State die tussen schermen gedeeld wordt.
keplin.session Wie de app gebruikt, en wat die mag doen.
keplin.auth Aanmelden, registreren en wachtwoordherstel (systeemschermen).
keplin.i18n Vertaalde zinnen.
keplin.storage Voorkeuren die op het apparaat bewaard worden.
keplin.api De API's van de app rechtstreeks aanroepen.
keplin.reports Rapporten openen en downloaden.
keplin.workflow Processen starten, taken opsommen en voltooien.

De widgets

keplin.widgets.get("id") geeft de handle van een widget terug. Alle handles hebben dezelfde basis:

const w = keplin.widgets.get("w_fic_tel1");
w.show();               // tonen
w.hide();               // verbergen
w.setEnabled(false);    // uitschakelen
w.set("label", "Mobiel");   // elke eigenschap uit de inspector wijzigen
w.get("label");         // de werkelijke waarde lezen
w.reset();              // de wijzigingen tijdens uitvoering vergeten

En daarna voegt elke familie toe wat haar eigen is:

Familie Wat die toevoegt
Formuliervelden getValue(), setValue(v), validate(), error
Gegevenswidgets (Tabel, Lijst, Kaarten, Grafiek, KPI, Kanban, Kalender, Gantt) rows, total, refresh(), setFilter(where), setSort(sort)
Tabel selectedRow, selectedRows, clearSelection()
KPI value, values, valueOf(indicatorId)
Kanban columns, moveCard(id, kolom, index?)
Kalender view, start, end, goTo(datum), setView(weergave)
Gantt zoom, setZoom(z)
Tabbladen activeTab, tab("id") — en, op het tabblad, activate(), show(), hide(), setEnabled()
Label / Knop / Link / Kruimelpad setText(t) / setLabel(t)
Markdown setContent(md)
Externe pagina setUrl(url), reload()
Exporteren export()
Rapport url, download()

Nota

De suggesties van de editor bieden alle werkwoorden van alle families, omdat de editor niet van tevoren weet welke widget dat id is. Tijdens de uitvoering bestaan alleen die van het echte type — moveCard op een Knop doet niets nuttigs.

De gegevens

keplin.data.store("naam") geeft een datastore van het scherm terug op naam (zie Datastores en gegevens).

In een record-datastore:

const conta = keplin.data.store("conta");
conta.get("nome");                 // een veld lezen
conta.set("estado", "ativo");      // een veld schrijven (nog niet opgeslagen)
conta.record();                    // het hele record
conta.isDirty();                   // zijn er wijzigingen die nog niet opgeslagen zijn?
conta.reset();                     // de wijzigingen weggooien
const ok = await conta.save();     // valideert en slaat op; true als er opgeslagen is

In een lijst-datastore:

const contas = keplin.data.store("contas");
contas.rows();                     // de geladen rijen
contas.total();                    // het totaal (wanneer de server het geeft)
contas.reload();                   // opnieuw lezen
contas.setWhere({ estado: { eq: "ativo" } });   // extra filter; null wist het
contas.setSort([{ field: "nome", direction: "ASC" }]);
contas.goToPage(2);

In beide zegt status() hoe het laden ervoor staat (idle, loading, ready, error).

keplin.nav.go("/ficha-de-conta/17");   // naar een route gaan (met parameters)
keplin.nav.back();                      // teruggaan
keplin.nav.params;                      // de parameters van het huidige scherm, op naam

Meldingen, bevestigingen en modale vensters

keplin.ui.toast("Opgeslagen.", "success");     // "success" | "error" | "info"
const ok = await keplin.ui.confirm("Het record verwijderen?");
if (!ok) return;

De bevestiging is een venster met het thema van de app — nooit het grijze kadertje van de browser.

State, sessie en voorkeuren

keplin.state.set("filtroContas", "activas");   // leeft zolang het tabblad open is
keplin.state.get("filtroContas");
keplin.state.remove("filtroContas");

keplin.session.user;              // { id, username, name } — null op openbare schermen
keplin.session.roles;             // de rollen van wie de app gebruikt
keplin.session.can("contas.editar");   // heeft die deze actie? (Instellingen ▸ Rechten)
await keplin.session.logout();

keplin.storage.set("colunasContas", ["nome", "cidade"]);   // blijft op het apparaat
keplin.storage.get("colunasContas");

Dica

Vraag keplin.session.can("...") om te beslissen wat iemand mag doen, en niet hasRole("gestor"). De acties worden gedeclareerd bij Instellingen ▸ Rechten en overleven herindelingen van rollen; de naam van een rol niet.

De API's en de rapporten

const linhas = await keplin.api.query("contas", { estado: "ativo" }, ["id", "nome"]);
await keplin.api.mutate("criarConta", { nome: "Nova" }, ["id"]);

keplin.reports.open("Contactos da conta", { contaId: 17 });
keplin.reports.download("Contactos da conta", { contaId: 17 }, "xlsx");

Bij een query is de lijst met velden verplicht — zij is het die zegt wat u wilt ophalen.

Atenção

keplin.reports.open opent een nieuw tabblad en mag daarom niet achter een await staan: buiten het gebaar van de gebruiker blokkeert de browser het venster. Open eerst, doe de rest daarna.

Workflows

const registo = keplin.data.store("oportunidade").get("id");
await keplin.workflow.start("wf_aprovacao", registo);

const tarefas = await keplin.workflow.tasks();
await keplin.workflow.complete(tarefas[0].id, "aprovar");

const { woken } = await keplin.workflow.signal("documento-recebido", registo);

Vertaalde zinnen

keplin.i18n.t("{n} contas activas", { n: linhas.length });
keplin.i18n.locale;

Modale schermen

Een scherm van Keplin is niet modaal omdat het op een bepaalde manier geopend is — het is modaal omdat het zo is ingesteld. De beslissing zit in de inspector van het scherm, in de categorie Presentatie:

De sectie Presentatie van het scherm: hier wordt een scherm een Modaal venster (gecentreerd) of een Zijpaneel (rechts).
De sectie Presentatie van het scherm: hier wordt een scherm een Modaal venster (gecentreerd) of een Zijpaneel (rechts).

Optie Wat die doet
Modus Scherm (een gewone pagina), Modaal venster (gecentreerd) of Zijpaneel (rechts).
Breedte (px) / Hoogte (px) Het formaat van het modale venster. Het zijpaneel gebruikt de volle hoogte.
Sluitknop Toont de × in de hoek.
Klik ernaast sluit / Esc sluit De twee gebruikelijke uitgangen.
Het scherm erachter vernieuwen bij sluiten Bij het sluiten lezen de datastores van het aanroepende scherm opnieuw.

De tip van de sectie zelf vat het samen: Opent BOVEN OP het scherm dat het aanroept (Link, gebeurtenissen of keplin.ui.openModal). Valt buiten de directe navigatie.

Openen en sluiten met code

const resultado = await keplin.ui.openModal("/nova-conta", { setor: "banca" });
if (resultado) {
  keplin.data.store("contas").reload();
}
  • openModal ontvangt de route (of het id) van het scherm en, eventueel, de parameters.
  • De belofte lost pas op wanneer het modale venster sluit, en brengt de waarde mee die het venster teruggaf.
  • Binnen het modale venster sluit keplin.ui.closeModal(waarde) het en geeft die waarde terug.
  • Modale vensters stapelen: een modaal venster mag een ander openen.

Nota

keplin.nav.go("/route") naar een scherm dat als Modaal venster (gecentreerd) of Zijpaneel (rechts) is ingesteld, opent het als modaal venster in plaats van ernaartoe te navigeren. Dat is met opzet: een modaal scherm heeft geen eigen adres in de navigatie.

Recepten

Opslaan en teruggaan (de onClick van de knop Opslaan van Ficha de Conta):

const ok = await keplin.data.store("conta").save();
if (ok) {
  keplin.ui.toast("Account opgeslagen");
  keplin.nav.go("/contas");
}

De kaart van de aangeklikte rij openen (onRowClick van een Tabel):

keplin.nav.go(`/ficha-de-conta/${keplin.event.row["id"]}`);

Een tabel filteren op een tekstvak (onChange van het tekstvak — vervang de id's door die van uw scherm):

const texto = keplin.widgets.get("w_pesquisa").getValue();
keplin.widgets.get("w_cta_tab1").setFilter(texto ? { nome: { contains: texto } } : null);

Bevestigen vóór een destructieve actie (onClick van een knop):

if (!(await keplin.ui.confirm("Deze account verwijderen?"))) return;

Een knop verbergen voor wie niet mag (onLoad van het scherm):

if (!keplin.session.can("contas.eliminar")) {
  keplin.widgets.get("w_apagar").hide();
}

Waarom niet…?

  • Waarom laat hij mij de gebeurtenis niet opslaan? De code compileert niet. De boodschap is De gebeurtenis is niet opgeslagen: de code is niet uitvoerbaar — herstel het en sla op.
  • Waarom geeft keplin.widgets.get("...") een fout? Het id bestaat niet op dit scherm. Controleer het bovenaan de inspector, met de widget geselecteerd; en denk eraan dat elk apparaat een eigen boom is (zie Lay-outs en ontwerp per apparaat).
  • Waarom ging onParamsChange niet af bij het openen? Dat is met opzet: hij gaat alleen af bij wijzigingen. Gebruik voor het opstarten onLoad.
  • Waarom geeft het modale venster niets terug? Ofwel bestaat het doelscherm niet, ofwel heeft wie de app gebruikt geen recht om het te openen — in beide gevallen lost de belofte op zonder waarde. Controleer de route en de rechten.
  • Waarom opent het venster van het rapport niet? U hebt de open achter een await gezet. Open eerst.
  • Waarom lijkt mijn gebeurtenis niet te draaien? Kijk in Radar: de fouten van de code van de gebeurtenissen belanden daar, met scherm, widget en gebeurtenis — en Radar brengt u rechtstreeks naar de editor van die gebeurtenis.