KEPLIN Docs

Händelser och SDK:t

Widgetarnas och skärmens händelser, kodredigeraren, de fördefinierade åtgärderna och SDK:t keplin i TypeScript — data, widgetar, navigering, session, modaler och arbetsflöden.

Mycket av en skärm görs utan att skriva en rad: binda en datastore, dra widgetar, peka en knapp mot en annan skärm. Men förr eller senare dyker ”när det här händer, gör det där” upp — spara och gå tillbaka, ladda om en tabell efter ett filter, bekräfta innan något raderas, öppna en modal och använda det den lämnade tillbaka.

Det är vad händelserna är till för: punkter på skärmen där din egen kod körs, skriven i TypeScript, med ett SDK — objektet keplin — som ger åtkomst till allt skärmen har.

Var händelserna finns

I inspektorn heter en widgets (och skärmens egen) sista kategori Händelser. Den har en rad per tillgänglig händelse, och på varje rad:

  • en punkt till vänster: fylld när händelsen redan har kod, tom när den inte har det;
  • en knapp till höger, som öppnar redigeraren.

Kategorin Händelser på en Knapp: en fylld punkt markerar de händelser som redan har kod; … öppnar redigeraren.
Kategorin Händelser på en Knapp: en fylld punkt markerar de händelser som redan har kod; … öppnar redigeraren.

Händelsernas namn översätts inte — de är desamma på alla språk (onClick, onRowClick, onLoad), eftersom de också är namnen som dyker upp i koden och i Radars loggar.

Skärmens händelser

Klicka på en tom yta på canvasen så att inspektorn visar skärmen. Kategorin Händelser har tre:

Händelse När den utlöses Till vad
onLoad En gång, när skärmen öppnas. Förbereda tillstånd, ladda sådant som datastorerna inte laddar, hälsa välkommen.
onParamsChange Varje gång ruttens parametrar ändras — och inte vid det första öppnandet. Reagera på ett postbyte utan att öppna skärmen på nytt.
onUnload När skärmen lämnas. Rensa tillstånd, spara utkast.

Skärmens egna händelser — onLoad, onParamsChange och onUnload — i inspektorn utan markering.
Skärmens egna händelser — onLoad, onParamsChange och onUnload — i inspektorn utan markering.

Varje widgets händelser

Varje widgettyp deklarerar sina egna. Utöver namnet är payloaden det intressanta — de data som händelsen bär med sig, och som koden läser i keplin.event.

Formulärfält

Widget Händelser keplin.event
Textruta, Textområde, Tal, Ja/Nej, Listruta, Datum, Färg onChange { value }
Fil onChange, onUpload onUpload: { file, name }

Åtgärder och navigering

Widget Händelser keplin.event
Knapp onClick {}
Knapp med meny onClick, onMenuItem onMenuItem: { id, label }
Länk onClick {}
Exportera onExport, onDataLoaded onExport: { rows, filename }

Struktur och innehåll

Widget Händelser keplin.event
Flikar onTabChange { tab }
Rapport onLoad { report }

Datawidgetar

Widget Händelser keplin.event
Tabell onRowClick, onRowDoubleClick, onSelectionChange, onDataLoaded { row, index } · onSelectionChange: { row, rows }
Lista, Kort onRowClick, onDataLoaded { row, index }
Diagram onClick { name, seriesName, value, dataIndex }
KPI onClick, onDataLoaded { value, indicatorId }

Tavlor och planering

Widget Händelser 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 }

Processer

Widget Händelser keplin.event
Processens status onDecide { task, outcome }
Mina uppgifter onOpen, onDecide { task, screenId }

Nota

Widgetar som du själv programmerat (de som dyker upp i paletten under Anpassad) deklarerar sina egna händelser, och de visas här som vilka andra som helst.

Kodredigeraren

Knappen på en händelse öppnar redigeraren i en modal. Titeln säger var du är: widgetens id (eller skärmens namn) och händelsens namn — w_fic_sav1 · onClick.

