feat(admin): Einstellungsseite überarbeitet, auch für das Handy
Verbindung: Probleme vor der Anleitung. Tools: Suche, Filter, Alle ein-/ausklappen, Zurücksetzen je Gruppe. Divi-Reiter in Klartext mit Statussymbolen. Rollenhinweise, Hilfe-Tab, Reiter als Raster und Karten auf dem Handy, Kontrast, Tippflächen, einheitliche Du-Anrede. Bestätigungen über data-lit-mcp-confirm statt Inline-onclick. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
165e61d7fe
commit
96fa58188b
@@ -107,7 +107,7 @@ final class DiviTab implements AdminTab
|
||||
/* translators: 1: Divi version, 2: comma separated feature names */
|
||||
__(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong -- WordPress.WP.I18n forbids splitting the text argument.
|
||||
'LIT MCP: Mit Divi %1$s sind diese Fähigkeiten nicht nutzbar: %2$s. Die betroffenen Werkzeuge lehnen ab, alle anderen laufen weiter.',
|
||||
'LIT MCP: Mit Divi %1$s sind diese Fähigkeiten nicht nutzbar: %2$s. Die betroffenen Tools lehnen ab, alle anderen laufen weiter.',
|
||||
'wp-lit-mcp'
|
||||
),
|
||||
$this->version(),
|
||||
@@ -211,7 +211,7 @@ final class DiviTab implements AdminTab
|
||||
echo '<h2>' . esc_html__('Divi-Freigabe', 'wp-lit-mcp') . '</h2>';
|
||||
echo '<p>' . esc_html__(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong -- WordPress.WP.I18n forbids splitting the text argument.
|
||||
'LIT MCP prüft nach einem Divi-Update jede Fähigkeit einzeln (z. B. „Seiten schreiben“). Ist sie nicht nutzbar, lehnen nur die Werkzeuge ab, die sie brauchen; alle anderen laufen weiter.',
|
||||
'LIT MCP prüft nach einem Divi-Update jede Fähigkeit einzeln (z. B. „Seiten schreiben“). Ist sie nicht nutzbar, lehnen nur die Tools ab, die sie brauchen; alle anderen laufen weiter.',
|
||||
'wp-lit-mcp'
|
||||
) . '</p>';
|
||||
if ($this->removed !== []) {
|
||||
@@ -225,6 +225,7 @@ final class DiviTab implements AdminTab
|
||||
);
|
||||
}
|
||||
|
||||
$this->renderNextStep($status);
|
||||
$this->renderStatus($status);
|
||||
$this->renderFeatures($status);
|
||||
$this->renderForms($status, $report);
|
||||
@@ -233,6 +234,45 @@ final class DiviTab implements AdminTab
|
||||
}
|
||||
}
|
||||
|
||||
/** One sentence on what to do now, above the details; a released version needs none. */
|
||||
private function renderNextStep(ReleaseStatus $status): void
|
||||
{
|
||||
if ($status->version === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$text = match ($status->state) {
|
||||
ReleaseState::Untested => sprintf(
|
||||
/* translators: %s: Divi version */
|
||||
__(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong -- WordPress.WP.I18n forbids splitting the text.
|
||||
'Divi %s ist noch nicht geprüft. Starte unten die Prüfung; danach kannst du die Version freigeben.',
|
||||
'wp-lit-mcp'
|
||||
),
|
||||
$status->version
|
||||
),
|
||||
ReleaseState::Incompatible => sprintf(
|
||||
/* translators: %s: Divi version */
|
||||
__(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong -- WordPress.WP.I18n forbids splitting the text.
|
||||
'Divi %s hat Stellen geändert, die LIT MCP nutzt. Die betroffenen Tools bleiben gesperrt, bis ein Plugin-Update erscheint.',
|
||||
'wp-lit-mcp'
|
||||
),
|
||||
$status->version
|
||||
),
|
||||
default => null,
|
||||
};
|
||||
if ($text === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf(
|
||||
'<div class="notice notice-%s inline"><p><strong>%s</strong></p></div>',
|
||||
$status->state === ReleaseState::Incompatible ? 'error' : 'warning',
|
||||
esc_html($text)
|
||||
);
|
||||
}
|
||||
|
||||
private function renderStatus(ReleaseStatus $status): void
|
||||
{
|
||||
echo '<table class="form-table" role="presentation"><tbody>';
|
||||
@@ -242,9 +282,10 @@ final class DiviTab implements AdminTab
|
||||
esc_html($status->version === '' ? __('nicht erkannt', 'wp-lit-mcp') : $status->version)
|
||||
);
|
||||
printf(
|
||||
'<tr><th scope="row">%s</th><td><strong>%s</strong> – %s</td></tr>',
|
||||
'<tr><th scope="row">%s</th><td>%s – %s</td></tr>',
|
||||
esc_html__('Gesamtzustand', 'wp-lit-mcp'),
|
||||
esc_html($this->stateLabel($status->state)),
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped in stateBadge().
|
||||
$this->stateBadge($status->state),
|
||||
esc_html($this->explanation($status))
|
||||
);
|
||||
if ($status->problems !== []) {
|
||||
@@ -259,31 +300,47 @@ final class DiviTab implements AdminTab
|
||||
|
||||
private function renderFeatures(ReleaseStatus $status): void
|
||||
{
|
||||
echo '<h3>' . esc_html__('Fähigkeiten', 'wp-lit-mcp') . '</h3>';
|
||||
// Open when something needs attention; a released version keeps the long table folded.
|
||||
printf(
|
||||
'<details class="lit-mcp-divi-details"%s><summary>%s</summary>',
|
||||
$status->state === ReleaseState::Released ? '' : ' open',
|
||||
esc_html__('Fähigkeiten im Detail', 'wp-lit-mcp')
|
||||
);
|
||||
echo '<table class="widefat striped lit-mcp-divi-features"><thead><tr>';
|
||||
$headings = [
|
||||
__('Fähigkeit', 'wp-lit-mcp'),
|
||||
__('Zustand', 'wp-lit-mcp'),
|
||||
__('Quelle', 'wp-lit-mcp'),
|
||||
__('Probleme', 'wp-lit-mcp'),
|
||||
__('Betroffene Werkzeuge', 'wp-lit-mcp'),
|
||||
__('Betroffene Tools', 'wp-lit-mcp'),
|
||||
];
|
||||
foreach ($headings as $heading) {
|
||||
echo '<th scope="col">' . esc_html($heading) . '</th>';
|
||||
}
|
||||
echo '</tr></thead><tbody>';
|
||||
foreach (($this->overview ?? FeatureOverview::withoutTools())->rows($status->matrix) as $row) {
|
||||
echo '<tr><td>' . esc_html($row['label']) . '</td>';
|
||||
echo '<td><strong>' . esc_html($this->stateLabel(ReleaseState::from($row['state']))) . '</strong></td>';
|
||||
echo '<td>' . esc_html($this->sourceLabel($row['source'])) . '</td>';
|
||||
echo '<td>';
|
||||
// data-label: on phones each row becomes a card and the cell names itself.
|
||||
printf('<tr><td data-label="%s">%s</td>', esc_attr($headings[0]), esc_html($row['label']));
|
||||
printf(
|
||||
'<td data-label="%s">%s</td>',
|
||||
esc_attr($headings[1]),
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped in stateBadge().
|
||||
$this->stateBadge(ReleaseState::from($row['state']))
|
||||
);
|
||||
printf(
|
||||
'<td data-label="%s">%s</td>',
|
||||
esc_attr($headings[2]),
|
||||
esc_html($this->sourceLabel($row['source']))
|
||||
);
|
||||
printf('<td data-label="%s">', esc_attr($headings[3]));
|
||||
$this->renderList($row['problems'], false);
|
||||
echo '</td><td>';
|
||||
printf('</td><td data-label="%s">', esc_attr($headings[4]));
|
||||
$this->renderList($row['tools'], true);
|
||||
echo '</td></tr>';
|
||||
}
|
||||
echo '</tbody></table>';
|
||||
$this->renderAutomationNote();
|
||||
echo '</details>';
|
||||
}
|
||||
|
||||
/** @param list<string> $items */
|
||||
@@ -305,9 +362,9 @@ final class DiviTab implements AdminTab
|
||||
private function sourceLabel(?string $source): string
|
||||
{
|
||||
return match ($source) {
|
||||
ReleaseStatus::SOURCE_CODE => __('Plugin (code)', 'wp-lit-mcp'),
|
||||
ReleaseStatus::SOURCE_DATABASE => __('Freigabe auf dieser Website (database)', 'wp-lit-mcp'),
|
||||
ReleaseStatus::SOURCE_AUTO => __('Automatik (auto)', 'wp-lit-mcp'),
|
||||
ReleaseStatus::SOURCE_CODE => __('Im Plugin als getestet hinterlegt', 'wp-lit-mcp'),
|
||||
ReleaseStatus::SOURCE_DATABASE => __('Von dir auf dieser Website freigegeben', 'wp-lit-mcp'),
|
||||
ReleaseStatus::SOURCE_AUTO => __('Automatisch geprüft', 'wp-lit-mcp'),
|
||||
default => '–',
|
||||
};
|
||||
}
|
||||
@@ -331,6 +388,23 @@ final class DiviTab implements AdminTab
|
||||
) . '</p>';
|
||||
}
|
||||
|
||||
/** Same coloured icons as the status list on the tab "Verbindung"; the word stays, colour is never alone. */
|
||||
private function stateBadge(ReleaseState $state): string
|
||||
{
|
||||
$icon = match ($state) {
|
||||
ReleaseState::Released => 'yes-alt',
|
||||
ReleaseState::Untested => 'warning',
|
||||
ReleaseState::Incompatible => 'dismiss',
|
||||
};
|
||||
|
||||
return sprintf(
|
||||
'<span class="lit-mcp-state lit-mcp-status-%1$s"><span class="dashicons dashicons-%1$s"'
|
||||
. ' aria-hidden="true"></span> <strong>%2$s</strong></span>',
|
||||
$icon,
|
||||
esc_html($this->stateLabel($state))
|
||||
);
|
||||
}
|
||||
|
||||
private function stateLabel(ReleaseState $state): string
|
||||
{
|
||||
return match ($state) {
|
||||
@@ -352,7 +426,7 @@ final class DiviTab implements AdminTab
|
||||
if ($status->state === ReleaseState::Untested) {
|
||||
return __(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong -- WordPress.WP.I18n forbids splitting the text argument.
|
||||
'Diese Version ist nicht geprüft. Die Werkzeuge der ungetesteten Fähigkeiten (Tabelle unten) lehnen ab, bis die Version freigegeben ist; alle anderen laufen weiter.',
|
||||
'Diese Version ist nicht geprüft. Die Tools der ungetesteten Fähigkeiten (Tabelle unten) lehnen ab, bis die Version freigegeben ist; alle anderen laufen weiter.',
|
||||
'wp-lit-mcp'
|
||||
);
|
||||
}
|
||||
@@ -446,8 +520,18 @@ final class DiviTab implements AdminTab
|
||||
))
|
||||
);
|
||||
foreach ($report->steps as $step) {
|
||||
$mark = $step->skipped ? '–' : ($step->green() ? '✓' : '✗');
|
||||
printf('<li>%s %s', esc_html($mark), esc_html($step->label()));
|
||||
[$icon, $word] = match (true) {
|
||||
$step->skipped => ['minus', __('übersprungen', 'wp-lit-mcp')],
|
||||
$step->green() => ['yes-alt', __('bestanden', 'wp-lit-mcp')],
|
||||
default => ['dismiss', __('fehlgeschlagen', 'wp-lit-mcp')],
|
||||
};
|
||||
printf(
|
||||
'<li class="lit-mcp-state lit-mcp-status-%1$s"><span class="dashicons dashicons-%1$s"'
|
||||
. ' aria-hidden="true"></span><span class="screen-reader-text">%2$s:</span> %3$s',
|
||||
esc_attr($icon),
|
||||
esc_html($word),
|
||||
esc_html($step->label())
|
||||
);
|
||||
if ($step->skipped) {
|
||||
echo ' (' . esc_html__('nicht ausgeführt', 'wp-lit-mcp') . ')';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user