# Changelog Format orientiert an [Keep a Changelog](https://keepachangelog.com/de/1.1.0/). Versionierung folgt [Semantic Versioning](https://semver.org/lang/de/) — solange das Tool noch in der `0.x.y`-Phase ist, sind Breaking Changes erlaubt. --- ## [0.1.29] - 2026-08-24 Geräte-Offboarding (v1). ### Neu - **Geräte-Offboarding** als neue Ansicht: Geräte über **Intune, Autopilot und Entra ID** hinweg entfernen (Decommissioning). Portiert aus dem [Device Offboarding Manager](https://github.com/ugurkocde/DeviceOffboardingManager) von Ugur Koc (MIT-Lizenz). - Suche per Gerätename/Seriennummer, Auflösung der IDs über alle drei Dienste (`$batch`) - **Recovery-Keys vor dem Löschen**: BitLocker/FileVault und LAPS-Passwörter werden angezeigt - Bestätigungs-Dialog mit Dienst-Auswahl (Entra löschen/deaktivieren, Intune, Autopilot), Pflicht-Bestätigung und Ergebnis-Liste; **403/Multi-Admin-Approval** wird abgefangen - Im **Read-Only-Modus gesperrt** - Neue Endpoints: `GET /api/offboard/search`, `POST /api/offboard/keys`, `POST /api/offboard/execute` (neues Modul `src/Offboard.ps1`) - Zusätzliche Berechtigungen dokumentiert; Setup-Skript-Schalter `-IncludeOffboarding`. (MDE-Offboarding bewusst nicht in v1.) --- ## [0.1.28] - 2026-08-24 Umbenennen beim Import, UI-Fixes, Geräte-Export repariert. ### Neu - **Umbenennen beim Import**: Vor dem Anlegen kann jeder importierten Policy im neuen Dialog „Policies importieren" ein anderer Name gegeben werden (das richtige Namensfeld je Typ — `name`/`displayName` — wird gesetzt). ### Behoben - **Geräte-Export im App Report**: Der von Graph entfernte synchrone Endpoint `getDeviceInstallStatusReport` (400 „Resource not found for the segment") ist durch den asynchronen Export-Job **`DeviceInstallStatusByApp`** ersetzt (ZIP/CSV-Auswertung, tolerantes Spalten-Mapping). ZIP/CSV-Logik in `Get-IntuneReportRows` ausgelagert. - **Darkmode-Kontrast** im Zuweisungs-Dialog: Gruppen-Chips nutzen jetzt die Theme-Variablen (`--surface-strong`/`--ink` statt fester heller Farben) — heller Text auf hellem Chip behoben. - **Dialog-Breite**: Lange Policy-Namen im Zuweisungs-/Import-Dialog brechen jetzt um (`overflow-wrap`/`flex-wrap`) statt horizontal zu scrollen; das Fenster passt sich der Breite an. --- ## [0.1.27] - 2026-08-23 Policy-Import härter, Administrative Vorlagen, Zuweisung nach Import, Git-Snapshot, App-Registrierungs-Doku. ### Neu - **Administrative Vorlagen (ADMX / `groupPolicyConfigurations`)** als vierter Policy-Typ für Export und Import. Beim Import wird die Konfigurations-Hülle angelegt und jede Einstellung einzeln über `definition@odata.bind` / `presentation@odata.bind` angehängt (eingebaute ADMX-Definitionen sind tenantübergreifend gültig). Neuer Endpoint `GET /api/policies/administrativetemplate`. - **Zuweisung direkt nach Import**: Dialog listet die neu angelegten Policies und lässt **pro Policy Include-/Exclude-Gruppen** im Ziel-Tenant zuweisen (Typeahead über die vorhandene Gruppensuche). Neuer Endpoint `POST /api/policies/assign` (nutzt die typ-spezifische `/assign`-Action für alle vier Typen). - **Git-Snapshot (versioniertes Policy-Backup)**: Button „Git-Snapshot" schreibt alle Policies aller Typen als JSON in einen konfigurierten lokalen Git-Ordner und committet sie (optional `git push` über den vorhandenen Credential-Helper). Stabile Dateinamen + deterministische, zeitstempel-freie Ausgabe → saubere Diffs. Neue Settings-Sektion `policyBackup` (`gitRepoPath`, `push`). - Import akzeptiert jetzt auch **Git-Snapshot-Dateien** (Feld `policyType` zusätzlich zu `exportType`). - **Doku + Provisioning-Skript für die App-Registrierung**: [`docs/App-Registration.md`](docs/App-Registration.md) listet alle benötigten delegierten Graph-Berechtigungen (Kern, Geräte-Tab, Read-Only) samt Auth-Konfiguration; [`docs/Setup-AppRegistration.ps1`](docs/Setup-AppRegistration.ps1) legt die Registrierung automatisch an bzw. aktualisiert sie (Rechte, Public-Client-Flow, Redirect-URIs, optional Admin-Consent) — Berechtigungs-IDs werden live aufgelöst, keine fest verdrahteten GUIDs. ### Behoben - **Settings-Catalog-Import** war gegen Graph-Schema-Fehler anfällig: verschachtelte Collection-Properties (`children`, `*SettingCollectionValue`) werden jetzt konsequent als Arrays serialisiert (repariert PowerShell-5.1-JSON-Roundtrip-Schäden), `null`-Collections werden zu `[]` (Graph verlangt `Nullable=False`), der Wrapper-`@odata.type` wird je Setting gesetzt und das read-only `id`-Feld entfernt. - **Phantom-Fehler beim Import**: ein fehlendes `fileNames`-Feld erzeugte über `@($null)` einen Geisterdurchlauf im Archiv-Pfad und meldete fälschlich „1 fehlgeschlagen". - **Tenant-Wechsel**: das Frontend zeigte weiter die Apps/Gruppen des vorherigen Tenants, weil die Lade-Guards nicht zurückgesetzt wurden. Alle datentragenden Caches werden jetzt beim Wechsel verworfen (`resetClientState`). - **WAM-Anmeldefenster** kommt beim Login/Tenant-Wechsel zuverlässig in den Vordergrund (AttachThreadInput + kurzer ALT-Tap zum Lösen des Windows-Foreground-Locks). --- ## [0.1.26] - 2026-08-21 Multi-Tenant, Pro-Tenant-Vorgaben, RPA entfernt. ### Neu - **Multi-Tenant-Modus** (umschaltbar in den Einstellungen, Single/Multi): mehrere Mandanten mit **je eigener App-Registrierung**; Umschalter in der Topbar mit **Sofort-Reconnect**. Bestehende Single-Tenant-Konfiguration wird verlustfrei übernommen. - **Pro-Tenant-Vorgaben** mit globalem Fallback: **Abteilungs-Präfixe** sowie **Required-/Available-Gruppen-Naming** je Profil überschreibbar (leer = globale Vorgabe). - **Policy-Export als Einzeldateien** bei Mehrfachauswahl (statt Bundle). - **CI**: gebaute MSI wird zusätzlich als **Gitea-Release-Asset** gespiegelt (Secret `GITEA_TOKEN`). - Hilfe-Fenster: Hinweis „Entwickelt von WendeIT – Marco Wende". ### Geändert / Entfernt - **RPA-Funktion entfernt**: RPA-Tab, RPA-Einstellungen und RPA-Test-Anzeige sind nicht mehr vorhanden. - Setup-Zwang gelockert: nur **Tenant ID + Client ID** sind Pflicht; Abteilungs-Präfixe sind optional. - Klarere Fehlermeldung bei nicht erreichbarem lokalen Server (statt „Failed to fetch"). --- ## [0.1.25] - 2026-08-19 Policy Export/Import und Geräte-Tab. ### Neu - **Policies-Tab**: Export und Import von Intune-Policies — **Settings Catalog** (`configurationPolicies`), **Compliance Policies** (`deviceCompliancePolicies`) und **Konfigurationsprofile** (`deviceConfigurations`) - Tabelle über alle drei Typen mit Suche, Typ-Filter und Sortierung; Auswahl per Checkbox - **Export** als JSON-Download (einzeln oder als gebündelte Datei bei mehreren) — zusätzlich server-seitig unter `%APPDATA%\IntuneAppManager-Web\policy-exports` archiviert - **Import** per Datei-Upload (einzelne Envelopes oder Bundle) — legt Policies **immer als Neuanlage** an, überschreibt nie bestehende; im Read-Only-Modus ausgeblendet - Neuer Scope `DeviceManagementConfiguration.ReadWrite.All` (bzw. `.Read.All`) wird automatisch zur Verbindung ergänzt - Neue Endpoints: `GET /api/policies/{settingscatalog|compliance|configuration}`, `POST /api/policies/export`, `GET /api/policies/exports`, `POST /api/policies/import` --- ## [0.1.24] - 2026-07-03 Navigation-Tabs, Group Management, Read-Only-Modus, App Report, CSV-Import. ### Neu - **Navigation-Tabs** im Topbar: *App Management* | *Group Management* | *App Report* — Topbar-Grid auf 3 Spalten (Brand | Nav | Actions) erweitert - **Group Management** als eigene View (statt Modal): Mitglieder & Export, Benutzer hinzufügen, CSV-Import — drei Tabs, linke Gruppen-Suche + rechte Aktionspane - **Read-Only-Modus**: `clientIdRo` + `scopesRo` in Settings; Verbindung versucht RW, fällt bei Fehler auf RO zurück; `body.read-only`-CSS-Klasse blendet alle Schreib-Elemente aus (Buttons, Tabs, Formular-Bereiche) - **−R / −A Buttons** pro App-Zeile: Gruppe direkt aus Required- oder Available-Zuweisung entfernen (mit Gruppen-Picker bei mehreren) - **App Report** (neuer Tab): Installationszähler für alle Apps via `deviceStatuses` aggregiert; Tabelle sortierbar, Suchfilter; CSV-Export der gefilterten Ansicht - **Geräte-Export pro App**: Button in jeder Zeile des App Reports → `GET /api/apps/devicestatus?appId=` → CSV mit Gerätename, Benutzer, Status, Fehlercode, OS-Version, Sync-Datum - **CSV-Import** im Group Management: UPNs/E-Mails einfügen oder CSV hochladen; automatische Spalten-Erkennung (Header `UserPrincipalName`/`Mail`/`Email`/`UPN`; Quoted-Fields; `,`/`;`/Tab); Graph-Batch-Lookup; Vorschau-Tabelle mit ✓/✗; Ergebnis-Banner mit farbigen Chips (hinzugefügt / bereits Mitglied / Fehler / nicht gefunden) - **Toast-Z-Index** auf 3000 angehoben (war 1000 → lag hinter Modals mit z-index 1500) - **Neuer Endpoint** `POST /api/groups/resolve-upns` — UPN-Liste → UserId + DisplayName via $batch - **Neuer Endpoint** `GET /api/apps/devicestatus?appId=` — Geräte-Installationsstatus einer App ### Geändert - **Group Management Modal** zur eigenständigen View umgebaut — keine doppelten IDs mehr - **`openGroupExportModal()`** leitet jetzt auf `switchMainView('groups')` um - **`switchMainView(view)`** verwaltet alle drei Views (apps / groups / report) - **`applyReadOnlyMode()`** schaltet aktiven Schreib-Tab automatisch auf Export zurück wenn Read-Only einsetzt - **Settings-Modal**: Felder `setClientIdRo` und `setScopesRo` hinzugefügt - **`GET /api/status`**: liefert jetzt `readOnly: bool` - **`POST /api/connect`**: setzt `$script:State.ReadOnly` nach RO-Fallback - **`POST /api/disconnect`**: setzt `ReadOnly = $false` zurück - **App Report Backend**: mehrfach überarbeitet — `installSummary` (400 für alle App-Typen ohne `DeviceManagementManagedDevices.Read.All`), `getAppInstallSummaryReport` (404 in beta und v1.0 ohne MDM-Berechtigung) → finaler Ansatz: `deviceStatuses` via `$batch` aggregiert ### Behoben - **`$script:State.ReadOnly` Property-Fehler**: `[pscustomobject]` erlaubt keine dynamischen Properties — `ReadOnly = $false` musste in der Definition in `Start.ps1` stehen - **Duplicate-ID-Bug**: `gexSearch`, `gexMembersArea` etc. existierten doppelt (alt: im Modal-Body, neu: in `#groupMgmtView`) — Modal-Body geleert ### Technisch - `src/Models.ps1`: `clientIdRo`, `scopesRo` als optionale Settings-Felder - `src/Api.ps1`: `Sync-ConfigFromSettings` + `Get-StatusEndpoint` + `Invoke-ConnectEndpoint` + `Invoke-DisconnectEndpoint` für RO-Logik erweitert; `Get-AppInstallReportEndpoint` (deviceStatuses-Aggregation); `Get-AppDeviceStatusEndpoint`; `Resolve-UpnsEndpoint` - `www/styles.css`: `.topbar-nav`, `.nav-tab`, `.group-mgmt-view`, `.app-report-view`, `.app-report-table`, `.sortable`, `.btn-report-device-export`, `.csv-import-*`, `.csv-result-*`; `body.read-only`-Regeln erweitert um `#gexPaneImport` und `[data-tab="import"]` --- ## [0.1.23] - 2026-05-21 Setup-Datei nativer Apps aktualisierbar + Microsoft-Graph-Audit-Fixes. ### Neu - **Setup-Datei aktualisieren** (Phase 1: `.intunewin` / win32LobApp): im App-Detail neuer Abschnitt *Setup-Datei* mit Button, der eine neue Setup-Datei von einem lokalen Server-Pfad hochlaedt und als neue contentVersion aktiviert — inkl. optionaler neuer Versionsnummer (`displayVersion`). Voller Graph-Upload-Flow: contentVersion → file → Azure-Blob-Chunk-Upload → commit → committedContentVersion. Vendor-verwaltete Apps (PMPC/Robopack) sind ausgeschlossen. MSI/MSIX folgen in spaeteren Phasen - **Kategorie-Filter** in der App-Liste: neuer Dropdown, der sich dynamisch aus den vorkommenden App-Kategorien fuellt (inkl. *Ohne Kategorie*) - **Kategorien-Anzeige** im App-Detail (immer sichtbar; "Default" wenn keine zugewiesen) - **Mehrere Abteilungs-Praefixe** konfigurierbar (z.B. `abt-hm` *und* `abt-extern` parallel): neues Schema `departments.prefixes[]`, Settings-UI mit Textarea (eine pro Zeile). Der Graph-Filter wird OR-verkettet, ein einziger Listen-Request. Alter Single-String `prefix` wird weiter gelesen (Backward-Compat); Test-Endpoint zeigt Trefferzahl pro Praefix ### Geändert - **App-Liste laedt `$expand=categories`** mit — `categories` ist eine Graph-Navigation-Property und kommt sonst leer (`null`) zurueck - **Default-Scope** `DeviceManagementApps.Read.All` → `DeviceManagementApps.ReadWrite.All`: assign/rename/delete/content-update auf mobileApps brauchen ReadWrite (verifiziert via msgraph-Skill gegen den offiziellen Permission-Index) ### Behoben - **429/503-Throttling**: neuer Retry-Wrapper `Invoke-MgGraphRequestRetry` mit `Retry-After`-Honorierung + Backoff (2/5/10s) in `Get-GraphPaged` (alle Lese-Pfade) + `Add-GraphMember` (Bulk-Member-Add). 403/404 werden unveraendert durchgereicht - **Kategorien** wurden nie angezeigt — Ursache war die fehlende `$expand`-Klausel (s.o.), nicht das Frontend ### Technisch - Neue Graph-Funktionen: `Read-IntuneWinPackage`, `New-GraphAppContentVersion`, `New-GraphAppContentFile`, `Wait-GraphContentFileState`, `Send-GraphContentToAzureBlob`, `Invoke-GraphContentRenewUpload`, `Invoke-GraphContentCommit`, `Update-GraphAppContent`, `Invoke-MgGraphRequestRetry` - Neuer Endpoint: `POST /api/apps/{id}/content` (`Update-AppContentEndpoint`), Body `{ filePath, displayVersion? }` - Intune-Content-Verschluesselung dokumentiert (AES-256-CBC + HMAC-SHA256, Layout `[HMAC|IV|Ciphertext]`, ProfileVersion1) — fuer `.intunewin` aus Detection.xml uebernommen - `api()`-Helper unterstuetzt jetzt `timeoutMs` (AbortController) fuer lange Upload-Requests --- ## [0.1.22] - 2026-05-19 Robopack als zweiter Vendor analog zu PatchMyPC. Detection-Regeln wurden vom Hardcode in eine konfigurierbare Vendor-Registry verlagert. ### Neu - **Robopack-Integration**: eigenes Source-Logo (`robopack.png`), Portal-Link auf `https://app.robopack.com/`, Lock-Icons fuer Delete/Rename, Filter-Eintrag "Nur Robopack-Apps". Default-Detection: `developer equals "Robopack"` - **Vendor-Registry in `settings.json`**: neue Sektion `vendors[]` mit `id`, `displayName`, `portalUrl`, `logoFile`, `detection.field` (commandLine | developer | publisher | displayName | notes | owner), `detection.match` (contains | equals | regex | startsWith), `detection.pattern`, `block.delete`, `block.rename`. Mehrere Vendoren moeglich, erster Match gewinnt - **Dynamisches Filter-Dropdown**: pro konfiguriertem Vendor wird eine Option `Nur -Apps` zur Laufzeit erzeugt - **Vendor-Counts im Konfig-Test**: `Verbindung + Lookups testen` zeigt jetzt pro Vendor, wie viele Apps in der aktuellen Liste matchen — 0-Treffer warnen mit Hinweis auf die Detection-Regel - **Letter-Fallback fuers Vendor-Logo**: wenn die Logo-Datei fehlt, zeigt der Badge den ersten Buchstaben des Vendor-Namens als Pille ### Geändert - **Detection-Logik in `src/Graph.ps1`**: `Format-AppForFrontend` ruft `Resolve-AppVendorSource` mit `Test-AppVendorRule` auf, statt hardcoded `match "PatchMyPC"`. `Source`-String entspricht `vendor.displayName` ("PatchMyPC", "Robopack", ...) — bestehende PMPC-Datensaetze unveraendert - **Backend-Blocking generisch** (`Remove-AppEndpoint`, `Update-AppEndpoint`): pro Vendor pruefen ob `block.delete`/`block.rename` gesetzt ist, HTTP 409 mit `code = "Managed"` (z.B. `patchmypcManaged`, `robopackManaged`) - **Frontend-Render generisch**: Source-Badge, Delete-Lock und Rename-Lock werden aus dem Vendor-Eintrag (`SettingsState.vendorsByDisplayName`) abgeleitet — keine PMPC-Hardcodes mehr im UI - **`code`-Format geaendert** von `PatchMyPCManaged` zu `patchmypcManaged` (kleines `id` + `Managed`-Suffix) — Frontend-Stellen, die den exakten String pruefen, sind keine vorhanden ### Behoben - (keine; reine Feature-Erweiterung) ### Technisch - Neue PowerShell-Funktionen: `Test-AppVendorRule`, `Resolve-AppVendorSource` (in `src/Graph.ps1`), `Find-VendorBySource` (in `src/Api.ps1`) - Neue JS-Funktionen: `rebuildVendorIndexes(settings)`, `rebuildVendorFilterOptions()` (in `www/app.js`) - Neue CSS-Klassen: `.app-source.app-source-letter` (Letter-Fallback), `.set-test-icon.warn` (gelbe Warn-Pille im Konfig-Test) - Asset hinzu: `robopack.png` (Projekt-Root, ca. 53 KB) - Migration: `Merge-Settings` ergaenzt fehlende `vendors`-Sektion aus den Defaults — bestehende `settings.json` bekommt PMPC + Robopack automatisch dazu --- ## [0.1.21] - 2026-05-19 Multi-Tenant-Readiness: das Tool ist jetzt fuer fremde Tenants ausrollbar, ohne dass HanseMerkur-spezifische Werte im Code als Defaults erscheinen. ### Neu - **First-Run-Onboarding**: Bei leerem Tenant/Client/Praefix oeffnet sich das Settings-Modal automatisch beim Start. Setup-Banner im Modal und im Connect-Panel; Connect-Button bleibt disabled bis die kritischen Felder gefuellt sind - **Konfiguration testen**: Neuer Button im Settings-Modal sowie neuer Endpoint `POST /api/settings/test` — prueft die aktuell eingetragenen Werte (auch vor dem Speichern) gegen Microsoft Graph: Verbindung, Abteilungs-Gruppen-Lookup mit Trefferzahl + Sample, RPA-Gruppen mit Found/Missing-Liste, User-Such-Probe. Inline-Ergebnis mit OK/FAIL-Pillen - **Setup-Hilfetexte** unter den Connection-Feldern: Wo finde ich Tenant ID, Client ID, welche Redirect-URI ist noetig ### Geändert - **Defaults neutralisiert** (`Get-DefaultSettings` in `src/Models.ps1`): `tenantId`, `clientId`, `departments.prefix` sind leer, `rpa.groupNames = @()`. Scopes/Naming/Theme bleiben generisch. Bestehende `settings.json` werden ueber Merge-Settings unveraendert geladen - **Hilfedatei generisch**: `abt-hm-bd24-controlling` und `intune-win-app-adobe-reader-required` durch Platzhalter (`-team-controlling`, `intune-win-app--required`) ersetzt; "Default: abt-hm"-Hinweis entfernt ### Behoben - **Backend-Fallbacks entfernt**: `Get-GroupsEndpoint` liefert HTTP 412 + `code = "SettingsRequired"` wenn Praefix leer (vorher stiller `abt-hm`-Fallback). `Get-RpaGroupsEndpoint` liefert `notConfigured = $true` statt HM-RPA-Namen einzusetzen — Konfig-Probleme werden sichtbar statt kaschiert - **PowerShell 5.1-Kompatibilitaet** (`src/Server.ps1`): `Read-RequestBody` nutzt `-AsHashtable` nur ab PS 6, in 5.1 wird ohne den Switch geparst. Endpoints handhaben sowohl Hashtable als auch PSCustomObject. Vorher: POST/PUT mit Body brach in Windows PowerShell 5.1 mit "Parameter 'AsHashtable' nicht gefunden" - **Router-Logger-Bug** (`src/Router.ps1:33`): fehlende Parens um den `-f`-Format-Operator → PowerShell band `-f` als Prefix von `-ForegroundColor` und versuchte den Zeitstempel in eine ConsoleColor-Enum zu konvertieren. Folge: Unknown-Endpoint-Responses warfen 500er statt 404. Fix wie in Line 13/42 mit Klammern ### Technisch - Neuer Endpoint: `POST /api/settings/test` (Body optional — testet uebergebene Werte gegen Graph, ohne sie zu speichern) - Neue CSS-Klassen: `.banner-warning`, `.settings-test-result`, `.set-test-line`, `.set-test-icon.ok|fail` --- ## [0.1.20] - 2026-05-19 Konsolidierter Stand aller bisherigen Iterationen. Erster offiziell versionierter Release. ### Neu — App-Verwaltung - **App-Zuweisungs-Workflow** mit Session-Konzept: mehrere Apps nacheinander Pillen klicken → alle Vorgänge in einem Rutsch ausführen → HTML-Report - **App umbenennen** via Stift-Icon (Modal mit alter/neuer Name) - **App löschen** via Trash-Icon (mit Bestätigung; bei Graph-Fehler wird Original-Message + Relationship-Hinweis ausgegeben) - **PatchMyPC-Apps**: Rename + Delete blockiert (Lock-Icon + HTTP 409 mit `code: PatchMyPCManaged`) ### Neu — Zuweisungen - **Zuweisung-Erstellen-Dialog** mit 6 Optionen in zwei Spalten: - Required: Neue Gruppe / All Users / All Devices - Available: Neue Gruppe / All Users / All Devices - **Aktive Native-Zuweisungen werden ausgegraut** — keine Duplikate möglich - **Available-/Required-Gruppen-Naming** unabhängig konfigurierbar (Präfix + Suffix) - **Zuweisung entfernen** direkt im App-Detail oder im Picker-Popover (Trash-Icon pro Gruppe) - **Native Zuweisungen** (All Users / All Devices) per `POST /api/apps/{id}/assignments` ### Neu — App-Detail-Panel - **2-Spalten-Layout** statt 3 (Auto-Fit), Wide-Sektionen für lange Inhalte - **Markdown-Rendering** der App-Beschreibung (Tabellen, Listen, Code-Blöcke) via gebundeltes [marked v15](https://github.com/markedjs/marked) - **Installations-Statistik** je App (Geräte + Benutzer × Installiert / Fehler / Pending / N/A) mit Erfolgsquote-Pille - **Abhängigkeiten** mit SVG-Flow-Diagramm (orthogonale Linien, klickbare Knoten) + Klartext-Erklärung pro Relation - **Supersedence** analog mit Klartext-Erklärung (update / replace) - **Klick auf Flow-Knoten** springt zur Ziel-App und expandiert sie (mit Highlight-Flash) ### Neu — Filter & Suche - **Datums-Range-Filter** für "Zuletzt geändert" (via gebundeltes [flatpickr v4](https://flatpickr.js.org/), deutsche Lokalisierung) - **Preset-Dropdown** (Alle / Ohne Zuweisungen / Nur Available / Nur Required / Mehrere / All Users / All Devices / Intune / PatchMyPC) - **Checkbox-Chips** "Bereits Gruppenmitglied" und "All Users/Devices ausblenden" ### Neu — Einstellungen - **Settings-Cog** im Header öffnet Modal mit: - Connection: Tenant-ID, Client-ID, Scopes - Abteilungs-Gruppen: konfigurierbarer Präfix (Default `abt-hm`) - RPA-Gruppen: explizite Liste - Benutzer-Suche: konfigurierbare Felder (DisplayName / UPN / Mail / Department) - Required + Available Naming-Schema (Präfix + Suffix) - Branding: Logo-Upload (PNG/JPG/SVG/WEBP/GIF, max 2 MB) - Farben: 8 Akzentfarben + "Standardfarben wiederherstellen" - Persistenz in `%APPDATA%\IntuneAppManager-Web\settings.json` - **WCAG-Kontrast-Algorithmus** wählt automatisch Text-/Icon-Farbe (Schwarz/Weiß) je nach gewähltem Tint - **Surface-Shade-Algorithmus** leitet harmonische innere Surfaces aus der gewählten Detail-Panel-Farbe ab ### Neu — Branding - **Default-Logo** `application.png` im Projekt-Root wird angezeigt, sofern kein eigenes hochgeladen wurde - **Brand-Farbe** ist eigene Konzeptfarbe (separat von Available) — Logo-Hintergrund und Stepper-Indikator - **Avatar** im Header: Bootstrap `person-circle`-Icon, eingefärbt in Brand-Primary, mit pulsierendem grünem Online-Dot - **Logout** als Türsymbol mit Pfeil ### Neu — Header - **Cog-Icon** für Einstellungen - **Fragezeichen-Icon** für Hilfe - **Theme-Toggle** als Sun/Mond-Slider - **Avatar** mit Tooltip (vollständiger UPN) - **Logout-Icon** (statt Text-Button) ### Neu — Hilfe-System - **Hilfe-Modal** (1320 px breit) mit: - TOC-Sidebar (auto-generiert aus H2-Headings) - Aktiver Eintrag wird via Scroll-Position highlighted - Inhalt aus `www/help.md` (Markdown, jederzeit ohne Code-Änderung anpassbar) - Inhalt: Schnellstart, Hauptworkflow, Header, Spalten, App-Detail, Einstellungen, Einschränkungen, Tastatur, Fehlerbehebung ### Neu — Empfänger-Liste - **Drei Modi**: Abteilungen, RPA-Gruppen, Einzel-Benutzer — frei mischbar - **Gruppen aufklappen** (Pfeil rechts) → Mitglieder inline mit Suchfilter - **Teams-Icon** bei jedem User → Direkt-Chat in Teams-Desktop-App - **Externer-Link- und Members-Tab-Icons** öffnen direkt im Intune-Portal - **Icons immer sichtbar** (vorher hover-only) ### Neu — Backend - **Graph `$batch`-Optimierung** für App-Details: 3 Sub-Calls in 1 HTTP-Roundtrip, server-seitig parallelisiert - **PowerShell-Module-Pre-Flight** in `Start.ps1`: prüft, prompted, installiert fehlende Module im User-Scope - **WAM-Window-Focus-Helper**: Auth-Popup wird automatisch nach vorne geholt (Background-Runspace) - **HTML-Apply-Report** in `%TEMP%\IntuneAppManager-Reports\` mit Erfolg/Fehler-Tabelle nach App gruppiert - **Caches**: Apps + Groups + Membership im Server-Process. Selektive Invalidierung bei Settings-Änderungen - **Run.cmd** als plattform-unabhängiger Launcher; PowerShell-Fenster startet minimiert ### Geändert - **App-Row-Layout**: schmalere Type-/Version-Spalten, breitere Name-Spalte; Icons rechtsbündig vertikal mittig - **Filter-Chips**: keine Pillen-Rahmen mehr, mehr Gap zwischen Chips (20 px) - **App-Namen**: brechen jetzt um statt zu truncieren (kein `…` mehr) - **Detail-Panel**: max 2 Spalten statt Auto-Fit, lange Inhalte als Wide-Sektion - **Modal-Höhe**: max 85 vh statt 60 vh, kein Scrollen für übliche Dialog-Inhalte - **Stepper** im Header entfernt (war redundant) - **Default-Farben**: Brand `#27a078`, Required `#cb2a7a`, RowSelected `#71e5c4`, DetailPanel `#f7f7f7` ### Behoben - **PowerShell Single-Element-Array-JSON-Bug**: `@()` am Call-Site erzwingt Array-Serialisierung (sonst wurde Single-Dep als Objekt statt Array im JSON gerendert → Frontend ignorierte sie) - **Date-Picker Blink-Effekt** beim Klick: nativer Browser-Picker ersetzt durch flatpickr (kein Chromium-Initial-Render-Quirk mehr) - **Date-Picker Dark-Mode**: Calendar-Icon war nicht sichtbar — durch `filter: invert(1) brightness(1.4)` korrigiert - **WAM-Auth-Fenster** versteckt hinter anderen Fenstern → Parallel-Runspace holt es nach vorne - **Browser-Cache**: aggressive `no-store`-Header für HTML/JS/CSS sorgen für sofortige Updates - **Transparenz-Slider** komplett entfernt — picked color = solid background (war zuvor verwirrend) - **Logo-Cache** zweiter Upload greift sofort (mtime als Cache-Bust-Tag) - **Settings-Save**: Selektive Cache-Invalidierung statt aller Caches (Logo-Update reloaded nicht mehr die Apps) - **`jumpToAppById`**: triggert jetzt den Details-Fetch (vorher: ewiger Spinner + toggleAppExpand-Konflikt → "App geht nicht auf") - **Portal-URLs**: Group-Links auf `intune.microsoft.com/.../GroupDetailsMenuBlade/.../menuId/` korrigiert (vorher `entra.microsoft.com` ohne `/menuId/`-Suffix) - **App-Name-Icons** vertikal mittig zur ganzen Row (nicht nur zur Name-Line) - **Type/Version-Chips in markierter Row**: Kontrast korrekt (vorher unleserlich) - **Stepper-Reste**: Position der Header-Actions wieder rechts - **Connect-Endpoint**: bessere Fehlermeldung mit echter Graph-Antwort statt nur "Ungültige Anfrage" ### Entfernt - **Workflow-Stepper** im Header (Verbinden → App-Zuweisungen → Apps zuweisen → Ausführen) - **Transparenz-Slider** in den Theme-Color-Settings - **`members.html`-Standalone-Seite**: ersetzt durch direkten Intune-Portal-Link - **Native Date-Inputs** (`type="date"`): ersetzt durch flatpickr - **`color-scheme: light`**-Workaround für Date-Picker (nicht mehr nötig nach flatpickr-Integration) ### Bundled Libraries - `marked v15.0.12` (MIT) — Markdown-Renderer für App-Beschreibung + Help-Page - `flatpickr v4.6.13` (MIT) — Date-Range-Filter ### Technisch - **PowerShell-Server**: HttpListener, Single-Thread Request-Loop, ausreichend für Single-Admin-Tool - **Frontend**: Vanilla JS + CSS, keine Frameworks - **Persistenz**: JSON-Datei in `%APPDATA%\IntuneAppManager-Web\settings.json` - **Cache-Strategy**: Apps + Gruppen + GroupMembers im PS-Prozess; Theme + Logo per CSS-Variable zur Laufzeit überschrieben