Fejlesztőknek
Kezdj bele
Appok/Adminfelület

Adminfelület

Hol jelenik meg egy app a Poltura adminfelületén. Natív oldalak és az Alkalmazások menüpont, kezdőlapi kártyák, panelek a termék-, gyűjtemény-, rendelés- és vásárlói oldalakon, worker-beállítások, valamint hosztolt oldalak iframe-ben.

Ezen az oldalon

Egy app négyféle elemet adhat hozzá az adminfelülethez: saját oldalakat, egy kezdőlapi kártyát, paneleket a részletező oldalakon, valamint egy hosztolt oldalt, amelyet magad szolgálsz ki. Az első három natív worker; az utolsó egy iframe.

Oldalak és navigáció

Egy admin.page célú worker akkor válik oldallá, ha szerepel a manifest adminPages listájában – legfeljebb 8 ilyen adható meg. Az adminfelület az Alkalmazások menüpont alatt jeleníti meg őket a navigációban, a /apps/<installation id>/<page id> útvonalon. A lista nélkül az oldal létezik ugyan a release-ben, de semmi sem hivatkozik rá.

A useNavigate() hookkal navigálhatsz az oldalak között, a vissza- és előregombok a megszokott módon működnek: a { kind: 'app_page', pageId } az appod egy másik oldalát nyitja meg, a { kind: 'host', target } pedig egy adminfelületi képernyőt, ahol a target értéke app_home, products, collections, orders, customers, product, collection, order vagy customer lehet.

A teljes példa adminfelületi oldala beolvassa a beállításait, megnyitja a product pickert, toast üzeneteket jelenít meg, és meghív egy műveletet:

export function AdminPage(): ReactNode {
  const copy = copyFor(useLocale());
  const settings = useSettings();
  const navigate = useNavigate();
  const toast = useToast();
  const pick = useResourcePicker();
  const saveFeatured = useAction('save_featured');
  const heading = String(settings.heading ?? copy.heading);
  const [picked, setPicked] = useState('');

  return (
    <Card className='offer-panel rounded-theme bg-surface text-foreground p-4'>
      <Stack>
        <Heading>{heading}</Heading>
        <Text>{copy.adminIntro}</Text>
        <TextField label={copy.featuredLabel} value={picked} onChange={setPicked} />
        <Inline>
          <Button
            label={copy.pickProducts}
            onPress={async () => {
              const ids = await pick('product', true);
              if (ids === null) return;
              setPicked(ids.join(','));
              await toast('success', copy.pickedToast);
            }}
          />
          <Button
            label={copy.save}
            onPress={async () => {
              const productIds = picked
                .split(',')
                .map((value) => value.trim())
                .filter((value) => value.length > 0);
              await saveFeatured({
                productIds,
                expectedVersion: 0,
                idempotencyKey: crypto.randomUUID(),
              });
              await toast('success', copy.savedToast);
            }}
          />
          <Button
            label={copy.openPage}
            onPress={() => navigate({ kind: 'app_page', pageId: RECOMMENDATIONS_PAGE })}
          />
        </Inline>
      </Stack>
    </Card>
  );
}
  • useSettings(): visszaadja a worker beállításait az adott telepítéshez. Lásd: Worker-beállítások.
  • useResourcePicker(): megnyitja az adminfelület saját product pickerét vagy collection pickerét: a pick('product' | 'collection', multiple) a kiválasztott azonosítókat adja vissza legfeljebb 50 elemig, vagy null értéket, ha a kereskedő megszakítja a műveletet. A hívás 15 másodperc után leáll.
  • useToast(): megjelenít egy adminfelületi toast üzenetet: toast('info' | 'success' | 'warning' | 'critical', message), legfeljebb 200 karakteres üzenettel.
  • useAction('save_featured'): meghívja a szerveredet. Egy worker nem küldhet kérést közvetlenül a szerveredre vagy bármilyen más címre; ehelyett a Poltura küld egy aláírt POST kérést a backendOrigin /actions/save_featured endpointjára, amelyet a szervered ellenőriz:
const raw = await readBody(req);
const output = await actions.handle(raw, requestHeaders(req));
send(res, 200, JSON.stringify(output), 'application/json; charset=utf-8');

A szerveroldali részletekért lásd: Aláírt műveletek.

Kezdőlapi kártyák

