Orbito - Dokumentacja modułówOrbito - Dokumentacja modułów
Wprowadzenie
Pierwsze kroki
API
Komunikacja
Widoki
Wdrożenie
Społeczność
For AI agents
Wprowadzenie
Pierwsze kroki
API
Komunikacja
Widoki
Wdrożenie
Społeczność
For AI agents
  • API biblioteki

    • API biblioteki @orbito/api-lib
    • Core
    • Log
    • Utils
    • Pages
    • Automation
    • DB
    • Config
    • Files
    • Problems
    • History
    • OAuth
    • Time
    • Mail
    • Templates
    • Lock
    • Uprawnienia

Pages

Moduł Pages pozwala modułowi udostępniać własne widoki (ekrany UI) w panelu Orbito. Moduł rejestruje gotowe, deklaratywne widoki OVE, a platforma zapisuje je w swojej bazie (per firma) i sama serwuje frontendowi — kontener modułu nie musi wstawać przy każdym wejściu na stronę.

const { Pages } = require('@orbito/api-lib');

Nowy model rejestracji

Widoki rejestruje się teraz z góry przez Pages.registerPages — moduł zgłasza całą treść widoku przy starcie. Wcześniejsze Pages.registerPage(path, handler) (generowanie treści na żądanie) jest wycofywane.

Pages.registerPages

Rejestruje komplet widoków modułu. Widoki bywają długie (nierzadko kilkaset linii), dlatego trzyma się je w osobnych plikach, a w kodzie podaje tylko ścieżkę.

Pages.registerPages(pages)
ParametrTypOpis
pagesobjectMapa pagePath → definicja widoku

Kluczem jest pagePath — ścieżka widoku w obrębie modułu (np. /list, /order/:orderId). Pełny URL w panelu powstaje z kodu modułu i tej ścieżki.

Definicja pojedynczego widoku:

