diff --git a/composer.json b/composer.json index 42991b3ac..aca51721a 100644 --- a/composer.json +++ b/composer.json @@ -78,6 +78,7 @@ "drupal/user_bundle": "^1.4", "drupal/user_registrationpassword": "^2.0", "drupal/views_bulk_edit": "^3.0", + "drupal/views_infinite_scroll": "^2.0", "drupal/yearonly": "^9.1", "drush/drush": "^13.7", "kenwheeler/slick": "^1.8", @@ -158,7 +159,8 @@ "patches": { "drupal/helfi_platform_config": { "Catch exception during hero paragraphs update": "patches/helfi_platform_config_hero_paragraph_fix.patch", - "Skip update_9400 on Drupal 11 (HAL/RDF modules removed)": "patches/helfi_platform_config-d11-update-9400.patch" + "Skip update_9400 on Drupal 11 (HAL/RDF modules removed)": "patches/helfi_platform_config-d11-update-9400.patch", + "Make update_9328 idempotent when status field is already deleting/purging": "patches/helfi_platform_config-update-9328-idempotent.patch" }, "drupal/config_terms": { "Drupal 11 compatibility fixes": "https://www.drupal.org/files/issues/2024-06-02/config_terms.1.x-dev.rector.patch" diff --git a/composer.lock b/composer.lock index 7121886b7..669372216 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "58eedf106252323583ad03816db8e8a1", + "content-hash": "e09ed94add98d74a04af8ea6678c7981", "packages": [ { "name": "asm89/stack-cors", @@ -1986,29 +1986,29 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.5", + "version": "1.1.6", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", + "reference": "d4fe3e6fd9bb9e72557a19674f44d8ac7db4c6ca", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "conflict": { - "phpunit/phpunit": "<=7.5 || >=13" + "phpunit/phpunit": "<=7.5 || >=14" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^12 || ^13", - "phpstan/phpstan": "1.4.10 || 2.1.11", + "doctrine/coding-standard": "^9 || ^12 || ^14", + "phpstan/phpstan": "1.4.10 || 2.1.30", "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12.4 || ^13.0", "psr/log": "^1 || ^2 || ^3" }, "suggest": { @@ -2028,9 +2028,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.5" + "source": "https://github.com/doctrine/deprecations/tree/1.1.6" }, - "time": "2025-04-07T20:06:18+00:00" + "time": "2026-02-07T07:09:04+00:00" }, { "name": "doctrine/lexer", @@ -20569,6 +20569,18 @@ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state", + "type": "tidelift" } ], "time": "2024-03-02T07:19:19+00:00" diff --git a/patches/helfi_platform_config-update-9328-idempotent.patch b/patches/helfi_platform_config-update-9328-idempotent.patch new file mode 100644 index 000000000..d24793dce --- /dev/null +++ b/patches/helfi_platform_config-update-9328-idempotent.patch @@ -0,0 +1,65 @@ +diff --git a/helfi_platform_config.install b/helfi_platform_config.install +index 37e8a45d..b7aab1fe 100644 +--- a/helfi_platform_config.install ++++ b/helfi_platform_config.install +@@ -459,22 +459,38 @@ function helfi_platform_config_update_9328(): void { + // Redirect implemented EntityPublishableInterface: + // https://www.drupal.org/project/redirect/issues/3424962. + // We implemented similar field in UHF-10539. + $db = \Drupal::database(); ++ $schema = $db->schema(); + +- // Migrate our data to the redirect module format: +- $db->update('redirect') +- ->expression('enabled', 'status') +- ->execute(); ++ // Migrate our data to the redirect module format when both columns exist. ++ if ($schema->fieldExists('redirect', 'status') && $schema->fieldExists('redirect', 'enabled')) { ++ $db->update('redirect') ++ ->expression('enabled', 'status') ++ ->execute(); + +- // Verify the data was copied successfully. +- $status_count = $db->select('redirect', 'r') +- ->fields('r', ['rid']) +- ->where('r.status != r.enabled') +- ->countQuery() +- ->execute() +- ->fetchField(); ++ // Verify the data was copied successfully. ++ $status_count = $db->select('redirect', 'r') ++ ->fields('r', ['rid']) ++ ->where('r.status != r.enabled') ++ ->countQuery() ++ ->execute() ++ ->fetchField(); + +- if ($status_count > 0) { +- throw new UpdateException("Data migration failed: {$status_count} records have mismatched status/enabled values."); ++ if ($status_count > 0) { ++ throw new UpdateException("Data migration failed: {$status_count} records have mismatched status/enabled values."); ++ } + } + + // Remove the status field. + $fieldStorageDefinition = \Drupal::entityDefinitionUpdateManager() + ->getFieldStorageDefinition('status', 'redirect'); + + if ($fieldStorageDefinition instanceof FieldStorageDefinitionInterface) { +- \Drupal::entityDefinitionUpdateManager()->uninstallFieldStorageDefinition($fieldStorageDefinition); ++ try { ++ \Drupal::entityDefinitionUpdateManager()->uninstallFieldStorageDefinition($fieldStorageDefinition); ++ } ++ catch (\Exception $e) { ++ if (str_contains($e->getMessage(), 'already been deleted') || str_contains($e->getMessage(), 'process of being purged')) { ++ \Drupal::logger('helfi_platform_config') ++ ->notice('Skipping redirect status field uninstall in update 9328: @message', [ ++ '@message' => $e->getMessage(), ++ ]); ++ } ++ else { ++ throw $e; ++ } ++ } + } + } diff --git a/public/modules/custom/asu_application/assets/css/application-submit.css b/public/modules/custom/asu_application/assets/css/application-submit.css new file mode 100644 index 000000000..8ada64a94 --- /dev/null +++ b/public/modules/custom/asu_application/assets/css/application-submit.css @@ -0,0 +1,119 @@ +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"], +.ui-dialog[data-asu-application-confirm-dialog="1"] { + --gin-spacing-m: 1rem; + --gin-spacing-l: 1.5rem; + --gin-border-m: 0.5rem; + --gin-bg-layer: #fff !important; +} + +.asu-application-confirm-dialog.ui-dialog, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] { + border: 1px solid var(--color-black-20, #cfd4d9) !important; + border-radius: 8px !important; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.14); + overflow: hidden; + z-index: 100; + background: #fff !important; +} + +.asu-application-confirm-dialog .ui-dialog-titlebar, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] + .ui-dialog-titlebar { + background: var(--color-black, #1b1b1b) !important; + border: 0 !important; + border-radius: 0 !important; + color: var(--color-white, #fff); + padding: 20px 24px !important; +} + +.asu-application-confirm-dialog .ui-dialog-title, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] + .ui-dialog-title { + color: inherit; + font-weight: 700; +} + +.asu-application-confirm-dialog .ui-dialog-content, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] + .ui-dialog-content { + padding: 20px 24px; + position: relative; + z-index: 2; +} + +.asu-application-confirm-dialog + #asu-application-delete-confirm-dialog + .hds-modal__content, +.asu-application-confirm-dialog + #asu-application-delete-confirm-dialog + .hds-modal__body, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] + #asu-application-delete-confirm-dialog + .hds-modal__content, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] + #asu-application-delete-confirm-dialog + .hds-modal__body { + background: transparent; + display: block; + margin: 0; + max-width: none; + padding: 0; + position: static; + width: auto; +} + +.asu-application-confirm-dialog__message { + margin: 0; + line-height: 1.5; +} + +.asu-application-confirm-dialog .ui-dialog-buttonpane, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] + .ui-dialog-buttonpane { + border-top: 1px solid var(--color-black-10, #e5e8eb) !important; + margin: 0; + padding: 12px 24px !important; + position: relative; + z-index: 3; +} + +.asu-application-confirm-dialog .ui-dialog-buttonset, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] + .ui-dialog-buttonset { + display: flex; + gap: 8px; +} + +.asu-application-confirm-dialog .ui-dialog-buttonpane button, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] + .ui-dialog-buttonpane + button { + border: 1px solid #000; + background: #fff; + color: #000; + padding: 10px 16px; + font-weight: 600; + cursor: pointer; +} + +.asu-application-confirm-dialog .ui-dialog-buttonpane .hds-button, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] + .ui-dialog-buttonpane + .hds-button { + align-items: center; + display: inline-flex; + justify-content: center; + min-height: 0; + pointer-events: auto; + position: relative; + width: auto; + z-index: 4; +} + +.asu-application-confirm-dialog .ui-dialog-buttonpane button:first-child, +.ui-dialog[aria-describedby="asu-application-delete-confirm-dialog"] + .ui-dialog-buttonpane + button:first-child { + background: #000; + color: #fff; +} diff --git a/public/modules/custom/asu_application/assets/js/application-submit.js b/public/modules/custom/asu_application/assets/js/application-submit.js index b543867ef..12918f706 100644 --- a/public/modules/custom/asu_application/assets/js/application-submit.js +++ b/public/modules/custom/asu_application/assets/js/application-submit.js @@ -34,6 +34,10 @@ $dialog.dialog({ modal: true, width: 450, + dialogClass: "asu-application-confirm-dialog", + classes: { + "ui-dialog": "asu-application-confirm-dialog", + }, buttons: { [continueLabel]: function () { $confirmInput.val("1"); @@ -45,6 +49,11 @@ }, }, }); + + $dialog + .dialog("widget") + .addClass("asu-application-confirm-dialog") + .attr("data-asu-application-confirm-dialog", "1"); } if (isDeleteAction) { @@ -58,6 +67,10 @@ $dialog.dialog({ modal: true, width: 450, + dialogClass: "asu-application-confirm-dialog", + classes: { + "ui-dialog": "asu-application-confirm-dialog", + }, buttons: { [continueLabel]: function () { $(this).dialog("close"); @@ -68,6 +81,11 @@ }, }, }); + + $dialog + .dialog("widget") + .addClass("asu-application-confirm-dialog") + .attr("data-asu-application-confirm-dialog", "1"); } }); }); diff --git a/public/modules/custom/asu_application/asu_application.libraries.yml b/public/modules/custom/asu_application/asu_application.libraries.yml index ee7d6aa1d..1860b78e6 100644 --- a/public/modules/custom/asu_application/asu_application.libraries.yml +++ b/public/modules/custom/asu_application/asu_application.libraries.yml @@ -6,6 +6,9 @@ application_submit: version: 1.x js: assets/js/application-submit.js: {} + css: + component: + assets/css/application-submit.css: {} dependencies: - core/jquery - core/drupal.dialog diff --git a/public/modules/custom/asu_application/src/Form/ApplicationForm.php b/public/modules/custom/asu_application/src/Form/ApplicationForm.php index a394ff6d0..bb2be8a9b 100644 --- a/public/modules/custom/asu_application/src/Form/ApplicationForm.php +++ b/public/modules/custom/asu_application/src/Form/ApplicationForm.php @@ -146,11 +146,7 @@ public static function addConfirmDialogHtml(string $html, array $form): string { $modal = << -
{$message}
-