Schedule-grid¶
konti-schedule-grid viser rader mot kalenderperioder. Den brukes når data skal leses som plan, bemanning, kapasitet eller avtaler på dager og perioder, med støtte for grupper, periodebytte og egne templates for radetiketter og blokker. Seks måneder vises som ukebøtter, mens ett år vises som månedsbøtter, slik at lange perioder forblir lesbare uten hundrevis av dagskolonner.
Kilde og import¶
| Del | Sti |
|---|---|
| Komponent | ui/ePortal.ui/src/app/shared/schedule-grid/schedule-grid.component.ts |
| Modeller | ui/ePortal.ui/src/app/shared/schedule-grid/schedule-grid.models.ts |
| Template-direktiv | ui/ePortal.ui/src/app/shared/schedule-grid/schedule-grid-cell.directive.ts |
| Shared export | ui/ePortal.ui/src/app/shared/shared.module.ts |
Komponenten er standalone og eksportert fra SharedModule. Standalone-forbrukere kan importere ScheduleGridComponent og ScheduleGridCellDirective direkte.
import {
ScheduleBlockClickEvent,
ScheduleBucketClickEvent,
ScheduleCellClickEvent,
ScheduleGroup,
ScheduleInfoColumn,
ScheduleRow,
} from 'src/app/shared/schedule-grid/schedule-grid.models';
Feature-tabell¶
| Feature | Støtte | Konfigurasjon |
|---|---|---|
| Uke, to uker og detaljert måned | Ja | viewMode, startDate, periodChange, viewModeChange |
| Aggregert halvår og år | Ja | six-months bruker uker, one-year bruker måneder, bucketClick |
| Konfigurerbare periodevalg | Ja | primaryViewModes, moreViewModes |
| Grupper | Ja | groups, collapsibleGroups |
| Sticky radetikett | Ja | labelWidth, rowLabelHeader, rowLabel template |
| Ekstra infokolonner | Ja | infoColumns |
| Custom blokkinnhold | Ja | appScheduleGridCell="blockContent" |
| Custom tom celle | Ja | appScheduleGridCell="emptyCell" |
| Klikk på celle, blokk og aggregat | Ja | cellClick, blockClick, bucketClick |
| Range select | Opt-in | enableRangeSelect, rangeSelect |
| Loading overlay | Ja | showLoader |
| Rad-virtualisering | Nei | Avgrens antall rader i parent |
Brukseksempel¶
TypeScript:
groups: ScheduleGroup[] = [
{ id: 'sales', label: this.translate.instant('Schedule.Groups.Sales') },
{ id: 'service', label: this.translate.instant('Schedule.Groups.Service') },
];
infoColumns: ScheduleInfoColumn[] = [
{ field: 'role', title: this.translate.instant('Employee.Role'), width: 120 },
];
rows: ScheduleRow[] = [
{
id: 101,
label: 'Alex Morgan',
sublabel: 'AMO',
groupId: 'sales',
days: {
'2026-06-25': [
{
label: this.translate.instant('Schedule.Blocks.CustomerMeeting'),
start: '09:00',
end: '12:00',
color: '#0d6efd',
meta: { assignmentId: 5001 },
},
],
},
meta: { role: this.translate.instant('Employee.Roles.Consultant') },
},
];
openBlock(event: ScheduleBlockClickEvent): void {
this.openAssignment(event.block.meta?.assignmentId);
}
createBlock(event: ScheduleCellClickEvent): void {
this.openCreateDialog(event.row.id, event.date);
}
openAggregate(event: ScheduleBucketClickEvent): void {
this.openPeriod(event.startDate, event.endDate);
}
HTML:
<konti-schedule-grid
[rows]="rows"
[groups]="groups"
[infoColumns]="infoColumns"
viewMode="week"
[primaryViewModes]="['week', 'two-weeks', 'month']"
[moreViewModes]="['six-months', 'one-year']"
[drillDownAggregates]="true"
[startDate]="selectedDate"
[showWeekNumbers]="true"
[showMonthHeader]="true"
[highlightToday]="true"
[enableRangeSelect]="true"
(blockClick)="openBlock($event)"
(cellClick)="createBlock($event)"
(bucketClick)="openAggregate($event)"
(rangeSelect)="createRange($event)">
<ng-template appScheduleGridCell="rowLabel" let-row>
<strong>{{ row.label }}</strong>
<small class="d-block text-muted">{{ row.sublabel }}</small>
</ng-template>
<ng-template appScheduleGridCell="blockContent" let-block let-row="row" let-date="date">
<span class="fw-semibold">{{ block.label }}</span>
<small class="d-block">{{ block.start }}-{{ block.end }}</small>
</ng-template>
<ng-template appScheduleGridCell="emptyCell" let-row let-date="date">
<button type="button" class="btn btn-link btn-sm p-0">
{{ 'Common.Add' | translate }}
</button>
</ng-template>
</konti-schedule-grid>
Viktige inputs¶
| Input | Default | Beskrivelse |
|---|---|---|
rows |
[] |
Planrader. Hver rad har days indeksert på ISO-dato. |
groups |
[] |
Grupper som rader kan kobles til via groupId. |
viewMode |
week |
Uke, to uker og måned viser dager. Seks måneder aggregeres per uke, ett år per måned. |
primaryViewModes |
Uke, 2 uker, måned, 1 mnd, 3 mnd | Perioder som vises direkte i knappgruppen. |
moreViewModes |
[] |
Perioder som vises i Mer-menyen. CRM bruker 1, 3, 6 og 12 måneder her. |
startDate |
ikke satt | Første dato i perioden. Hvis den ikke settes, brukes dagens dato. |
infoColumns |
[] |
Ekstra kolonner ved siden av radetiketten. |
labelWidth |
200 |
Bredde i piksler på sticky label-kolonnen. |
rowLabelHeader |
tom | Valgfri tittel over sticky label-kolonnen. |
cellMinWidth |
44 |
Minstebredde for detaljerte dagskolonner. |
aggregateCellMinWidth |
56 |
Minstebredde for ukebøtter og månedsbøtter. |
ariaLabel |
oversatt standard | Tilgjengelig navn på kalendertabellen. |
drillDownAggregates |
false |
Bytter ukebøtte til to uker og månedsbøtte til detaljert måned ved klikk. |
showWeekNumbers |
true |
Viser ukenummer i header der perioden bruker uker. |
showMonthHeader |
true |
Viser månedslinje over dagene. |
highlightToday |
true |
Marker dagens dato. |
collapsibleGroups |
true |
Lar brukeren kollapse grupper. |
enableRangeSelect |
false |
Lar brukeren dra over flere dager og emitter rangeSelect. |
showLoader |
false |
Viser loading-state over gridet. |
Outputs¶
| Output | Payload | Bruk |
|---|---|---|
cellClick |
ScheduleCellClickEvent |
Åpne opprett-dialog for rad og dato. |
blockClick |
ScheduleBlockClickEvent |
Åpne eksisterende blokk eller tilknyttet objekt. |
periodChange |
SchedulePeriodChangeEvent |
Last data for ny periode. |
viewModeChange |
ScheduleViewMode |
Persister brukerens valgte visning. |
rangeSelect |
ScheduleRangeSelectEvent |
Opprett periodebaserte blokker. |
bucketClick |
ScheduleBucketClickEvent |
Reager på valgt uke- eller månedsbøtte med rad, periode, granularitet og blokker. |
Modellnotater¶
ScheduleRow.days bruker ISO-dato som nøkkel, for eksempel 2026-06-25. Verdien er en liste med ScheduleBlock, slik at samme rad og dato kan ha flere blokker.
ScheduleBlock.meta og ScheduleRow.meta er bevisst åpne felter for fagmodulens egne id-er og presentasjonsdata. Ikke legg brukerrettet logikk inn i meta; bruk den til å finne tilbake til domenedata i parent.
I six-months og one-year summerer komponenten blokkene fra alle ISO-datoene i bøtten. Bøtter med innhold kan åpnes og emitter bucketClick; tomme bøtter er ikke fokusbare. Med drillDownAggregates aktivert emitter komponenten deretter ny detaljert periode via viewModeChange og periodChange.
Kjente fallgruver¶
| Fallgruve | Riktig mønster |
|---|---|
Bruke lokal datoformatnøkkel i days |
Bruk ISO-dato YYYY-MM-DD. |
| Rendere for mange rader | Filtrer i parent eller del opp på gruppe/periode. Komponenten har ikke radvirtualisering. Seks måneder og ett år bruker derfor aggregerte kolonner. |
| Legge 6/12 måneder i hovedknappene | Bruk moreViewModes for lange horisonter og behold de hyppigste periodene i primaryViewModes. |
| Hardkode tekst i blokkdata | Bruk i18n i parent når labels bygges. |
| Glemme å laste data på periodebytte | Håndter periodChange når data hentes fra API. |
Bruke emptyCell uten å stoppe klikk ved behov |
Pass på at knapper i template ikke dobbeltrigger parent-logikk. |