diff --git a/alfa-client/apps/admin/src/app/app.component.html b/alfa-client/apps/admin/src/app/app.component.html
index 69e4b50b55c887010dbdea890b1f62c3b275478f..f2b6f351107b9ad56a829832c750d7b9f6956033 100644
--- a/alfa-client/apps/admin/src/app/app.component.html
+++ b/alfa-client/apps/admin/src/app/app.component.html
@@ -11,31 +11,26 @@
     >
       <ods-admin-logo-icon />
     </a>
-    <user-profile-button-container
-      data-test-id="user-profile-button"
-    ></user-profile-button-container>
+    <user-profile-button-container data-test-id="user-profile-button"></user-profile-button-container>
   </header>
   <div class="flex h-screen w-full justify-center overflow-y-auto">
     <ods-navbar data-test-id="navigation">
       <ng-container *ngIf="apiRoot | hasLink: ApiRootLinkRel.CONFIGURATION">
-        <!--        <ods-nav-item caption="Organisationseinheiten" to="/organisationseinheiten">-->
-        <!--          <ods-orga-unit-icon icon />-->
-        <!--        </ods-nav-item>-->
-        <ods-nav-item caption="Benutzer & Rollen" to="/benutzer_und_rollen">
+        <ods-nav-item caption="Benutzer & Rollen" path="/benutzer_und_rollen">
           <ods-users-icon class="stroke-text" icon />
         </ods-nav-item>
         <hr />
-        <ods-nav-item caption="Postfach" to="/postfach">
+        <ods-nav-item caption="Postfach" path="/postfach">
           <ods-mailbox-icon icon />
         </ods-nav-item>
+        <ods-nav-item caption="Organisationseinheiten" path="/organisationseinheiten">
+          <ods-orga-unit-icon icon />
+        </ods-nav-item>
       </ng-container>
     </ods-navbar>
     <main class="flex-1 overflow-y-auto bg-white px-6 py-4">
       <router-outlet
-        *ngIf="
-          apiRoot | hasLink: ApiRootLinkRel.CONFIGURATION;
-          else configurationResourceLinkNotAvailable
-        "
+        *ngIf="apiRoot | hasLink: ApiRootLinkRel.CONFIGURATION; else configurationResourceLinkNotAvailable"
         data-test-id="router-outlet"
       ></router-outlet>
       <ng-template #configurationResourceLinkNotAvailable>
diff --git a/alfa-client/apps/admin/src/app/app.module.ts b/alfa-client/apps/admin/src/app/app.module.ts
index 7c9c63cf24edf02b34858e9a0f9f1ce98b2ffdcd..29e55f5de54331beb3a2195b83e6265c056dcb5b 100644
--- a/alfa-client/apps/admin/src/app/app.module.ts
+++ b/alfa-client/apps/admin/src/app/app.module.ts
@@ -28,7 +28,8 @@ import { OAuthModule } from 'angular-oauth2-oidc';
 import { HttpUnauthorizedInterceptor } from 'libs/authentication/src/lib/http-unauthorized.interceptor';
 import { UserProfileButtonContainerComponent } from '../common/user-profile-button-container/user-profile.button-container.component';
 import { environment } from '../environments/environment';
-import { OrganisationseinheitPageComponent } from '../pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component';
+import { OrganisationsEinheitFormPageComponent } from '../pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component';
+import { OrganisationsEinheitPageComponent } from '../pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component';
 import { PostfachPageComponent } from '../pages/postfach/postfach-page/postfach-page.component';
 import { UnavailablePageComponent } from '../pages/unavailable/unavailable-page/unavailable-page.component';
 import { UserRolesPageComponent } from '../pages/users-roles/user-roles-page/user-roles-page.component';
@@ -40,7 +41,8 @@ import { appRoutes } from './app.routes';
     AppComponent,
     PostfachPageComponent,
     UserRolesPageComponent,
-    OrganisationseinheitPageComponent,
+    OrganisationsEinheitPageComponent,
+    OrganisationsEinheitFormPageComponent,
     UserProfileButtonContainerComponent,
     UnavailablePageComponent,
   ],
diff --git a/alfa-client/apps/admin/src/app/app.routes.ts b/alfa-client/apps/admin/src/app/app.routes.ts
index 9594ce3ee2736d7a990774c0b57db4f75e3a7582..4225458cdaeb73330edbafa34f76c46209ebfc27 100644
--- a/alfa-client/apps/admin/src/app/app.routes.ts
+++ b/alfa-client/apps/admin/src/app/app.routes.ts
@@ -1,4 +1,6 @@
 import { Route } from '@angular/router';
+import { OrganisationsEinheitFormPageComponent } from '../pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component';
+import { OrganisationsEinheitPageComponent } from '../pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component';
 import { PostfachPageComponent } from '../pages/postfach/postfach-page/postfach-page.component';
 import { UserRolesPageComponent } from '../pages/users-roles/user-roles-page/user-roles-page.component';
 
@@ -18,9 +20,14 @@ export const appRoutes: Route[] = [
     component: UserRolesPageComponent,
     title: 'Admin | Benutzer & Rollen',
   },
-  // {
-  //   path: 'organisationseinheiten',
-  //   component: OrganisationseinheitPageComponent,
-  //   title: 'Admin | Organisationseinheiten',
-  // },
+  {
+    path: 'organisationseinheiten',
+    component: OrganisationsEinheitPageComponent,
+    title: 'Admin | Organisationseinheiten',
+  },
+  {
+    path: 'organisationseinheiten/:organisationsEinheitUrl',
+    component: OrganisationsEinheitFormPageComponent,
+    title: 'Admin | Organisationseinheit',
+  },
 ];
diff --git a/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component.html b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..2449a303b186022b68d062f7b59ba73c5cb6a790
--- /dev/null
+++ b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component.html
@@ -0,0 +1 @@
+<admin-organisationseinheit-form-container/>
\ No newline at end of file
diff --git a/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component.spec.ts b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4ad49ca4595e598e66a9e6b0d40b46cca0d606b5
--- /dev/null
+++ b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component.spec.ts
@@ -0,0 +1,26 @@
+import { OrganisationsEinheitFormContainerComponent } from '@admin-client/admin-settings';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MockComponent } from 'ng-mocks';
+import { OrganisationsEinheitFormPageComponent } from './organisationseinheit-form-page.component';
+
+describe('OrganisationsEinheitFormPageComponent', () => {
+  let component: OrganisationsEinheitFormPageComponent;
+  let fixture: ComponentFixture<OrganisationsEinheitFormPageComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [OrganisationsEinheitFormPageComponent, MockComponent(OrganisationsEinheitFormContainerComponent)],
+    }).compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(OrganisationsEinheitFormPageComponent);
+    component = fixture.componentInstance;
+
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component.ts b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b7c9e0ea72a6ccd313239a4461f3a75692be5d9d
--- /dev/null
+++ b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-form-page/organisationseinheit-form-page.component.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'organisationseinheit-form-page',
+  templateUrl: './organisationseinheit-form-page.component.html',
+})
+export class OrganisationsEinheitFormPageComponent {}
diff --git a/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.html b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.html
index ff86abb3c13e73397ead229e205a03fa87c3f944..792930158756ab6bea2bf0e8fbd5c164c5037c0a 100644
--- a/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.html
+++ b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.html
@@ -1 +1 @@
-<admin-organisationseinheit-container></admin-organisationseinheit-container>
+<admin-organisationseinheit-container/>
diff --git a/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.spec.ts b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.spec.ts
index e5c52e8433943e7eaedee4c2cc541400b7eb873c..59ddda81ab9c26fbac8f8bd976298596c9283b5a 100644
--- a/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.spec.ts
+++ b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.spec.ts
@@ -1,23 +1,20 @@
-import { OrganisationseinheitContainerComponent } from '@admin-client/admin-settings';
+import { OrganisationsEinheitContainerComponent } from '@admin-client/admin-settings';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { MockComponent } from 'ng-mocks';
-import { OrganisationseinheitPageComponent } from './organisationseinheit-page.component';
+import { OrganisationsEinheitPageComponent } from './organisationseinheit-page.component';
 
-describe('OrganisationseinheitPageComponent', () => {
-  let component: OrganisationseinheitPageComponent;
-  let fixture: ComponentFixture<OrganisationseinheitPageComponent>;
+describe('OrganisationsEinheitPageComponent', () => {
+  let component: OrganisationsEinheitPageComponent;
+  let fixture: ComponentFixture<OrganisationsEinheitPageComponent>;
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      declarations: [
-        OrganisationseinheitPageComponent,
-        MockComponent(OrganisationseinheitContainerComponent),
-      ],
+      declarations: [OrganisationsEinheitPageComponent, MockComponent(OrganisationsEinheitContainerComponent)],
     }).compileComponents();
   });
 
   beforeEach(() => {
-    fixture = TestBed.createComponent(OrganisationseinheitPageComponent);
+    fixture = TestBed.createComponent(OrganisationsEinheitPageComponent);
     component = fixture.componentInstance;
 
     fixture.detectChanges();
diff --git a/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.ts b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.ts
index a87b271644db44803dd63e84c99ca71b0be15443..4d653b6ed7b3701a4f74ce763f313cc93ca29dc6 100644
--- a/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.ts
+++ b/alfa-client/apps/admin/src/pages/organisationseinheit/organisationseinheit-page/organisationseinheit-page.component.ts
@@ -4,4 +4,4 @@ import { Component } from '@angular/core';
   selector: 'organisationseinheit-page',
   templateUrl: './organisationseinheit-page.component.html',
 })
-export class OrganisationseinheitPageComponent {}
+export class OrganisationsEinheitPageComponent {}
diff --git a/alfa-client/libs/admin/settings/src/index.ts b/alfa-client/libs/admin/settings/src/index.ts
index c4fb8070ef7b2b2df0fcfbe70f30c84a06235327..a13f84185d2480694cbb145fb300e553cc668381 100644
--- a/alfa-client/libs/admin/settings/src/index.ts
+++ b/alfa-client/libs/admin/settings/src/index.ts
@@ -1,5 +1,7 @@
 export * from './lib/admin-settings.module';
+export * from './lib/organisationseinheit/organisations-einheit.model';
 export * from './lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component';
+export * from './lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component';
 export * from './lib/postfach/postfach-container/postfach-container.component';
 export * from './lib/shared/navigation-item/navigation-item.component';
 export * from './lib/users-roles/users-roles.component';
diff --git a/alfa-client/libs/admin/settings/src/lib/admin-settings.module.ts b/alfa-client/libs/admin/settings/src/lib/admin-settings.module.ts
index 321e7c04c5850b85027d827f2bc43e971cdef1b1..ad13c6426adbf09d39909c175b215c4e79f6c932 100644
--- a/alfa-client/libs/admin/settings/src/lib/admin-settings.module.ts
+++ b/alfa-client/libs/admin/settings/src/lib/admin-settings.module.ts
@@ -1,20 +1,39 @@
 import { ApiRootService } from '@alfa-client/api-root-shared';
 import { Environment, ENVIRONMENT_CONFIG } from '@alfa-client/environment-shared';
+import { NavigationSharedModule } from '@alfa-client/navigation-shared';
 import { ResourceRepository, TechSharedModule } from '@alfa-client/tech-shared';
+import { UiModule } from '@alfa-client/ui';
 import { CommonModule } from '@angular/common';
 import { NgModule } from '@angular/core';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterModule } from '@angular/router';
 import KcAdminClient from '@keycloak/keycloak-admin-client';
 import { ButtonWithSpinnerComponent, TextareaEditorComponent } from '@ods/component';
-import { MailboxIconComponent, PersonIconComponent, TextInputComponent } from '@ods/system';
+import {
+  ExclamationIconComponent,
+  ListComponent,
+  ListItemComponent,
+  MailboxIconComponent,
+  PersonIconComponent,
+  TextInputComponent,
+} from '@ods/system';
 import { createSettingListResourceService, SettingListResourceService } from './admin-settings-resource.service';
 import { SettingsService } from './admin-settings.service';
 import { ConfigurationResourceService, createConfigurationResourceService } from './configuration/configuration-resource.service';
 import { ConfigurationService } from './configuration/configuration.service';
-import { OrganisationseinheitContainerComponent } from './organisationseinheit/organisationseinheit-container/organisationseinheit-container.component';
-import { OrganisationseinheitFormComponent } from './organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.component';
-import { OrganisationseinheitListComponent } from './organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component';
+import {
+  createOrganisationsEinheitListResourceService,
+  OrganisationsEinheitListResourceService,
+} from './organisationseinheit/organisations-einheit-list-resource.service';
+import {
+  createOrganisationsEinheitResourceService,
+  OrganisationsEinheitResourceService,
+} from './organisationseinheit/organisations-einheit-resource.service';
+import { OrganisationsEinheitContainerComponent } from './organisationseinheit/organisationseinheit-container/organisationseinheit-container.component';
+import { OrganisationsEinheitListComponent } from './organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component';
+import { OrganisationsEinheitFormContainerComponent } from './organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component';
+import { OrganisationsEinheitFormComponent } from './organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component';
+import { OrganisationsEinheitSignaturComponent } from './organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-signatur/organisationseinheit-signatur.component';
 import { PostfachContainerComponent } from './postfach/postfach-container/postfach-container.component';
 import { PostfachFormComponent } from './postfach/postfach-container/postfach-form/postfach-form.component';
 import { PostfachSignaturComponent } from './postfach/postfach-container/postfach-form/postfach-signatur/postfach-signatur.component';
@@ -37,11 +56,13 @@ import { UsersRolesComponent } from './users-roles/users-roles.component';
     PostfachSignaturComponent,
     NavigationItemComponent,
     TextFieldComponent,
-    OrganisationseinheitContainerComponent,
-    OrganisationseinheitFormComponent,
+    OrganisationsEinheitContainerComponent,
+    OrganisationsEinheitListComponent,
+    OrganisationsEinheitFormContainerComponent,
+    OrganisationsEinheitFormComponent,
+    OrganisationsEinheitSignaturComponent,
     PrimaryButtonComponent,
     SecondaryButtonComponent,
-    OrganisationseinheitListComponent,
     MoreMenuComponent,
     MoreItemButtonComponent,
     SpinnerComponent,
@@ -58,8 +79,19 @@ import { UsersRolesComponent } from './users-roles/users-roles.component';
     MailboxIconComponent,
     PersonIconComponent,
     ToUserNamePipe,
+    ListComponent,
+    ListItemComponent,
+    ExclamationIconComponent,
+    UiModule,
+    NavigationSharedModule,
+  ],
+  exports: [
+    PostfachContainerComponent,
+    OrganisationsEinheitContainerComponent,
+    OrganisationsEinheitFormContainerComponent,
+    NavigationItemComponent,
+    UsersRolesComponent,
   ],
-  exports: [PostfachContainerComponent, OrganisationseinheitContainerComponent, NavigationItemComponent, UsersRolesComponent],
   providers: [
     ConfigurationService,
     SettingsService,
@@ -88,6 +120,16 @@ import { UsersRolesComponent } from './users-roles/users-roles.component';
       useFactory: createSettingListResourceService,
       deps: [ResourceRepository, ConfigurationService],
     },
+    {
+      provide: OrganisationsEinheitListResourceService,
+      useFactory: createOrganisationsEinheitListResourceService,
+      deps: [ResourceRepository, ApiRootService],
+    },
+    {
+      provide: OrganisationsEinheitResourceService,
+      useFactory: createOrganisationsEinheitResourceService,
+      deps: [ResourceRepository, OrganisationsEinheitListResourceService],
+    },
   ],
 })
 export class AdminSettingsModule {}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit-list-resource.service.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit-list-resource.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6fd977e0f5cffdd20fc701931e73e023279efafc
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit-list-resource.service.ts
@@ -0,0 +1,24 @@
+import { AdminOrganisationsEinheitItemResource, AdminOrganisationsEinheitListResource } from '@admin-client/admin-settings';
+import { ApiRootLinkRel, ApiRootResource, ApiRootService } from '@alfa-client/api-root-shared';
+import { ListResourceServiceConfig, ResourceListService, ResourceRepository } from '@alfa-client/tech-shared';
+import { ConfigurationResource } from 'libs/admin/settings/src/lib/configuration/configuration.model';
+import { OrganisationsEinheitListLinkRel } from './organisations-einheit.linkrel';
+
+export class OrganisationsEinheitListResourceService extends ResourceListService<
+  ApiRootResource,
+  AdminOrganisationsEinheitListResource,
+  AdminOrganisationsEinheitItemResource
+> {}
+
+export function createOrganisationsEinheitListResourceService(repository: ResourceRepository, apiRootService: ApiRootService) {
+  return new ResourceListService(buildConfig(apiRootService), repository);
+}
+
+function buildConfig(apiRootService: ApiRootService): ListResourceServiceConfig<ConfigurationResource> {
+  return {
+    baseResource: apiRootService.getApiRoot(),
+    createLinkRel: 'TODO',
+    listLinkRel: ApiRootLinkRel.ORGANISATIONS_EINHEIT,
+    listResourceListLinkRel: OrganisationsEinheitListLinkRel.LIST,
+  };
+}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit-resource.service.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit-resource.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7722ed1bc822c933a67f33f74b7175ae2e7e2f47
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit-resource.service.ts
@@ -0,0 +1,25 @@
+import { AdminOrganisationsEinheitResource } from '@admin-client/admin-settings';
+import { ApiResourceService, ResourceRepository, ResourceServiceConfig } from '@alfa-client/tech-shared';
+import { ConfigurationResource } from 'libs/admin/settings/src/lib/configuration/configuration.model';
+import { OrganisationsEinheitListResourceService } from './organisations-einheit-list-resource.service';
+import { OrganisationsEinheitLinkRel } from './organisations-einheit.linkrel';
+
+export class OrganisationsEinheitResourceService extends ApiResourceService<
+  AdminOrganisationsEinheitResource,
+  AdminOrganisationsEinheitResource
+> {}
+
+export function createOrganisationsEinheitResourceService(
+  repository: ResourceRepository,
+  listResourceService: OrganisationsEinheitListResourceService,
+) {
+  return new ApiResourceService(buildConfig(listResourceService), repository);
+}
+
+function buildConfig(listResourceService: OrganisationsEinheitListResourceService): ResourceServiceConfig<ConfigurationResource> {
+  return {
+    resource: listResourceService.getSelected(),
+    getLinkRel: OrganisationsEinheitLinkRel.SELF,
+    edit: { linkRel: OrganisationsEinheitLinkRel.SELF },
+  };
+}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit.linkrel.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit.linkrel.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6e941e1fc3ac3406b32d44085fcde10284fde8ba
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit.linkrel.ts
@@ -0,0 +1,7 @@
+export enum OrganisationsEinheitListLinkRel {
+  LIST = 'organisationsEinheitList',
+}
+
+export enum OrganisationsEinheitLinkRel {
+  SELF = 'self',
+}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit.model.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f74a83a382373287cfc21afe8654c9023d67e341
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisations-einheit.model.ts
@@ -0,0 +1,26 @@
+import { ListResource } from '@alfa-client/tech-shared';
+import { Resource } from '@ngxp/rest';
+
+export interface AdminOrganisationsEinheit {
+  name: string;
+  organisationsEinheitId: string;
+  syncResult: AdminOrganisationsEinheitSyncResult;
+  settings?: AdminOrganisationsEinheitSettings;
+  isChild?: boolean;
+}
+
+export enum AdminOrganisationsEinheitSyncResult {
+  OK = 'OK',
+  NOT_FOUND_IN_PVOG = 'NOT_FOUND_IN_PVOG',
+  NAME_MISMATCH = 'NAME_MISMATCH',
+  ORGANISATIONSEINHEIT_ID_NOT_UNIQUE = 'ORGANISATIONSEINHEIT_ID_NOT_UNIQUE',
+  DELETED = 'DELETED',
+}
+
+export interface AdminOrganisationsEinheitSettings {
+  signatur?: string;
+}
+
+export interface AdminOrganisationsEinheitResource extends AdminOrganisationsEinheit, Resource {}
+export interface AdminOrganisationsEinheitListResource extends ListResource {}
+export declare type AdminOrganisationsEinheitItemResource = Resource & AdminOrganisationsEinheit;
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.html b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.html
index 3e7af75f493ada03112994766ea980b90033e282..5dc954e2c97ce3b5bc3cef43b0cee24532dc987c 100644
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.html
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.html
@@ -1,27 +1,7 @@
-<ng-container *ngIf="organisationseinheitItems$ | async as organisationseinheitItems">
-  <h1 class="heading-1 pb-4">Organisationseinheiten</h1>
-  <p id="absender-desc" class="p-1">Hinterlegen Sie Name und ID der Organisationseinheiten.</p>
+<h1 class="heading-1 pb-4">Organisationseinheiten</h1>
 
-  <admin-organisationseinheit-form
-    data-test-id="organisationseinheit-form"
-    [organisationseinheitItems]="organisationseinheitItems"
-  ></admin-organisationseinheit-form>
-
-  <admin-secondary-button
-    (clickEmitter)="openDialogForNewGroup()"
-    data-test-id="organisationseinheit-open-dialog-button"
-    label="Neue Organisationseinheit anlegen"
-  >
-  </admin-secondary-button>
-  <admin-spinner
-    data-test-id="organisationseinheit-spinner"
-    *ngIf="deleteInProgress$ | async"
-  ></admin-spinner>
-
-  <admin-organisationseinheit-list
-    [organisationseinheitItems]="organisationseinheitItems"
-    (editOrganisationseinheit)="edit($event)"
-    (deleteOrganisationseinheit)="delete($event)"
-    data-test-id="organisationseinheit-list"
-  ></admin-organisationseinheit-list>
-</ng-container>
+<admin-organisationseinheit-list
+  *ngIf="organisationsEinheitResources$ | async as organisationsEinheitResources"
+  [organisationsEinheitResources]="organisationsEinheitResources"
+  data-test-id="organisations-einheit-list"
+/>
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.spec.ts
index 1c5f9731bdfef401363bc423391cf1c7a2ed0529..43ee626c39887b1f882a4b5af5d23619171a0a63 100644
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.spec.ts
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.spec.ts
@@ -1,126 +1,91 @@
+import { AdminOrganisationsEinheitResource, OrganisationsEinheitContainerComponent } from '@admin-client/admin-settings';
 import { createStateResource } from '@alfa-client/tech-shared';
-import {
-  Mock,
-  dispatchEventFromFixture,
-  existsAsHtmlElement,
-  getElementFromFixtureByType,
-  mock,
-  notExistsAsHtmlElement,
-} from '@alfa-client/test-utils';
+import { Mock, existsAsHtmlElement, mock } from '@alfa-client/test-utils';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
-import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
-import { singleCold } from 'libs/tech-shared/test/marbles';
+import { ButtonWithSpinnerComponent } from '@ods/component';
 import { MockComponent } from 'ng-mocks';