PoleTypWymaganeOpis
namestring✔Przyjazna nazwa strony pokazywana w nawigacji (np. „Lista zamówień")
viewstring✔Ścieżka do pliku z treścią widoku. Bezwzględna lub względna do katalogu roboczego modułu (process.cwd()). Format wnioskowany z rozszerzenia: .yaml/.yml → YAML, .json → JSON. Plik jest wczytywany przy rejestracji
moduleDependenciesobjectMapa zależności modułowych, np. { "core/orders": "^1.0.2" }
placementobjectUmiejscowienie automatycznego linku do strony w panelu — górny pasek albo menu ustawień (od SDK 3.2.0). Bez tego pola strona działa, ale nie dostaje linku. Patrz Linki do stron w panelu

Przykład rejestracji w index.js:

const { Pages } = require('@orbito/api-lib');

Pages.registerPages({
  '/list': {
    name: 'Lista zamówień',
    view: 'pages/orders-list.yaml',
    moduleDependencies: { 'core/orders': '^1.0.0' },
    placement: { location: 'navbar', icon: 'checkup-list', order: 10 }
  },
  '/order/:orderId': {
    name: 'Szczegóły zamówienia',
    view: 'pages/order-details.yaml'
  }
});

Sugerowana struktura projektu modułu:

my-module/
├── index.js
└── pages/
    ├── orders-list.yaml
    └── order-details.yaml

Plik widoku

Plik zawiera drzewo widoku OVE — deklaratywny opis UI. Treść z ciała żądania i parametry ścieżki są dostępne w szablonie przez scope $page (Handlebars), więc nie potrzebujesz handlera po stronie modułu do wyrenderowania strony.

pages/orders-list.yaml:

type: card
title: Zamówienia
content:
  type: datatable
  dataSource:
    method: listOrders          # metoda modułu (Core.registerMethod)
  columns:
    - { key: number, title: Numer }
    - { key: status, title: Status }

Ścieżka z parametrami (/order/:orderId) — wartość parametru czytasz w szablonie ze scope $page:

type: card
title: Zamówienie {{ $page.orderId }}
content:
  type: dynamic
  dataSource:
    method: getOrder
    params: { orderId: '{{ $page.orderId }}' }

Pełną składnię widoków opisuje sekcja Widoki.

Linki do stron w panelu (placement)

Sama rejestracja widoku sprawia, że strona istnieje pod swoim adresem — ale nie mówi jeszcze, gdzie użytkownik ma ją znaleźć. Bez pola placement strona nie dostaje żadnego linku w panelu; trafi na nią tylko ten, kto zna adres, przejdzie z innego widoku albo doda zakładkę ręcznie w Ustawienia → Nawigacja.

Pole placement (od SDK 3.2.0) pozwala modułowi zadeklarować link samodzielnie — w górnym pasku nawigacji albo w menu ustawień:

Pages.registerPages({
  '/list': {
    name: 'Lista zamówień',
    view: 'pages/orders-list.yaml',
    placement: { location: 'navbar', icon: 'checkup-list', order: 10 }
  },
  '/statuses': {
    name: 'Konfiguracja statusów',
    view: 'pages/statuses.yaml',
    placement: { location: 'settings', section: 'orders', icon: 'adjustments' }
  }
});

Pola placement:

PoleTypWymaganeOpis
location'navbar' | 'settings'✔Gdzie ma się pojawić link: górny pasek nawigacji czy menu ustawień
sectionstringTylko dla settings — klucz sekcji menu ustawień, do której trafi link (patrz registerSettingsSections). Brak = link na pierwszym poziomie menu
iconstringNazwa ikony Tabler bez prefiksu ti-, np. 'truck', 'adjustments'
ordernumberKolejność linku (rosnąco). Bez order link ląduje na końcu, a linki bez kolejności sortują się alfabetycznie

Walidacja przy rejestracji

Błędny placement (nieznane location, section przy location: 'navbar', klucz sekcji spoza [a-z0-9_-]) powoduje wyjątek z registerPages — cały zestaw stron nie zostanie zgłoszony. Błąd zobaczysz w logach kontenera od razu przy starcie modułu.

Link w górnym pasku (navbar)

Pages.registerPages({
  '/list': {
    name: 'Przesyłki',
    view: 'pages/shipments.yaml',
    placement: { location: 'navbar', icon: 'truck', order: 20 }
  }
});

Zakładki modułów doklejane są za zakładkami skonfigurowanymi przez firmę i sortowane po order. Firma zachowuje kontrolę: w Ustawienia → Nawigacja administrator może zakładkę modułu ukryć albo wstawić ją we własnej kolejności — Twoja deklaracja jest propozycją domyślną, nie ustawieniem twardym.

Navbar to miejsce na pracę codzienną

W górnym pasku umieszczaj ekrany, z których użytkownik korzysta na co dzień (lista przesyłek, kolejka zamówień). Ekrany konfiguracyjne kieruj do settings — pasek nawigacji jest wspólny dla wszystkich modułów i szybko się zapełnia.

Link w menu ustawień (settings)

Pages.registerPages({
  '/statuses': {
    name: 'Mapowanie statusów',
    view: 'pages/statuses.yaml',
    placement: { location: 'settings', icon: 'adjustments' }
  }
});

Strona zostaje osadzona w panelu ustawień (/settings/p/...), więc użytkownik nie traci kontekstu — menu ustawień zostaje na swoim miejscu. Bez pola section link pojawia się na pierwszym poziomie menu; z section trafia do zwijanej sekcji grupującej.

To nie to samo co ekran konfiguracji modułu

Deklaratywny ekran ustawień z formularzami i walidacją dostajesz „za darmo" przez Config.registerConfigBlocks. placement: { location: 'settings' } służy do ekranów, które robią coś więcej niż formularz — mapowania, tabele, kreatory, podgląd stanu integracji.

Pages.registerSettingsSections

Sekcja to zwijana grupa w menu ustawień — pozwala zebrać kilka stron modułu (albo kilku modułów) pod jedną nazwą zamiast rozsypywać je po pierwszym poziomie menu.

Pages.registerSettingsSections(key, name, opts?)
ParametrTypWymaganeOpis
keystring✔Klucz (slug) sekcji: [a-z0-9_-], zaczyna się od litery lub cyfry, normalizowany do małych liter. To on jest tożsamością sekcji — strony wskazują go w placement.section
namestring | object✔Nazwa wyświetlana: string albo mapa językowa, np. { pl: 'Zamówienia', en: 'Orders' }
opts.iconstringIkona Tabler sekcji (bez prefiksu ti-)
opts.ordernumberKolejność sekcji w menu (rosnąco); bez niej sekcja ląduje na końcu, alfabetycznie
const { Pages } = require('@orbito/api-lib');

await Pages.registerSettingsSections('orders', { pl: 'Zamówienia', en: 'Orders' }, {
  icon: 'shopping-cart',
  order: 10
});

Pages.registerPages({
  '/statuses': {
    name: 'Mapowanie statusów',
    view: 'pages/statuses.yaml',
    placement: { location: 'settings', section: 'orders', icon: 'adjustments' }
  },
  '/carriers': {
    name: 'Przewoźnicy',
    view: 'pages/carriers.yaml',
    placement: { location: 'settings', section: 'orders', icon: 'truck', order: 20 }
  }
});

Efekt w menu ustawień:

Ustawienia
└── Zamówienia            (sekcja, ikona shopping-cart)
    ├── Mapowanie statusów
    └── Przewoźnicy

Metoda wywołuje się raz na sekcję; kolejne wywołania dokładają sekcje i re-wysyłają pełny zestaw. Rejestracja jest, tak jak przy stronach, replace-setem — sekcja, której moduł przestał deklarować, znika, a po reconnect zestaw wysyłany jest automatycznie.

Wspólna sekcja kilku modułów

Klucz sekcji jest niezależny od języka i globalny w obrębie firmy — dwa moduły rejestrujące 'orders' trafią do tej samej sekcji menu, a ich strony pojawią się obok siebie. Dzięki temu użytkownik ma jedno miejsce „Zamówienia" zamiast osobnej pozycji per moduł. Nazwy i ikony z wielu rejestracji są scalane (brakujące metadane uzupełnia pierwsza rejestracja, która je podała).

Sytuacje brzegowe, o które nie musisz się martwić:

  • sekcja bez stron nie jest renderowana — możesz zarejestrować ją zawczasu;
  • strona wskazująca niezarejestrowany klucz nie znika z menu — panel pokaże sekcję zastępczą nazwaną kluczem (np. orders → „Orders"). Zawsze warto jednak zarejestrować sekcję, żeby dostać czytelną nazwę i ikonę.

Linki do stron — uwagi praktyczne

Nie nadawaj placement stronom z parametrami w ścieżce

Link do /order/:orderId prowadziłby do dosłownego :orderId — panel nie ma skąd wziąć wartości parametru. Strony parametryczne otwiera się z innego widoku (np. akcją generatePage z listy — patrz Action Handler), a placement rezerwuj dla stron wejściowych.

Dostęp. Link dziedziczy ustawienia dostępu strony — użytkownik spoza whitelisty (allowedUsers, ustawianej przez właściciela firmy) nie zobaczy ani strony, ani jej linku.

Wiele instalacji tego samego modułu. Gdy firma ma więcej niż jedną instancję modułu, panel sam dopisuje do etykiety nazwę instancji (np. „Przesyłki (Sklep PL)"), a link zawiera wskazanie instancji. Ten sam placement w każdej instancji jest więc bezpieczny — nie trzeba różnicować nazw w kodzie.

Wycofanie linku. placement jest częścią zestawu wysyłanego przy każdej rejestracji, więc usunięcie pola w nowej wersji modułu usuwa link przy pierwszym połączeniu po aktualizacji (strona zostaje).

Aktualizacja treści i wycofywanie widoków

Cały zestaw wysyłany jest jednorazowo przy każdym połączeniu modułu, a platforma robi replace-set:

  • treść widoków jest nadpisywana — nowa wersja modułu może zmienić dowolny widok, wystarczy zaktualizować plik;
  • widoki, których moduł przestał deklarować (np. usunięte w nowej wersji), platforma usuwa;
  • rejestracja jest ponawiana automatycznie po każdym reconnect.

Ustawienia dostępu należą do firmy

Nadpisywana jest wyłącznie treść widoku. Whitelista dostępu (allowedUsers), którą właściciel firmy ustawia w panelu, jest własnością firmy i przy aktualizacji modułu pozostaje nietknięta.

Dostęp do stron

Domyślnie widok modułu jest dostępny dla wszystkich użytkowników firmy. Właściciel/administrator firmy może w panelu ograniczyć dostęp do wybranej strony do konkretnych użytkowników — to ustawienie firmy, moduł na nie nie wpływa.

Cykl życia: wyłączenie vs odinstalowanie

OperacjaCo się dzieje z widokami
Wyłączenie modułu (disable)Widoki pozostają w bazie (podobnie jak konfiguracja). Po ponownym włączeniu i połączeniu modułu treść jest odświeżana, a ustawienia dostępu zachowane
Odinstalowanie modułu z firmyWidoki modułu tej firmy są trwale usuwane

Pages.registerPage (wycofane)

Metoda wycofana

Pages.registerPage(path, title, controller) należy do starego modelu, w którym platforma pobierała treść strony z żywego modułu na żądanie (getPage). Została zastąpiona przez registerPages i jest utrzymywana wyłącznie dla kompatybilności wstecznej — w nowych modułach jej nie używaj.

Migracja jest prosta — zamiast zwracać template z handlera, przenieś jego treść do pliku widoku i zarejestruj ścieżką:

// PRZED (wycofane) — treść generowana w handlerze
Pages.registerPage('/list', 'Lista zamówień', async (body, params) => ({
  type: 'ove',
  template: { type: 'card', title: 'Zamówienia', /* ... */ }
}));

// PO — treść w pliku, rejestracja z góry
Pages.registerPages({
  '/list': { name: 'Lista zamówień', view: 'pages/orders-list.yaml' }
});

Dane, które handler dobierał do wyrenderowania strony, w nowym modelu dostarczają metody modułu wskazane w widoku przez dataSource (patrz Widoki oraz Core.registerMethod).

Ostatnio zaktualizowano:: 20.08.2026, 13:03
Contributors: Wiktor Koźmiński, Claude Opus 4.8 (1M context), Claude Opus 5 (1M context)
Prev
Utils
Next
Automation