Redigeraren för händelsen onClick på knappen Spara: koden sparar datastoren och, om det gick bra, meddelar den och går tillbaka till listan.
Redigeraren för händelsen onClick på knappen Spara: koden sparar datastoren och, om det gick bra, meddelar den och går tillbaka till listan.

Knapp Vad den gör
Infoga åtgärd Skriver koden för en vanlig uppgift åt dig (härnäst).
Ta bort hanteraren Raderar den här händelsens kod. Punkten blir tom igen.
Avbryt Stänger utan att spara.
Spara Kontrollerar och sparar.

Redigeraren har förslag medan du skriver (Ctrl+Blanksteg): hela keplin är deklarerat, med rätt typer — och, ännu bättre, id:na för widgetarna på den här skärmen finns där inne. Att skriva keplin.widgets.get(" visar listan över skärmens widgetar, och ett id som inte finns markeras som fel innan du sparar.

Atenção

När du sparar kompileras koden. Om den inte går att köra vägrar plattformen den — Händelsen sparades inte: koden går inte att köra — och modalen förblir öppen så att du kan rätta. En skärm blir aldrig kvar med trasig kod inuti sig.

De fördefinierade åtgärderna

Infoga åtgärd öppnar en lista över de vanligaste uppgifterna. Du väljer en, och koden skrivs in i slutet av det som redan finns där, redan med de riktiga namnen från din skärm — den första postdatastoren, den första tabellen, den första textrutan.

Infoga åtgärd — de fördefinierade åtgärderna som skriver koden åt dig, från datastorerna till arbetsflödena.
Infoga åtgärd — de fördefinierade åtgärderna som skriver koden åt dig, från datastorerna till arbetsflödena.

Åtgärd Vad den skriver
Spara datastore Validerar och sparar posten, med bekräftelse.
Ladda om datastore Läser om data från en datastore.
Filtrera datastore (på text) Läser texten från en ruta och tillämpar den som filter.
Navigera till en skärm Hoppar till en annan rutt i appen.
Ladda om en tabell Uppdaterar data i en tabellwidget.
Filtrera tabell på värdet i en textruta Det klassiska interaktiva filtret.
Visa/dölj en widget Växlar en widgets synlighet.
Bekräfta och visa en toast Frågar innan den agerar och meddelar efteråt.
Starta ett arbetsflöde Sätter en process i rörelse över den aktuella posten.
Lista och slutför uppgifter Listar uppgifterna för den som använder appen och avgör en.
Skicka en signal till ett arbetsflöde Väcker processer som stod och väntade.
Logga ut Lämnar appen.

Den infogade koden är en utgångspunkt: den blir din, och den är till för att redigeras. Den genereras inte om.

Hur koden körs

Varje händelse är en asynkron funktion som tar emot en enda sak: keplin. Därifrån följer tre praktiska konsekvenser:

  • await fungerar direkt på översta nivån. Ingenting behöver lindas in.
  • return lämnar händelsen. Det är det normala sättet att ge upp halvvägs (till exempel när en bekräftelse nekades).
  • Det finns inga parametrar. Kontexten kommer inuti keplin självt: keplin.event bär payloaden och keplin.ctx säger var du är (ctx.widget är widgeten som utlöste den — null i skärmens händelser —, ctx.event är händelsens namn och ctx.screen skärmen).

Så länge en knapps kod inte är klar visar knappen tre animerade punkter: den som använder appen förstår att den arbetar. Om koden kraschar går skärmen inte sönder: en varning dyker upp och felet loggas i Radar, med skärmen, widgeten och händelsen där det hände.

SDK:t keplin

Allt som koden kan göra ligger under keplin. Det här är områdena:

Område Till vad
keplin.event / keplin.ctx Händelsens payload och kontexten den körs i.
keplin.widgets Tala med skärmens widgetar.
keplin.data Datastorerna: läsa, skriva, filtrera, spara.
keplin.nav Navigera och läsa ruttens parametrar.
keplin.ui Meddelanden, bekräftelser och modaler.
keplin.state Tillstånd som delas mellan skärmar.
keplin.session Vem som använder appen, och vad hen får göra.
keplin.auth Inloggning, registrering och lösenordsåterställning (systemskärmar).
keplin.i18n Översatta fraser.
keplin.storage Inställningar sparade på enheten.
keplin.api Anropa appens API:er direkt.
keplin.reports Öppna och ladda ner rapporter.
keplin.workflow Starta processer, lista och slutföra uppgifter.

Widgetarna

keplin.widgets.get("id") returnerar en widgets handle. Alla handles har samma grundläggande delar:

const w = keplin.widgets.get("w_fic_tel1");
w.show();               // visa
w.hide();               // dölj
w.setEnabled(false);    // inaktivera
w.set("label", "Mobil");   // ändra vilken egenskap som helst från inspektorn
w.get("label");         // läs det faktiska värdet
w.reset();              // glöm ändringarna som gjorts under körning

Och sedan lägger varje familj till det som är dess eget:

Familj Vad den lägger till
Formulärfält getValue(), setValue(v), validate(), error
Datawidgetar (Tabell, Lista, Kort, Diagram, KPI, Kanban, Kalender, Gantt) rows, total, refresh(), setFilter(where), setSort(sort)
Tabell selectedRow, selectedRows, clearSelection()
KPI value, values, valueOf(indikatorId)
Kanban columns, moveCard(id, kolumn, index?)
Kalender view, start, end, goTo(datum), setView(vy)
Gantt zoom, setZoom(z)
Flikar activeTab, tab("id") — och, på fliken, activate(), show(), hide(), setEnabled()
Etikett / Knapp / Länk / Breadcrumb setText(t) / setLabel(t)
Markdown setContent(md)
Extern sida setUrl(url), reload()
Exportera export()
Rapport url, download()

Nota

Redigerarens förslag erbjuder alla verb från alla familjer, eftersom redigeraren inte i förväg vet vilken widget det id:t är. Under körning finns bara de som hör till den verkliga typen — moveCard på en Knapp gör inget nyttigt.

Data

keplin.data.store("namn") returnerar en av skärmens datastorer via dess namn (se Datastorer och data).

I en post-datastore:

const conta = keplin.data.store("conta");
conta.get("nome");                 // läs ett fält
conta.set("estado", "ativo");      // skriv ett fält (blir osparat)
conta.record();                    // hela posten
conta.isDirty();                   // finns det osparade ändringar?
conta.reset();                     // kasta bort ändringarna
const ok = await conta.save();     // validerar och sparar; true om den sparades

I en list-datastore:

const contas = keplin.data.store("contas");
contas.rows();                     // de laddade raderna
contas.total();                    // totalen (när servern ger den)
contas.reload();                   // läs om
contas.setWhere({ estado: { eq: "ativo" } });   // extra filter; null rensar
contas.setSort([{ field: "nome", direction: "ASC" }]);
contas.goToPage(2);

I båda säger status() hur långt laddningen har kommit (idle, loading, ready, error).

keplin.nav.go("/ficha-de-conta/17");   // gå till en rutt (med parametrar)
keplin.nav.back();                      // gå tillbaka
keplin.nav.params;                      // den aktuella skärmens parametrar, per namn

Meddelanden, bekräftelser och modaler

keplin.ui.toast("Sparat.", "success");        // "success" | "error" | "info"
const ok = await keplin.ui.confirm("Ta bort posten?");
if (!ok) return;

Bekräftelsen är en dialog med appens tema — aldrig webbläsarens grå ruta.

Tillstånd, session och inställningar

keplin.state.set("filtroContas", "activas");   // lever så länge fliken är öppen
keplin.state.get("filtroContas");
keplin.state.remove("filtroContas");

keplin.session.user;              // { id, username, name } — null på publika skärmar
keplin.session.roles;             // rollerna hos den som använder appen
keplin.session.can("contas.editar");   // har hen den här åtgärden? (Inställningar ▸ Behörigheter)
await keplin.session.logout();

keplin.storage.set("colunasContas", ["nome", "cidade"]);   // stannar på enheten
keplin.storage.get("colunasContas");

Dica

För att avgöra vad någon får göra: fråga keplin.session.can("...") och inte hasRole("gestor"). Åtgärderna deklareras i Inställningar ▸ Behörigheter och överlever omorganisationer av roller; en rolls namn gör det inte.

API:erna och rapporterna

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

keplin.reports.open("Kontaktpersoner för kontot", { contaId: 17 });
keplin.reports.download("Kontaktpersoner för kontot", { contaId: 17 }, "xlsx");

I en fråga är fältlistan obligatorisk — det är den som säger vad du vill hämta.

Atenção

keplin.reports.open öppnar en ny flik och kan därför inte ligga efter ett await: utanför användarens gest blockerar webbläsaren fönstret. Öppna först, gör resten sedan.

Arbetsflöden

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);