-import { of } from 'rxjs';
-import { createOrganisationseinheit } from '../../../../test/user/user';
-import { SecondaryButtonComponent } from '../../shared/secondary-button/secondary-button.component';
-import { SpinnerComponent } from '../../shared/spinner/spinner.component';
-import { Organisationseinheit } from '../../user/user.model';
-import { OrganisationseinheitService } from '../organisationseinheit.service';
-import { OrganisationseinheitContainerComponent } from './organisationseinheit-container.component';
-import { OrganisationseinheitFormComponent } from './organisationseinheit-form/organisationseinheit-form.component';
-import { OrganisationseinheitListComponent } from './organisationseinheit-list/organisationseinheit-list.component';
-
-describe('OrganisationseinheitContainerComponent', () => {
-  let component: OrganisationseinheitContainerComponent;
-  let fixture: ComponentFixture<OrganisationseinheitContainerComponent>;
-
-  const organisationseinheitService: Mock<OrganisationseinheitService> = mock(OrganisationseinheitService);
-
-  const dialogOpenButtonSelector: string = getDataTestIdOf('organisationseinheit-open-dialog-button');
-  const spinnerSelector: string = getDataTestIdOf('organisationseinheit-spinner');
+import { Observable, of } from 'rxjs';
+import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test';
+import {
+  createAdminOrganisationsEinheitListResource,
+  createAdminOrganisationsEinheitResource,
+} from '../../../../test/organisations-einheit/organisations-einheit';
+import { OrganisationsEinheitService } from '../organisationseinheit.service';
+import { OrganisationsEinheitListComponent } from './organisationseinheit-list/organisationseinheit-list.component';
 
-  const organisationseinheitItems: Organisationseinheit[] = [createOrganisationseinheit()];
+describe('OrganisationsEinheitContainerComponent', () => {
+  let component: OrganisationsEinheitContainerComponent;
+  let fixture: ComponentFixture<OrganisationsEinheitContainerComponent>;
 
-  let formComponent: OrganisationseinheitFormComponent;
-  let listComponent: OrganisationseinheitListComponent;
+  const organisationsEinheitService: Mock<OrganisationsEinheitService> = mock(OrganisationsEinheitService);
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      declarations: [
-        OrganisationseinheitContainerComponent,
-        MockComponent(SecondaryButtonComponent),
-        MockComponent(OrganisationseinheitFormComponent),
-        MockComponent(OrganisationseinheitListComponent),
-        MockComponent(SpinnerComponent),
-      ],
-      providers: [{ provide: OrganisationseinheitService, useValue: organisationseinheitService }],
+      declarations: [OrganisationsEinheitContainerComponent, MockComponent(OrganisationsEinheitListComponent)],
+      imports: [ButtonWithSpinnerComponent],
+      providers: [{ provide: OrganisationsEinheitService, useValue: organisationsEinheitService }],
     }).compileComponents();
 
-    fixture = TestBed.createComponent(OrganisationseinheitContainerComponent);
+    fixture = TestBed.createComponent(OrganisationsEinheitContainerComponent);
     component = fixture.componentInstance;
 
-    organisationseinheitService.get = jest.fn().mockReturnValue(of(createStateResource(organisationseinheitItems)));
-    fixture.detectChanges();
+    organisationsEinheitService.getList = jest
+      .fn()
+      .mockReturnValue(of(createStateResource(createAdminOrganisationsEinheitListResource())));
 
-    formComponent = getElementFromFixtureByType(fixture, OrganisationseinheitFormComponent);
-    listComponent = getElementFromFixtureByType(fixture, OrganisationseinheitListComponent);
+    fixture.detectChanges();
   });
 
   it('should create', () => {
     expect(component).toBeTruthy();
   });
 
