Add related help titles and fix umlauts
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Services\Help;
|
|||||||
|
|
||||||
use Illuminate\Filesystem\Filesystem;
|
use Illuminate\Filesystem\Filesystem;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
@@ -70,6 +71,8 @@ class HelpSyncService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$articles = $this->hydrateRelatedTitles($articles);
|
||||||
|
|
||||||
$disk = config('help.disk');
|
$disk = config('help.disk');
|
||||||
$compiledPath = trim(config('help.compiled_path'), '/');
|
$compiledPath = trim(config('help.compiled_path'), '/');
|
||||||
$written = [];
|
$written = [];
|
||||||
@@ -87,6 +90,58 @@ class HelpSyncService
|
|||||||
return $written;
|
return $written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function hydrateRelatedTitles(Collection $articles): Collection
|
||||||
|
{
|
||||||
|
$titleIndex = $articles->mapWithKeys(function (array $article) {
|
||||||
|
$audience = Arr::get($article, 'audience');
|
||||||
|
$locale = Arr::get($article, 'locale');
|
||||||
|
$slug = Arr::get($article, 'slug');
|
||||||
|
|
||||||
|
if (! $audience || ! $locale || ! $slug) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [$this->articleKey((string) $audience, (string) $locale, (string) $slug) => Arr::get($article, 'title')];
|
||||||
|
});
|
||||||
|
|
||||||
|
return $articles->map(function (array $article) use ($titleIndex) {
|
||||||
|
$related = Arr::get($article, 'related', []);
|
||||||
|
|
||||||
|
if (empty($related)) {
|
||||||
|
return $article;
|
||||||
|
}
|
||||||
|
|
||||||
|
$audience = (string) Arr::get($article, 'audience');
|
||||||
|
$locale = (string) Arr::get($article, 'locale');
|
||||||
|
|
||||||
|
$article['related'] = collect($related)
|
||||||
|
->map(function ($item) use ($titleIndex, $audience, $locale) {
|
||||||
|
$slug = is_array($item) ? Arr::get($item, 'slug') : (is_string($item) ? $item : null);
|
||||||
|
|
||||||
|
if (! $slug) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = $titleIndex->get($this->articleKey($audience, $locale, $slug));
|
||||||
|
|
||||||
|
return array_filter([
|
||||||
|
'slug' => $slug,
|
||||||
|
'title' => $title,
|
||||||
|
], static fn ($value) => $value !== null && $value !== '');
|
||||||
|
})
|
||||||
|
->filter()
|
||||||
|
->values()
|
||||||
|
->all();
|
||||||
|
|
||||||
|
return $article;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private function articleKey(string $audience, string $locale, string $slug): string
|
||||||
|
{
|
||||||
|
return sprintf('%s::%s::%s', $audience, $locale, $slug);
|
||||||
|
}
|
||||||
|
|
||||||
private function parseFile(SplFileInfo $file): array
|
private function parseFile(SplFileInfo $file): array
|
||||||
{
|
{
|
||||||
$contents = $this->files->get($file->getPathname());
|
$contents = $this->files->get($file->getPathname());
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: "FAQ: Event-Admin"
|
|||||||
locale: de
|
locale: de
|
||||||
slug: faq-admin
|
slug: faq-admin
|
||||||
audience: admin
|
audience: admin
|
||||||
summary: "Kurze Antworten auf die haeufigsten Fragen von Event-Admins."
|
summary: "Kurze Antworten auf die häufigsten Fragen von Event-Admins."
|
||||||
version_introduced: 2025.4
|
version_introduced: 2025.4
|
||||||
requires_app_version: "^3.2.0"
|
requires_app_version: "^3.2.0"
|
||||||
status: draft
|
status: draft
|
||||||
@@ -19,8 +19,8 @@ related:
|
|||||||
**Wo finde ich Join-Link oder QR-Code?**
|
**Wo finde ich Join-Link oder QR-Code?**
|
||||||
Im Event-Dashboard unter den Schnellaktionen.
|
Im Event-Dashboard unter den Schnellaktionen.
|
||||||
|
|
||||||
**Gaeste koennen nicht beitreten.**
|
**Gäste können nicht beitreten.**
|
||||||
Pruefe, ob das Event **veroeffentlicht** ist, und teile den Join-Link oder QR erneut.
|
Prüfe, ob das Event **veröffentlicht** ist, und teile den Join-Link oder QR erneut.
|
||||||
|
|
||||||
## Uploads & Moderation
|
## Uploads & Moderation
|
||||||
**Uploads erscheinen nicht.**
|
**Uploads erscheinen nicht.**
|
||||||
@@ -31,7 +31,7 @@ Im Control Room ausblenden, dann verschwindet es sofort aus der Galerie.
|
|||||||
|
|
||||||
## Live Show
|
## Live Show
|
||||||
**Die Live Show bleibt leer.**
|
**Die Live Show bleibt leer.**
|
||||||
Pruefe den Show-Link und ob Fotos freigegeben wurden.
|
Prüfe den Show-Link und ob Fotos freigegeben wurden.
|
||||||
|
|
||||||
### Weitere Hilfe
|
### Weitere Hilfe
|
||||||
`control-room-moderation` fuer die Queue oder `live-show-setup` fuer die Leinwand.
|
`control-room-moderation` für die Queue oder `live-show-setup` für die Leinwand.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Dieses Portal sammelt alles, was Event-Admins für Vorbereitung, Kern-Workflows
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Dashboard | Wo sehe ich Status, KPIs und Schnellaktionen? | `tenant-dashboard-overview` |
|
| Dashboard | Wo sehe ich Status, KPIs und Schnellaktionen? | `tenant-dashboard-overview` |
|
||||||
| Event-Vorbereitung | Was muss vor dem Start erledigt sein? | `event-prep-checklist` |
|
| Event-Vorbereitung | Was muss vor dem Start erledigt sein? | `event-prep-checklist` |
|
||||||
| FAQ | Was sind die haeufigsten Fragen? | `faq-admin` |
|
| FAQ | Was sind die häufigsten Fragen? | `faq-admin` |
|
||||||
| Control Room | Wie moderiere ich Uploads und steuere die Queue? | `control-room-moderation` |
|
| Control Room | Wie moderiere ich Uploads und steuere die Queue? | `control-room-moderation` |
|
||||||
| Live Show | Wie richte ich den Live-Show-Player ein? | `live-show-setup` |
|
| Live Show | Wie richte ich den Live-Show-Player ein? | `live-show-setup` |
|
||||||
| Abschluss & Exporte | Was erledige ich nach dem Event? | `post-event-wrapup` |
|
| Abschluss & Exporte | Was erledige ich nach dem Event? | `post-event-wrapup` |
|
||||||
|
|||||||
@@ -365,7 +365,7 @@ export type HelpCenterArticleSummary = {
|
|||||||
updated_at?: string;
|
updated_at?: string;
|
||||||
status?: string;
|
status?: string;
|
||||||
translation_state?: string;
|
translation_state?: string;
|
||||||
related?: Array<{ slug: string }>;
|
related?: Array<{ slug: string; title?: string | null }>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type HelpCenterArticle = HelpCenterArticleSummary & {
|
export type HelpCenterArticle = HelpCenterArticleSummary & {
|
||||||
|
|||||||
@@ -20,5 +20,15 @@ class HelpSyncServiceTest extends TestCase
|
|||||||
$this->assertNotEmpty($result);
|
$this->assertNotEmpty($result);
|
||||||
Storage::disk('local')->assertExists('help/guest/en/articles.json');
|
Storage::disk('local')->assertExists('help/guest/en/articles.json');
|
||||||
Storage::disk('local')->assertExists('help/guest/de/articles.json');
|
Storage::disk('local')->assertExists('help/guest/de/articles.json');
|
||||||
|
Storage::disk('local')->assertExists('help/admin/en/articles.json');
|
||||||
|
|
||||||
|
$articles = json_decode(Storage::disk('local')->get('help/admin/en/articles.json'), true);
|
||||||
|
$this->assertIsArray($articles);
|
||||||
|
|
||||||
|
$controlRoom = collect($articles)->firstWhere('slug', 'control-room-moderation');
|
||||||
|
$this->assertNotNull($controlRoom);
|
||||||
|
|
||||||
|
$related = collect($controlRoom['related'] ?? [])->firstWhere('slug', 'event-prep-checklist');
|
||||||
|
$this->assertSame('Event Preparation Checklist', $related['title'] ?? null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user