Översatta fraser

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

Modala skärmar

En skärm i Keplin är inte modal för att den öppnades på ett visst sätt — den är modal för att den konfigurerades så. Beslutet fattas i skärmens inspektor, i kategorin Presentation:

Avsnittet Presentation på skärmen: det är här en skärm blir Modal (centrerad) eller Sidopanel (höger).
Avsnittet Presentation på skärmen: det är här en skärm blir Modal (centrerad) eller Sidopanel (höger).

Alternativ Vad det gör
Läge Skärm (en vanlig sida), Modal (centrerad) eller Sidopanel (höger).
Bredd (px) / Höjd (px) Modalens storlek. Sidopanelen använder hela höjden.
Stängknapp Visar × i hörnet.
Klick utanför stänger / Esc stänger De två vanliga utgångarna.
Uppdatera skärmen bakom vid stängning Vid stängning läser datastorerna på skärmen som anropade den om sina data.

Avsnittets eget tips sammanfattar: Öppnas OVANPÅ skärmen som anropar den (Länk, händelser eller keplin.ui.openModal). Ingår inte i den direkta navigeringen.

Öppna och stänga med kod

const resultado = await keplin.ui.openModal("/nova-conta", { setor: "banca" });
if (resultado) {
  keplin.data.store("contas").reload();
}
  • openModal tar emot skärmens rutt (eller id) och, valfritt, parametrarna.
  • Löftet resolvar först när modalen stängs, och bär med sig värdet som modalen lämnade tillbaka.
  • Inuti modalen stänger keplin.ui.closeModal(värde) och returnerar det värdet.
  • Modaler staplas: en modal kan öppna en annan.