-  it('should open form on new organisationseinheit button', () => {
-    formComponent.open = jest.fn();
-
-    dispatchEventFromFixture(fixture, dialogOpenButtonSelector, 'clickEmitter');
-
-    expect(formComponent.open).toHaveBeenCalled();
-  });
-
-  describe('organisationseinheit list', () => {
-    it('should open form for editing on editOrganisationseinheit event', () => {
-      const organisationseinheit: Organisationseinheit = organisationseinheitItems[0];
-      formComponent.openEdit = jest.fn();
-
-      listComponent.editOrganisationseinheit.emit(organisationseinheit);
-
-      expect(formComponent.openEdit).toHaveBeenCalledWith(organisationseinheit);
-    });
-
-    it('should call deleteOrganisationseinheit form on deleteOrganisationseinheit event', () => {
-      const organisationseinheit: Organisationseinheit = organisationseinheitItems[0];
-      component.delete = jest.fn();
-
-      listComponent.deleteOrganisationseinheit.emit(organisationseinheit);
-
-      expect(component.delete).toHaveBeenCalledWith(organisationseinheit);
-    });
-  });
-
-  describe('delete', () => {
-    const organisationseinheit: Organisationseinheit = organisationseinheitItems[0];
-
-    beforeEach(() => {
-      organisationseinheitService.delete = jest.fn().mockReturnValue(singleCold(true));
+  describe('component', () => {
+    describe('ngOnInit', () => {
+      beforeEach(() => {
+        component.loadOrganisationsEinheitResources = jest.fn().mockReturnValue(of([createAdminOrganisationsEinheitResource()]));
+      });
+
+      it('should call loadOrganisationsEinheitResources', () => {
+        component.organisationsEinheitResources$.subscribe(() => {
+          expect(component.loadOrganisationsEinheitResources).toHaveBeenCalled();
+        });
+      });
+
+      it('should set organisationsEinheitResources', () => {
+        component.ngOnInit();
+
+        component.organisationsEinheitResources$.subscribe(
+          (organisationsEinheitResources: AdminOrganisationsEinheitResource[]) => {
+            expect(organisationsEinheitResources.length).toBe(1);
+          },
+        );
+      });
     });
 
-    it('should call service method', () => {
-      component.delete(organisationseinheit);
+    describe('loadOrganisationsEinheitResources', () => {
+      it('should call organisationsEinheitService getList', () => {
+        component.loadOrganisationsEinheitResources();
 
-      expect(organisationseinheitService.delete).toHaveBeenCalledWith(organisationseinheit.id);
-    });
+        expect(organisationsEinheitService.getList).toHaveBeenCalled();
+      });
 
-    it('should assign delete progress observable', () => {
-      component.delete(organisationseinheit);
+      it('should set organisationsEinheitResources', () => {
+        const organisationsEinheitResources$: Observable<AdminOrganisationsEinheitResource[]> =
+          component.loadOrganisationsEinheitResources();
 
-      expect(component.deleteInProgress$).toBeObservable(singleCold(true));
+        organisationsEinheitResources$.subscribe((organisationsEinheitResources: AdminOrganisationsEinheitResource[]) => {
+          expect(organisationsEinheitResources.length).toBe(1);
+        });
+      });
     });
   });
 
-  describe('spinner', () => {
-    it('should not show if delete in not progress', () => {
-      fixture.detectChanges();
-
-      notExistsAsHtmlElement(fixture, spinnerSelector);
-    });
-    it('should show if delete in progress', () => {
-      component.deleteInProgress$ = of(true);
-
-      fixture.detectChanges();
-
-      existsAsHtmlElement(fixture, spinnerSelector);
+  describe('template', () => {
+    describe('organisationsEinheiten list', () => {
+      it('should show list', () => {
+        existsAsHtmlElement(fixture, getDataTestIdOf('organisations-einheit-list'));
+      });
     });
   });
 });
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.ts
index c8dc13a8eda3ff1f0825c7282020040695df6ecd..ce5610b8b2d295c591265cc930f96f4b5c1684a4 100644
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.ts
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-container.component.ts
@@ -1,36 +1,33 @@
-import { StateResource } from '@alfa-client/tech-shared';
-import { Component, OnInit, ViewChild } from '@angular/core';
-import { Observable, of } from 'rxjs';
-import { Organisationseinheit } from '../../user/user.model';
-import { OrganisationseinheitService } from '../organisationseinheit.service';
-import { OrganisationseinheitFormComponent } from './organisationseinheit-form/organisationseinheit-form.component';
+import { getEmbeddedResources, StateResource } from '@alfa-client/tech-shared';
+import { Component, OnInit } from '@angular/core';
+import { map, Observable } from 'rxjs';
+import { OrganisationsEinheitListLinkRel } from '../organisations-einheit.linkrel';
+import { AdminOrganisationsEinheitListResource, AdminOrganisationsEinheitResource } from '../organisations-einheit.model';
+import { OrganisationsEinheitService } from '../organisationseinheit.service';
 
 @Component({
   selector: 'admin-organisationseinheit-container',
   templateUrl: './organisationseinheit-container.component.html',
 })
-export class OrganisationseinheitContainerComponent implements OnInit {
-  organisationseinheitItems$: Observable<StateResource<Organisationseinheit[]>>;
-  deleteInProgress$: Observable<boolean> = of(false);
+export class OrganisationsEinheitContainerComponent implements OnInit {
+  organisationsEinheitResources$: Observable<AdminOrganisationsEinheitResource[]>;
 
-  @ViewChild(OrganisationseinheitFormComponent)
-  private form!: OrganisationseinheitFormComponent;
-
-  constructor(private organisationseinheitService: OrganisationseinheitService) {}
+  constructor(private organisationsEinheitService: OrganisationsEinheitService) {}
 
   ngOnInit(): void {
-    this.organisationseinheitItems$ = this.organisationseinheitService.get();
-  }
-
-  public openDialogForNewGroup(): void {
-    this.form.open();
-  }
-
-  public edit(organisationseinheit: Organisationseinheit): void {
-    this.form.openEdit(organisationseinheit);
+    this.organisationsEinheitResources$ = this.loadOrganisationsEinheitResources();
   }
 
-  public delete(organisationseinheit: Organisationseinheit): void {
-    this.deleteInProgress$ = this.organisationseinheitService.delete(organisationseinheit.id);
+  loadOrganisationsEinheitResources(): Observable<AdminOrganisationsEinheitResource[]> {
+    return this.organisationsEinheitService
+      .getList()
+      .pipe(
+        map((organisationsEinheitListResource: StateResource<AdminOrganisationsEinheitListResource>) =>
+          getEmbeddedResources<AdminOrganisationsEinheitResource>(
+            organisationsEinheitListResource,
+            OrganisationsEinheitListLinkRel.LIST,
+          ),
+        ),
+      );
   }
 }
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.component.html b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.component.html
deleted file mode 100644
index 3bd257438d0545a41b7b791b9574b1cf9184b009..0000000000000000000000000000000000000000
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.component.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<ng-container *ngIf="submitInProgress$ | async"></ng-container>
-<dialog #OrganisationseinheitDialog data-test-id="organisationseinheit-dialog" class="bg-gray-50">
-  <button
-    (click)="OrganisationseinheitDialog.close()"
-    data-test-id="organisationseinheit-close-button"
-    class="absolute right-3 top-1 text-2xl text-black hover:font-bold active:text-black/80"
-  >
-    &#x2715;
-  </button>
-  <form [formGroup]="formService.form" class="m-5 grid grid-cols-1 gap-5">
-    <h1 class="text-2xl" data-test-id="organisationseinheit-form-header">
-      {{ label }}
-    </h1>
-    <text-field
-      label="Name"
-      data-test-id="organisationseinheit-name"
-      [formControlName]="OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD"
-    ></text-field>
-    <text-field
-      label="OrganisationseinheitID"
-      data-test-id="organisationseinheit-id"
-      [formControlName]="OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD"
-    ></text-field>
-
-    <ods-button-with-spinner
-      data-test-id="organisationseinheit-save-button"
-      class="justify-self-end"
-      (clickEmitter)="submit()"
-      [stateResource]="organisationseinheitItems"
-      text="Speichern"
-    >
-    </ods-button-with-spinner>
-  </form>
-</dialog>
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.component.spec.ts
deleted file mode 100644
index fd81569ecb52fceecb829096f4e859aeb73fad36..0000000000000000000000000000000000000000
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.component.spec.ts
+++ /dev/null
@@ -1,281 +0,0 @@
-import { createEmptyStateResource } from '@alfa-client/tech-shared';
-import {
-  dispatchEventFromFixture,
-  getDebugElementFromFixtureByCss,
-  getElementFromFixture,
-  mock,
-  Mock,
-} from '@alfa-client/test-utils';
-import { DebugElement } from '@angular/core';
-import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
-import { AbstractControl, FormsModule, ReactiveFormsModule, UntypedFormGroup } from '@angular/forms';
-import { ButtonWithSpinnerComponent } from '@ods/component';
-import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
-import { MockComponent, ngMocks } from 'ng-mocks';
-import { of, throwError } from 'rxjs';
-import { createOrganisationseinheit } from '../../../../../test/user/user';
-import { TextFieldComponent } from '../../../shared/text-field/text-field.component';
-import { Organisationseinheit } from '../../../user/user.model';
-import { OrganisationseinheitService } from '../../organisationseinheit.service';
-import { OrganisationseinheitFormComponent } from './organisationseinheit-form.component';
-import { OrganisationseinheitFormService } from './organisationseinheit-form.service';
-
-describe('OrganisationseinheitFormComponent', () => {
-  let component: OrganisationseinheitFormComponent;
-  let fixture: ComponentFixture<OrganisationseinheitFormComponent>;
-  let form: UntypedFormGroup;
-
-  const organisationseinheitService: Mock<OrganisationseinheitService> = mock(OrganisationseinheitService);
-
-  const saveButtonSelector: string = getDataTestIdOf('organisationseinheit-save-button');
-  const closeButtonSelector: string = getDataTestIdOf('organisationseinheit-close-button');
-  const headerSelector: string = getDataTestIdOf('organisationseinheit-form-header');
-
-  beforeEach(async () => {
-    await TestBed.configureTestingModule({
-      declarations: [
-        OrganisationseinheitFormComponent,
-        MockComponent(TextFieldComponent),
-        MockComponent(ButtonWithSpinnerComponent),
-      ],
-      imports: [ReactiveFormsModule, FormsModule, ButtonWithSpinnerComponent],
-      providers: [{ provide: OrganisationseinheitService, useValue: organisationseinheitService }],
-    }).compileComponents();
-
-    fixture = TestBed.createComponent(OrganisationseinheitFormComponent);
-    component = fixture.componentInstance;
-    form = fixture.componentInstance.formService.form;
-    fixture.detectChanges();
-
-    component.dialog.showModal = jest.fn();
-    component.dialog.close = jest.fn();
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-
-  describe('form element', () => {
-    const fields: string[][] = [
-      [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD, 'Name', 'organisationseinheit-name'],
-      [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD, 'OrganisationseinheitID', 'organisationseinheit-id'],
-    ];
-
-    it.each(fields)('should have label for field "%s" with name "%s"', (fieldName: string, text: string, inputId: string) => {
-      const textFieldElement = getElementFromFixture(fixture, getDataTestIdOf(inputId));
-      expect(textFieldElement.getAttribute('label')).toBe(text);
-    });
-
-    it.each(fields)('should bind form for text-field "%s"', (fieldName, text, dataTestId) => {
-      const fieldValue: string = `some text-field ${text}`;
-      const formControl: AbstractControl = form.get(fieldName);
-
-      const textFieldComponent: DebugElement = getDebugElementFromFixtureByCss(fixture, getDataTestIdOf(dataTestId));
-      ngMocks.change(textFieldComponent, fieldValue);
-      expect(formControl.value).toBe(fieldValue);
-    });
-  });
-
-  describe('save button', () => {
-    let saveButtonComponent: ButtonWithSpinnerComponent;
-
-    beforeEach(() => {
-      saveButtonComponent = getDebugElementFromFixtureByCss(fixture, saveButtonSelector).componentInstance;
-    });
-
-    it('should call submit on click', () => {
-      component.submit = jest.fn();
-
-      dispatchEventFromFixture(fixture, saveButtonSelector, 'clickEmitter');
-
-      expect(component.submit).toHaveBeenCalled();
-    });
-
-    it('should be disabled while stateResource in loading', () => {
-      component.organisationseinheitItems = createEmptyStateResource(true);
-
-      fixture.detectChanges();
-
-      expect(saveButtonComponent.stateResource.loading).toBe(true);
-    });
-
-    it('should be enabled while not in progress', () => {
-      component.organisationseinheitItems = createEmptyStateResource(false);
-
-      fixture.detectChanges();
-
-      expect(saveButtonComponent.stateResource.loading).toBe(false);
-    });
-  });
-
-  describe('submit', () => {
-    beforeEach(() => {
-      component.handleProgressChange = jest.fn();
-    });
-
-    it('should not call complete on submit error', fakeAsync(() => {
-      component.formService.submit = () => throwError(() => new Error('some error'));
-
-      component.submit();
-      component.submitInProgress$.subscribe({
-        error: () => {},
-      });
-      tick();
-
-      expect(component.handleProgressChange).not.toHaveBeenCalled();
-    }));
-
-    it('should call complete on submit event', fakeAsync(() => {
-      component.formService.submit = () => of(false);
-
-      component.submit();
-      component.submitInProgress$.subscribe();
-      tick();
-
-      expect(component.handleProgressChange).toHaveBeenCalled();
-    }));
-
-    it.each([true, false])('should use submit progress "%s"', (progress) => {
-      component.organisationseinheitItems = createEmptyStateResource(progress);
-
-      fixture.detectChanges();
-
-      const saveButtonComponent: ButtonWithSpinnerComponent = getDebugElementFromFixtureByCss(
-        fixture,
-        saveButtonSelector,
-      ).componentInstance;
-
-      expect(saveButtonComponent.stateResource.loading).toBe(progress);
-    });
-  });
-
-  describe('handle progress change', () => {
-    it('should call complete if no errors with progress false', () => {
-      component.completeIfNoErrors = jest.fn();
-
-      component.handleProgressChange(false);
-
-      expect(component.completeIfNoErrors).toHaveBeenCalled();
-    });
-
-    it('should call complete if no errors with progress true', () => {
-      component.completeIfNoErrors = jest.fn();
-
-      component.handleProgressChange(true);
-
-      expect(component.completeIfNoErrors).not.toHaveBeenCalled();
-    });
-  });
-
-  describe('complete if no errors', () => {
-    beforeEach(() => {
-      component.complete = jest.fn();
-    });
-
-    it('should call not complete with errors', () => {
-      component.formService.isInvalid = jest.fn().mockReturnValue(true);
-
-      component.completeIfNoErrors();
-
-      expect(component.complete).not.toHaveBeenCalled();
-    });
-
-    it('should call complete without errors', () => {
-      component.formService.isInvalid = jest.fn().mockReturnValue(false);
-
-      component.completeIfNoErrors();
-
-      expect(component.complete).toHaveBeenCalled();
-    });
-  });
-
-  describe('complete', () => {
-    beforeEach(() => {
-      component.dialog.close = jest.fn();
-      component.formService.reset = jest.fn();
-    });
-
-    it('should close dialog', () => {
-      component.complete();
-
-      expect(component.dialog.close).toHaveBeenCalled();
-    });
-    it('should reset form', () => {
-      component.complete();
-
-      expect(component.formService.reset).toHaveBeenCalled();
-    });
-  });
-
-  describe('close button', () => {
-    it('should call to close dialog', () => {
-      component.dialog.close = jest.fn();
-
-      dispatchEventFromFixture(fixture, closeButtonSelector, 'click');
-
-      expect(component.dialog.close).toHaveBeenCalled();
-    });
-  });
-
-  describe('open', () => {
-    beforeEach(() => {
-      form.markAsTouched();
-    });
-
-    it('should set create label', () => {
-      component.open();
-
-      expect(component.label).toEqual(OrganisationseinheitFormComponent.CREATE_LABEL);
-    });
-
-    it('should open form', () => {
-      component.open();
-
-      expect(component.dialog.showModal).toHaveBeenCalled();
-    });
-
-    it('should reset form', () => {
-      component.formService.reset = jest.fn();
-
-      component.open();
-
-      expect(component.formService.reset).toHaveBeenCalled();
-    });
-  });
-
-  describe('open edit', () => {
-    const organisationseinheit: Organisationseinheit = createOrganisationseinheit();
-
-    it('should set edit label', () => {
-      component.openEdit(organisationseinheit);
-
-      expect(component.label).toEqual(OrganisationseinheitFormComponent.EDIT_LABEL);
-    });
-
-    it('should open dialog', () => {
-      component.open();
-
-      expect(component.dialog.showModal).toHaveBeenCalled();
-    });
-
-    it('should patch form', () => {
-      component.formService.patch = jest.fn();
-
-      component.openEdit(organisationseinheit);
-
-      expect(component.formService.patch).toHaveBeenCalledWith(organisationseinheit);
-    });
-  });
-
-  describe('header', () => {
-    it('should show label text', () => {
-      const text: string = 'test-text';
-      component.label = text;
-
-      fixture.detectChanges();
-
-      const headerElement: HTMLElement = getElementFromFixture(fixture, headerSelector);
-      expect(headerElement.textContent.trim()).toEqual(text);
-    });
-  });
-});
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.component.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.component.ts
deleted file mode 100644
index 4f4976209bc7976af17a5ce954585efbcffaff15..0000000000000000000000000000000000000000
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.component.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { StateResource, createStateResource } from '@alfa-client/tech-shared';
-import { AfterViewInit, Component, ElementRef, Input, ViewChild } from '@angular/core';
-import { Observable, of, tap } from 'rxjs';
-import { Organisationseinheit } from '../../../user/user.model';
-import { OrganisationseinheitFormService } from './organisationseinheit-form.service';
-
-@Component({
-  selector: 'admin-organisationseinheit-form',
-  templateUrl: './organisationseinheit-form.component.html',
-  providers: [OrganisationseinheitFormService],
-})
-export class OrganisationseinheitFormComponent implements AfterViewInit {
-  @Input() organisationseinheitItems: StateResource<Organisationseinheit[]> = createStateResource([]);
-
-  static CREATE_LABEL: string = 'Neue Organisationseinheit anlegen';
-  static EDIT_LABEL: string = 'Organisationseinheit bearbeiten';
-
-  protected readonly OrganisationseinheitFormService = OrganisationseinheitFormService;
-
-  @ViewChild('OrganisationseinheitDialog') private dialogRef: ElementRef<HTMLDialogElement>;
-  dialog: HTMLDialogElement;
-
-  submitInProgress$: Observable<boolean> = of(false);
-
-  label: string;
-
-  constructor(public formService: OrganisationseinheitFormService) {}
-
-  ngAfterViewInit(): void {
-    this.dialog = this.dialogRef.nativeElement;
-  }
-
-  public submit() {
-    this.submitInProgress$ = this.formService.submit().pipe(tap((progress: boolean) => this.handleProgressChange(progress)));
-  }
-
-  handleProgressChange(progress: boolean): void {
-    if (!progress) {
-      this.completeIfNoErrors();
-    }
-  }
-
-  completeIfNoErrors(): void {
-    if (!this.formService.isInvalid()) {
-      this.complete();
-    }
-  }
-
-  public open(): void {
-    this.label = OrganisationseinheitFormComponent.CREATE_LABEL;
-    this.formService.reset();
-    this.dialog.showModal();
-  }
-
-  public openEdit(organisationseinheit: Organisationseinheit): void {
-    this.label = OrganisationseinheitFormComponent.EDIT_LABEL;
-    this.formService.patch(organisationseinheit);
-    this.dialog.showModal();
-  }
-
-  complete(): void {
-    this.dialog.close();
-    this.formService.reset();
-  }
-}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.service.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.service.ts
deleted file mode 100644
index fb65fa06cc6959e5df3f029f7e2894307d140d43..0000000000000000000000000000000000000000
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit-form.service.ts
+++ /dev/null
@@ -1,135 +0,0 @@
-import { createStateResource, isNotNil, StateResource } from '@alfa-client/tech-shared';
-import { Injectable, Input } from '@angular/core';
-import { AbstractControl, FormControl, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
-import { catchError, Observable, of } from 'rxjs';
-import { Organisationseinheit, OrganisationseinheitError, OrganisationseinheitErrorType } from '../../../user/user.model';
-import { getOrganisationseinheitErrorMessage } from '../../../user/user.util';
-import { OrganisationseinheitService } from '../../organisationseinheit.service';
-
-@Injectable()
-export class OrganisationseinheitFormService {
-  @Input() organisationseinheitItems: StateResource<Organisationseinheit[]> = createStateResource([]);
-
-  public static readonly ORGANISATIONSEINHEIT_NAME_FIELD: string = 'name';
-  public static readonly ORGANISATIONSEINHEIT_IDS_FIELD: string = 'organisationseinheit';
-
-  form: UntypedFormGroup;
-
-  source: Organisationseinheit;
-
-  constructor(
-    private formBuilder: UntypedFormBuilder,
-    private organisationsEinheitService: OrganisationseinheitService,
-  ) {
-    this.form = this.formBuilder.group({
-      [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD]: new FormControl(''),
-      [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD]: new FormControl(''),
-    });
-  }
-
-  public submit(): Observable<boolean> {
-    if (this.validate()) {
-      return this.callService().pipe(
-        catchError((error: OrganisationseinheitError) => {
-          this.handleError(error);
-          return of(false);
-        }),
-      );
-    } else {
-      return of(false);
-    }
-  }
-
-  callService(): Observable<boolean> {
-    return this.isPatch() ? this.save() : this.create();
-  }
-
-  create(): Observable<boolean> {
-    return this.organisationsEinheitService.create({
-      name: this.getName(),
-      organisationseinheitIds: this.getOrganisationseinheitIds(),
-    });
-  }
-
-  save(): Observable<boolean> {
-    return this.organisationsEinheitService.save({
-      ...this.source,
-      name: this.getName(),
-      organisationseinheitIds: this.getOrganisationseinheitIds(),
-    });
-  }
-
-  validate(): boolean {
-    let valid: boolean = true;
-
-    if (this.getOrganisationseinheitIds().length == 0) {
-      this.setError(OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD, {
-        errorType: OrganisationseinheitErrorType.ID_MISSING,
-        detail: '',
-      });
-      valid = false;
-    }
-
-    return valid;
-  }
-
-  private getName(): string {
-    return this.getStringFromPotentiallyEmptyField(OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD);
-  }
-
-  private getOrganisationseinheitIds(): string[] {
-    return this.splitOrganisationseinheitIds(
-      this.form.get(OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD).value ?? '',
-    );
-  }
-
-  private getStringFromPotentiallyEmptyField(fieldName: string): string {
-    return this.form.get(fieldName).value ?? '';
-  }
-
-  public isPatch(): boolean {
-    return isNotNil(this.source);
-  }
-
-  handleError(error: OrganisationseinheitError): void {
-    if (
-      error.errorType === OrganisationseinheitErrorType.NAME_CONFLICT ||
-      error.errorType === OrganisationseinheitErrorType.NAME_MISSING
-    ) {
-      this.setError(OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD, error);
-    }
-  }
-
-  private setError(controlName: string, error: OrganisationseinheitError): void {
-    const control: AbstractControl = this.form.get(controlName);
-    control.setErrors({
-      [error.errorType]: getOrganisationseinheitErrorMessage(error),
-    });
-  }
-
-  splitOrganisationseinheitIds(organisationseinheitIdsString: string): string[] {
-    return organisationseinheitIdsString
-      .split(',')
-      .map((organisationseinheitId) => organisationseinheitId.trim())
-      .filter((organisationseinheitId) => organisationseinheitId.length > 0);
-  }
-
-  public patch(organisationseinheit: Organisationseinheit): void {
-    this.reset();
-    this.source = organisationseinheit;
-    this.form.patchValue({
-      [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD]: organisationseinheit.name,
-      [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD]: organisationseinheit.organisationseinheitIds.join(', '),
-    });
-  }
-
-  public reset(): void {
-    this.source = null;
-    this.form.reset();
-    this.form.markAsUntouched();
-  }
-
-  public isInvalid(): boolean {
-    return this.form.invalid;
-  }
-}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit.formservice.spec.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit.formservice.spec.ts
deleted file mode 100644
index 30b0562d0e2ab18a08381eb1bded287beb3dcd68..0000000000000000000000000000000000000000
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-form/organisationseinheit.formservice.spec.ts
+++ /dev/null
@@ -1,344 +0,0 @@
-import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
-import { Type } from '@angular/core';
-import { fakeAsync, tick } from '@angular/core/testing';
-import { AbstractControl, FormBuilder } from '@angular/forms';
-import { hot } from 'jest-marbles';
-import { singleCold, singleHot } from 'libs/tech-shared/test/marbles';
-import { Observable, lastValueFrom, throwError } from 'rxjs';
-import { createOrganisationseinheit, createOrganisationseinheitError } from '../../../../../test/user/user';
-import { Organisationseinheit, OrganisationseinheitError, OrganisationseinheitErrorType } from '../../../user/user.model';
-import { getOrganisationseinheitErrorMessage } from '../../../user/user.util';
-import { OrganisationseinheitService } from '../../organisationseinheit.service';
-import { OrganisationseinheitFormService } from './organisationseinheit-form.service';
-
-describe('OrganisationseinheitFormService', () => {
-  let formService: OrganisationseinheitFormService;
-  let organisationseinheit: Organisationseinheit;
-  const organisationseinheitService: Mock<OrganisationseinheitService> = mockResourceService(OrganisationseinheitService);
-
-  const formBuilder: FormBuilder = new FormBuilder();
-
-  beforeEach(() => {
-    formService = new OrganisationseinheitFormService(formBuilder, useFromMock(organisationseinheitService));
-    organisationseinheit = createOrganisationseinheit();
-    formService.form.setValue({
-      [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD]: organisationseinheit.name,
-      [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD]: organisationseinheit.organisationseinheitIds.join(','),
-    });
-  });
-
-  it('should create', () => {
-    expect(formService).toBeTruthy();
-  });
-
-  describe('submit', () => {
-    beforeEach(() => {
-      formService.handleError = jest.fn();
-    });
-
-    describe('with successful validation', () => {
-      beforeEach(() => {
-        formService.validate = jest.fn().mockReturnValue(true);
-      });
-      it('should call handle error with service call observable', fakeAsync(() => {
-        const error: OrganisationseinheitError = createOrganisationseinheitError();
-        formService.callService = jest.fn().mockReturnValue(throwError(() => error));
-
-        formService.submit().subscribe();
-        tick();
-
-        expect(formService.handleError).toHaveBeenCalledWith(error);
-      }));
-
-      it('should emit emit progress as false on error', () => {
-        const error: OrganisationseinheitError = createOrganisationseinheitError();
-        formService.callService = jest.fn().mockReturnValue(hot('a#', { a: true }, error));
-
-        const progressObservable: Observable<boolean> = formService.submit();
-
-        expect(progressObservable).toBeObservable(hot('a(b|)', { a: true, b: false }));
-      });
-
-      it('should return progress observable', () => {
-        formService.callService = jest.fn().mockReturnValue(singleCold(true));
-
-        const progressObservable: Observable<boolean> = formService.submit();
-
-        expect(progressObservable).toBeObservable(singleCold(true));
-      });
-    });
-    describe('with unsuccessful validation', () => {
-      beforeEach(() => {
-        formService.validate = jest.fn().mockReturnValue(false);
-      });
-
-      it('should return progress observable with false', async () => {
-        const progressObservable: Observable<boolean> = formService.submit();
-
-        const progress: boolean = await lastValueFrom(progressObservable);
-
-        expect(progress).toBeFalsy();
-      });
-    });
-  });
-
-  describe('validate', () => {
-    const hasIdMissingError = () =>
-      formService.form.hasError(
-        OrganisationseinheitErrorType.ID_MISSING,
-        OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD,
-      );
-    describe('without organisationeinheitIds', () => {
-      beforeEach(() => {
-        formService.form.setValue({
-          [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD]: organisationseinheit.name,
-          [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD]: ',',
-        });
-      });
-
-      it('should set id-missing error', () => {
-        formService.validate();
-
-        expect(hasIdMissingError()).toBeTruthy();
-      });
-      it('should be invalid', () => {
-        const valid: boolean = formService.validate();
-
-        expect(valid).toBeFalsy();
-      });
-    });
-    describe('with organisationeinheitIds', () => {
-      it('should not set error', () => {
-        formService.validate();
-
-        expect(hasIdMissingError()).toBeFalsy();
-      });
-
-      it('should be valid', () => {
-        const valid: boolean = formService.validate();
-
-        expect(valid).toBeTruthy();
-      });
-    });
-  });
-
-  describe('call service', () => {
-    it('should use create if is not patch', () => {
-      formService.isPatch = jest.fn().mockReturnValue(false);
-      formService.create = jest.fn().mockReturnValue(singleHot(true));
-
-      const progressObservable: Observable<boolean> = formService.callService();
-
-      expect(progressObservable).toBeObservable(singleHot(true));
-    });
-
-    it('should use save if is patch', () => {
-      formService.isPatch = jest.fn().mockReturnValue(true);
-      formService.save = jest.fn().mockReturnValue(singleHot(true));
-
-      const progressObservable: Observable<boolean> = formService.callService();
-
-      expect(progressObservable).toBeObservable(singleHot(true));
-    });
-  });
-
-  describe('is patch', () => {
-    it('should return false without source', () => {
-      formService.source = null;
-
-      const isPatch: boolean = formService.isPatch();
-
-      expect(isPatch).toBeFalsy();
-    });
-    it('should return true with source', () => {
-      formService.source = createOrganisationseinheit();
-
-      const isPatch: boolean = formService.isPatch();
-
-      expect(isPatch).toBeTruthy();
-    });
-  });
-
-  describe('create', () => {
-    it('should call create organisationseinheit', () => {
-      formService.create();
-
-      expect(organisationseinheitService.create).toHaveBeenCalledWith({
-        name: organisationseinheit.name,
-        organisationseinheitIds: organisationseinheit.organisationseinheitIds,
-      });
-    });
-
-    it('should call create organisationseinheit with empty form', () => {
-      formService.form.setValue({
-        [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD]: null,
-        [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD]: null,
-      });
-      formService.create();
-
-      expect(organisationseinheitService.create).toHaveBeenCalledWith({
-        name: '',
-        organisationseinheitIds: [],
-      });
-    });
-
-    it('should return progress observable', () => {
-      organisationseinheitService.create.mockReturnValue(singleCold(true));
-
-      const progressObservable: Observable<boolean> = formService.create();
-
-      expect(progressObservable).toBeObservable(singleCold(true));
-    });
-  });
-
-  describe('save', () => {
-    it('should call save organisationseinheit', () => {
-      formService.source = createOrganisationseinheit();
-
-      formService.save();
-
-      expect(organisationseinheitService.save).toHaveBeenCalledWith({
-        id: formService.source.id,
-        name: organisationseinheit.name,
-        organisationseinheitIds: organisationseinheit.organisationseinheitIds,
-      });
-    });
-
-    it('should call save organisationseinheit with empty form', () => {
-      formService.source = createOrganisationseinheit();
-      formService.form.setValue({
-        [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD]: null,
-        [OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD]: null,
-      });
-      formService.save();
-
-      expect(organisationseinheitService.save).toHaveBeenCalledWith({
-        id: formService.source.id,
-        name: '',
-        organisationseinheitIds: [],
-      });
-    });
-
-    it('should return progress observable', () => {
-      organisationseinheitService.save.mockReturnValue(singleCold(true));
-
-      const progressObservable: Observable<boolean> = formService.save();
-
-      expect(progressObservable).toBeObservable(singleCold(true));
-    });
-  });
-
-  describe('handle error', () => {
-    it.each([OrganisationseinheitErrorType.NAME_CONFLICT, OrganisationseinheitErrorType.NAME_MISSING])(
-      'should set error on name field on %s',
-      (type: OrganisationseinheitErrorType) => {
-        const error: OrganisationseinheitError = {
-          ...createOrganisationseinheitError(),
-          errorType: type,
-        };
-
-        formService.handleError(error);
-        const errorMessage = formService.form.getError(type, OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD);
-        expect(errorMessage).toEqual(getOrganisationseinheitErrorMessage(error));
-      },
-    );
-
-    it('should not set error on name field for unknown errors', () => {
-      const unknownError: OrganisationseinheitError = createOrganisationseinheitError(undefined);
-
-      formService.handleError(unknownError);
-
-      expect(formService.form.errors).toBeNull();
-    });
-  });
-
-  describe('patch', () => {
-    const organisationseinheit: Organisationseinheit = createOrganisationseinheit();
-
-    it('should reset', () => {
-      formService.reset = jest.fn();
-
-      formService.patch(organisationseinheit);
-
-      expect(formService.reset).toHaveBeenCalled();
-    });
-
-    it('should set source', () => {
-      formService.patch(organisationseinheit);
-
-      expect(formService.source).toBe(organisationseinheit);
-    });
-
-    it('should set name', () => {
-      formService.patch(organisationseinheit);
-
-      const formControl: AbstractControl = formService.form.get(OrganisationseinheitFormService.ORGANISATIONSEINHEIT_NAME_FIELD);
-      expect(formControl.value).toEqual(organisationseinheit.name);
-    });
-
-    it('should set organisationseinheitIds', () => {
-      formService.patch(organisationseinheit);
-
-      const formControl: AbstractControl = formService.form.get(OrganisationseinheitFormService.ORGANISATIONSEINHEIT_IDS_FIELD);
-      expect(formControl.value).toEqual(organisationseinheit.organisationseinheitIds.join(', '));
-    });
-  });
-
-  describe('split organisationseinheitIds by comma', () => {
-    it('should return', () => {
-      const organisationseinheitIds: string[] = formService.splitOrganisationseinheitIds('123, 555 ,  666');
-
-      expect(organisationseinheitIds).toEqual(['123', '555', '666']);
-    });
-
-    it('should filter empty organisationseinheitIds', () => {
-      const organisationseinheitIds: string[] = formService.splitOrganisationseinheitIds(',55,,66,');
-
-      expect(organisationseinheitIds).toEqual(['55', '66']);
-    });
-  });
-
-  describe('reset', () => {
-    it('should set source to null', () => {
-      formService.form.reset = jest.fn();
-
-      formService.reset();
-
-      expect(formService.source).toBeNull();
-    });
-
-    it('should call form reset', () => {
-      formService.form.reset = jest.fn();
-
-      formService.reset();
-
-      expect(formService.form.reset).toHaveBeenCalled();
-    });
-
-    it('should mark as untouched', () => {
-      formService.patch(organisationseinheit);
-
-      expect(formService.form.untouched).toBeTruthy();
-    });
-  });
-
-  describe('is invalid', () => {
-    it('should return true', () => {
-      formService.form.setErrors({ some: 'message' });
-
-      const invalid: boolean = formService.isInvalid();
-
-      expect(invalid).toBeTruthy();
-    });
-
-    it('should return false', () => {
-      const invalid: boolean = formService.isInvalid();
-
-      expect(invalid).toBeFalsy();
-    });
-  });
-});
-
-function mockResourceService<T>(service: Type<T>): Mock<T> {
-  return <Mock<T>>{ ...mock(service), create: jest.fn(), save: jest.fn() };
-}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.html b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.html
index 35f04a2f2e65d9cd6354ccc65e4ebe980c7ad8bb..a42709e0e2447833b65c7c6b658cbd2bc56b6b15 100644
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.html
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.html
@@ -1,54 +1,29 @@
-<ng-container *ngIf="organisationseinheitItems.resource">
-  <table
-    *ngIf="organisationseinheitItems.resource.length; else emptyMessage"
-    aria-label="Keycloak-Gruppen mit OrganisationseinheitIDs"
-    class="mb-2 mt-2 table-fixed"
-    data-test-id="organisationseinheit-table"
+<ods-list *ngIf="organisationsEinheitResources.length > 0" data-test-id="organisations-einheit-list">
+  <ods-list-item
+    *ngFor="let organisationsEinheitResource of organisationsEinheitResources"
+    [routerLink]="getEncodedSelfLink(organisationsEinheitResource)"
+    [class.text-red-500]="syncResultIsNotOk(organisationsEinheitResource)"
+    data-test-id="organisations-einheit-list-item"
   >
-    <tr class="invisible">
-      <th scope="col">Name</th>
-      <th scope="col">Attribute</th>
-    </tr>
-    <tr *ngFor="let organisationseinheit of organisationseinheitItems.resource" [id]="organisationseinheit.id">
-      <td
-        [attr.data-test-id]="
-          'organisationseinheit-name-' + organisationseinheit.id | convertForDataTest
-        "
-        class="w-96 border border-slate-500 p-2 font-bold"
-      >
-        {{ organisationseinheit.name }}
-      </td>
-      <td
-        [attr.data-test-id]="
-          'organisationseinheit-attr-' + organisationseinheit.id | convertForDataTest
-        "
-        class="w-96 border border-slate-500 p-2"
-      >
-        OrganisationseinheitID: {{ organisationseinheit.organisationseinheitIds.join(', ') }}
-        <admin-more-menu class="float-right">
-          <admin-more-item-button
-            (clickEmitter)="editOrganisationseinheit.emit(organisationseinheit)"
-            more-menu-item
-            [attr.data-test-id]="
-              'organisationseinheit-edit-' + organisationseinheit.id | convertForDataTest
-            "
-            label="Bearbeiten"
-          ></admin-more-item-button>
-          <admin-more-item-button
-            (clickEmitter)="deleteOrganisationseinheit.emit(organisationseinheit)"
-            more-menu-item
-            [attr.data-test-id]="
-              'organisationseinheit-delete-' + organisationseinheit.id | convertForDataTest
-            "
-            label="Löschen"
-          ></admin-more-item-button>
-        </admin-more-menu>
-      </td>
-    </tr>
-  </table>
-  <ng-template #emptyMessage
-    ><span data-test-id="organisationseinheit-empty-message" class="mb-2 mt-2 block italic"
-      >Keine Organisationseinheiten vorhanden.</span
-    >
-  </ng-template>
-</ng-container>
+    <dl class="flex-1 basis-3/4 font-semibold" [class.pl-4]="organisationsEinheitResource.isChild">
+      <dt class="sr-only">Name</dt>
+      <dd data-test-id="organisations-einheit-name">{{ organisationsEinheitResource.name }}</dd>
+    </dl>
+
+    <dl class="flex-1 basis-3/12">
+      <dt class="sr-only">Organisationseinheit-ID</dt>
+      <dd data-test-id="organisations-einheit-id">{{ organisationsEinheitResource.organisationsEinheitId }}</dd>
+    </dl>
+
+    <dl class="flex-1 basis-1/12">
+      <dt class="sr-only">Synchronisationsergebnis</dt>
+      <dd class="mt-1">
+        <ods-exclamation-icon
+          *ngIf="syncResultIsNotOk(organisationsEinheitResource)"
+          matTooltip="Organisationseinheit wurde nicht in den PVOG-Daten gefunden."
+          size="small"
+        />
+      </dd>
+    </dl>
+  </ods-list-item>
+</ods-list>
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.spec.ts
index 53a1347003495d3b5501794c11b04af3f60008c7..fa4d2943bd5e3e46e03c4d532379ac3a077290c9 100644
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.spec.ts
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.spec.ts
@@ -1,48 +1,42 @@
+import { AdminOrganisationsEinheitResource, AdminOrganisationsEinheitSyncResult } from '@admin-client/admin-settings';
+import { ConvertForDataTestPipe } from '@alfa-client/tech-shared';
 import {
-  ConvertForDataTestPipe,
-  StateResource,
-  convertForDataTest,
-  createStateResource,
-} from '@alfa-client/tech-shared';
-import {
-  dispatchEventFromFixture,
   existsAsHtmlElement,
   getElementFromFixture,
+  getElementsFromFixture,
+  mock,
   notExistsAsHtmlElement,
 } from '@alfa-client/test-utils';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MatTooltipModule } from '@angular/material/tooltip';
+import { ActivatedRoute } from '@angular/router';
+import { ResourceUri } from '@ngxp/rest';
+import { ExclamationIconComponent, ListComponent, ListItemComponent } from '@ods/system';
 import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
-import { MockComponent } from 'ng-mocks';
-import { createOrganisationseinheit } from '../../../../../test/user/user';
-import { MoreItemButtonComponent } from '../../../shared/more-menu/more-item-button/more-item-button.component';
-import { MoreMenuComponent } from '../../../shared/more-menu/more-menu.component';
-import { Organisationseinheit } from '../../../user/user.model';
-import { OrganisationseinheitListComponent } from './organisationseinheit-list.component';
-
-describe('OrganisationseinheitListComponent', () => {
-  let component: OrganisationseinheitListComponent;
-  let fixture: ComponentFixture<OrganisationseinheitListComponent>;
-
-  const emptyMessageSelector: string = getDataTestIdOf('organisationseinheit-empty-message');
-  const tableSelector: string = getDataTestIdOf('organisationseinheit-table');
-
-  const organisationseinheitElementSelector = (
-    organisationseinheit: Organisationseinheit,
-    cell: string,
-  ) =>
-    getDataTestIdOf(convertForDataTest(`organisationseinheit-${cell}-${organisationseinheit.id}`));
+import { MockModule } from 'ng-mocks';
+import { createAdminOrganisationsEinheitResource } from '../../../../../test/organisations-einheit/organisations-einheit';
+import { OrganisationsEinheitListComponent } from './organisationseinheit-list.component';
+
+describe('OrganisationsEinheitListComponent', () => {
+  let component: OrganisationsEinheitListComponent;
+  let fixture: ComponentFixture<OrganisationsEinheitListComponent>;
+
+  const listSelector: string = getDataTestIdOf('organisations-einheit-list');
+  const listItemSelector: string = getDataTestIdOf('organisations-einheit-list-item');
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      declarations: [
-        OrganisationseinheitListComponent,
-        ConvertForDataTestPipe,
-        MockComponent(MoreMenuComponent),
-        MockComponent(MoreItemButtonComponent),
+      providers: [
+        {
+          provide: ActivatedRoute,
+          useValue: mock(ActivatedRoute),
+        },
       ],
+      declarations: [OrganisationsEinheitListComponent, ConvertForDataTestPipe, MockModule(MatTooltipModule)],
+      imports: [ListComponent, ListItemComponent, ExclamationIconComponent],
     }).compileComponents();
 
-    fixture = TestBed.createComponent(OrganisationseinheitListComponent);
+    fixture = TestBed.createComponent(OrganisationsEinheitListComponent);
     component = fixture.componentInstance;
     fixture.detectChanges();
   });
@@ -51,104 +45,127 @@ describe('OrganisationseinheitListComponent', () => {
     expect(component).toBeTruthy();
   });
 
-  describe('table rows', () => {
-    describe('without organisationseinheit items', () => {
-      it('should show empty message', () => {
-        existsAsHtmlElement(fixture, emptyMessageSelector);
-      });
-      it('should not show table', () => {
-        notExistsAsHtmlElement(fixture, tableSelector);
-      });
-    });
+  describe('input', () => {
+    describe('organisationsEinheitResources', () => {
+      const organisationsEinheitResource: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource(
+        AdminOrganisationsEinheitSyncResult.NAME_MISMATCH,
+      );
 
-    describe('with organisationseinheit items', () => {
-      const organisationseinheitItems: StateResource<Organisationseinheit[]> = createStateResource([
-        createOrganisationseinheit(),
-        createOrganisationseinheit(),
-      ]);
       beforeEach(() => {
-        component.organisationseinheitItems = organisationseinheitItems;
+        component.organisationsEinheitResources = [organisationsEinheitResource];
         fixture.detectChanges();
       });
 
-      it('should show table', () => {
-        existsAsHtmlElement(fixture, tableSelector);
+      it('should set organisationsEinheitResource name', () => {
+        const listItemElement: HTMLElement = getElementFromFixture(fixture, listItemSelector);
+        const nameElement: Element = listItemElement.querySelector('[data-test-id="organisations-einheit-name"]');
+
+        expect(nameElement.textContent).toBe(organisationsEinheitResource.name);
       });
-      it('should not show empty message', () => {
-        notExistsAsHtmlElement(fixture, emptyMessageSelector);
+
+      it('should set organisationsEinheitResource organisationsEinheitId', () => {
+        const listItemElement: HTMLElement = getElementFromFixture(fixture, listItemSelector);
+        const idElement: Element = listItemElement.querySelector('[data-test-id="organisations-einheit-id"]');
+
+        expect(idElement.textContent).toBe(organisationsEinheitResource.organisationsEinheitId);
       });
 
-      it('should show rows in order', () => {
-        const tableElement: HTMLTableElement = getElementFromFixture(fixture, tableSelector);
-        const rows: HTMLTableRowElement[] = Array.from(tableElement.querySelectorAll('tr[id]'));
-        const rowIds: string[] = rows.map((row) => row.id);
+      it('should set exclamation icon', () => {
+        const listItemElement: HTMLElement = getElementFromFixture(fixture, listItemSelector);
+        const iconElement: Element = listItemElement.querySelector('ods-exclamation-icon');
+
+        expect(iconElement).toBeTruthy();
+      });
+    });
+  });
 
-        expect(rowIds).toEqual(
-          organisationseinheitItems.resource.map(
-            (organisationseinheit: Organisationseinheit) => organisationseinheit.id,
-          ),
+  describe('component', () => {
+    describe('moveChildrenIntoParentLevel', () => {
+      it('should move children one level up', () => {
+        const childList: AdminOrganisationsEinheitResource[] = [
+          createAdminOrganisationsEinheitResource(),
+          createAdminOrganisationsEinheitResource(),
+        ];
+        const item1: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource();
+        const item2: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource();
+        item2['_embedded'] = { childList };
+        component.organisationsEinheitResources = [item1, item2];
+
+        expect(component.organisationsEinheitResources.length).toBe(4);
+      });
+
+      it('should set isChild property at moved children', () => {
+        const childList: AdminOrganisationsEinheitResource[] = [
+          createAdminOrganisationsEinheitResource(),
+          createAdminOrganisationsEinheitResource(),
+        ];
+        const item1: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource();
+        const item2: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource();
+        item2['_embedded'] = { childList };
+        component.organisationsEinheitResources = [item1, item2];
+
+        expect(component.organisationsEinheitResources[2].isChild).toBeTruthy();
+      });
+    });
+    describe('syncResultIsNotOk', () => {
+      it('should return true', () => {
+        const organisationsEinheitResource: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource(
+          AdminOrganisationsEinheitSyncResult.NAME_MISMATCH,
         );
+        const result: boolean = component.syncResultIsNotOk(organisationsEinheitResource);
+
+        expect(result).toBeTruthy();
       });
 
-      it.each(organisationseinheitItems.resource)(
-        'should show name of organisationseinheit %#',
-        (organisationseinheit: Organisationseinheit) => {
-          const nameTableCell = getElementFromFixture(
-            fixture,
-            organisationseinheitElementSelector(organisationseinheit, 'name'),
-          );
+      it('should return false', () => {
+        const organisationsEinheitResource: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource(
+          AdminOrganisationsEinheitSyncResult.OK,
+        );
+        const result: boolean = component.syncResultIsNotOk(organisationsEinheitResource);
 
-          expect(nameTableCell.textContent.trim()).toBe(organisationseinheit.name);
-        },
-      );
+        expect(result).toBeFalsy();
+      });
+    });
 
-      it.each(organisationseinheitItems.resource)(
-        'should show organisationseinheitId of organisationseinheit %#',
-        (organisationseinheit: Organisationseinheit) => {
-          const attrTableCell = getElementFromFixture(
-            fixture,
-            organisationseinheitElementSelector(organisationseinheit, 'attr'),
-          );
-
-          expect(attrTableCell.textContent.trim()).toBe(
-            `OrganisationseinheitID: ${organisationseinheit.organisationseinheitIds.join(', ')}`,
-          );
-        },
-      );
+    describe('getEncodedSelfLink', () => {
+      it('should return encoded self link', () => {
+        const organisationsEinheitResource: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource();
+        const result: ResourceUri = component.getEncodedSelfLink(organisationsEinheitResource);
+
+        expect(result).toBeDefined();
+      });
+    });
+  });
 
-      it.each(organisationseinheitItems.resource)(
-        'should emit editOrganisationseinheit %# on edit button click ',
-        (organisationseinheit: Organisationseinheit) => {
-          component.editOrganisationseinheit.emit = jest.fn();
+  describe('template', () => {
+    describe('organisationsEinheiten list', () => {
+      describe('without organisationsEinheiten', () => {
+        it('should not show list', () => {
+          notExistsAsHtmlElement(fixture, listSelector);
+        });
+      });
 
-          dispatchEventFromFixture(
-            fixture,
-            organisationseinheitElementSelector(organisationseinheit, 'edit'),
-            'clickEmitter',
-          );
+      describe('with organisationsEinheiten', () => {
+        const organisationsEinheiten: AdminOrganisationsEinheitResource[] = [
+          createAdminOrganisationsEinheitResource(),
+          createAdminOrganisationsEinheitResource(),
+        ];
 
-          expect(component.editOrganisationseinheit.emit).toHaveBeenCalledWith(
-            organisationseinheit,
-          );
-        },
-      );
+        beforeEach(() => {
+          component.organisationsEinheitResources = organisationsEinheiten;
+          fixture.detectChanges();
+        });
 
-      it.each(organisationseinheitItems.resource)(
-        'should emit deleteOrganisationseinheit %# on delete button click ',
-        (organisationseinheit: Organisationseinheit) => {
-          component.deleteOrganisationseinheit.emit = jest.fn();
+        it('should show list', () => {
+          existsAsHtmlElement(fixture, listSelector);
+        });
 
-          dispatchEventFromFixture(
-            fixture,
-            organisationseinheitElementSelector(organisationseinheit, 'delete'),
-            'clickEmitter',
-          );
+        it('should show rows', () => {
+          const rows = getElementsFromFixture(fixture, listItemSelector);
 
-          expect(component.deleteOrganisationseinheit.emit).toHaveBeenCalledWith(
-            organisationseinheit,
-          );
-        },
-      );
+          expect(rows.length).toEqual(2);
+        });
+      });
     });
   });
 });
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.ts
index 39b105cb05759aad5be906fb7b78e7b0b167dcb6..aab7414ed051b840b30523baa114828fba2a4fc6 100644
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.ts
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-container/organisationseinheit-list/organisationseinheit-list.component.ts
@@ -1,18 +1,44 @@
-import { createStateResource, StateResource } from '@alfa-client/tech-shared';
-import { Component, EventEmitter, Input, Output } from '@angular/core';
-import { Organisationseinheit } from '../../../user/user.model';
+import { AdminOrganisationsEinheitResource, AdminOrganisationsEinheitSyncResult } from '@admin-client/admin-settings';
+import { encodeUrlForEmbedding } from '@alfa-client/tech-shared';
+import { Component, Input } from '@angular/core';
+import { ResourceUri, getLink } from '@ngxp/rest';
+import { OrganisationsEinheitLinkRel } from '../../organisations-einheit.linkrel';
 
 @Component({
   selector: 'admin-organisationseinheit-list',
   templateUrl: './organisationseinheit-list.component.html',
 })
-export class OrganisationseinheitListComponent {
+export class OrganisationsEinheitListComponent {
+  private _organisationsEinheitResources: AdminOrganisationsEinheitResource[] = [];
+
   @Input()
-  organisationseinheitItems: StateResource<Organisationseinheit[]> = createStateResource([]);
+  public get organisationsEinheitResources(): AdminOrganisationsEinheitResource[] {
+    return this._organisationsEinheitResources;
+  }
+
+  public set organisationsEinheitResources(list: AdminOrganisationsEinheitResource[]) {
+    this.moveChildrenIntoParentLevel(list);
+  }
+
+  moveChildrenIntoParentLevel(list: AdminOrganisationsEinheitResource[]): void {
+    list.forEach((parent) => {
+      this._organisationsEinheitResources.push(parent);
+
+      if (parent._embedded && Array.isArray(parent._embedded.childList)) {
+        parent._embedded.childList.forEach((child: AdminOrganisationsEinheitResource) => {
+          child.isChild = true;
+          this._organisationsEinheitResources.push(child);
+        });
+      }
+    });
+  }
 
-  @Output()
-  editOrganisationseinheit: EventEmitter<Organisationseinheit> = new EventEmitter();
+  syncResultIsNotOk(organisationsEinheitResource: AdminOrganisationsEinheitResource): boolean {
+    return organisationsEinheitResource.syncResult !== AdminOrganisationsEinheitSyncResult.OK;
+  }
 
-  @Output()
-  deleteOrganisationseinheit: EventEmitter<Organisationseinheit> = new EventEmitter();
+  getEncodedSelfLink(organisationsEinheitResource: AdminOrganisationsEinheitResource): ResourceUri {
+    const resourceUri: ResourceUri = getLink(organisationsEinheitResource, OrganisationsEinheitLinkRel.SELF).href;
+    return encodeUrlForEmbedding(resourceUri);
+  }
 }
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component.html b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..f31e92e3c557900090fce127c00d206ce8f19d51
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component.html
@@ -0,0 +1,8 @@
+<h1 class="heading-1" data-test-id="organisations-form-container-headline">
+    {{ (organisationsEinheitStateResource$ | async)?.resource?.name }}
+</h1>
+
+<admin-organisationseinheit-form
+  [organisationsEinheitStateResource]="organisationsEinheitStateResource$ | async"
+  data-test-id="organisations-form"
+/>
\ No newline at end of file
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c0854bf5313ee7fc349c7049dc8f7befe498c869
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component.spec.ts
@@ -0,0 +1,73 @@
+import { AdminOrganisationsEinheitResource, OrganisationsEinheitFormContainerComponent } from '@admin-client/admin-settings';
+import { StateResource, createStateResource } from '@alfa-client/tech-shared';
+import { Mock, existsAsHtmlElement, mock } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MockComponent } from 'ng-mocks';
+import { of } from 'rxjs';
+import { getDataTestIdOf } from '../../../../../../tech-shared/test/data-test';
+import { createAdminOrganisationsEinheitResource } from '../../../../test/organisations-einheit/organisations-einheit';
+import { OrganisationsEinheitService } from '../organisationseinheit.service';
+import { OrganisationsEinheitFormComponent } from './organisationseinheit-form/organisationseinheit-form.component';
+
+describe('OrganisationsEinheitFormContainerComponent', () => {
+  let component: OrganisationsEinheitFormContainerComponent;
+  let fixture: ComponentFixture<OrganisationsEinheitFormContainerComponent>;
+
+  const organisationsEinheitService: Mock<OrganisationsEinheitService> = mock(OrganisationsEinheitService);
+
+  const organisationsEinheitStateResource = createStateResource(createAdminOrganisationsEinheitResource());
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [OrganisationsEinheitFormContainerComponent, MockComponent(OrganisationsEinheitFormComponent)],
+      providers: [{ provide: OrganisationsEinheitService, useValue: organisationsEinheitService }],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(OrganisationsEinheitFormContainerComponent);
+    component = fixture.componentInstance;
+
+    organisationsEinheitService.get = jest.fn().mockReturnValue(of(organisationsEinheitStateResource));
+
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('component', () => {
+    describe('ngOnInit', () => {
+      it('should call organisationsEinheitService get', () => {
+        component.ngOnInit();
+
+        component.organisationsEinheitStateResource$.subscribe(() => {
+          expect(organisationsEinheitService.get).toHaveBeenCalled();
+        });
+      });
+
+      it('should set organisationsEinheitStateResource', () => {
+        component.ngOnInit();
+
+        component.organisationsEinheitStateResource$.subscribe(
+          (organisationsEinheitStateResource: StateResource<AdminOrganisationsEinheitResource>) => {
+            expect(organisationsEinheitStateResource).toEqual(organisationsEinheitStateResource);
+          },
+        );
+      });
+    });
+  });
+
+  describe('template', () => {
+    describe('headline', () => {
+      it('should show organisationsEinheit name', () => {
+        existsAsHtmlElement(fixture, getDataTestIdOf('organisations-form-container-headline'));
+      });
+    });
+
+    describe('organisationsEinheit form', () => {
+      it('should show organisationsEinheit form', () => {
+        existsAsHtmlElement(fixture, getDataTestIdOf('organisations-form'));
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cc46ee5d86126541187b2ebd9d41dce928d553e8
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form-container.component.ts
@@ -0,0 +1,19 @@
+import { StateResource } from '@alfa-client/tech-shared';
+import { Component, OnInit } from '@angular/core';
+import { Observable } from 'rxjs';
+import { AdminOrganisationsEinheitResource } from '../organisations-einheit.model';
+import { OrganisationsEinheitService } from '../organisationseinheit.service';
+
+@Component({
+  selector: 'admin-organisationseinheit-form-container',
+  templateUrl: './organisationseinheit-form-container.component.html',
+})
+export class OrganisationsEinheitFormContainerComponent implements OnInit {
+  organisationsEinheitStateResource$: Observable<StateResource<AdminOrganisationsEinheitResource>>;
+
+  constructor(private organisationsEinheitService: OrganisationsEinheitService) {}
+
+  ngOnInit(): void {
+    this.organisationsEinheitStateResource$ = this.organisationsEinheitService.get();
+  }
+}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.html b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..3e8708c6939b72e0796be10b943baf18bc9cf892
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.html
@@ -0,0 +1,18 @@
+<form class="form flex-col" [formGroup]="formService.form">
+    <admin-organisationseinheit-signatur class="mb-6 block" data-test-id="organisations-einheit-signatur-component" />
+
+    <ods-button-with-spinner
+      data-test-id="save-button"
+      text="Speichern"
+      [stateResource]="submitInProgress$ | async"
+      (clickEmitter)="submit()"
+    ></ods-button-with-spinner>
+
+    <span
+      *ngIf="formService.invalidEmpty"
+      data-test-id="invalid-empty-message-span"
+      class="m-2 text-red-500"
+    >
+      *Es müssen alle Felder ausgefüllt sein.
+    </span>
+</form>
\ No newline at end of file
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1976562c9a9fa7aa270e230278e4ce3093775503
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.spec.ts
@@ -0,0 +1,120 @@
+import { AdminOrganisationsEinheitResource } from '@admin-client/admin-settings';
+import { createEmptyStateResource, createStateResource, ProblemDetail } from '@alfa-client/tech-shared';
+import { existsAsHtmlElement, Mock, mock, notExistsAsHtmlElement } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { ButtonWithSpinnerComponent } from '@ods/component';
+import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
+import { MockComponent } from 'ng-mocks';
+import { of } from 'rxjs';
+import { createInvalidParam, createProblemDetail } from '../../../../../../../tech-shared/test/error';
+import { createAdminOrganisationsEinheitResource } from '../../../../../test/organisations-einheit/organisations-einheit';
+import { TextFieldComponent } from '../../../shared/text-field/text-field.component';
+import { OrganisationsEinheitService } from '../../organisationseinheit.service';
+import { OrganisationsEinheitFormComponent } from './organisationseinheit-form.component';
+import { OrganisationsEinheitSignaturComponent } from './organisationseinheit-signatur/organisationseinheit-signatur.component';
+import { OrganisationsEinheitFormService } from './organisationseinheit.formservice';
+
+describe('OrganisationsEinheitFormComponent', () => {
+  let component: OrganisationsEinheitFormComponent;
+  let fixture: ComponentFixture<OrganisationsEinheitFormComponent>;
+  let formService: OrganisationsEinheitFormService;
+
+  const organisationsEinheitService: Mock<OrganisationsEinheitService> = mock(OrganisationsEinheitService);
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [
+        OrganisationsEinheitFormComponent,
+        MockComponent(TextFieldComponent),
+        MockComponent(OrganisationsEinheitSignaturComponent),
+        MockComponent(ButtonWithSpinnerComponent),
+      ],
+      imports: [ReactiveFormsModule, FormsModule],
+      providers: [{ provide: OrganisationsEinheitService, useValue: organisationsEinheitService }],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(OrganisationsEinheitFormComponent);
+    component = fixture.componentInstance;
+    formService = component.formService;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('input', () => {
+    describe('organisationsEinheitStateResource', () => {
+      it('should return resource', () => {
+        const updateOrganisationsEinheitResourceFn: jest.SpyInstance = jest.spyOn(
+          component,
+          'updateOrganisationsEinheitResource',
+        );
+        const organisationsEinheitResource: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource();
+
+        component.organisationsEinheitStateResource = createStateResource(organisationsEinheitResource);
+
+        expect(updateOrganisationsEinheitResourceFn).toHaveBeenCalledWith(organisationsEinheitResource);
+      });
+    });
+  });
+
+  describe('component', () => {
+    describe('updateOrganisationsEinheitResource', () => {
+      it('should call formService patch', () => {
+        formService.patch = jest.fn();
+
+        const organisationsEinheitResource: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource();
+
+        component.updateOrganisationsEinheitResource(organisationsEinheitResource);
+
+        expect(formService.patch).toHaveBeenCalledWith(organisationsEinheitResource.settings);
+      });
+    });
+
+    describe('submit', () => {
+      it('should call formService submit', () => {
+        formService.submit = jest.fn().mockReturnValue(of(createEmptyStateResource()));
+
+        component.submit();
+
+        expect(formService.submit).toHaveBeenCalled();
+      });
+    });
+  });
+
+  describe('template', () => {
+    describe('organisationsEinheit signatur component', () => {
+      it('should show signatur component', () => {
+        existsAsHtmlElement(fixture, getDataTestIdOf('organisations-einheit-signatur-component'));
+      });
+    });
+
+    describe('save button', () => {
+      it('should show save button', () => {
+        existsAsHtmlElement(fixture, getDataTestIdOf('save-button'));
+      });
+    });
+
+    describe('invalid message', () => {
+      const invalidMessageSpan: string = getDataTestIdOf('invalid-empty-message-span');
+
+      it('should show if form invalidEmpty', () => {
+        const problemDetail: ProblemDetail = {
+          ...createProblemDetail(),
+          invalidParams: [{ ...createInvalidParam(), name: 'settingBody.signatur' }],
+        };
+        formService.setErrorByProblemDetail(problemDetail);
+
+        fixture.detectChanges();
+
+        existsAsHtmlElement(fixture, invalidMessageSpan);
+      });
+
+      it('should not show if form valid', () => {
+        notExistsAsHtmlElement(fixture, invalidMessageSpan);
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e23d78e48258b6444fa11e4375ce8259f46742fd
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-form.component.ts
@@ -0,0 +1,31 @@
+import { AdminOrganisationsEinheitResource } from '@admin-client/admin-settings';
+import { StateResource, createEmptyStateResource, isNotNil } from '@alfa-client/tech-shared';
+import { Component, Input } from '@angular/core';
+import { Resource } from '@ngxp/rest';
+import { Observable, of } from 'rxjs';
+import { OrganisationsEinheitFormService } from './organisationseinheit.formservice';
+
+@Component({
+  selector: 'admin-organisationseinheit-form',
+  templateUrl: './organisationseinheit-form.component.html',
+  providers: [OrganisationsEinheitFormService],
+})
+export class OrganisationsEinheitFormComponent {
+  submitInProgress$: Observable<StateResource<Resource>> = of(createEmptyStateResource<Resource>());
+
+  @Input() set organisationsEinheitStateResource(stateResource: StateResource<AdminOrganisationsEinheitResource>) {
+    this.updateOrganisationsEinheitResource(stateResource.resource);
+  }
+
+  updateOrganisationsEinheitResource(organisationsEinheitResource: AdminOrganisationsEinheitResource): void {
+    if (isNotNil(organisationsEinheitResource)) {
+      this.formService.patch(organisationsEinheitResource.settings);
+    }
+  }
+
+  constructor(public formService: OrganisationsEinheitFormService) {}
+
+  public submit(): void {
+    this.submitInProgress$ = this.formService.submit();
+  }
+}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-signatur/organisationseinheit-signatur.component.html b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-signatur/organisationseinheit-signatur.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..08db87e61bb3198d993070fdb54ab8ae5a68eb0c
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-signatur/organisationseinheit-signatur.component.html
@@ -0,0 +1,16 @@
+<form [formGroup]="formService.form" class="max-w-[960px]">
+    <h2 class="heading-2">Signatur</h2>
+    <p id="signatur-desc">
+      Diese Signatur gilt für die ausgewählte Organisationseinheit und wird bei allen Nachrichten an den Antragsteller angezeigt.
+    </p>
+    <ods-textarea-editor
+      [formControlName]="formServiceClass.ORGANISATIONSEINHEIT_SIGNATUR_FIELD"
+      [isResizable]="false"
+      [showLabel]="false"
+      data-test-id="signatur-text"
+      label="signature"
+      rows="6"
+      class="w-full"
+      aria-describedby="signatur-desc"
+    />
+</form>
\ No newline at end of file
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-signatur/organisationseinheit-signatur.component.spec.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-signatur/organisationseinheit-signatur.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..da98a3b87601a0830743d69fbe6ed99cb2325f1f
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-signatur/organisationseinheit-signatur.component.spec.ts
@@ -0,0 +1,57 @@
+import { NavigationSharedModule } from '@alfa-client/navigation-shared';
+import { getElementFromFixture, mock, useFromMock } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
+import { EffectsModule } from '@ngrx/effects';
+import { StoreModule } from '@ngrx/store';
+import { TextareaEditorComponent } from '@ods/component';
+import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
+import { MockComponent } from 'ng-mocks';
+import { OrganisationsEinheitService } from '../../../organisationseinheit.service';
+import { OrganisationsEinheitFormService } from '../organisationseinheit.formservice';
+import { OrganisationsEinheitSignaturComponent } from './organisationseinheit-signatur.component';
+
+describe('OrganisationsEinheitSignaturComponent', () => {
+  let component: OrganisationsEinheitSignaturComponent;
+  let fixture: ComponentFixture<OrganisationsEinheitSignaturComponent>;
+
+  const formService: OrganisationsEinheitFormService = new OrganisationsEinheitFormService(
+    new FormBuilder(),
+    useFromMock(mock(OrganisationsEinheitService)),
+  );
+
+  const signaturTextarea = getDataTestIdOf('signatur-text');
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ReactiveFormsModule, NavigationSharedModule, StoreModule.forRoot({}), EffectsModule.forRoot([])],
+      declarations: [OrganisationsEinheitSignaturComponent, MockComponent(TextareaEditorComponent)],
+      providers: [
+        {
+          provide: OrganisationsEinheitFormService,
+          useValue: formService,
+        },
+      ],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(OrganisationsEinheitSignaturComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('template', () => {
+    describe('ods-textarea-editor', () => {
+      describe('input', () => {
+        it('should set signatur field', () => {
+          const textAreaEditor = getElementFromFixture(fixture, signaturTextarea);
+
+          expect(textAreaEditor.getAttribute('rows')).toEqual('6');
+        });
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-signatur/organisationseinheit-signatur.component.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-signatur/organisationseinheit-signatur.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..112353d7b5cf1a613f3f81fd77662b7b11c8a2c0
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit-signatur/organisationseinheit-signatur.component.ts
@@ -0,0 +1,12 @@
+import { Component } from '@angular/core';
+import { OrganisationsEinheitFormService } from '../organisationseinheit.formservice';
+
+@Component({
+  selector: 'admin-organisationseinheit-signatur',
+  templateUrl: './organisationseinheit-signatur.component.html',
+})
+export class OrganisationsEinheitSignaturComponent {
+  protected readonly formServiceClass = OrganisationsEinheitFormService;
+
+  constructor(public formService: OrganisationsEinheitFormService) {}
+}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit.formservice.spec.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit.formservice.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..249af7021abcd360680e7c7318c2123763089d20
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit.formservice.spec.ts
@@ -0,0 +1,42 @@
+import { AdminOrganisationsEinheitResource } from '@admin-client/admin-settings';
+import { StateResource, createStateResource } from '@alfa-client/tech-shared';
+import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
+import { FormBuilder } from '@angular/forms';
+import { of } from 'rxjs';
+import { createAdminOrganisationsEinheitResource } from '../../../../../test/organisations-einheit/organisations-einheit';
+import { OrganisationsEinheitService } from '../../organisationseinheit.service';
+import { OrganisationsEinheitFormService } from './organisationseinheit.formservice';
+
+describe('OrganisationsEinheitFormService', () => {
+  let service: OrganisationsEinheitFormService;
+  let organisationsEinheitService: Mock<OrganisationsEinheitService>;
+  const formBuilder: FormBuilder = new FormBuilder();
+
+  beforeEach(() => {
+    organisationsEinheitService = mock(OrganisationsEinheitService);
+    service = new OrganisationsEinheitFormService(formBuilder, useFromMock(organisationsEinheitService));
+  });
+
+  it('should create', () => {
+    expect(service).toBeTruthy();
+  });
+
+  describe('submit', () => {
+    const organisationsEinheitResource: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource();
+
+    beforeEach(() => {
+      const stateResource: StateResource<AdminOrganisationsEinheitResource> = createStateResource(organisationsEinheitResource);
+      organisationsEinheitService.patch.mockReturnValue(of(stateResource));
+      organisationsEinheitService.get.mockReturnValue(of(stateResource));
+      service.form.setValue({
+        [OrganisationsEinheitFormService.ORGANISATIONSEINHEIT_SIGNATUR_FIELD]: organisationsEinheitResource.settings.signatur,
+      });
+    });
+
+    it('should call organisationsEinheitService patch', () => {
+      service.submit();
+
+      expect(organisationsEinheitService.patch).toHaveBeenCalledWith(organisationsEinheitResource.settings);
+    });
+  });
+});
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit.formservice.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit.formservice.ts
new file mode 100644
index 0000000000000000000000000000000000000000..82beca0dfb6fd1cb9210090f7a11cac3c2b497eb
--- /dev/null
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit-form-container/organisationseinheit-form/organisationseinheit.formservice.ts
@@ -0,0 +1,36 @@
+import { AdminOrganisationsEinheitResource } from '@admin-client/admin-settings';
+import { AbstractFormService, EMPTY_STRING, StateResource } from '@alfa-client/tech-shared';
+import { Injectable } from '@angular/core';
+import { FormControl, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
+import { Observable } from 'rxjs';
+import { OrganisationsEinheitService } from '../../organisationseinheit.service';
+
+@Injectable()
+export class OrganisationsEinheitFormService extends AbstractFormService {
+  public static readonly ORGANISATIONSEINHEIT_SIGNATUR_FIELD: string = 'signatur';
+
+  constructor(
+    formBuilder: UntypedFormBuilder,
+    private organisationsEinheitService: OrganisationsEinheitService,
+  ) {
+    super(formBuilder);
+  }
+
+  protected initForm(): UntypedFormGroup {
+    return this.formBuilder.group({
+      [OrganisationsEinheitFormService.ORGANISATIONSEINHEIT_SIGNATUR_FIELD]: new FormControl(EMPTY_STRING),
+    });
+  }
+
+  protected doSubmit(): Observable<StateResource<AdminOrganisationsEinheitResource>> {
+    return this.organisationsEinheitService.patch(this.getFormValue());
+  }
+
+  protected getPathPrefix(): string {
+    return 'settingBody';
+  }
+
+  public get invalidEmpty(): boolean {
+    return this.form.invalid;
+  }
+}
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit.service.spec.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit.service.spec.ts
index 4e16cd2a3421cac02ddcd38e472322fc5942e808..77d2d39309893316e9a99db8d6e6796fcd1a9d05 100644
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit.service.spec.ts
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit.service.spec.ts
@@ -1,48 +1,155 @@
-import { mock, Mock, useFromMock } from '@alfa-client/test-utils';
-import { createOrganisationseinheit } from '../../../test/user/user';
-import { UserRepository } from '../user/user.repository.service';
-import { OrganisationseinheitService } from './organisationseinheit.service';
+import { AdminOrganisationsEinheitListResource, AdminOrganisationsEinheitResource } from '@admin-client/admin-settings';
+import { NavigationService } from '@alfa-client/navigation-shared';
+import { StateResource, createStateResource } from '@alfa-client/tech-shared';
+import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
+import { SnackBarService } from '@alfa-client/ui';
+import { singleColdCompleted } from 'libs/tech-shared/test/marbles';
+import { Observable, of } from 'rxjs';
+import {
+  createAdminOrganisationsEinheitListResource,
+  createAdminOrganisationsEinheitResource,
+} from '../../../test/organisations-einheit/organisations-einheit';
+import { OrganisationsEinheitListResourceService } from './organisations-einheit-list-resource.service';
+import { OrganisationsEinheitResourceService } from './organisations-einheit-resource.service';
+import { OrganisationsEinheitService } from './organisationseinheit.service';
 
-describe('OrganisationseinheitService', () => {
-  let service: OrganisationseinheitService;
-  let repository: Mock<UserRepository>;
+jest.mock('./organisations-einheit-list-resource.service');
+jest.mock('./organisations-einheit-resource.service');
+jest.mock('../../../../../navigation-shared/src/lib/navigation.service');
+jest.mock('../../../../../ui/src/lib/snackbar/snackbar.service');
 
-  const organisationseinheit = createOrganisationseinheit();
+describe('OrganisationsEinheitService', () => {
+  let service: OrganisationsEinheitService;
+  let listResourceService: Mock<OrganisationsEinheitListResourceService>;
+  let resourceService: Mock<OrganisationsEinheitResourceService>;
+  let navigationService: Mock<NavigationService>;
+  let snackBarService: Mock<SnackBarService>;
 
   beforeEach(() => {
-    repository = mock(UserRepository);
-    service = new OrganisationseinheitService(useFromMock(repository));
+    listResourceService = mock(OrganisationsEinheitListResourceService);
+    resourceService = mock(OrganisationsEinheitResourceService);
+
+    navigationService = mock(NavigationService);
+    navigationService.urlChanged.mockReturnValue(of({}));
+
+    snackBarService = mock(SnackBarService);
+    service = new OrganisationsEinheitService(
+      useFromMock(listResourceService),
+      useFromMock(resourceService),
+      useFromMock(navigationService),
+      useFromMock(snackBarService),
+    );
   });
 
-  describe('getItemsFromKeycloak', () => {
-    it('should call findOrganisationseinheitItems from userRepository', () => {
-      service.getItemsFromKeycloak();
+  describe('onNavigation', () => {
+    it('should not call listResourceService select', () => {
+      service.onNavigation({});
+
+      expect(listResourceService.select).not.toHaveBeenCalled();
+    });
+
+    it('should call listResourceService select', () => {
+      service.onNavigation({ [OrganisationsEinheitService.ORGANISATIONS_EINHEIT_URL]: 'some-uri' });
 
-      expect(repository.findOrganisationseinheitItems).toHaveBeenCalled();
+      expect(listResourceService.select).toHaveBeenCalled();
+    });
+
+    it('should call getOrganisationsEinheitUrl', () => {
+      (<any>service).getOrganisationsEinheitUrl = jest.fn();
+
+      service.onNavigation({ [OrganisationsEinheitService.ORGANISATIONS_EINHEIT_URL]: 'some-uri' });
+
+      expect((<any>service).getOrganisationsEinheitUrl).toHaveBeenCalled();
     });
   });
 
-  describe('saveInKeycloak', () => {
-    it('should call saveOrganisationseinheit from userRepository', () => {
-      service.saveInKeycloak(organisationseinheit);
+  describe('getOrganisationsEinheitUrl', () => {
+    it('should call navigationService getDecodedParam', () => {
+      service.getOrganisationsEinheitUrl();
 
-      expect(repository.saveOrganisationseinheit).toHaveBeenCalledWith(organisationseinheit);
+      expect(navigationService.getDecodedParam).toHaveBeenCalled();
+    });
+
+    it('should return uri', () => {
+      navigationService.getDecodedParam.mockReturnValue('some-uri');
+
+      expect(service.getOrganisationsEinheitUrl()).toBe('some-uri');
     });
   });
 
-  describe('createInKeycloak', () => {
-    it('should call createOrganisationseinheit from userRepository', () => {
-      service.createInKeycloak(organisationseinheit);
+  describe('getList', () => {
+    const organisationsEinheitListResource: AdminOrganisationsEinheitListResource = createAdminOrganisationsEinheitListResource();
+    const organisationsEinheitStateListResource: StateResource<AdminOrganisationsEinheitListResource> =
+      createStateResource(organisationsEinheitListResource);
+
+    beforeEach(() => {
+      listResourceService.getList.mockReturnValue(of(organisationsEinheitStateListResource));
+    });
+
+    it('should call listResourceService', () => {
+      service.getList();
 
-      expect(repository.createOrganisationseinheit).toHaveBeenCalledWith(organisationseinheit);
+      expect(listResourceService.getList).toHaveBeenCalled();
+    });
+
+    it('should return value', () => {
+      const list$: Observable<StateResource<AdminOrganisationsEinheitListResource>> = service.getList();
+
+      expect(list$).toBeObservable(singleColdCompleted(organisationsEinheitStateListResource));
     });
   });
 
-  describe('deleteInKeycloak', () => {
-    it('should call deleteOrganisationseinheit from userRepository', () => {
-      service.deleteInKeycloak(organisationseinheit.id);
+  describe('get', () => {
+    const organisationsEinheitResource: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource();
+    const organisationsEinheitStateResource: StateResource<AdminOrganisationsEinheitResource> =
+      createStateResource(organisationsEinheitResource);
+
+    beforeEach(() => {
+      resourceService.get.mockReturnValue(of(organisationsEinheitStateResource));
+    });
+
+    it('should call resourceService', () => {
+      service.get();
+
+      expect(resourceService.get).toHaveBeenCalled();
+    });
+
+    it('should return value', () => {
+      const resource$: Observable<StateResource<AdminOrganisationsEinheitResource>> = service.get();
+
+      expect(resource$).toBeObservable(singleColdCompleted(organisationsEinheitStateResource));
+    });
+  });
+
+  describe('patch', () => {
+    const organisationsEinheitResource: AdminOrganisationsEinheitResource = createAdminOrganisationsEinheitResource();
+    const organisationsEinheitStateResource: StateResource<AdminOrganisationsEinheitResource> =
+      createStateResource(organisationsEinheitResource);
+
+    beforeEach(() => {
+      resourceService.patch.mockReturnValue(of(organisationsEinheitStateResource));
+    });
+
+    it('should call resourceService', () => {
+      service.patch(organisationsEinheitResource.settings).subscribe();
+
+      expect(resourceService.patch).toHaveBeenCalled();
+    });
+
+    it('should call snackBarService showInfo', () => {
+      service.patch(organisationsEinheitResource.settings).subscribe();
+
+      expect(snackBarService.showInfo).toHaveBeenCalled();
+    });
+
+    it('should return value', () => {
+      const resource$: Observable<StateResource<AdminOrganisationsEinheitResource>> = service.patch(
+        organisationsEinheitResource.settings,
+      );
 
-      expect(repository.deleteOrganisationseinheit).toHaveBeenCalledWith(organisationseinheit.id);
+      resource$.subscribe((result: StateResource<AdminOrganisationsEinheitResource>) => {
+        expect(result).toEqual(organisationsEinheitStateResource);
+      });
     });
   });
 });
diff --git a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit.service.ts b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit.service.ts
index d07d400cdb35c40955a164a99bcd66faf933b911..d20e30cc1f824e8f912a624540ff8047b3771041 100644
--- a/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit.service.ts
+++ b/alfa-client/libs/admin/settings/src/lib/organisationseinheit/organisationseinheit.service.ts
@@ -1,30 +1,81 @@
+import {
+  AdminOrganisationsEinheitListResource,
+  AdminOrganisationsEinheitResource,
+  AdminOrganisationsEinheitSettings,
+} from '@admin-client/admin-settings';
+import { NavigationService } from '@alfa-client/navigation-shared';
+import { StateResource, createEmptyStateResource, isNotUndefined } from '@alfa-client/tech-shared';
+import { SnackBarService } from '@alfa-client/ui';
 import { Injectable } from '@angular/core';
-import { Observable } from 'rxjs';
-import { KeycloakResourceService } from '../user/keycloak.resource.service';
-import { Organisationseinheit } from '../user/user.model';
-import { UserRepository } from '../user/user.repository.service';
+import { Params } from '@angular/router';
+import { ResourceUri } from '@ngxp/rest';
+import { isNil } from 'lodash-es';
+import { Observable, Subscription, startWith, tap } from 'rxjs';
+import { OrganisationsEinheitListResourceService } from './organisations-einheit-list-resource.service';
+import { OrganisationsEinheitResourceService } from './organisations-einheit-resource.service';
 
 @Injectable({
   providedIn: 'root',
 })
-export class OrganisationseinheitService extends KeycloakResourceService<Organisationseinheit> {
-  constructor(private userRepository: UserRepository) {
-    super();
+export class OrganisationsEinheitService {
+  static ORGANISATIONS_EINHEIT_URL: string = 'organisationsEinheitUrl';
+
+  private subscription: Subscription;
+
+  constructor(
+    private listResourceService: OrganisationsEinheitListResourceService,
+    private resourceService: OrganisationsEinheitResourceService,
+    private navigationService: NavigationService,
+    private snackBarService: SnackBarService,
+  ) {
+    this.listenToNavigation();
+  }
+
+  private listenToNavigation(): void {
+    this.unsubscribe();
+    this.subscription = this.navigationService.urlChanged().subscribe((params: Params) => this.onNavigation(params));
+  }
+
+  private unsubscribe(): void {
+    if (!isNil(this.subscription)) {
+      this.subscription.unsubscribe();
+    }
+  }
+
+  onNavigation(params: Params): void {
+    if (this.navigateToOrganisationsEinheitDetailPage(params)) {
+      this.listResourceService.select(this.getOrganisationsEinheitUrl());
+    }
+  }
+
+  private navigateToOrganisationsEinheitDetailPage(params: Params): boolean {
+    return isNotUndefined(params[OrganisationsEinheitService.ORGANISATIONS_EINHEIT_URL]);
+  }
+
+  getOrganisationsEinheitUrl(): ResourceUri {
+    return this.navigationService.getDecodedParam(OrganisationsEinheitService.ORGANISATIONS_EINHEIT_URL);
   }
 
-  getItemsFromKeycloak(): Observable<Organisationseinheit[]> {
-    return this.userRepository.findOrganisationseinheitItems();
+  public getList(): Observable<StateResource<AdminOrganisationsEinheitListResource>> {
+    return this.listResourceService.getList();
   }
 
-  saveInKeycloak(organisationseinheit: Organisationseinheit): Observable<void> {
-    return this.userRepository.saveOrganisationseinheit(organisationseinheit);
+  public get(): Observable<StateResource<AdminOrganisationsEinheitResource>> {
+    return this.resourceService.get();
   }
 
-  createInKeycloak(organisationseinheit: { name: string; organisationseinheitIds: string[] }): Observable<Organisationseinheit> {
-    return this.userRepository.createOrganisationseinheit(organisationseinheit);
+  public patch(
+    organisationsEinheitSettings: AdminOrganisationsEinheitSettings,
+  ): Observable<StateResource<AdminOrganisationsEinheitResource>> {
+    return this.resourceService.patch(organisationsEinheitSettings).pipe(
+      tap((stateResource: StateResource<AdminOrganisationsEinheitResource>) => this.showInfoAfterPatch(stateResource)),
+      startWith(createEmptyStateResource<AdminOrganisationsEinheitResource>(true)),
+    );
   }
 
-  deleteInKeycloak(id: string): Observable<void> {
-    return this.userRepository.deleteOrganisationseinheit(id);
+  private showInfoAfterPatch(stateResource: StateResource<AdminOrganisationsEinheitResource>) {
+    if (!stateResource.loading) {
+      this.snackBarService.showInfo('Die Signatur wurde erfolgreich gespeichert.');
+    }
   }
 }
diff --git a/alfa-client/libs/admin/settings/src/lib/user/user.model.ts b/alfa-client/libs/admin/settings/src/lib/user/user.model.ts
index 742ca490a50a84a8f9026204e573bcf729bf3c30..43f4181229bb301da6124cde831ab9f7346c5ea9 100644
--- a/alfa-client/libs/admin/settings/src/lib/user/user.model.ts
+++ b/alfa-client/libs/admin/settings/src/lib/user/user.model.ts
@@ -1,20 +1,3 @@
-export interface Organisationseinheit {
-  id: string;
-  name: string;
-  organisationseinheitIds: string[];
-}
-
-export enum OrganisationseinheitErrorType {
-  NAME_CONFLICT = 'name-conflict',
-  NAME_MISSING = 'name-missing',
-  ID_MISSING = 'id-missing',
-}
-
-export interface OrganisationseinheitError {
-  errorType: OrganisationseinheitErrorType;
-  detail: string;
-}
-
 export interface User {
   id: string;
   username: string;
diff --git a/alfa-client/libs/admin/settings/src/lib/user/user.repository.service.ts b/alfa-client/libs/admin/settings/src/lib/user/user.repository.service.ts
index 5415be30358d129923f64c6f837885a5d78e2fd4..f7da378621af67111a8ce3640a4a86e566cc1f14 100644
--- a/alfa-client/libs/admin/settings/src/lib/user/user.repository.service.ts
+++ b/alfa-client/libs/admin/settings/src/lib/user/user.repository.service.ts
@@ -1,5 +1,5 @@
 import { Injectable } from '@angular/core';
-import KcAdminClient, { NetworkError } from '@keycloak/keycloak-admin-client';
+import KcAdminClient from '@keycloak/keycloak-admin-client';
 import { TokenProvider } from '@keycloak/keycloak-admin-client/lib/client';
 import GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation';
 import MappingsRepresentation from '@keycloak/keycloak-admin-client/lib/defs/mappingsRepresentation';
@@ -7,9 +7,8 @@ import RoleRepresentation from '@keycloak/keycloak-admin-client/lib/defs/roleRep
 import UserRepresentation from '@keycloak/keycloak-admin-client/lib/defs/userRepresentation';
 import { OAuthService } from 'angular-oauth2-oidc';
 import { isNil } from 'lodash-es';
-import { Observable, OperatorFunction, catchError, forkJoin, from, map, mergeMap, throwError } from 'rxjs';
-import { Organisationseinheit, OrganisationseinheitError, User } from './user.model';
-import { KEYCLOAK_CREATE_GROUPS_ERROR_STATUS } from './user.util';
+import { Observable, forkJoin, from, map, mergeMap } from 'rxjs';
+import { User } from './user.model';
 
 @Injectable({
   providedIn: 'root',
@@ -32,69 +31,6 @@ export class UserRepository {
     };
   }
 
-  public deleteOrganisationseinheit(id: string): Observable<void> {
-    return from(this.kcAdminClient.groups.del({ id }));
-  }
-
-  public findOrganisationseinheitItems(): Observable<Organisationseinheit[]> {
-    return from(this.kcAdminClient.groups.find({ briefRepresentation: false })).pipe(
-      map((reps: GroupRepresentation[]) =>
-        reps.map((rep: GroupRepresentation) => this.mapGroupRepresentationToOrganisationseinheit(rep)),
-      ),
-    );
-  }
-
-  mapGroupRepresentationToOrganisationseinheit(group: GroupRepresentation): Organisationseinheit {
-    return {
-      id: group.id,
-      name: group.name,
-      organisationseinheitIds: group.attributes?.organisationseinheitId ?? [],
-    };
-  }
-
-  public saveOrganisationseinheit(organisationseinheit: Organisationseinheit): Observable<void> {
-    return from(
-      this.kcAdminClient.groups.update(
-        { id: organisationseinheit.id },
-        {
-          name: organisationseinheit.name,
-          attributes: { organisationseinheitId: organisationseinheit.organisationseinheitIds },
-        },
-      ),
-    ).pipe(this.rethrowMappedGroupsError());
-  }
-
-  public createOrganisationseinheit(organisationseinheit: {
-    name: string;
-    organisationseinheitIds: string[];
-  }): Observable<Organisationseinheit> {
-    return from(
-      this.kcAdminClient.groups.create({
-        name: organisationseinheit.name,
-        attributes: { organisationseinheitId: organisationseinheit.organisationseinheitIds },
-      }),
-    ).pipe(
-      map(
-        ({ id }): Organisationseinheit => ({
-          ...organisationseinheit,
-          id,
-        }),
-      ),
-      this.rethrowMappedGroupsError(),
-    );
-  }
-
-  rethrowMappedGroupsError<T>(): OperatorFunction<T, T> {
-    return catchError((err) => throwError(() => this.mapCreateGroupsNetworkError(err)));
-  }
-
-  mapCreateGroupsNetworkError(error: NetworkError): OrganisationseinheitError {
-    return {
-      errorType: KEYCLOAK_CREATE_GROUPS_ERROR_STATUS[error.response.status],
-      detail: error.responseData['errorMessage'] ?? '',
-    };
-  }
-
   public getUsers(): Observable<User[]> {
     return from(this.kcAdminClient.users.find()).pipe(
       map((userReps: UserRepresentation[]) => userReps.map((userReps) => this.mapToUser(userReps))),
diff --git a/alfa-client/libs/admin/settings/src/lib/user/user.repository.spec.ts b/alfa-client/libs/admin/settings/src/lib/user/user.repository.spec.ts
index ef000f8630a3fd9990283d882b023b30e253a060..812c138f9bf00724b2f260a7e3a6247b863beb3f 100644
--- a/alfa-client/libs/admin/settings/src/lib/user/user.repository.spec.ts
+++ b/alfa-client/libs/admin/settings/src/lib/user/user.repository.spec.ts
@@ -1,39 +1,23 @@
 import { Mock, mock } from '@alfa-client/test-utils';
 import { TestBed, fakeAsync, tick } from '@angular/core/testing';
 import { faker } from '@faker-js/faker';
-import KcAdminClient, { NetworkError } from '@keycloak/keycloak-admin-client';
+import KcAdminClient from '@keycloak/keycloak-admin-client';
 import { TokenProvider } from '@keycloak/keycloak-admin-client/lib/client';
 import GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation';
 import MappingsRepresentation from '@keycloak/keycloak-admin-client/lib/defs/mappingsRepresentation';
-import { Groups } from '@keycloak/keycloak-admin-client/lib/resources/groups';
 import { OAuthService } from 'angular-oauth2-oidc';
-import { Observable, OperatorFunction, catchError, firstValueFrom, of, throwError } from 'rxjs';
-import {
-  createGroupRepresentation,
-  createNetworkError,
-  createOrganisationseinheit,
-  createOrganisationseinheitError,
-  createUser,
-} from '../../../test/user/user';
-import { Organisationseinheit, OrganisationseinheitError, OrganisationseinheitErrorType, User } from './user.model';
+import { createUser } from '../../../test/user/user';
+import { User } from './user.model';
 import { UserRepository } from './user.repository.service';
 
 describe('UserRepository', () => {
   const accessToken: string = faker.random.alphaNumeric(40);
-  const error: OrganisationseinheitError = createOrganisationseinheitError();
-  const networkError: NetworkError = createNetworkError(400, '');
 
   let repository: UserRepository;
 
   let kcAdminClient: Mock<KcAdminClient>;
   let oAuthService: Mock<OAuthService>;
 
-  const mockGroupsFunc = (groupsKey: keyof Groups, implementation: jest.Mock) => {
-    kcAdminClient.groups = <any>{
-      [groupsKey]: implementation,
-    };
-  };
-
   beforeEach(() => {
     kcAdminClient = mock(KcAdminClient);
     oAuthService = mock(OAuthService);
@@ -59,257 +43,6 @@ describe('UserRepository', () => {
     });
   });
 
-  describe('map organisationseinheit representation', () => {
-    const expectedOrganisationseinheit: Organisationseinheit = createOrganisationseinheit();
-
-    it('should map field "id"', () => {
-      const organisationseinheit: Organisationseinheit = repository.mapGroupRepresentationToOrganisationseinheit({
-        id: expectedOrganisationseinheit.id,
-      });
-
-      expect(organisationseinheit.id).toEqual(expectedOrganisationseinheit.id);
-    });
-
-    it('should map field "name"', () => {
-      const organisationseinheit: Organisationseinheit = repository.mapGroupRepresentationToOrganisationseinheit({
-        name: expectedOrganisationseinheit.name,
-      });
-
-      expect(organisationseinheit.name).toEqual(expectedOrganisationseinheit.name);
-    });
-
-    it('should map field "organisationseinheitIds"', () => {
-      const organisationseinheit: Organisationseinheit = repository.mapGroupRepresentationToOrganisationseinheit({
-        attributes: {
-          organisationseinheitId: expectedOrganisationseinheit.organisationseinheitIds,
-        },
-      });
-
-      expect(organisationseinheit.organisationseinheitIds).toEqual(expectedOrganisationseinheit.organisationseinheitIds);
-    });
-
-    it('should map missing organisationseinheitIds to empty list', () => {
-      const organisationseinheit: Organisationseinheit = repository.mapGroupRepresentationToOrganisationseinheit({});
-
-      expect(organisationseinheit.organisationseinheitIds).toEqual([]);
-    });
-  });
-
-  describe('find organisationseinheitItems', () => {
-    const organisationseinheitItems: Organisationseinheit[] = [
-      createOrganisationseinheit(),
-      createOrganisationseinheit(),
-      createOrganisationseinheit(),
-    ];
-
-    const groupReps: GroupRepresentation[] = organisationseinheitItems.map(createGroupRepresentation);
-
-    it('should return mapped organisationseinheit search result', async () => {
-      const findMock: jest.Mock = jest.fn().mockReturnValue(Promise.resolve(groupReps));
-      mockGroupsFunc('find', findMock);
-
-      const groupsResult: Organisationseinheit[] = await firstValueFrom(repository.findOrganisationseinheitItems());
-
-      expect(groupsResult).toEqual(groupsResult);
-    });
-
-    it('should call with brief representation', fakeAsync(() => {
-      const findMock: jest.Mock = jest.fn().mockReturnValue(Promise.resolve(groupReps));
-      mockGroupsFunc('find', findMock);
-
-      repository.findOrganisationseinheitItems().subscribe();
-      tick();
-
-      expect(findMock).toHaveBeenCalledWith({ briefRepresentation: false });
-    }));
-  });
-
-  describe('save organisationseinheit', () => {
-    const saveGroup: Organisationseinheit = createOrganisationseinheit();
-
-    it('should call kcAdminClient.groups.save', async () => {
-      const updateMock: jest.Mock = jest.fn(() => of(null));
-      mockGroupsFunc('update', updateMock);
-
-      await firstValueFrom(repository.saveOrganisationseinheit(saveGroup));
-
-      expect(updateMock).toHaveBeenCalledWith(
-        { id: saveGroup.id },
-        {
-          name: saveGroup.name,
-          attributes: {
-            organisationseinheitId: saveGroup.organisationseinheitIds,
-          },
-        },
-      );
-    });
-
-    it('should return organisationseinheit save observable', async () => {
-      const updateMock: jest.Mock = jest.fn(() => Promise.resolve(null));
-      mockGroupsFunc('update', updateMock);
-
-      const voidResult = await firstValueFrom(repository.saveOrganisationseinheit(saveGroup));
-
-      expect(voidResult).toBe(null);
-    });
-
-    it('should pipe rethrowMappedGroupsError', (done) => {
-      const updateMock: jest.Mock = jest.fn(() => Promise.reject(networkError));
-      mockGroupsFunc('update', updateMock);
-      repository.rethrowMappedGroupsError = jest.fn().mockReturnValue(catchError(() => throwError(() => error)));
-
-      repository.saveOrganisationseinheit(saveGroup).subscribe({
-        error: (err) => {
-          expect(err).toBe(error);
-          done();
-        },
-      });
-    });
-  });
-
-  describe('create organisationseinheit', () => {
-    const newOrganisationseinheit: Organisationseinheit = createOrganisationseinheit();
-
-    it('should call kcAdminClient.groups.create', async () => {
-      const createMock: jest.Mock = jest.fn(() => of({ id: newOrganisationseinheit.id }));
-      mockGroupsFunc('create', createMock);
-
-      await firstValueFrom(
-        repository.createOrganisationseinheit({
-          name: newOrganisationseinheit.name,
-          organisationseinheitIds: newOrganisationseinheit.organisationseinheitIds,
-        }),
-      );
-
-      expect(createMock).toHaveBeenCalledWith({
-        name: newOrganisationseinheit.name,
-        attributes: {
-          organisationseinheitId: newOrganisationseinheit.organisationseinheitIds,
-        },
-      });
-    });
-
-    it('should return mapped organisationseinheit result', async () => {
-      const createMock: jest.Mock = jest.fn(() => Promise.resolve({ id: newOrganisationseinheit.id }));
-      mockGroupsFunc('create', createMock);
-
-      const newGroupResult: Organisationseinheit = await firstValueFrom(
-        repository.createOrganisationseinheit({
-          name: newOrganisationseinheit.name,
-          organisationseinheitIds: newOrganisationseinheit.organisationseinheitIds,
-        }),
-      );
-
-      expect(newGroupResult).toEqual(newOrganisationseinheit);
-    });
-
-    it('should pipe rethrowMappedGroupsError', (done) => {
-      const createMock: jest.Mock = jest.fn(() => Promise.reject(networkError));
-      mockGroupsFunc('create', createMock);
-      repository.rethrowMappedGroupsError = jest.fn().mockReturnValue(catchError(() => throwError(() => error)));
-
-      repository
-        .createOrganisationseinheit({
-          name: newOrganisationseinheit.name,
-          organisationseinheitIds: newOrganisationseinheit.organisationseinheitIds,
-        })
-        .subscribe({
-          error: (err) => {
-            expect(err).toBe(error);
-            done();
-          },
-        });
-    });
-  });
-
-  describe('rethrow mapped groups error', () => {
-    let networkErrorObservable: Observable<never>;
-
-    beforeEach(() => {
-      repository.mapCreateGroupsNetworkError = jest.fn().mockReturnValue(error);
-      networkErrorObservable = throwError(() => networkError);
-    });
-
-    it('should throw mapped error', (done) => {
-      const rethrowOperator: OperatorFunction<never, never> = repository.rethrowMappedGroupsError();
-
-      networkErrorObservable.pipe(rethrowOperator).subscribe({
-        error: (err) => {
-          expect(err).toBe(error);
-          done();
-        },
-      });
-    });
-
-    it('should call mapCreateGroupsNetworkError', (done) => {
-      const rethrowOperator: OperatorFunction<never, never> = repository.rethrowMappedGroupsError();
-
-      networkErrorObservable.pipe(rethrowOperator).subscribe({
-        error: () => {
-          expect(repository.mapCreateGroupsNetworkError).toHaveBeenCalledWith(networkError);
-          done();
-        },
-      });
-    });
-  });
-
-  describe('map create groups network error', () => {
-    it('should interpret 409 status as name conflict', () => {
-      const keycloakError: OrganisationseinheitError = createOrganisationseinheitError(
-        OrganisationseinheitErrorType.NAME_CONFLICT,
-      );
-      const networkError: NetworkError = createNetworkError(409, keycloakError.detail);
-
-      const error: OrganisationseinheitError = repository.mapCreateGroupsNetworkError(networkError);
-
-      expect(error).toEqual(keycloakError);
-    });
-
-    it('should interpret 400 status as name missing', () => {
-      const keycloakError: OrganisationseinheitError = createOrganisationseinheitError(
-        OrganisationseinheitErrorType.NAME_MISSING,
-      );
-      const networkError: NetworkError = createNetworkError(400, keycloakError.detail);
-
-      const error: OrganisationseinheitError = repository.mapCreateGroupsNetworkError(networkError);
-
-      expect(error).toEqual(keycloakError);
-    });
-
-    it('should map missing errorMessage to empty string', () => {
-      const networkError: NetworkError = createNetworkError(500, undefined);
-
-      const error: OrganisationseinheitError = repository.mapCreateGroupsNetworkError(networkError);
-      expect(error.detail).toEqual('');
-    });
-  });
-
-  describe('delete organisationseinheit', () => {
-    const deleteOrganisationseinheit: Organisationseinheit = createOrganisationseinheit();
-
-    it('should call kcAdminClient.groups.del', async () => {
-      const delMock: jest.Mock = jest.fn(() => Promise.resolve({ id: deleteOrganisationseinheit.id }));
-      mockGroupsFunc('del', delMock);
-
-      await firstValueFrom(repository.deleteOrganisationseinheit(deleteOrganisationseinheit.id));
-
-      expect(delMock).toHaveBeenCalledWith({
-        id: deleteOrganisationseinheit.id,
-      });
-    });
-
-    it('should return void', async () => {
-      mockGroupsFunc(
-        'del',
-        jest.fn(() => Promise.resolve(null)),
-      );
-
-      const voidResult: void = await firstValueFrom(repository.deleteOrganisationseinheit(deleteOrganisationseinheit.id));
-
-      expect(voidResult).toBeNull();
-    });
-  });
-
   describe('getUsers', () => {
     const userRep: User = createUser();
     const userRepArray: User[] = [userRep, userRep, userRep];
diff --git a/alfa-client/libs/admin/settings/src/lib/user/user.util.spec.ts b/alfa-client/libs/admin/settings/src/lib/user/user.util.spec.ts
index f4d9cc168ecb9eaca45f28cead659716ff232845..7ede2e6daccb6281372e0f3a161fed776447c8bb 100644
--- a/alfa-client/libs/admin/settings/src/lib/user/user.util.spec.ts
+++ b/alfa-client/libs/admin/settings/src/lib/user/user.util.spec.ts
@@ -1,30 +1,8 @@
-import { EMPTY_STRING } from '@alfa-client/tech-shared';
-import { createOrganisationseinheitError, createUser } from '../../../test/user/user';
-import { OrganisationseinheitError, OrganisationseinheitErrorType, User } from './user.model';
-import { KEYCLOAK_ERROR_MESSAGES, getOrganisationseinheitErrorMessage, sortUsersByLastName } from './user.util';
+import { createUser } from '../../../test/user/user';
+import { User } from './user.model';
+import { sortUsersByLastName } from './user.util';
 
 describe('user util', () => {
-  describe('get organisationseinheit error message', () => {
-    it('should map known error message', () => {
-      const nameConflictError: OrganisationseinheitError = createOrganisationseinheitError(
-        OrganisationseinheitErrorType.NAME_CONFLICT,
-      );
-      const expectedMessage: string = KEYCLOAK_ERROR_MESSAGES[nameConflictError.errorType];
-
-      const message: string = getOrganisationseinheitErrorMessage(nameConflictError);
-
-      expect(message).toEqual(expectedMessage);
-    });
-
-    it('should map unknown error message to empty string', () => {
-      const nameConflictError: OrganisationseinheitError = createOrganisationseinheitError(null);
-
-      const message: string = getOrganisationseinheitErrorMessage(nameConflictError);
-
-      expect(message).toEqual(EMPTY_STRING);
-    });
-  });
-
   describe('sort users by last name', () => {
     const users: User[] = [
       { ...createUser(), lastName: 'Müller' },
diff --git a/alfa-client/libs/admin/settings/src/lib/user/user.util.ts b/alfa-client/libs/admin/settings/src/lib/user/user.util.ts
index 9878f7021e501b38d8d0938228a3c2c7c1df51b9..f801d3276c4ce3cdf05b67ab9412bcda0dde7fcd 100644
--- a/alfa-client/libs/admin/settings/src/lib/user/user.util.ts
+++ b/alfa-client/libs/admin/settings/src/lib/user/user.util.ts
@@ -1,21 +1,4 @@
-import { OrganisationseinheitError, OrganisationseinheitErrorType, User } from './user.model';
-
-export const KEYCLOAK_ERROR_MESSAGES: { [type: string]: string } = {
-  [OrganisationseinheitErrorType.NAME_CONFLICT]: 'Der Name exisitert bereits.',
-  [OrganisationseinheitErrorType.NAME_MISSING]: 'Bitte den Namen angeben.',
-  [OrganisationseinheitErrorType.ID_MISSING]: 'Bitte mindestens eine Organisationseinheit ID angeben.',
-};
-
-export const KEYCLOAK_CREATE_GROUPS_ERROR_STATUS: {
-  [status: number]: OrganisationseinheitErrorType;
-} = {
-  409: OrganisationseinheitErrorType.NAME_CONFLICT,
-  400: OrganisationseinheitErrorType.NAME_MISSING,
-};
-
-export function getOrganisationseinheitErrorMessage(error: OrganisationseinheitError): string {
-  return KEYCLOAK_ERROR_MESSAGES[error.errorType] ?? '';
-}
+import { User } from './user.model';
 
 export function sortUsersByLastName(users: User[]): User[] {
   return users.sort((a, b) => (a.lastName ?? '').localeCompare(b.lastName ?? ''));
diff --git a/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html b/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html
index c177ace12d14e3cd467b795ef256a70f1831d229..e22ebee9686297df2df289a14d42508c0d008ad7 100644
--- a/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html
+++ b/alfa-client/libs/admin/settings/src/lib/users-roles/users-roles.component.html
@@ -1,62 +1,51 @@
 <h1 class="heading-1">Benutzer & Rollen</h1>
 <ods-button-with-spinner text="Benutzer hinzufügen" class="py-8" dataTestId="add-user-button" />
-<ng-container *ngIf="users$ | async as users">
-  <ul class="divide-y divide-gray-300 rounded-md bg-background-50 text-text shadow-sm ring-1 ring-gray-300 empty:hidden">
-    <li *ngFor="let user of users.resource">
-      <a
-        href="#"
-        (click)="(false)"
-        class="flex flex-col items-start justify-between gap-6 border-primary-600/50 px-6 py-4 hover:bg-background-150 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus lg:flex-row"
-        [attr.data-test-id]="'user-entry-' + user.username"
-      >
-        <div class="flex-1 basis-1/2">
-          <div class="mb-2 flex flex-wrap items-center gap-3">
-            <h3 class="text-md font-semibold">{{ user | toUserName }}</h3>
-            <dl class="flex flex-wrap gap-2">
-              <dt class="sr-only">Rollen:</dt>
-              <dd
-                *ngFor="let role of user.roles"
-                class="inline-flex flex-shrink-0 items-center rounded-full bg-green-50 px-1.5 py-0.5 text-sm font-medium text-green-700 ring-1 ring-inset ring-green-600/20"
-              >
-                {{ role }}
-              </dd>
-            </dl>
-          </div>
+<ods-list *ngIf="users$ | async as users">
+  <ods-list-item *ngFor="let user of users.resource" [routerLink]="user.username">
+    <div class="flex-1 basis-1/2">
+      <div class="mb-2 flex flex-wrap items-center gap-3">
+        <h3 class="text-md font-semibold">{{ user | toUserName }}</h3>
+        <dl class="flex flex-wrap gap-2">
+          <dt class="sr-only">Rollen:</dt>
+          <dd
+            *ngFor="let role of user.roles"
+            class="inline-flex flex-shrink-0 items-center rounded-full bg-green-50 px-1.5 py-0.5 text-sm font-medium text-green-700 ring-1 ring-inset ring-green-600/20"
+          >
+            {{ role }}
+          </dd>
+        </dl>
+      </div>
 
-          <dl>
-            <div *ngIf="user.email" class="flex items-center gap-2">
-              <dt>
-                <span class="sr-only">E-Mail:</span>
-                <ods-mailbox-icon size="small" class="stroke-gray-600" />
-              </dt>
-              <dd>{{ user.email }}</dd>
-            </div>
-            <div class="flex items-center gap-2">
-              <dt>
-                <span class="sr-only">Benutzername:</span>
-                <ods-person-icon />
-              </dt>
-              <dd>{{ user.username }}</dd>
-            </div>
-          </dl>
+      <dl>
+        <div *ngIf="user.email" class="flex items-center gap-2">
+          <dt>
+            <span class="sr-only">E-Mail:</span>
+            <ods-mailbox-icon size="small" class="stroke-gray-600" />
+          </dt>
+          <dd>{{ user.email }}</dd>
         </div>
+        <div class="flex items-center gap-2">
+          <dt>
+            <span class="sr-only">Benutzername:</span>
+            <ods-person-icon />
+          </dt>
+          <dd>{{ user.username }}</dd>
+        </div>
+      </dl>
+    </div>
 
-        <div class="flex-1 basis-1/2">
-          <h4 class="sr-only">Zuständige Stellen</h4>
+    <div class="flex-1 basis-1/2">
+      <h4 class="sr-only">Zuständige Stellen</h4>
 
-          <ng-container *ngIf="user.groups.length > 0; else noGroups">
-            <ul class="list-outside list-disc pl-4">
-              <ng-container *ngFor="let group of user.groups | slice: 0 : GROUPS_TO_DISPLAY">
-                <li>{{ group }}</li>
-              </ng-container>
-            </ul>
-            <p *ngIf="user.groups.length > GROUPS_TO_DISPLAY" class="pl-4 text-gray-500">
-              und {{ user.groups.length - 3 }} weitere
-            </p>
+      <ng-container *ngIf="user.groups.length > 0; else noGroups">
+        <ul class="list-outside list-disc pl-4">
+          <ng-container *ngFor="let group of user.groups | slice: 0 : GROUPS_TO_DISPLAY">
+            <li>{{ group }}</li>
           </ng-container>
-          <ng-template #noGroups>keine zuständige Stelle zugewiesen</ng-template>
-        </div>
-      </a>
-    </li>
-  </ul>
-</ng-container>
+        </ul>
+        <p *ngIf="user.groups.length > GROUPS_TO_DISPLAY" class="pl-4 text-gray-500">und {{ user.groups.length - 3 }} weitere</p>
+      </ng-container>
+      <ng-template #noGroups>keine zuständige Stelle zugewiesen</ng-template>
+    </div>
+  </ods-list-item>
+</ods-list>
diff --git a/alfa-client/libs/admin/settings/test/organisations-einheit/organisations-einheit.ts b/alfa-client/libs/admin/settings/test/organisations-einheit/organisations-einheit.ts
new file mode 100644
index 0000000000000000000000000000000000000000..600e815386e1d52dce43597b5187f1310a1be713
--- /dev/null
+++ b/alfa-client/libs/admin/settings/test/organisations-einheit/organisations-einheit.ts
@@ -0,0 +1,41 @@
+import { faker } from '@faker-js/faker';
+import { times } from 'lodash-es';
+import { toResource } from '../../../../tech-shared/test/resource';
+import {
+  AdminOrganisationsEinheit,
+  AdminOrganisationsEinheitListResource,
+  AdminOrganisationsEinheitResource,
+  AdminOrganisationsEinheitSyncResult,
+} from '../../src';
+import { OrganisationsEinheitListLinkRel } from '../../src/lib/organisationseinheit/organisations-einheit.linkrel';
+
+export function createAdminOrganisationsEinheit(syncResult?: AdminOrganisationsEinheitSyncResult): AdminOrganisationsEinheit {
+  return {
+    name: faker.random.word(),
+    organisationsEinheitId: faker.random.word(),
+    syncResult: syncResult ?? AdminOrganisationsEinheitSyncResult.OK,
+    settings: {
+      signatur: faker.random.words(5),
+    },
+  };
+}
+
+export function createAdminOrganisationsEinheitResource(
+  syncResult?: AdminOrganisationsEinheitSyncResult,
+  linkRel: string[] = [],
+): AdminOrganisationsEinheitResource {
+  return toResource(createAdminOrganisationsEinheit(syncResult), linkRel);
+}
+
+export function createAdminOrganisationsEinheitResources(linkRelations: string[] = []): AdminOrganisationsEinheitResource[] {
+  return times(10, () => toResource(createAdminOrganisationsEinheit(), [...linkRelations]));
+}
+
+export function createAdminOrganisationsEinheitListResource(
+  resources?: AdminOrganisationsEinheitResource[],
+  linkRelations: string[] = [],
+): AdminOrganisationsEinheitListResource {
+  return toResource({}, [...linkRelations], {
+    [OrganisationsEinheitListLinkRel.LIST]: resources ? resources : createAdminOrganisationsEinheitResources(),
+  });
+}
diff --git a/alfa-client/libs/admin/settings/test/user/user.ts b/alfa-client/libs/admin/settings/test/user/user.ts
index 8e9c06e922483b856f0b179d14e476d7b81ddc83..275d726ad9dcdae99412a3e936cc0777dffe1197 100644
--- a/alfa-client/libs/admin/settings/test/user/user.ts
+++ b/alfa-client/libs/admin/settings/test/user/user.ts
@@ -1,12 +1,5 @@
 import { faker } from '@faker-js/faker';
-import { NetworkError } from '@keycloak/keycloak-admin-client';
-import type GroupRepresentation from '@keycloak/keycloak-admin-client/lib/defs/groupRepresentation';
-import {
-  Organisationseinheit,
-  OrganisationseinheitError,
-  OrganisationseinheitErrorType,
-  User,
-} from '../../src/lib/user/user.model';
+import { User } from '../../src/lib/user/user.model';
 
 export function createUser(): User {
   return {
@@ -19,41 +12,3 @@ export function createUser(): User {
     groups: null,
   };
 }
-
-export function createOrganisationseinheit(): Organisationseinheit {
-  return {
-    id: faker.random.alphaNumeric(16),
-    name: faker.name.jobTitle(),
-    organisationseinheitIds: [faker.random.numeric(10), faker.random.numeric(10)],
-  };
-}
-
-export function createGroupRepresentation(
-  organisationseinheit: Organisationseinheit = createOrganisationseinheit(),
-): GroupRepresentation {
-  return {
-    id: organisationseinheit.id,
-    name: organisationseinheit.name,
-    attributes: {
-      organisationseinheitId: organisationseinheit.organisationseinheitIds,
-    },
-  };
-}
-
-export function createOrganisationseinheitError(
-  errorType: OrganisationseinheitErrorType = OrganisationseinheitErrorType.NAME_MISSING,
-): OrganisationseinheitError {
-  return {
-    errorType,
-    detail: faker.lorem.sentence(10),
-  };
-}
-
-export function createNetworkError(status: number, errorMessage: string | undefined): NetworkError {
-  return new NetworkError('...', {
-    response: { status } as Response,
-    responseData: {
-      errorMessage,
-    },
-  });
-}
diff --git a/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts b/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts
index fed6b6cc56cb6ded4a3d5b9f19a68578ec28edcb..231bfb91adcc94fad96c9727f06992960376dc3f 100644
--- a/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts
+++ b/alfa-client/libs/api-root-shared/src/lib/api-root.linkrel.ts
@@ -61,4 +61,5 @@ export enum ApiRootLinkRel {
   DOCUMENTATIONS = 'documentations',
   HINTS = 'hints',
   RESOURCE = 'resource',
+  ORGANISATIONS_EINHEIT = 'organisationsEinheiten',
 }
diff --git a/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts b/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts
index 01af08536ee53c2b081a2da1a34d0823958d5e5c..282d49ecc2c827b47980b536a152681c9df26a3c 100644
--- a/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts
+++ b/alfa-client/libs/command-shared/src/lib/command-resource.service.spec.ts
@@ -42,26 +42,31 @@ describe('CommandResourceService', () => {
     repository = mock(ResourceRepository);
     commandService = mock(CommandService);
 
-    service = new CommandResourceService(
-      config,
-      useFromMock(repository),
-      useFromMock(commandService),
-    );
+    service = new CommandResourceService(config, useFromMock(repository), useFromMock(commandService));
   });
 
   it('should be created', () => {
     expect(service).toBeTruthy();
   });
 
+  describe('doSave', () => {
+    it('should throw error', () => {
+      expect(() => service.doSave(configResource, {})).toThrowError('Method not implemented.');
+    });
+  });
+
+  describe('doPatch', () => {
+    it('should throw error', () => {
+      expect(() => service.doPatch(configResource, {})).toThrowError('Method not implemented.');
+    });
+  });
+
   describe('delete', () => {
     const resourceWithDeleteLinkRel: Resource = createDummyResource([deleteLinkRel]);
-    const stateResourceWithDeleteLink: StateResource<Resource> =
-      createStateResource(resourceWithDeleteLinkRel);
+    const stateResourceWithDeleteLink: StateResource<Resource> = createStateResource(resourceWithDeleteLinkRel);
 
     beforeEach(() => {
-      commandService.createCommandByProps.mockReturnValue(
-        of(createStateResource(createCommandResource())),
-      );
+      commandService.createCommandByProps.mockReturnValue(of(createStateResource(createCommandResource())));
       service.stateResource.next(stateResourceWithDeleteLink);
     });
 
diff --git a/alfa-client/libs/command-shared/src/lib/command-resource.service.ts b/alfa-client/libs/command-shared/src/lib/command-resource.service.ts
index 9a564442fd23862a0c85f645a6a93573ddca3612..4ec5a90e60890c26a04a3fd2d8aeed14794176d4 100644
--- a/alfa-client/libs/command-shared/src/lib/command-resource.service.ts
+++ b/alfa-client/libs/command-shared/src/lib/command-resource.service.ts
@@ -11,10 +11,7 @@ import { BehaviorSubject, Observable } from 'rxjs';
 import { CommandResource, CreateCommandProps } from './command.model';
 import { CommandService } from './command.service';
 
-export class CommandResourceService<B extends Resource, T extends Resource> extends ResourceService<
-  B,
-  T
-> {
+export class CommandResourceService<B extends Resource, T extends Resource> extends ResourceService<B, T> {
   deleteStateCommandResource: BehaviorSubject<StateResource<CommandResource>> = new BehaviorSubject<
     StateResource<CommandResource>
   >(createEmptyStateResource());
@@ -31,6 +28,10 @@ export class CommandResourceService<B extends Resource, T extends Resource> exte
     throw new Error('Method not implemented.');
   }
 
+  doPatch(resource: T, toPatch: unknown): Observable<T> {
+    throw new Error('Method not implemented.');
+  }
+
   public delete(): Observable<StateResource<CommandResource>> {
     return this.commandService.createCommandByProps(this.buildDeleteCommandProps());
   }
diff --git a/alfa-client/libs/design-system/src/index.ts b/alfa-client/libs/design-system/src/index.ts
index 79ec5d05a2a170233a108690d7d7046a4dbddd7c..dae1c087a831f7b46b22c93f751404403aef90bd 100644
--- a/alfa-client/libs/design-system/src/index.ts
+++ b/alfa-client/libs/design-system/src/index.ts
@@ -38,6 +38,8 @@ export * from './lib/icons/stamp-icon/stamp-icon.component';
 export * from './lib/icons/users-icon/users-icon.component';
 export * from './lib/instant-search/instant-search/instant-search.component';
 export * from './lib/instant-search/instant-search/instant-search.model';
+export * from './lib/list/list-item/list-item.component';
+export * from './lib/list/list.component';
 export * from './lib/navbar/nav-item/nav-item.component';
 export * from './lib/navbar/navbar/navbar.component';
 export * from './lib/testbtn/testbtn.component';
diff --git a/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts b/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ecec5321cbfbc0feb43f59e6523a67612db186a3
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.spec.ts
@@ -0,0 +1,40 @@
+import { getElementFromFixture } from '@alfa-client/test-utils';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { provideRouter } from '@angular/router';
+import faker from '@faker-js/faker';
+import { getDataTestClassOf } from 'libs/tech-shared/test/data-test';
+import { ListItemComponent } from './list-item.component';
+
+describe('ListItemComponent', () => {
+  let component: ListItemComponent;
+  let fixture: ComponentFixture<ListItemComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ListItemComponent],
+      providers: [provideRouter([])],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(ListItemComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  describe('input', () => {
+    describe('routerLink', () => {
+      it('should set href attribute', () => {
+        component.routerLink = faker.system.filePath();
+        const resultingLink: string = 'http://localhost' + component.routerLink;
+        const linkElement: HTMLLinkElement = getElementFromFixture(fixture, getDataTestClassOf('list-item-link'));
+
+        fixture.detectChanges();
+
+        expect(linkElement.href).toBe(resultingLink);
+      });
+    });
+  });
+});
diff --git a/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.ts b/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..89e51332eda0375bfd8cfc77a383dca0a3f70175
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/list/list-item/list-item.component.ts
@@ -0,0 +1,21 @@
+import { CommonModule } from '@angular/common';
+import { Component, Input } from '@angular/core';
+import { RouterLink } from '@angular/router';
+
+@Component({
+  selector: 'ods-list-item',
+  standalone: true,
+  imports: [CommonModule, RouterLink],
+  template: `<li>
+    <a
+      [routerLink]="routerLink"
+      data-test-class="list-item-link"
+      class="flex flex-col items-start justify-between gap-6 border-primary-600/50 px-6 py-4 hover:bg-background-150 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus lg:flex-row"
+      ><ng-content
+    /></a>
+  </li>`,
+  styles: [':host { @apply block w-full }'],
+})
+export class ListItemComponent {
+  @Input() routerLink: string;
+}
diff --git a/alfa-client/libs/design-system/src/lib/list/list.component.spec.ts b/alfa-client/libs/design-system/src/lib/list/list.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..35076e4e0ed34c166da97e496571c43c642f14a0
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/list/list.component.spec.ts
@@ -0,0 +1,21 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ListComponent } from './list.component';
+
+describe('ListComponent', () => {
+  let component: ListComponent;
+  let fixture: ComponentFixture<ListComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ListComponent],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(ListComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/alfa-client/libs/design-system/src/lib/list/list.component.ts b/alfa-client/libs/design-system/src/lib/list/list.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c4e903c1990ebc67a3bcb51f7e3596d0391c011e
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/list/list.component.ts
@@ -0,0 +1,15 @@
+import { CommonModule } from '@angular/common';
+import { Component } from '@angular/core';
+import { ListItemComponent } from './list-item/list-item.component';
+
+@Component({
+  selector: 'ods-list',
+  standalone: true,
+  imports: [CommonModule, ListItemComponent],
+  template: `
+    <ul class="divide-y divide-gray-300 rounded-md bg-background-50 text-text shadow-sm ring-1 ring-gray-300 empty:hidden">
+      <ng-content />
+    </ul>
+  `,
+})
+export class ListComponent {}
diff --git a/alfa-client/libs/design-system/src/lib/list/list.stories.ts b/alfa-client/libs/design-system/src/lib/list/list.stories.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c3164eabfb7facd2ec68b48b1199caf8d49296fe
--- /dev/null
+++ b/alfa-client/libs/design-system/src/lib/list/list.stories.ts
@@ -0,0 +1,42 @@
+import { APP_BASE_HREF } from '@angular/common';
+import { importProvidersFrom } from '@angular/core';
+import { RouterModule } from '@angular/router';
+import { applicationConfig, moduleMetadata, type Meta, type StoryObj } from '@storybook/angular';
+import { ListItemComponent } from './list-item/list-item.component';
+import { ListComponent } from './list.component';
+
+const meta: Meta<ListComponent> = {
+  title: 'List',
+  component: ListComponent,
+  excludeStories: /.*Data$/,
+  tags: ['autodocs'],
+  decorators: [
+    applicationConfig({
+      providers: [importProvidersFrom(RouterModule.forRoot([]))],
+    }),
+    moduleMetadata({
+      imports: [ListItemComponent],
+      providers: [
+        {
+          provide: APP_BASE_HREF,
+          useValue: '/',
+        },
+      ],
+    }),
+  ],
+};
+
+export default meta;
+type Story = StoryObj<ListComponent>;
+
+export const Default: Story = {
+  args: {},
+  render: () => ({
+    template: `
+      <ods-list>
+        <ods-list-item routerLink="/pfad/1">List Item 1</ods-list-item>
+        <ods-list-item routerLink="/pfad/2">List Item 2</ods-list-item>
+        <ods-list-item routerLink="/pfad/3">List Item 3</ods-list-item>
+      </ods-list>`,
+  }),
+};
diff --git a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts
index 88cde90f95160002d9f799f93bbd318cc6b87195..220af3f589fc2bb8ad7eea2817af77a01ccf98e5 100644
--- a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts
+++ b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.spec.ts
@@ -1,8 +1,8 @@
+import { convertForDataTest, TechSharedModule } from '@alfa-client/tech-shared';
 import { getElementFromFixture, Mock, mock } from '@alfa-client/test-utils';
 import { importProvidersFrom } from '@angular/core';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { Router, RouterModule } from '@angular/router';
-import { ConvertForDataTestPipe } from 'libs/tech-shared/src/lib/pipe/convert-for-data-test.pipe';
 import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
 import { NavItemComponent } from './nav-item.component';
 
@@ -14,7 +14,7 @@ describe('NavItemComponent', () => {
 
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      imports: [ConvertForDataTestPipe, NavItemComponent],
+      imports: [NavItemComponent, TechSharedModule],
       providers: [
         {
           provide: Router,
@@ -37,21 +37,23 @@ describe('NavItemComponent', () => {
     describe('caption', () => {
       it('should set link text', () => {
         component.caption = 'Test caption';
-        fixture.detectChanges();
+        const testId: string = 'caption-' + convertForDataTest(component.caption);
 
-        const captionElement: HTMLParagraphElement = getElementFromFixture(fixture, getDataTestIdOf('link-caption'));
+        fixture.detectChanges();
 
+        const captionElement: HTMLParagraphElement = getElementFromFixture(fixture, getDataTestIdOf(testId));
         expect(captionElement.innerHTML).toBe('Test caption');
       });
     });
 
-    describe('to', () => {
+    describe('path', () => {
       it('should set href', () => {
-        component.to = '/';
-        fixture.detectChanges();
+        component.path = 'pfad';
+        const testId: string = 'link-path-' + convertForDataTest(component.path);
 
-        const linkElement: HTMLAnchorElement = getElementFromFixture(fixture, getDataTestIdOf('link-to-/'));
+        fixture.detectChanges();
 
+        const linkElement: HTMLAnchorElement = getElementFromFixture(fixture, getDataTestIdOf(testId));
         expect(linkElement).toHaveProperty('href');
       });
     });
diff --git a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts
index 67ecdbddabe3133079b97dc26c2249b62b3f5ce7..0bf2f5580404c802a94c8f25d167638a9a5bf901 100644
--- a/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts
+++ b/alfa-client/libs/design-system/src/lib/navbar/nav-item/nav-item.component.ts
@@ -8,20 +8,20 @@ import { RouterLink, RouterLinkActive } from '@angular/router';
   standalone: true,
   imports: [CommonModule, RouterLink, RouterLinkActive, TechSharedModule],
   template: `<a
-    [routerLink]="to"
+    [routerLink]="path"
     routerLinkActive="bg-selected-light border-selected"
     class="flex min-h-8 items-center gap-2 rounded-2xl border border-transparent
     px-4 py-2 outline-2 outline-offset-2 outline-focus hover:border-primary
     focus-visible:border-background-200 focus-visible:outline"
-    [attr.data-test-id]="'link-to-' + to | convertForDataTest"
+    [attr.data-test-id]="'link-path-' + path | convertForDataTest"
   >
     <ng-content select="[icon]" />
-    <p class="text-left text-sm text-text" [attr.data-test-id]="'nav-item-' + caption | convertForDataTest">{{ caption }}</p>
+    <p class="text-left text-sm text-text" [attr.data-test-id]="'caption-' + caption | convertForDataTest">{{ caption }}</p>
   </a>`,
 })
 export class NavItemComponent {
   @Input({ required: true }) caption!: string;
-  @Input() to: string;
+  @Input() path: string;
 
-  @HostBinding('attr.role') role = 'menuitem';
+  @HostBinding('attr.role') role: string = 'menuitem';
 }
diff --git a/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.stories.ts b/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.stories.ts
index fa5b213b2e0f14fe9de3643ce21e123f042df68c..8ae3842b6143820d0340035f9522a285610018d6 100644
--- a/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.stories.ts
+++ b/alfa-client/libs/design-system/src/lib/navbar/navbar/navbar.stories.ts
@@ -34,10 +34,10 @@ export const Default: Story = {
   args: {},
   render: () => ({
     template: `<ods-navbar>
-      <ods-nav-item caption="First link" to="/"><ods-office-icon icon /></ods-nav-item>
-      <ods-nav-item caption="Second link" to="/second"><ods-office-icon icon /></ods-nav-item>
+      <ods-nav-item caption="First link" path="/"><ods-office-icon icon /></ods-nav-item>
+      <ods-nav-item caption="Second link" path="/second"><ods-office-icon icon /></ods-nav-item>
       <hr />
-      <ods-nav-item caption="Third link" to="/third"><ods-office-icon icon /></ods-nav-item>
+      <ods-nav-item caption="Third link" path="/third"><ods-office-icon icon /></ods-nav-item>
     </ods-navbar>`,
   }),
 };
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.spec.ts
index 977db3428026e075b535d45b53e6cdd9865579fb..e608186534a4f3573d8a78a4fdda739926d7c7fb 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.spec.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.spec.ts
@@ -91,4 +91,56 @@ describe('ApiResourceService', () => {
       expect(service.stateResource.value).toEqual(createStateResource(loadedResource));
     }));
   });
+
+  describe('patch', () => {
+    const dummyToPatch: unknown = {};
+    const loadedResource: Resource = createDummyResource();
+
+    const resourceWithEditLinkRel: Resource = createDummyResource([editLinkRel]);
+
+    it('should call repository', fakeAsync(() => {
+      service.stateResource.next(createStateResource(resourceWithEditLinkRel));
+      repository.patch.mockReturnValue(of(loadedResource));
+
+      service.patch(dummyToPatch).subscribe();
+      tick();
+
+      const expectedSaveResourceData: SaveResourceData<Resource> = {
+        resource: resourceWithEditLinkRel,
+        linkRel: editLinkRel,
+        toSave: dummyToPatch,
+      };
+      expect(repository.patch).toHaveBeenCalledWith(expectedSaveResourceData);
+    }));
+
+    it('should return patched object', () => {
+      service.stateResource.next(createStateResource(resourceWithEditLinkRel));
+      repository.patch.mockReturnValue(singleHot(loadedResource));
+
+      const saved: Observable<StateResource<Resource>> = service.patch(dummyToPatch);
+
+      expect(saved).toBeObservable(singleCold(createStateResource(loadedResource)));
+    });
+
+    it('should call handleError', () => {
+      service.stateResource.next(createStateResource(createDummyResource([config.edit.linkRel])));
+      const errorResponse: ProblemDetail = createProblemDetail();
+      repository.patch.mockReturnValue(throwError(() => errorResponse));
+      service.handleError = jest.fn();
+
+      service.patch(<any>{}).subscribe();
+
+      expect(service.handleError).toHaveBeenCalledWith(errorResponse);
+    });
+
+    it('should update state resource subject', fakeAsync(() => {
+      service.stateResource.next(createStateResource(resourceWithEditLinkRel));
+      repository.patch.mockReturnValue(of(loadedResource));
+
+      service.patch(dummyToPatch).subscribe();
+      tick();
+
+      expect(service.stateResource.value).toEqual(createStateResource(loadedResource));
+    }));
+  });
 });
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.ts b/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.ts
index d19c4a6fdc52813b270661c560bf76bed7f3ba24..f27414058aae8584e3ce77dd8668735232c33acd 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/api-resource.service.ts
@@ -4,10 +4,7 @@ import { ResourceServiceConfig } from './resource.model';
 import { ResourceRepository } from './resource.repository';
 import { ResourceService } from './resource.service';
 
-export class ApiResourceService<B extends Resource, T extends Resource> extends ResourceService<
-  B,
-  T
-> {
+export class ApiResourceService<B extends Resource, T extends Resource> extends ResourceService<B, T> {
   constructor(
     protected config: ResourceServiceConfig<B>,
     protected repository: ResourceRepository,
@@ -22,4 +19,12 @@ export class ApiResourceService<B extends Resource, T extends Resource> extends
       toSave,
     });
   }
+
+  doPatch(resource: T, toPatch: unknown): Observable<T> {
+    return <Observable<T>>this.repository.patch({
+      resource,
+      linkRel: this.config.edit.linkRel,
+      toSave: toPatch,
+    });
+  }
 }
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts
index 9983f8acf61e11a6c642761e7b0d6e8e3351c253..a2aa79b4339145dbe72c5d3bd4b0be155a9ab354 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.spec.ts
@@ -4,29 +4,14 @@ import faker from '@faker-js/faker';
 import { Resource, ResourceUri } from '@ngxp/rest';
 import { cold } from 'jest-marbles';
 import { DummyLinkRel, DummyListLinkRel } from 'libs/tech-shared/test/dummy';
-import {
-  createDummyListResource,
-  createDummyResource,
-  createFilledDummyListResource,
-} from 'libs/tech-shared/test/resource';
+import { createDummyListResource, createDummyResource, createFilledDummyListResource } from 'libs/tech-shared/test/resource';
 import { BehaviorSubject, Observable, of } from 'rxjs';
 import { singleCold, singleHot } from '../../../test/marbles';
+import { EMPTY_ARRAY } from '../tech.util';
 import { ResourceListService } from './list-resource.service';
-import {
-  CreateResourceData,
-  LinkRelationName,
-  ListItemResource,
-  ListResourceServiceConfig,
-} from './resource.model';
+import { CreateResourceData, LinkRelationName, ListItemResource, ListResourceServiceConfig } from './resource.model';
 import { ResourceRepository } from './resource.repository';
-import {
-  ListResource,
-  StateResource,
-  createEmptyStateResource,
-  createStateResource,
-} from './resource.util';
-
-import { EMPTY_ARRAY } from '../tech.util';
+import { ListResource, StateResource, createEmptyStateResource, createStateResource } from './resource.util';
 
 import * as ResourceUtil from './resource.util';
 
@@ -42,9 +27,9 @@ describe('ListResourceService', () => {
 
   const baseResource: Resource = createDummyResource();
   const baseStateResource: StateResource<Resource> = createStateResource(baseResource);
-  const baseResourceSubj: BehaviorSubject<StateResource<Resource>> = new BehaviorSubject<
-    StateResource<Resource>
-  >(baseStateResource);
+  const baseResourceSubj: BehaviorSubject<StateResource<Resource>> = new BehaviorSubject<StateResource<Resource>>(
+    baseStateResource,
+  );
 
   beforeEach(() => {
     config = {
@@ -63,8 +48,7 @@ describe('ListResourceService', () => {
   });
 
   describe('getList', () => {
-    const listStateResource: StateResource<ListResource> =
-      createStateResource(createDummyListResource());
+    const listStateResource: StateResource<ListResource> = createStateResource(createDummyListResource());
 
     let isInvalidResourceCombinationSpy: jest.SpyInstance;
 
@@ -73,9 +57,7 @@ describe('ListResourceService', () => {
 
       service.handleNullConfigResource = jest.fn();
       service.handleChanges = jest.fn();
-      isInvalidResourceCombinationSpy = jest
-        .spyOn(ResourceUtil, 'isInvalidResourceCombination')
-        .mockReturnValue(true);
+      isInvalidResourceCombinationSpy = jest.spyOn(ResourceUtil, 'isInvalidResourceCombination').mockReturnValue(true);
     });
 
     it('should handle config resource changed', fakeAsync(() => {
@@ -104,15 +86,12 @@ describe('ListResourceService', () => {
 
       const apiRootStateResource$: Observable<StateResource<Resource>> = service.getList();
 
-      expect(apiRootStateResource$).toBeObservable(
-        cold('a', { a: createEmptyStateResource(true) }),
-      );
+      expect(apiRootStateResource$).toBeObservable(cold('a', { a: createEmptyStateResource(true) }));
     });
   });
 
   describe('handle changes', () => {
-    const listStateResource: StateResource<ListResource> =
-      createStateResource(createDummyListResource());
+    const listStateResource: StateResource<ListResource> = createStateResource(createDummyListResource());
     const changedConfigResource: Resource = createDummyResource();
 
     describe('on different config resource', () => {
@@ -127,8 +106,7 @@ describe('ListResourceService', () => {
     });
 
     describe('on same config resource', () => {
-      const listStateResource: StateResource<ListResource> =
-        createStateResource(createDummyListResource());
+      const listStateResource: StateResource<ListResource> = createStateResource(createDummyListResource());
 
       beforeEach(() => {
         service.baseResource = baseResource;
@@ -210,8 +188,7 @@ describe('ListResourceService', () => {
 
       it('should keep current current list resource on unstable state resource', () => {
         jest.spyOn(ResourceUtil, 'isStateResoureStable').mockReturnValue(false);
-        const currentListStateResource: StateResource<ListResource> =
-          createStateResource(createDummyListResource());
+        const currentListStateResource: StateResource<ListResource> = createStateResource(createDummyListResource());
         service.listResource.next(currentListStateResource);
 
         const configResuorceWithoutLink: Resource = createDummyListResource();
@@ -318,18 +295,6 @@ describe('ListResourceService', () => {
       resourceRepository.getResource.mockReturnValue(of(loadedResource));
     });
 
-    it('should throw error if listResource is not valid', () => {
-      service.listResource.next(createEmptyStateResource());
-
-      expect(() => service.select(selfHref)).toThrowError('No list resource available.');
-    });
-
-    it('should throw error if uri not exists in list resource', () => {
-      expect(() => service.select('uriNotExistsInListResource')).toThrowError(
-        'No entry match with given uri.',
-      );
-    });
-
     it('should set resource loading', () => {
       service.setSelectedResourceLoading = jest.fn();
 
@@ -375,8 +340,7 @@ describe('ListResourceService', () => {
 
   describe('getSelected', () => {
     it('should return selected resource', (done) => {
-      const dummyStateResource: StateResource<Resource> =
-        createStateResource(createDummyResource());
+      const dummyStateResource: StateResource<Resource> = createStateResource(createDummyResource());
 
       service.getSelected().subscribe((selected) => {
         expect(selected).toEqual(dummyStateResource);
@@ -411,10 +375,7 @@ describe('ListResourceService', () => {
 
       service.prev();
 
-      expect(resourceRepository.getListResource).toHaveBeenCalledWith(
-        listResource,
-        service.prevLink,
-      );
+      expect(resourceRepository.getListResource).toHaveBeenCalledWith(listResource, service.prevLink);
     });
 
     it('should update listResource', () => {
@@ -443,10 +404,7 @@ describe('ListResourceService', () => {
 
       service.next();
 
-      expect(resourceRepository.getListResource).toHaveBeenCalledWith(
-        listResourceWithPrevLink,
-        service.nextLink,
-      );
+      expect(resourceRepository.getListResource).toHaveBeenCalledWith(listResourceWithPrevLink, service.nextLink);
     });
 
     it('should update listResource', () => {
@@ -485,9 +443,7 @@ describe('ListResourceService', () => {
 
   describe('get items', () => {
     const listResourceItems: ListItemResource[] = [createDummyResource()];
-    const stateListResource: StateResource<ListResource> = createStateResource(
-      createFilledDummyListResource(listResourceItems),
-    );
+    const stateListResource: StateResource<ListResource> = createStateResource(createFilledDummyListResource(listResourceItems));
     let getListSpy: jest.SpyInstance;
 
     beforeEach(() => {
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.ts b/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.ts
index 631e1c685eba0e9f96e5a4e1d97e1314a1cb7e9f..4bb6beecc38df96224fa5adf1b4ede5ed4729039 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/list-resource.service.ts
@@ -1,15 +1,6 @@
 import { Resource, ResourceUri, getUrl, hasLink } from '@ngxp/rest';
 import { isEqual, isNull } from 'lodash-es';
-import {
-  BehaviorSubject,
-  Observable,
-  combineLatest,
-  filter,
-  first,
-  map,
-  startWith,
-  tap,
-} from 'rxjs';
+import { BehaviorSubject, Observable, combineLatest, filter, first, map, startWith, tap } from 'rxjs';
 import { isNotNull, isNotUndefined } from '../tech.util';
 import { CreateResourceData, ListItemResource, ListResourceServiceConfig } from './resource.model';
 import { ResourceRepository } from './resource.repository';
@@ -31,21 +22,13 @@ import {
  * T = Type of listresource
  * I = Type of items in listresource
  */
-export class ResourceListService<
-  B extends Resource,
-  T extends ListResource,
-  I extends ListItemResource,
-> {
+export class ResourceListService<B extends Resource, T extends ListResource, I extends ListItemResource> {
   readonly nextLink: string = 'next';
   readonly prevLink: string = 'prev';
 
-  readonly listResource: BehaviorSubject<StateResource<T>> = new BehaviorSubject(
-    createEmptyStateResource(),
-  );
+  readonly listResource: BehaviorSubject<StateResource<T>> = new BehaviorSubject(createEmptyStateResource());
 
-  readonly selectedResource: BehaviorSubject<StateResource<I>> = new BehaviorSubject(
-    createEmptyStateResource(),
-  );
+  readonly selectedResource: BehaviorSubject<StateResource<I>> = new BehaviorSubject(createEmptyStateResource());
 
   baseResource: B = null;
 
@@ -56,7 +39,9 @@ export class ResourceListService<
 
   public getList(): Observable<StateResource<T>> {
     return combineLatest([this.listResource.asObservable(), this.getConfigResource()]).pipe(
-      tap(([stateResource, configResource]) => this.handleChanges(stateResource, configResource)),
+      tap(([stateResource, configResource]) => {
+        this.handleChanges(stateResource, configResource);
+      }),
       tap(([, configResource]) => this.handleNullConfigResource(configResource)),
       filter(([stateResource]) => !isInvalidResourceCombination(stateResource, this.baseResource)),
       mapToFirst<T, B>(),
@@ -109,9 +94,7 @@ export class ResourceListService<
 
   public create(toCreate: unknown): Observable<Resource> {
     this.verifyBeforeCreation();
-    return this.repository.createResource(
-      this.buildCreateResourceData(toCreate, this.config.createLinkRel),
-    );
+    return this.repository.createResource(this.buildCreateResourceData(toCreate, this.config.createLinkRel));
   }
 
   private verifyBeforeCreation(): void {
@@ -132,7 +115,6 @@ export class ResourceListService<
   }
 
   public select(uri: ResourceUri): void {
-    this.verifyBeforeSelection(uri);
     this.setSelectedResourceLoading();
     this.repository
       .getResource(uri)
@@ -156,10 +138,7 @@ export class ResourceListService<
   }
 
   existsUriInList(uri: ResourceUri): boolean {
-    const listResources: Resource[] = getEmbeddedResources(
-      this.listResource.value,
-      this.config.listLinkRel,
-    );
+    const listResources: Resource[] = getEmbeddedResources(this.listResource.value, this.config.listLinkRel);
 
     return isNotUndefined(listResources.find((resource) => getUrl(resource) === uri));
   }
@@ -234,10 +213,7 @@ export class ResourceListService<
     return this.getList().pipe(
       filter((listStateResource: StateResource<T>) => !listStateResource.loading),
       map((listStateResource: StateResource<T>) =>
-        getEmbeddedResources<ListItemResource>(
-          listStateResource,
-          this.config.listResourceListLinkRel,
-        ),
+        getEmbeddedResources<ListItemResource>(listStateResource, this.config.listResourceListLinkRel),
       ),
     );
   }
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.spec.ts
index 2c8c97bfd4304f4bad5545a11cbe97dcb8a7258f..dfbdeb0e8b3889808c4839004012f82e65b89875 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.spec.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.spec.ts
@@ -13,7 +13,7 @@ describe('ResourceRepository', () => {
   let repository: ResourceRepository;
 
   let resourceFactory = mock(ResourceFactory);
-  let resourceWrapper = { get: jest.fn(), post: jest.fn(), put: jest.fn(), delete: jest.fn() };
+  let resourceWrapper = { get: jest.fn(), post: jest.fn(), put: jest.fn(), patch: jest.fn(), delete: jest.fn() };
 
   beforeEach(() => {
     resourceFactory.from.mockReturnValue(resourceWrapper);
@@ -42,9 +42,7 @@ describe('ResourceRepository', () => {
     it('should call get url without parameter', () => {
       repository.getListResource(baseResource, listLinkRel);
 
-      expect(repository.getUrlWithoutParameter).toHaveBeenCalledWith(
-        getUrl(baseResource, listLinkRel),
-      );
+      expect(repository.getUrlWithoutParameter).toHaveBeenCalledWith(getUrl(baseResource, listLinkRel));
     });
 
     it('should call resourceFactory with uri', () => {
@@ -131,7 +129,7 @@ describe('ResourceRepository', () => {
       expect(resourceFactory.from).toHaveBeenCalledWith(resource);
     });
 
-    it('should call resourceWrapper with linkel and object to create', () => {
+    it('should call resourceWrapper with linkRel and object to create', () => {
       repository.createResource(createResourceData);
 
       expect(resourceWrapper.post).toHaveBeenCalledWith(linkRel, toCreate);
@@ -162,7 +160,7 @@ describe('ResourceRepository', () => {
       expect(resourceFactory.from).toHaveBeenCalledWith(resource);
     });
 
-    it('should call resourceWrapper with linkel and object to save', () => {
+    it('should call resourceWrapper with linkRel and object to save', () => {
       repository.save(saveResourceData);
 
       expect(resourceWrapper.put).toHaveBeenCalledWith(linkRel, toSave);
@@ -175,6 +173,37 @@ describe('ResourceRepository', () => {
     });
   });
 
+  describe('patch', () => {
+    const toPatch: unknown = {};
+    const linkRel: string = DummyLinkRel.DUMMY;
+    const resource: Resource = createDummyResource([linkRel]);
+    const patchResourceData: SaveResourceData<Resource> = { toSave: toPatch, linkRel, resource };
+
+    const patchedResource: Resource = createDummyResource();
+
+    beforeEach(() => {
+      resourceWrapper.patch.mockReturnValue(singleCold(patchedResource));
+    });
+
+    it('should call resourceFactory with resource', () => {
+      repository.patch(patchResourceData);
+
+      expect(resourceFactory.from).toHaveBeenCalledWith(resource);
+    });
+
+    it('should call resourceWrapper with linkRel and object to patch', () => {
+      repository.patch(patchResourceData);
+
+      expect(resourceWrapper.patch).toHaveBeenCalledWith(linkRel, toPatch);
+    });
+
+    it('should return value', () => {
+      const result: Observable<Resource> = repository.patch(patchResourceData);
+
+      expect(result).toBeObservable(singleHot(patchedResource));
+    });
+  });
+
   describe('delete', () => {
     const deleteLinkRel: LinkRelationName = faker.random.word();
     const resourceToDelete: Resource = createDummyResource([deleteLinkRel]);
@@ -191,7 +220,7 @@ describe('ResourceRepository', () => {
       expect(resourceFactory.from).toHaveBeenCalledWith(resourceToDelete);
     });
 
-    it('should call resourceWrapper with linkel', () => {
+    it('should call resourceWrapper with linkRel', () => {
       repository.delete(resourceToDelete, deleteLinkRel);
 
       expect(resourceWrapper.delete).toHaveBeenCalledWith(deleteLinkRel);
@@ -218,10 +247,7 @@ describe('ResourceRepository', () => {
 
       repository.search(dummyResource, linkRel, searchBy);
 
-      expect(repository.buildSearchUri).toHaveBeenCalledWith(
-        new URL(getUrl(dummyResource, linkRel)),
-        searchBy,
-      );
+      expect(repository.buildSearchUri).toHaveBeenCalledWith(new URL(getUrl(dummyResource, linkRel)), searchBy);
     });
 
     it('should call resourceFactory', () => {
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts
index b0fcb3995f0961983b8caef53160762ad3fc4416..fe199d6e0f55c932f385ecfa4d3dac96dd930230 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.repository.ts
@@ -23,9 +23,7 @@ export class ResourceRepository {
   }
 
   public createResource(createResourceData: CreateResourceData<Resource>): Observable<Resource> {
-    return this.resourceFactory
-      .from(createResourceData.resource)
-      .post(createResourceData.linkRel, createResourceData.toCreate);
+    return this.resourceFactory.from(createResourceData.resource).post(createResourceData.linkRel, createResourceData.toCreate);
   }
 
   public getResource<T>(uri: ResourceUri): Observable<T> {
@@ -33,9 +31,11 @@ export class ResourceRepository {
   }
 
   public save(saveResourceData: SaveResourceData<Resource>): Observable<Resource> {
-    return this.resourceFactory
-      .from(saveResourceData.resource)
-      .put(saveResourceData.linkRel, saveResourceData.toSave);
+    return this.resourceFactory.from(saveResourceData.resource).put(saveResourceData.linkRel, saveResourceData.toSave);
+  }
+
+  public patch(patchResourceData: SaveResourceData<Resource>): Observable<Resource> {
+    return this.resourceFactory.from(patchResourceData.resource).patch(patchResourceData.linkRel, patchResourceData.toSave);
   }
 
   public delete(resource: Resource, linkRel: LinkRelationName): Observable<Resource> {
@@ -43,9 +43,7 @@ export class ResourceRepository {
   }
 
   public search<T>(resource: Resource, linkRel: LinkRelationName, searchBy: string): Observable<T> {
-    return this.resourceFactory
-      .fromId(this.buildSearchUri(new URL(getUrl(resource, linkRel)), searchBy))
-      .get();
+    return this.resourceFactory.fromId(this.buildSearchUri(new URL(getUrl(resource, linkRel)), searchBy)).get();
   }
 
   buildSearchUri(url: URL, searchBy: string): ResourceUri {
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.service.spec.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.service.spec.ts
index 61f1ae622b0c4621da50136718665d0c5a94756e..1a7c4254c31475dde3488c115c80245b758d0145 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/resource.service.spec.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.service.spec.ts
@@ -12,12 +12,7 @@ import { ProblemDetail } from '../tech.model';
 import { LinkRelationName, ResourceServiceConfig } from './resource.model';
 import { ResourceRepository } from './resource.repository';
 import { ResourceService } from './resource.service';
-import {
-  StateResource,
-  createEmptyStateResource,
-  createErrorStateResource,
-  createStateResource,
-} from './resource.util';
+import { StateResource, createEmptyStateResource, createErrorStateResource, createStateResource } from './resource.util';
 
 import * as ResourceUtil from './resource.util';
 
@@ -62,9 +57,7 @@ describe('ResourceService', () => {
       service.stateResource.next(stateResource);
 
       service.handleResourceChanges = jest.fn();
-      isInvalidResourceCombinationSpy = jest
-        .spyOn(ResourceUtil, 'isInvalidResourceCombination')
-        .mockReturnValue(true);
+      isInvalidResourceCombinationSpy = jest.spyOn(ResourceUtil, 'isInvalidResourceCombination').mockReturnValue(true);
     });
 
     it('should handle config resource changed', fakeAsync(() => {
@@ -82,15 +75,11 @@ describe('ResourceService', () => {
     }));
 
     it('should return initial value', () => {
-      service.stateResource.asObservable = jest
-        .fn()
-        .mockReturnValue(singleHot(stateResource, '-a'));
+      service.stateResource.asObservable = jest.fn().mockReturnValue(singleHot(stateResource, '-a'));
 
       const apiRootStateResource$: Observable<StateResource<Resource>> = service.get();
 
-      expect(apiRootStateResource$).toBeObservable(
-        cold('a', { a: createEmptyStateResource(true) }),
-      );
+      expect(apiRootStateResource$).toBeObservable(cold('a', { a: createEmptyStateResource(true) }));
     });
   });
 
@@ -167,10 +156,7 @@ describe('ResourceService', () => {
       it('should update stateresource by configresource', () => {
         service.handleResourceChanges(stateResource, configResource);
 
-        expect(service.updateStateResourceByConfigResource).toHaveBeenCalledWith(
-          stateResource,
-          configResource,
-        );
+        expect(service.updateStateResourceByConfigResource).toHaveBeenCalledWith(stateResource, configResource);
       });
     });
 
@@ -235,10 +221,7 @@ describe('ResourceService', () => {
       });
 
       it('should return true if configresource has no get link', () => {
-        const shouldClear: boolean = service.shouldClearStateResource(
-          dummyStateResource,
-          createDummyResource(),
-        );
+        const shouldClear: boolean = service.shouldClearStateResource(dummyStateResource, createDummyResource());
 
         expect(shouldClear).toBeTruthy();
       });
@@ -246,19 +229,13 @@ describe('ResourceService', () => {
 
     describe('on empty stateresource', () => {
       it('should return false', () => {
-        const shouldClear: boolean = service.shouldClearStateResource(
-          createEmptyStateResource(),
-          null,
-        );
+        const shouldClear: boolean = service.shouldClearStateResource(createEmptyStateResource(), null);
 
         expect(shouldClear).toBeFalsy();
       });
 
       it('should return false if configresource has no get link', () => {
-        const shouldClear: boolean = service.shouldClearStateResource(
-          createEmptyStateResource(),
-          createDummyResource(),
-        );
+        const shouldClear: boolean = service.shouldClearStateResource(createEmptyStateResource(), createDummyResource());
 
         expect(shouldClear).toBeFalsy();
       });
@@ -306,9 +283,7 @@ describe('ResourceService', () => {
 
       service.loadResource(configResourceWithGetLinkRel);
 
-      expect(service.doLoadResource).toHaveBeenCalledWith(
-        getUrl(configResourceWithGetLinkRel, config.getLinkRel),
-      );
+      expect(service.doLoadResource).toHaveBeenCalledWith(getUrl(configResourceWithGetLinkRel, config.getLinkRel));
     });
   });
 
@@ -394,9 +369,7 @@ describe('ResourceService', () => {
     it('should do save', fakeAsync(() => {
       const stateResource: StateResource<Resource> = createStateResource(resourceWithEditLinkRel);
       service.stateResource.next(stateResource);
-      const doSaveMock: jest.Mock = (service.doSave = jest.fn()).mockReturnValue(
-        of(loadedResource),
-      );
+      const doSaveMock: jest.Mock = (service.doSave = jest.fn()).mockReturnValue(of(loadedResource));
 
       service.save(dummyToSave).subscribe();
       tick();
@@ -435,16 +408,62 @@ describe('ResourceService', () => {
     }));
   });
 
+  describe('patch', () => {
+    const dummyToPatch: unknown = {};
+    const loadedResource: Resource = createDummyResource();
+
+    const resourceWithEditLinkRel: Resource = createDummyResource([editLinkRel]);
+
+    it('should do patch', fakeAsync(() => {
+      const stateResource: StateResource<Resource> = createStateResource(resourceWithEditLinkRel);
+      service.stateResource.next(stateResource);
+      const doPatchMock: jest.Mock = (service.doPatch = jest.fn()).mockReturnValue(of(loadedResource));
+
+      service.patch(dummyToPatch).subscribe();
+      tick();
+
+      expect(doPatchMock).toHaveBeenCalledWith(resourceWithEditLinkRel, dummyToPatch);
+    }));
+
+    it('should return patched object', () => {
+      service.stateResource.next(createStateResource(resourceWithEditLinkRel));
+      service.doPatch = jest.fn().mockReturnValue(singleHot(loadedResource));
+
+      const patched: Observable<StateResource<Resource>> = service.patch(dummyToPatch);
+
+      expect(patched).toBeObservable(singleCold(createStateResource(loadedResource)));
+    });
+
+    it('should call handleError', () => {
+      service.stateResource.next(createStateResource(createDummyResource([config.edit.linkRel])));
+      const errorResponse: ProblemDetail = createProblemDetail();
+      service.doPatch = jest.fn().mockReturnValue(throwError(() => errorResponse));
+      service.handleError = jest.fn();
+
+      service.patch(<any>{}).subscribe();
+
+      expect(service.handleError).toHaveBeenCalledWith(errorResponse);
+    });
+
+    it('should update state resource subject', fakeAsync(() => {
+      service.stateResource.next(createStateResource(resourceWithEditLinkRel));
+      service.doPatch = jest.fn().mockReturnValue(of(loadedResource));
+
+      service.patch(dummyToPatch).subscribe();
+      tick();
+
+      expect(service.stateResource.value).toEqual(createStateResource(loadedResource));
+    }));
+  });
+
   describe('handleError', () => {
     it('should return error stateresource on problem unprocessable entity', (done: jest.DoneCallback) => {
       const error: ProblemDetail = createProblemDetail();
 
-      service
-        .handleError(<HttpErrorResponse>(<any>error))
-        .subscribe((responseError: StateResource<unknown>) => {
-          expect(responseError).toEqual(createErrorStateResource(error));
-          done();
-        });
+      service.handleError(<HttpErrorResponse>(<any>error)).subscribe((responseError: StateResource<unknown>) => {
+        expect(responseError).toEqual(createErrorStateResource(error));
+        done();
+      });
     });
 
     it('should rethrow error', () => {
@@ -503,10 +522,7 @@ describe('ResourceService', () => {
   });
 });
 
-export class DummyResourceService<B extends Resource, T extends Resource> extends ResourceService<
-  B,
-  T
-> {
+export class DummyResourceService<B extends Resource, T extends Resource> extends ResourceService<B, T> {
   constructor(
     protected config: ResourceServiceConfig<B>,
     protected repository: ResourceRepository,
@@ -517,4 +533,8 @@ export class DummyResourceService<B extends Resource, T extends Resource> extend
   doSave(resource: T, toSave: unknown): Observable<T> {
     return of(resource);
   }
+
+  doPatch(resource: T, toPatch: unknown): Observable<T> {
+    return of(resource);
+  }
 }
diff --git a/alfa-client/libs/tech-shared/src/lib/resource/resource.service.ts b/alfa-client/libs/tech-shared/src/lib/resource/resource.service.ts
index 6c9eb0a56f13fb81555b915c436119b742b2ec45..02abe975e853fe01912920f1bff836914c4779aa 100644
--- a/alfa-client/libs/tech-shared/src/lib/resource/resource.service.ts
+++ b/alfa-client/libs/tech-shared/src/lib/resource/resource.service.ts
@@ -1,19 +1,7 @@
 import { HttpErrorResponse } from '@angular/common/http';
 import { getUrl, hasLink, Resource, ResourceUri } from '@ngxp/rest';
 import { isEqual, isNull } from 'lodash-es';
-import {
-  BehaviorSubject,
-  catchError,
-  combineLatest,
-  filter,
-  first,
-  map,
-  Observable,
-  of,
-  startWith,
-  tap,
-  throwError,
-} from 'rxjs';
+import { BehaviorSubject, catchError, combineLatest, filter, first, map, Observable, of, startWith, tap, throwError } from 'rxjs';
 import { isUnprocessableEntity } from '../http.util';
 import { HttpError } from '../tech.model';
 import { isNotNull } from '../tech.util';
@@ -35,9 +23,7 @@ import {
  * T = Type of the resource which is working on
  */
 export abstract class ResourceService<B extends Resource, T extends Resource> {
-  readonly stateResource: BehaviorSubject<StateResource<T>> = new BehaviorSubject(
-    createEmptyStateResource(),
-  );
+  readonly stateResource: BehaviorSubject<StateResource<T>> = new BehaviorSubject(createEmptyStateResource());
 
   configResource: B = null;
 
@@ -48,12 +34,8 @@ export abstract class ResourceService<B extends Resource, T extends Resource> {
 
   public get(): Observable<StateResource<T>> {
     return combineLatest([this.stateResource.asObservable(), this.getConfigResource()]).pipe(
-      tap(([stateResource, configResource]) =>
-        this.handleResourceChanges(stateResource, configResource),
-      ),
-      filter(
-        ([stateResource]) => !isInvalidResourceCombination(stateResource, this.configResource),
-      ),
+      tap(([stateResource, configResource]) => this.handleResourceChanges(stateResource, configResource)),
+      filter(([stateResource]) => !isInvalidResourceCombination(stateResource, this.configResource)),
       mapToFirst<T, B>(),
       startWith(createEmptyStateResource<T>(true)),
     );
@@ -61,10 +43,7 @@ export abstract class ResourceService<B extends Resource, T extends Resource> {
 
   private getConfigResource(): Observable<B> {
     return this.config.resource.pipe(
-      filter(
-        (configStateResource: StateResource<B>) =>
-          !configStateResource.loading && !configStateResource.reload,
-      ),
+      filter((configStateResource: StateResource<B>) => !configStateResource.loading && !configStateResource.reload),
       mapToResource<B>(),
     );
   }
@@ -93,10 +72,7 @@ export abstract class ResourceService<B extends Resource, T extends Resource> {
   }
 
   shouldClearStateResource(stateResource: StateResource<T>, configResource: B): boolean {
-    return (
-      (isNull(configResource) || this.hasNotGetLink(configResource)) &&
-      !this.isStateResourceEmpty(stateResource)
-    );
+    return (isNull(configResource) || this.hasNotGetLink(configResource)) && !this.isStateResourceEmpty(stateResource);
   }
 
   private hasNotGetLink(configResource: B): boolean {
@@ -152,6 +128,15 @@ export abstract class ResourceService<B extends Resource, T extends Resource> {
     );
   }
 
+  public patch(toPatch: unknown): Observable<StateResource<T>> {
+    const previousResource: T = this.stateResource.value.resource;
+    return this.doPatch(previousResource, toPatch).pipe(
+      tap((loadedResource: T) => this.stateResource.next(createStateResource(loadedResource))),
+      map(() => this.stateResource.value),
+      catchError((errorResponse: HttpErrorResponse) => this.handleError(errorResponse)),
+    );
+  }
+
   handleError(errorResponse: HttpErrorResponse): Observable<StateResource<T>> {
     if (isUnprocessableEntity(errorResponse.status)) {
       return of(createErrorStateResource((<any>errorResponse) as HttpError));
@@ -161,6 +146,8 @@ export abstract class ResourceService<B extends Resource, T extends Resource> {
 
   abstract doSave(resource: T, toSave: unknown): Observable<T>;
 
+  abstract doPatch(resource: T, toPatch: unknown): Observable<T>;
+
   public refresh(): void {
     this.stateResource.next({ ...this.stateResource.value, reload: true });
   }
diff --git a/alfa-client/libs/zustaendige-stelle-shared/src/lib/organisations-einheit/organisations-einheit.model.ts b/alfa-client/libs/zustaendige-stelle-shared/src/lib/organisations-einheit/organisations-einheit.model.ts
index aafc23fbbce95dae57f511413b8e1c0dedd936ad..46320868558c4bcb58c907bcb3ad1ec3cd766b73 100644
--- a/alfa-client/libs/zustaendige-stelle-shared/src/lib/organisations-einheit/organisations-einheit.model.ts
+++ b/alfa-client/libs/zustaendige-stelle-shared/src/lib/organisations-einheit/organisations-einheit.model.ts
@@ -13,8 +13,6 @@ export interface Anschrift {
   ort: string;
 }
 
-export interface OrganisationsEinheitResource
-  extends OrganisationsEinheit,
-    Resource,
-    ListItemResource {}
+export interface OrganisationsEinheitResource extends OrganisationsEinheit, Resource, ListItemResource {}
 export interface OrganisationsEinheitListResource extends ListResource {}
+export declare type OrganisationsEinheitItemResource = Resource & OrganisationsEinheit;
diff --git a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.spec.ts b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.spec.ts
index f5a101175b95b57d2a75449fb53a487e17286166..6f6328bf87d2a6eec944f8b968dcbeb114238f50 100644
--- a/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.spec.ts
+++ b/alfa-client/libs/zustaendige-stelle/src/lib/search-zustaendige-stelle-dialog/search-zustaendige-stelle-form/search-zustaendige-stelle-form.component.spec.ts
@@ -100,8 +100,8 @@ describe('SearchZustaendigeStelleFormComponent', () => {
         };
       });
 
-      it('on searchResultClosed output', () => {
-        eventData = { ...eventData, name: 'searchResultClosed' };
+      it('on searchClosed output', () => {
+        eventData = { ...eventData, name: 'searchClosed' };
 
         triggerEvent(eventData);
 
@@ -109,7 +109,7 @@ describe('SearchZustaendigeStelleFormComponent', () => {
       });
 
       it('on searchQueryCleared output', () => {
-        eventData = { ...eventData, name: 'searchResultClosed' };
+        eventData = { ...eventData, name: 'searchClosed' };
 
         triggerEvent(eventData);