summaryrefslogtreecommitdiffstats
path: root/library/Icinga/Web/Widget/ItemList/MigrationListItem.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Icinga/Web/Widget/ItemList/MigrationListItem.php')
-rw-r--r--library/Icinga/Web/Widget/ItemList/MigrationListItem.php151
1 files changed, 151 insertions, 0 deletions
diff --git a/library/Icinga/Web/Widget/ItemList/MigrationListItem.php b/library/Icinga/Web/Widget/ItemList/MigrationListItem.php
new file mode 100644
index 0000000..284ce4c
--- /dev/null
+++ b/library/Icinga/Web/Widget/ItemList/MigrationListItem.php
@@ -0,0 +1,151 @@
+<?php
+
+/* Icinga Web 2 | (c) 2023 Icinga GmbH | GPLv2+ */
+
+namespace Icinga\Web\Widget\ItemList;
+
+use Icinga\Application\Hook\Common\DbMigrationStep;
+use Icinga\Application\Hook\DbMigrationHook;
+use ipl\Html\Attributes;
+use ipl\Html\BaseHtmlElement;
+use ipl\Html\Contract\FormElement;
+use ipl\Html\FormattedString;
+use ipl\Html\Html;
+use ipl\Html\HtmlElement;
+use ipl\Html\HtmlString;
+use ipl\Html\Text;
+use ipl\I18n\Translation;
+use ipl\Web\Common\BaseListItem;
+use ipl\Web\Url;
+use ipl\Web\Widget\EmptyState;
+use ipl\Web\Widget\Icon;
+use ipl\Web\Widget\Link;
+use LogicException;
+
+class MigrationListItem extends BaseListItem
+{
+ use Translation;
+
+ /** @var ?FormElement */
+ protected $migrateButton;
+
+ /** @var DbMigrationHook Just for type hint */
+ protected $item;
+
+ /**
+ * Set a migration form of this list item
+ *
+ * @param FormElement $migrateButton
+ *
+ * @return $this
+ */
+ public function setMigrateButton(FormElement $migrateButton): self
+ {
+ $this->migrateButton = $migrateButton;
+
+ return $this;
+ }
+
+ protected function assembleTitle(BaseHtmlElement $title): void
+ {
+ $title->addHtml(
+ FormattedString::create(
+ t('%s ', '<name>'),
+ HtmlElement::create('span', ['class' => 'subject'], $this->item->getName())
+ )
+ );
+ }
+
+ protected function assembleHeader(BaseHtmlElement $header): void
+ {
+ if ($this->migrateButton === null) {
+ throw new LogicException('Please set the migrate submit button beforehand');
+ }
+
+ $header->addHtml($this->createTitle());
+ $header->addHtml($this->migrateButton);
+ }
+
+ protected function assembleCaption(BaseHtmlElement $caption): void
+ {
+ $migrations = $this->item->getMigrations();
+ /** @var DbMigrationStep $migration */
+ $migration = array_shift($migrations);
+ if ($migration->getLastState()) {
+ if ($migration->getDescription()) {
+ $caption->addHtml(Text::create($migration->getDescription()));
+ } else {
+ $caption->addHtml(new EmptyState(Text::create($this->translate('No description provided.'))));
+ }
+
+ $scriptPath = $migration->getScriptPath();
+ /** @var string $parentDirs */
+ $parentDirs = substr($scriptPath, (int) strpos($scriptPath, 'schema'));
+ $parentDirs = substr($parentDirs, 0, strrpos($parentDirs, '/') + 1);
+
+ $title = new HtmlElement('div', Attributes::create(['class' => 'title']));
+ $title->addHtml(
+ new HtmlElement('span', null, Text::create($parentDirs)),
+ new HtmlElement(
+ 'span',
+ Attributes::create(['class' => 'version']),
+ Text::create($migration->getVersion() . '.sql')
+ ),
+ new HtmlElement(
+ 'span',
+ Attributes::create(['class' => 'upgrade-failed']),
+ Text::create($this->translate('Upgrade failed'))
+ )
+ );
+
+ $error = new HtmlElement('div', Attributes::create([
+ 'class' => 'collapsible',
+ 'data-visible-height' => '58',
+ ]));
+ $error->addHtml(new HtmlElement('pre', null, new HtmlString(Html::escape($migration->getLastState()))));
+
+ $errorSection = new HtmlElement('div', Attributes::create(['class' => 'errors-section',]));
+ $errorSection->addHtml(
+ new HtmlElement('header', null, new Icon('circle-xmark', ['class' => 'status-icon']), $title),
+ $caption,
+ $error
+ );
+
+ $caption->prependWrapper($errorSection);
+ }
+ }
+
+ protected function assembleFooter(BaseHtmlElement $footer): void
+ {
+ $footer->addHtml((new MigrationList($this->item->getLatestMigrations(3)))->setMinimal(false));
+ if ($this->item->count() > 3) {
+ $footer->addHtml(
+ new Link(
+ sprintf($this->translate('Show all %d migrations'), $this->item->count()),
+ Url::fromPath(
+ 'migrations/migration',
+ [DbMigrationHook::MIGRATION_PARAM => $this->item->getModuleName()]
+ ),
+ [
+ 'data-base-target' => '_next',
+ 'class' => 'show-more'
+ ]
+ )
+ );
+ }
+ }
+
+ protected function assembleMain(BaseHtmlElement $main): void
+ {
+ $main->addHtml($this->createHeader());
+ $caption = $this->createCaption();
+ if (! $caption->isEmpty()) {
+ $main->addHtml($caption);
+ }
+
+ $footer = $this->createFooter();
+ if ($footer) {
+ $main->addHtml($footer);
+ }
+ }
+}