Nota

keplin.nav.go("/rutt") till en skärm som är konfigurerad som Modal (centrerad) eller Sidopanel (höger) öppnar den som modal i stället för att navigera. Det är med flit: en modal skärm har ingen egen adress i navigeringen.

Recept

Spara och gå tillbaka (onClick på knappen Spara i Kontouppgifter):

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

Öppna kortet för den klickade raden (onRowClick på en Tabell):

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

Filtrera en tabell med en textruta (onChange på rutan — byt ut id:na mot dina egna skärms):

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

Bekräfta före en destruktiv åtgärd (onClick på en knapp):

if (!(await keplin.ui.confirm("Ta bort det här kontot?"))) return;

Dölja en knapp för den som inte får (onLoad på skärmen):

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

Varför inte…?

  • Varför får jag inte spara händelsen? Koden kompilerar inte. Meddelandet är Händelsen sparades inte: koden går inte att köra — rätta och spara.
  • Varför ger keplin.widgets.get("...") fel? Id:t finns inte på den här skärmen. Kontrollera det överst i inspektorn, med widgeten markerad; och kom ihåg att varje enhet är ett eget träd (se Layouter och design per enhet).
  • Varför utlöstes inte onParamsChange vid öppnandet? Det är med flit: den utlöses bara vid ändringar. Använd onLoad för starten.
  • Varför lämnar modalen inte tillbaka något? Antingen finns inte målskärmen, eller så saknar den som använder appen behörighet att öppna den — i båda fallen resolvar löftet utan värde. Kontrollera rutten och behörigheterna.
  • Varför öppnas inte rapportfönstret? Du satte open efter ett await. Öppna först.
  • Varför verkar min händelse inte köras? Titta i Radar: felen i händelsernas kod hamnar där, med skärm, widget och händelse — och Radar tar dig direkt till redigeraren för just den händelsen.