Az admin.home célú worker egy kártyát jelenít meg az adminfelület kezdőlapján. Ugyanazokat a komponenseket és beállításokat használja, mint egy oldal, és nem tartozik hozzá kiválasztott termék vagy rendelés.

Panelek a részletező oldalakon

Az admin.product, admin.collection, admin.order és admin.customer célú workerek ezeken a részletező oldalakon jelennek meg. A useSelectedEntity() azt a rekordot adja vissza a panelnek, amelyet a kereskedő éppen megnyitott, és kizárólag azt: a hook nem vár azonosítót. Egy rendelés beolvasásához az orders.read, egy vásárló beolvasásához a customers.read jogosultság szükséges.

export function AdminProduct(): ReactNode {
  const copy = copyFor(useLocale());
  const selected = useSelectedEntity();
  const navigate = useNavigate();
  if (selected.status !== 'ready' || selected.entity.kind !== 'product') {
    return <Text>{copy.unavailable}</Text>;
  }
  return (
    <Card className='rounded-theme bg-surface text-foreground p-4'>
      <Stack>
        <Heading>{selected.entity.product.title}</Heading>
        <Button
          label={copy.openSettings}
          onPress={() => navigate({ kind: 'app_page', pageId: RECOMMENDATIONS_PAGE })}
        />
      </Stack>
    </Card>
  );
}

A useSelectedEntity() kezdetben loading állapotú, majd ready vagy unavailable állapotra vált; jeleníts meg valamilyen hasznos tartalmat mindegyikhez. A natív widgetek példájában egy rendelési és egy termékpanel is található.

Worker-beállítások

Az adminfelület minden workerhez külön beállítási képernyőt hoz létre a defineBlock definíciójában szereplő settings alapján (a field type-ok: text, textarea, number, range, checkbox, select, radio, color és url). Amikor a kereskedő ment, a useSettings() az új értékeket adja vissza. defineBlock definíció nélkül a workernek nincsenek beállításai. A manifest saját settings listája egyelőre sehol sem jelenik meg (lásd: Manifest).

Hosztolt iframe-oldalak

A hosztolt oldal egy saját szervereden futó oldal, amely egy iframe-ben jelenik meg az adminfelületen. Akkor használd, ha saját HTML-, CSS- és JavaScript-kódra van szükséged. A manifestben az adminFrame mezőben deklarálhatod: itt kell megadnod a pontos HTTPS-címet, valamint az engedélyezett bridge actionöket (toast, set_loading, navigate_host, pick_resource, resize, get_session_token és get_appearance).

Az iframe allow-scripts allow-forms allow-same-origin védelemmel fut sandboxban: az oldal nem nyithat felugró ablakokat, és nem irányíthatja át az adminfelületet. Az oldalon belül a @poltura/app-sdk/frame csomagból származó connectAppFrame kapcsolódik az adminfelülethez ugyanezzel a műveletlistával. Ha meg akarod hívni a szerveredet, kérj le egy session tokent a requestAppSession segítségével, és csatold a kéréshez; a telepítési azonosító, amelyet az adminfelület a kapcsolódáskor átad az oldalnak, csupán megjelenítésre szolgál, nem hitelesítésre. A teljes folyamatot a Hitelesítés oldal ismerteti. A teljes példa szervere így ellenőrzi a tokent:

if (sessions === null) {
  send(res, 503, 'Session verification is not configured.');
  return;
}
const header = requestHeaders(req).get('authorization') ?? '';
const token = header.startsWith('Bearer ') ? header.slice('Bearer '.length) : '';
const assertion = await sessions.verify(token);
send(
  res,
  200,
  JSON.stringify({ installationId: assertion.installationId, storeId: assertion.storeId }),
  'application/json; charset=utf-8',
);

Ha a Poltura komponenseivel szeretnél felületet építeni egy hosztolt oldalon, importáld a @poltura/app-ui/dom csomagot, hívd meg a get_appearance műveletet, és csomagold az oldalt a PolturaProvider komponensbe. Ez a belépési pont kizárólag hosztolt adminfelületi oldalakhoz készült; önmagában nem nyújt elszigetelést.

A kereskedők a Kapcsolt alkalmazások (/connected-apps) menüpontból nyithatják meg a hosztolt oldalt; az a /connected-apps/<installation id>/page címen érhető el.

Következő lépések

  • Webáruház: blokkok, header- és lábléc-zónák, valamint webáruházi oldalak.
  • Hitelesítés: tokenek, session tokenek és aláírt műveletek.
Utoljára frissítve