Dokumentationen / Skal
Skalet (apps/portal)
SkalStartsideportalenKomponerar modulerna till en sammanhängande sida och äger allt krom, all identitet och all layout.
källa: apps/portal/src/shelluppdaterad: 2026-10-07
Ansvar
- Läsa modulregistret, filtrera på roll och rendera varje slot i ordning.
- Äga identiteten: rollen ur cookien, DemoUser, och UserContext som är allt modulerna får veta om användaren.
- Äga kromet: sidopanel, AI-fält, användarmeny, sidfot, fokuslägets topprad.
- Lägga ut rutnätet – nyckeltalsraden i fyra spår, arbetsytan i två spalter – och låta modulerna fylla det.
- Aldrig veta vad en widget innehåller. Skalet känner slotens namn, inte innehållet.
Filer
| Sökväg | Roll |
|---|---|
| shell/registry.ts | Modulregistret. En ny modul = en rad. Anropar provideRegistry för de aggregerande modulerna. |
| shell/session.ts | getCurrentUser ur cookien, toContext som gör om DemoUser till UserContext. |
| shell/demo-users.ts | Demoanvändarna – medarbetaren och fyra chefer på olika nivåer, för dialogstödet – sektionerna under "Sidor" och de verktygspunkter som ännu saknar modul. Kakan bär en roll eller en användares id. |
| shell/actions.ts | switchRole, loggaInSom och loggaUt: server actions som sätter eller rensar rollcookien. sparaLayout för kortens ordning, även standardordningen (ADR-018). markeraLasta för notiserna (ADR-020). stangFokus och visaFokusIgen (demo) för fokusytan (ADR-021). |
| shell/ShellFrame.tsx | Ramen: sidopanel plus arbetsyta. Klientkomponent för dockningsläget; children renderas på servern. |
| shell/Sidebar.tsx | Sidopanelen: Verktyg, Sidor, notiser, användarmeny. Sektionerna kommer som prop från layouten. |
| app/(skal)/verktyg/[...vag]/page.tsx | Modulvyer med mode "standard": slår upp vägen med routeFor och skickar vidare params (ADR-019). |
| shell/fokus/FokusYta.tsx | Fokusytan under AI-fältet, formad som en nyhet: bild, datum, rubrik, ingress, avsändare. Ljusblå botten och blå ram. Stäng flyttar fokus till AI-fältet (ADR-021). |
| shell/fokus/kaka.ts | Kakan med stängda fokus-id per roll. Samma logik och tak som de lästa notiserna. |
| shell/notiser/Notiser.tsx | Klockan och panelen: modulernas notiser, olästa först i räknaren, kantfärg efter status. Intern notis navigerar, extern öppnas i ny flik (ADR-020). |
| shell/notiser/lasta.ts | Kakan med lästa notis-id per roll: lasLasta, markera. Testad i lasta.test.ts. |
| shell/Board.tsx | Rutnätet. Läser widgetsFor för kpi, main och side, och användarens ordning ur kakan (ADR-018). |
| shell/AnpassaBoard.tsx | Spalterna i användarens ordning och läget "Anpassa startsidan": @dnd-kit, flyttknappar, svenska utrop. Ordningen ändras först när kortet släpps; målet är kortet under pekaren. Fokus stannar efter flytt, utropen anger ny plats, reducerad rörelse respekteras, Ångra och Återställ standardordning (ADR-018, WCAG 2.2). Varje kort i en @container. |
| shell/layout/ordning.ts | Ren logik: layoutSchema, lasLayout, tillampa (sparad över standard), flytta, hitta. Testad i ordning.test.ts. |
| shell/AskBand.tsx | AI-fältet på startsidan: hälsningen runt AskField. |
| shell/AskField.tsx | Själva AI-fältet: frågan, förslagen och det korta svaret från POST /api/assistant. Används av AskBand och av en sidas ingång. |
| app/(skal)/sidor/[...vag]/page.tsx | Sidtypen: slår upp sektion, ingång eller artikel, löser innehållet och sätter ctx.page. |
| shell/sida/SidaIngang.tsx | Ingången enligt it-support-prototyp.html: sidhuvud, AI-fält, snabbvägar, redaktionella kort (cards), modulens egna kort (slots), undersidor, källa (ADR-022). |
| shell/sida/SidaArtikel.tsx | Artikeln enligt innehallssida-prototyp.html: kicker, ingress, brödtext i kort, sidansvarig-fot. |
| shell/sida/Innehall.tsx | Den enda renderaren för ContentBlock, rekursiv för details (native <details> med chip). Intern länk via next/link, extern med ↗. |
| shell/Webbmeny.tsx | En webbplats meny som rad överst i arbetsytan (ADR-017). Fast höjd 5.2rem, som ramen räknar med. Klientkomponent för aktivt val. |
| shell/sida/SidaInbaddad.tsx | Sidan i en sandlådad ram som fyller arbetsytan under menyraden (100dvh − 5.2rem), eller förklaringen när källan blockerar inbäddning. |
| shell/sida/inbaddning.ts | tillaterInbaddning (ren) och kontrolleraInbaddning: läser X-Frame-Options och frame-ancestors mot vår origin. |
| shell/sida/Lanklista.tsx | PageLink som lista; en länk med children blir en hopfälld <details> med sidan själv först. |
| shell/sida/Kallmarkning.tsx | Källa, datum och länk till originalet; gult chip för sparad version. |
| shell/sida/ | Även Brodsmulor, Snabbvagar, SektionSida, Aterkoppling och datum. |
| shell/sektioner.test.ts | Varje sidas sektion finns i skalets lista; registrets invarianter håller. |
| shell/FlowBar.tsx | Fokuslägets topprad med Avbryt. |
| shell/store.ts | Zustand. Enda äkta klientstate: dockad sidopanel. |
| shell/shell.css | Kromets CSS, porterad 1:1 ur prototypen. Ägs av skalet – moduler skriver inte här. |
API
| Namn | Signatur | Beskrivning |
|---|---|---|
| getCurrentUser | () => Promise<DemoUser> | Den inloggade användaren. Läser rollcookien; i skarp drift SAML-sessionen. Anropsstället är detsamma. |
| toContext | (user: DemoUser, page?: string) => UserContext | Det modulerna får se om användaren. Fler uppgifter hämtar modulen själv. |
| switchRole | (role: Role) => Promise<void> | Server action bakom rollväxlaren i sidopanelen. Sätter httpOnly-cookie i 30 dagar och revaliderar layouten. |
| loggaInSom / loggaUt | (role: Role) => Promise<void> / () => Promise<void> | Prototypingångens start och utloggning. Samma cookie, men med redirect till /start respektive /portal. |
| registry | ModuleManifest[] | Modulregistret. Ordningen styr nav och fallordning när order saknas. |
Kontrakt
- Identiteten kommer alltid från servern. En profil som klienten skickar vore en injektionsväg rakt in i ärendet.
- Rollcookien heter startsidan-roll, är httpOnly och faller tillbaka på chef.
- Skalet renderar vilken modulrutt som helst: modulen äger vyn, skalet äger kromet.
- Rutterna: / är projektsidan och /portal prototypens ingång (båda utan krom), /start är startsidan, /flode/<namn> är fokusflöden, /verktyg/<väg> är modulvyer med skalets krom (ADR-019) – med mode "full" över hela arbetsytan i skärmens höjd, utan sidfot och AI-knapp (ADR-025), /sidor/<sektion>[/<ingång>[/<artikel>]] är sidor, /las-upp är åtkomstspärren.
- Skalet äger sektionerna under "Sidor". En sektion länkar först när någon modul har en ingång där.
- Modulernas genvägar (genvagarFor) står bredvid hälsningen i AI-fältet; en AI-genväg har AI-tonen och märks ✦ (ADR-025, ADR-026).
- Startsidan visar den nyaste fokusytan från fokusFor som användaren inte stängt, under AI-fältet (ADR-021). Användarmenyn har "Visa fokusnyheten igen (demo)".
- Klockans notiser kommer från modulerna via notificationsFor; layouten lägger på läst-status ur kakan startsidan-notiser-lasta-<roll> (ADR-020).
- Användaren ordnar korten i main och side (ADR-018). Ordningen sparas per roll i kakan startsidan-layout-<roll>, valideras på servern och läggs över modulernas order. Nya kort hamnar sist i sin standardspalt.
- Skalet äger också webbplatserna (ADR-017): samma form som en sektion, men visade som menyrad överst – bara inne på webbplatsen. Med under blir webbplatsen ett kort på en sektions sida. Sidopanelen står kvar runt en inramad sida.
- En sida får ctx.page = sidans slug, så att modulernas ai.suggestions kan svara på sidans ämne.
Beroenden och beslut
Kvarstår
- pendingTools och pendingSuggestions i demo-users.ts är platshållare tills modulerna tar över.
- Fyra av sex sektioner under "Sidor" saknar sidor och står kvar som "#".
- Återkopplingen på en artikel sparas inte – det finns ingen mottagare än.
- Kortens ordning följer webbläsaren, inte personen, tills SAML-sessionen finns i fas 4.