feat(admin): runtime feature flags (catalog-in-code, admin toggle, FE+backend)
Catalog declared in code (Domain/Features/FeatureFlags.cs, build-validated), on/off state
persisted in SQLite (FeatureFlagStore + migration). GET /flags (drives FE gating) + admin
PUT /admin/flags/{key} (new flags:manage capability + FlagsAdmin gate). Enforced end-to-end:
the `inschrijving-open` flag hides the Inschrijven nav item + dashboard action (FE) AND makes
POST /applications for a registratie 403 when off (backend). FE FeatureFlagStore mirrors
AccessStore (enabled() deny-by-default); admin toggle page at /beheer/functies in ADMIN_LINKS.
+4 backend tests, /me cap-list updated, client regenerated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -91,6 +91,13 @@ export const routes: Routes = [
|
||||
canActivate: [capabilityGuard('cases:manage')],
|
||||
loadComponent: () => import('@beheer/ui/audit.page').then((m) => m.AuditPage),
|
||||
},
|
||||
{
|
||||
path: 'beheer/functies',
|
||||
// Admin-only feature-flag toggles (WP-47), gated by `flags:manage`.
|
||||
canActivate: [capabilityGuard('flags:manage')],
|
||||
loadComponent: () =>
|
||||
import('@beheer/ui/feature-flags.page').then((m) => m.FeatureFlagsPage),
|
||||
},
|
||||
{
|
||||
path: 'concepts',
|
||||
loadComponent: () => import('./showcase/concepts.page').then((m) => m.ConceptsPage),
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
import { Component, computed, inject } from '@angular/core';
|
||||
import { PageShellComponent } from '@shared/layout/page-shell/page-shell.component';
|
||||
import { AlertComponent } from '@shared/ui/alert/alert.component';
|
||||
import { ButtonComponent } from '@shared/ui/button/button.component';
|
||||
import { ASYNC } from '@shared/ui/async/async.component';
|
||||
import { AccessStore } from '@shared/application/access.store';
|
||||
import { FeatureFlagStore } from '@shared/application/feature-flags.store';
|
||||
|
||||
/**
|
||||
* Admin page: toggle runtime feature flags (WP-47). Deny-by-default capability gate
|
||||
* (`flags:manage`). The catalog is server-owned (code); this only flips the on/off state, which
|
||||
* the whole app reads via the same `FeatureFlagStore`.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'app-feature-flags-page',
|
||||
imports: [PageShellComponent, AlertComponent, ButtonComponent, ...ASYNC],
|
||||
styles: [
|
||||
`
|
||||
.flag {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: var(--rhc-space-max-lg);
|
||||
padding: var(--rhc-space-max-md) 0;
|
||||
border-block-end: var(--rhc-border-width-sm) solid var(--rhc-color-cool-grey-200);
|
||||
}
|
||||
.flag .meta {
|
||||
min-inline-size: 0;
|
||||
}
|
||||
.flag .key {
|
||||
font-family: monospace;
|
||||
font-size: var(--rhc-text-font-size-sm);
|
||||
color: var(--rhc-color-grijs-700);
|
||||
}
|
||||
.state {
|
||||
font-weight: var(--rhc-text-font-weight-semi-bold);
|
||||
margin-inline-end: var(--rhc-space-max-md);
|
||||
}
|
||||
`,
|
||||
],
|
||||
template: `
|
||||
<app-page-shell [heading]="heading" [intro]="intro" backLink="/dashboard">
|
||||
@if (!access.ready()) {
|
||||
<!-- wait for /me before deciding -->
|
||||
} @else if (!canManage()) {
|
||||
<app-alert type="error">{{ deniedText }}</app-alert>
|
||||
} @else {
|
||||
<app-async [data]="store.flags()">
|
||||
<ng-template appAsyncError>
|
||||
<app-alert type="error">{{ failedText }}</app-alert>
|
||||
<app-button variant="secondary" (click)="reload()">{{ retryText }}</app-button>
|
||||
</ng-template>
|
||||
<ng-template appAsyncLoaded>
|
||||
@for (f of store.all(); track f.key) {
|
||||
<div class="flag">
|
||||
<div class="meta">
|
||||
<div>{{ f.description }}</div>
|
||||
<div class="key">{{ f.key }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<span class="state">{{ f.enabled ? onText : offText }}</span>
|
||||
<app-button
|
||||
[variant]="f.enabled ? 'secondary' : 'primary'"
|
||||
(click)="toggle(f.key, !f.enabled)"
|
||||
>{{ f.enabled ? disableText : enableText }}</app-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</ng-template>
|
||||
</app-async>
|
||||
}
|
||||
</app-page-shell>
|
||||
`,
|
||||
})
|
||||
export class FeatureFlagsPage {
|
||||
protected store = inject(FeatureFlagStore);
|
||||
protected access = inject(AccessStore);
|
||||
|
||||
protected canManage = computed(() => this.access.can('flags:manage'));
|
||||
|
||||
protected heading = $localize`:@@flags.heading:Functievlaggen`;
|
||||
protected intro = $localize`:@@flags.intro:Zet functionaliteit aan of uit tijdens runtime. De catalogus staat vast in code; hier beheert u de status.`;
|
||||
protected deniedText = $localize`:@@flags.denied:U hebt geen rechten om functievlaggen te beheren.`;
|
||||
protected failedText = $localize`:@@flags.failed:De functievlaggen konden niet worden geladen.`;
|
||||
protected retryText = $localize`:@@flags.retry:Opnieuw proberen`;
|
||||
protected onText = $localize`:@@flags.on:Aan`;
|
||||
protected offText = $localize`:@@flags.off:Uit`;
|
||||
protected enableText = $localize`:@@flags.enable:Aanzetten`;
|
||||
protected disableText = $localize`:@@flags.disable:Uitzetten`;
|
||||
|
||||
protected toggle(key: string, enabled: boolean) {
|
||||
void this.store.set(key, enabled);
|
||||
}
|
||||
protected reload() {
|
||||
void this.store.load();
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import { ApplicationListComponent } from '@shared/ui/application-list/applicatio
|
||||
import { ApplicationLinkComponent } from '@shared/ui/application-link/application-link.component';
|
||||
import { ASYNC } from '@shared/ui/async/async.component';
|
||||
import { AccessStore } from '@shared/application/access.store';
|
||||
import { FeatureFlagStore } from '@shared/application/feature-flags.store';
|
||||
import { FLAG_INSCHRIJVING_OPEN } from '@shared/domain/feature-flag';
|
||||
import { ADMIN_LINKS } from '@shared/layout/admin-links';
|
||||
import { RegistrationSummaryComponent } from '@registratie/ui/registration-summary/registration-summary.component';
|
||||
import { RegistrationTableComponent } from '@registratie/ui/registration-table/registration-table.component';
|
||||
@@ -176,7 +178,7 @@ import { tasksFromProfile } from '@registratie/domain/tasks';
|
||||
<section>
|
||||
<app-heading [level]="2" i18n="@@dashboard.watWiltUDoen">Wat wilt u doen?</app-heading>
|
||||
<app-application-list class="app-section">
|
||||
@for (a of acties; track a.to) {
|
||||
@for (a of acties(); track a.to) {
|
||||
<li
|
||||
app-application-link
|
||||
[heading]="a.titel"
|
||||
@@ -211,6 +213,7 @@ export class DashboardPage {
|
||||
protected store = inject(BigProfileStore);
|
||||
private apps = inject(ApplicationsStore);
|
||||
private access = inject(AccessStore);
|
||||
private flags = inject(FeatureFlagStore);
|
||||
private router = inject(Router);
|
||||
|
||||
/** Admin pages the current principal may reach — capability-gated (never role-derived),
|
||||
@@ -282,7 +285,7 @@ export class DashboardPage {
|
||||
/** Primary transactional actions, as an "aanvragen" list (see CIBG's
|
||||
componenten/aanvragen). The core portal sections live in the header nav now;
|
||||
the teaching pages (concepts/brief) are only reachable from here. */
|
||||
protected readonly acties = [
|
||||
private readonly allActies = [
|
||||
{
|
||||
to: '/registreren',
|
||||
titel: $localize`:@@dashboard.actie.inschrijven.titel:Inschrijven`,
|
||||
@@ -320,4 +323,11 @@ export class DashboardPage {
|
||||
actie: $localize`:@@dashboard.actie.brief.actie:Start brief`,
|
||||
},
|
||||
];
|
||||
|
||||
/** Hide the "Inschrijven" action when self-service registration is flagged off (WP-47). */
|
||||
protected readonly acties = computed(() =>
|
||||
this.allActies.filter(
|
||||
(a) => a.to !== '/registreren' || this.flags.enabled(FLAG_INSCHRIJVING_OPEN),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { Injectable, computed, inject, signal } from '@angular/core';
|
||||
import { RemoteData } from '@shared/application/remote-data';
|
||||
import { FeatureFlag } from '@shared/domain/feature-flag';
|
||||
import { FeatureFlagsAdapter, parseFlags } from '@shared/infrastructure/feature-flags.adapter';
|
||||
|
||||
type Err = Error | undefined;
|
||||
|
||||
/**
|
||||
* Runtime feature-flag state (WP-47) — one root singleton, mirroring `AccessStore`. Loads the
|
||||
* resolved flag set once from `GET /flags`; `enabled(key)` gates a feature (deny-by-default:
|
||||
* false until loaded / unknown key). `set()` is the admin toggle (PUT + reload). The catalog is
|
||||
* server-owned; the FE only mirrors + renders it.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class FeatureFlagStore {
|
||||
private adapter = inject(FeatureFlagsAdapter);
|
||||
private state = signal<RemoteData<Err, FeatureFlag[]>>({ tag: 'Loading' });
|
||||
|
||||
readonly flags = this.state.asReadonly();
|
||||
/** The resolved list (empty until loaded) — for the admin toggle UI. */
|
||||
readonly all = computed(() => {
|
||||
const rd = this.state();
|
||||
return rd.tag === 'Success' ? rd.value : [];
|
||||
});
|
||||
|
||||
constructor() {
|
||||
void this.load();
|
||||
}
|
||||
|
||||
async load() {
|
||||
if (this.state().tag !== 'Success') this.state.set({ tag: 'Loading' });
|
||||
try {
|
||||
const parsed = parseFlags(await this.adapter.list());
|
||||
this.state.set(
|
||||
parsed.ok
|
||||
? { tag: 'Success', value: parsed.value }
|
||||
: { tag: 'Failure', error: new Error(parsed.error) },
|
||||
);
|
||||
} catch (e) {
|
||||
this.state.set({ tag: 'Failure', error: e as Error });
|
||||
}
|
||||
}
|
||||
|
||||
/** Deny-by-default: false while loading/failed or for an unknown key. Reactive (reads the signal). */
|
||||
enabled(key: string): boolean {
|
||||
const rd = this.state();
|
||||
return rd.tag === 'Success' && (rd.value.find((f) => f.key === key)?.enabled ?? false);
|
||||
}
|
||||
|
||||
/** Admin toggle: persist then reload so the state reflects the server. */
|
||||
async set(key: string, enabled: boolean) {
|
||||
try {
|
||||
await this.adapter.set(key, enabled);
|
||||
} finally {
|
||||
await this.load();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,5 @@ export type Capability =
|
||||
| 'brief:send'
|
||||
| 'orgtemplate:edit'
|
||||
| 'stamdata:edit'
|
||||
| 'cases:manage';
|
||||
| 'cases:manage'
|
||||
| 'flags:manage';
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
/** A runtime feature flag as the FE sees it (resolved: catalog default + admin override). */
|
||||
export interface FeatureFlag {
|
||||
key: string;
|
||||
description: string;
|
||||
enabled: boolean;
|
||||
}
|
||||
|
||||
/** Known flag keys the FE gates on — must match the backend `FeatureFlags` catalog. */
|
||||
export const FLAG_INSCHRIJVING_OPEN = 'inschrijving-open';
|
||||
@@ -1198,6 +1198,92 @@ export class ApiClient {
|
||||
return Promise.resolve<MeDto>(null as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OK
|
||||
*/
|
||||
flagsAll(): Promise<FeatureFlagDto[]> {
|
||||
let url_ = this.baseUrl + "/api/v1/flags";
|
||||
url_ = url_.replace(/[?&]$/, "");
|
||||
|
||||
let options_: RequestInit = {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Accept": "application/json"
|
||||
}
|
||||
};
|
||||
|
||||
return this.http.fetch(url_, options_).then((_response: Response) => {
|
||||
return this.processFlagsAll(_response);
|
||||
});
|
||||
}
|
||||
|
||||
protected processFlagsAll(response: Response): Promise<FeatureFlagDto[]> {
|
||||
const status = response.status;
|
||||
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
|
||||
if (status === 200) {
|
||||
return response.text().then((_responseText) => {
|
||||
let result200: any = null;
|
||||
result200 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as FeatureFlagDto[];
|
||||
return result200;
|
||||
});
|
||||
} else if (status !== 200 && status !== 204) {
|
||||
return response.text().then((_responseText) => {
|
||||
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
|
||||
});
|
||||
}
|
||||
return Promise.resolve<FeatureFlagDto[]>(null as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return No Content
|
||||
*/
|
||||
flags(key: string, body: SetFeatureFlagRequest): Promise<void> {
|
||||
let url_ = this.baseUrl + "/api/v1/admin/flags/{key}";
|
||||
if (key === undefined || key === null)
|
||||
throw new globalThis.Error("The parameter 'key' must be defined.");
|
||||
url_ = url_.replace("{key}", encodeURIComponent("" + key));
|
||||
url_ = url_.replace(/[?&]$/, "");
|
||||
|
||||
const content_ = JSON.stringify(body);
|
||||
|
||||
let options_: RequestInit = {
|
||||
body: content_,
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
};
|
||||
|
||||
return this.http.fetch(url_, options_).then((_response: Response) => {
|
||||
return this.processFlags(_response);
|
||||
});
|
||||
}
|
||||
|
||||
protected processFlags(response: Response): Promise<void> {
|
||||
const status = response.status;
|
||||
let _headers: any = {}; if (response.headers && response.headers.forEach) { response.headers.forEach((v: any, k: any) => _headers[k] = v); };
|
||||
if (status === 204) {
|
||||
return response.text().then((_responseText) => {
|
||||
return;
|
||||
});
|
||||
} else if (status === 403) {
|
||||
return response.text().then((_responseText) => {
|
||||
let result403: any = null;
|
||||
result403 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver) as ProblemDetails;
|
||||
return throwException("Forbidden", status, _responseText, _headers, result403);
|
||||
});
|
||||
} else if (status === 404) {
|
||||
return response.text().then((_responseText) => {
|
||||
return throwException("Not Found", status, _responseText, _headers);
|
||||
});
|
||||
} else if (status !== 200 && status !== 204) {
|
||||
return response.text().then((_responseText) => {
|
||||
return throwException("An unexpected server error occurred.", status, _responseText, _headers);
|
||||
});
|
||||
}
|
||||
return Promise.resolve<void>(null as any);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return OK
|
||||
*/
|
||||
@@ -1918,6 +2004,12 @@ export interface DuoLookupDto {
|
||||
handmatig?: ManualDiplomaPolicyDto;
|
||||
}
|
||||
|
||||
export interface FeatureFlagDto {
|
||||
key?: string | undefined;
|
||||
description?: string | undefined;
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
export interface HerregistratieDecisionsDto {
|
||||
eligibleForHerregistratie?: boolean;
|
||||
herregistratieReason?: string | undefined;
|
||||
@@ -2098,6 +2190,10 @@ export interface SaveOrgTemplateRequest {
|
||||
draft?: OrgTemplateDto;
|
||||
}
|
||||
|
||||
export interface SetFeatureFlagRequest {
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
export interface StamdataColumnDto {
|
||||
name?: string | undefined;
|
||||
type?: string | undefined;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { Result, ok, err } from '@shared/kernel/fp';
|
||||
import { ApiClient } from '@shared/infrastructure/api-client';
|
||||
import { FeatureFlag } from '@shared/domain/feature-flag';
|
||||
|
||||
/**
|
||||
* Infrastructure adapter for feature flags (WP-47): `GET /flags` (resolved set, drives FE gating)
|
||||
* and the admin `PUT /admin/flags/{key}`. The single place the ApiClient lives for flags; the
|
||||
* store parses at the boundary.
|
||||
*/
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class FeatureFlagsAdapter {
|
||||
private client = inject(ApiClient);
|
||||
|
||||
list() {
|
||||
return this.client.flagsAll();
|
||||
}
|
||||
set(key: string, enabled: boolean) {
|
||||
return this.client.flags(key, { enabled });
|
||||
}
|
||||
}
|
||||
|
||||
/** Trust-boundary parse of the flag set. */
|
||||
export function parseFlags(json: unknown): Result<string, FeatureFlag[]> {
|
||||
if (!Array.isArray(json)) return err('flags: not an array');
|
||||
const out: FeatureFlag[] = [];
|
||||
for (const f of json) {
|
||||
if (typeof f !== 'object' || f === null) return err('flags: row not an object');
|
||||
const d = f as Partial<FeatureFlag>;
|
||||
if (typeof d.key !== 'string' || typeof d.enabled !== 'boolean') return err('flags: bad shape');
|
||||
out.push({
|
||||
key: d.key,
|
||||
description: typeof d.description === 'string' ? d.description : '',
|
||||
enabled: d.enabled,
|
||||
});
|
||||
}
|
||||
return ok(out);
|
||||
}
|
||||
@@ -10,6 +10,7 @@ const KNOWN: readonly Capability[] = [
|
||||
'orgtemplate:edit',
|
||||
'stamdata:edit',
|
||||
'cases:manage',
|
||||
'flags:manage',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,6 +14,7 @@ const ROLE_AWARE = [
|
||||
'/api/v1/admin/org-template',
|
||||
'/api/v1/admin/cases',
|
||||
'/api/v1/admin/audit',
|
||||
'/api/v1/admin/flags',
|
||||
'/api/v1/stamdata',
|
||||
'/api/v1/me',
|
||||
];
|
||||
|
||||
@@ -37,4 +37,10 @@ export const ADMIN_LINKS: readonly AdminLink[] = [
|
||||
to: '/beheer/audit',
|
||||
cap: 'cases:manage',
|
||||
},
|
||||
{
|
||||
label: $localize`:@@header.nav.functies:Functievlaggen`,
|
||||
description: $localize`:@@admin.link.functies.desc:Functionaliteit aan- of uitzetten`,
|
||||
to: '/beheer/functies',
|
||||
cap: 'flags:manage',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -4,6 +4,8 @@ import { NavigationEnd, Router, RouterLink, RouterLinkActive } from '@angular/ro
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
import { SESSION_PORT } from '@shared/application/session.port';
|
||||
import { AccessStore } from '@shared/application/access.store';
|
||||
import { FeatureFlagStore } from '@shared/application/feature-flags.store';
|
||||
import { FLAG_INSCHRIJVING_OPEN } from '@shared/domain/feature-flag';
|
||||
import { ADMIN_LINKS } from '@shared/layout/admin-links';
|
||||
import { BreadcrumbComponent } from '@shared/layout/breadcrumb/breadcrumb.component';
|
||||
import { trailFor } from '@shared/layout/breadcrumb/breadcrumb-trail';
|
||||
@@ -87,7 +89,7 @@ const NAV_ITEMS: readonly HeaderNavItem[] = [
|
||||
<nav i18n-aria-label="@@header.navAria" aria-label="Hoofdnavigatie">
|
||||
<div class="container">
|
||||
<ul>
|
||||
@for (item of navItems; track item.to) {
|
||||
@for (item of navItems(); track item.to) {
|
||||
<li routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }">
|
||||
<a [routerLink]="item.to">{{ item.label }}</a>
|
||||
</li>
|
||||
@@ -104,11 +106,15 @@ const NAV_ITEMS: readonly HeaderNavItem[] = [
|
||||
`,
|
||||
})
|
||||
export class SiteHeaderComponent {
|
||||
protected readonly navItems = NAV_ITEMS;
|
||||
private access = inject(AccessStore);
|
||||
private flags = inject(FeatureFlagStore);
|
||||
/** Hide "Inschrijven" when self-service registration is flagged off (WP-47). */
|
||||
protected readonly navItems = computed(() =>
|
||||
NAV_ITEMS.filter((i) => i.to !== '/registreren' || this.flags.enabled(FLAG_INSCHRIJVING_OPEN)),
|
||||
);
|
||||
|
||||
private router = inject(Router);
|
||||
private sessionPort = inject(SESSION_PORT, { optional: true });
|
||||
private access = inject(AccessStore);
|
||||
/** Injecting AccessStore here also warms `/me` at app start (the header renders on
|
||||
every page), so the admin routes' guard usually finds caps already resolved. */
|
||||
protected adminItems = computed(() => ADMIN_LINKS.filter((i) => this.access.can(i.cap)));
|
||||
|
||||
@@ -3682,6 +3682,50 @@
|
||||
<source>Auditlog</source>
|
||||
<target datatype="html">Audit log</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.nav.functies" datatype="html">
|
||||
<source>Functievlaggen</source>
|
||||
<target datatype="html">Feature flags</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="admin.link.functies.desc" datatype="html">
|
||||
<source>Functionaliteit aan- of uitzetten</source>
|
||||
<target datatype="html">Turn functionality on or off</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.heading" datatype="html">
|
||||
<source>Functievlaggen</source>
|
||||
<target datatype="html">Feature flags</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.intro" datatype="html">
|
||||
<source>Zet functionaliteit aan of uit tijdens runtime. De catalogus staat vast in code; hier beheert u de status.</source>
|
||||
<target datatype="html">Turn functionality on or off at runtime. The catalog is fixed in code; here you manage the state.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.denied" datatype="html">
|
||||
<source>U hebt geen rechten om functievlaggen te beheren.</source>
|
||||
<target datatype="html">You do not have permission to manage feature flags.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.failed" datatype="html">
|
||||
<source>De functievlaggen konden niet worden geladen.</source>
|
||||
<target datatype="html">The feature flags could not be loaded.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.retry" datatype="html">
|
||||
<source>Opnieuw proberen</source>
|
||||
<target datatype="html">Try again</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.on" datatype="html">
|
||||
<source>Aan</source>
|
||||
<target datatype="html">On</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.off" datatype="html">
|
||||
<source>Uit</source>
|
||||
<target datatype="html">Off</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.enable" datatype="html">
|
||||
<source>Aanzetten</source>
|
||||
<target datatype="html">Turn on</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.disable" datatype="html">
|
||||
<source>Uitzetten</source>
|
||||
<target datatype="html">Turn off</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="admin.link.audit.desc" datatype="html">
|
||||
<source>Toegangs- en inzagebeslissingen bekijken</source>
|
||||
<target datatype="html">View access and disclosure decisions</target>
|
||||
|
||||
+121
-44
@@ -178,6 +178,69 @@
|
||||
<context context-type="linenumber">113</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.heading" datatype="html">
|
||||
<source>Functievlaggen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/beheer/ui/feature-flags.page.ts</context>
|
||||
<context context-type="linenumber">82</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.intro" datatype="html">
|
||||
<source>Zet functionaliteit aan of uit tijdens runtime. De catalogus staat vast in code; hier beheert u de status.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/beheer/ui/feature-flags.page.ts</context>
|
||||
<context context-type="linenumber">83</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.denied" datatype="html">
|
||||
<source>U hebt geen rechten om functievlaggen te beheren.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/beheer/ui/feature-flags.page.ts</context>
|
||||
<context context-type="linenumber">84</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.failed" datatype="html">
|
||||
<source>De functievlaggen konden niet worden geladen.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/beheer/ui/feature-flags.page.ts</context>
|
||||
<context context-type="linenumber">85</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.retry" datatype="html">
|
||||
<source>Opnieuw proberen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/beheer/ui/feature-flags.page.ts</context>
|
||||
<context context-type="linenumber">86</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.on" datatype="html">
|
||||
<source>Aan</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/beheer/ui/feature-flags.page.ts</context>
|
||||
<context context-type="linenumber">87</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.off" datatype="html">
|
||||
<source>Uit</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/beheer/ui/feature-flags.page.ts</context>
|
||||
<context context-type="linenumber">88</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.enable" datatype="html">
|
||||
<source>Aanzetten</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/beheer/ui/feature-flags.page.ts</context>
|
||||
<context context-type="linenumber">89</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="flags.disable" datatype="html">
|
||||
<source>Uitzetten</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/beheer/ui/feature-flags.page.ts</context>
|
||||
<context context-type="linenumber">90</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="beheer.added" datatype="html">
|
||||
<source>toegevoegd</source>
|
||||
<context-group purpose="location">
|
||||
@@ -2057,235 +2120,235 @@
|
||||
<source>Mijn overzicht</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">47,48</context>
|
||||
<context context-type="linenumber">49,50</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.intro" datatype="html">
|
||||
<source>Welkom in uw persoonlijke omgeving van het BIG-register. Hier ziet u uw registratie en regelt u uw zaken.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">49,51</context>
|
||||
<context context-type="linenumber">51,53</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.mijnAanvragen" datatype="html">
|
||||
<source>Mijn aanvragen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">65,67</context>
|
||||
<context context-type="linenumber">67,69</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.pendingHerregistratie" datatype="html">
|
||||
<source>Uw herregistratie-aanvraag is in behandeling.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">87,91</context>
|
||||
<context context-type="linenumber">89,93</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.watMoetIkRegelen" datatype="html">
|
||||
<source>Wat moet ik regelen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">101,103</context>
|
||||
<context context-type="linenumber">103,105</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">106,108</context>
|
||||
<context context-type="linenumber">108,110</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.nietsOpenstaan" datatype="html">
|
||||
<source> U heeft op dit moment niets openstaan. </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">109,110</context>
|
||||
<context context-type="linenumber">111,112</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.mijnRegistratie" datatype="html">
|
||||
<source>Mijn registratie</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">116,118</context>
|
||||
<context context-type="linenumber">118,120</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.persoonsgegevens" datatype="html">
|
||||
<source>Persoonsgegevens (BRP)</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">124,126</context>
|
||||
<context context-type="linenumber">126,128</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.straat" datatype="html">
|
||||
<source>Straat</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">130</context>
|
||||
<context context-type="linenumber">132</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.postcode" datatype="html">
|
||||
<source>Postcode</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">135,136</context>
|
||||
<context context-type="linenumber">137,138</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.woonplaats" datatype="html">
|
||||
<source>Woonplaats</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">141,142</context>
|
||||
<context context-type="linenumber">143,144</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.specialismen" datatype="html">
|
||||
<source>Specialismen en aantekeningen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">155,157</context>
|
||||
<context context-type="linenumber">157,159</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.geenSpecialismen" datatype="html">
|
||||
<source> U heeft nog geen specialismen of aantekeningen. </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">169,171</context>
|
||||
<context context-type="linenumber">171,173</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.watWiltUDoen" datatype="html">
|
||||
<source>Wat wilt u doen?</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">177,178</context>
|
||||
<context context-type="linenumber">179,180</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.beheer" datatype="html">
|
||||
<source>Beheer</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">193,194</context>
|
||||
<context context-type="linenumber">195,196</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.inschrijven.titel" datatype="html">
|
||||
<source>Inschrijven</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">288</context>
|
||||
<context context-type="linenumber">291</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.inschrijven.tekst" datatype="html">
|
||||
<source>Schrijf u in in het BIG-register via de registratiewizard.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">289</context>
|
||||
<context context-type="linenumber">292</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.inschrijven.actie" datatype="html">
|
||||
<source>Start inschrijving</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">290</context>
|
||||
<context context-type="linenumber">293</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.herregistratie.titel" datatype="html">
|
||||
<source>Herregistratie aanvragen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">294</context>
|
||||
<context context-type="linenumber">297</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.herregistratie.tekst" datatype="html">
|
||||
<source>Verleng uw registratie voor de komende periode.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">295</context>
|
||||
<context context-type="linenumber">298</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.herregistratie.actie" datatype="html">
|
||||
<source>Vraag aan</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">296</context>
|
||||
<context context-type="linenumber">299</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.intake.titel" datatype="html">
|
||||
<source>Herregistratie-intake</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">300</context>
|
||||
<context context-type="linenumber">303</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.intake.tekst" datatype="html">
|
||||
<source>Vragenlijst met vertakkingen.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">301</context>
|
||||
<context context-type="linenumber">304</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.intake.actie" datatype="html">
|
||||
<source>Start intake</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">302</context>
|
||||
<context context-type="linenumber">305</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.wijzigen.titel" datatype="html">
|
||||
<source>Gegevens wijzigen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">306</context>
|
||||
<context context-type="linenumber">309</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.wijzigen.tekst" datatype="html">
|
||||
<source>Bekijk uw gegevens of geef een wijziging door.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">307</context>
|
||||
<context context-type="linenumber">310</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.wijzigen.actie" datatype="html">
|
||||
<source>Bekijk gegevens</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">308</context>
|
||||
<context context-type="linenumber">311</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.concepten.titel" datatype="html">
|
||||
<source>Functionele patronen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">312</context>
|
||||
<context context-type="linenumber">315</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.concepten.tekst" datatype="html">
|
||||
<source>Bekijk de FP/TEA-bouwstenen van deze POC.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">313</context>
|
||||
<context context-type="linenumber">316</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.concepten.actie" datatype="html">
|
||||
<source>Bekijk patronen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">314</context>
|
||||
<context context-type="linenumber">317</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.brief.titel" datatype="html">
|
||||
<source>Brief opstellen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">318</context>
|
||||
<context context-type="linenumber">321</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.brief.tekst" datatype="html">
|
||||
<source>Stel een brief samen uit vaste en vrije onderdelen.</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">319</context>
|
||||
<context context-type="linenumber">322</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="dashboard.actie.brief.actie" datatype="html">
|
||||
<source>Start brief</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/registratie/ui/dashboard.page.ts</context>
|
||||
<context context-type="linenumber">320</context>
|
||||
<context context-type="linenumber">323</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="registratie.kanaalEmail" datatype="html">
|
||||
@@ -2782,6 +2845,20 @@
|
||||
<context context-type="linenumber">36</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.nav.functies" datatype="html">
|
||||
<source>Functievlaggen</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/admin-links.ts</context>
|
||||
<context context-type="linenumber">41</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="admin.link.functies.desc" datatype="html">
|
||||
<source>Functionaliteit aan- of uitzetten</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/admin-links.ts</context>
|
||||
<context context-type="linenumber">42</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="crumb.dashboard" datatype="html">
|
||||
<source>Mijn overzicht</source>
|
||||
<context-group purpose="location">
|
||||
@@ -2842,14 +2919,14 @@
|
||||
<source>Taal / Language</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/language-switcher/language-switcher.component.ts</context>
|
||||
<context context-type="linenumber">72</context>
|
||||
<context context-type="linenumber">80</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="lang.heading" datatype="html">
|
||||
<source>Kies een taal</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/language-switcher/language-switcher.component.ts</context>
|
||||
<context context-type="linenumber">73</context>
|
||||
<context context-type="linenumber">81</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="pageShell.backLabel" datatype="html">
|
||||
@@ -2926,56 +3003,56 @@
|
||||
<source>Overzicht</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/site-header/site-header.component.ts</context>
|
||||
<context context-type="linenumber">17</context>
|
||||
<context context-type="linenumber">19</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.nav.gegevens" datatype="html">
|
||||
<source>Mijn gegevens</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/site-header/site-header.component.ts</context>
|
||||
<context context-type="linenumber">18</context>
|
||||
<context context-type="linenumber">20</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.nav.herregistratie" datatype="html">
|
||||
<source>Herregistratie</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/site-header/site-header.component.ts</context>
|
||||
<context context-type="linenumber">19</context>
|
||||
<context context-type="linenumber">21</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.nav.inschrijven" datatype="html">
|
||||
<source>Inschrijven</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/site-header/site-header.component.ts</context>
|
||||
<context context-type="linenumber">20</context>
|
||||
<context context-type="linenumber">22</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.sender" datatype="html">
|
||||
<source>BIG-register</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/site-header/site-header.component.ts</context>
|
||||
<context context-type="linenumber">55,56</context>
|
||||
<context context-type="linenumber">57,58</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.ministry" datatype="html">
|
||||
<source>Ministerie van Volksgezondheid, Welzijn en Sport</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/site-header/site-header.component.ts</context>
|
||||
<context context-type="linenumber">57,59</context>
|
||||
<context context-type="linenumber">59,61</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.uitloggen" datatype="html">
|
||||
<source> Uitloggen </source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/site-header/site-header.component.ts</context>
|
||||
<context context-type="linenumber">79,80</context>
|
||||
<context context-type="linenumber">81,82</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="header.navAria" datatype="html">
|
||||
<source>Hoofdnavigatie</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/shared/layout/site-header/site-header.component.ts</context>
|
||||
<context context-type="linenumber">87,88</context>
|
||||
<context context-type="linenumber">89,90</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="wizard.naarStap" datatype="html">
|
||||
|
||||
Reference in New Issue
Block a user