From 162724ab9baa2cae21a5827da7a281f37efc5ef4 Mon Sep 17 00:00:00 2001 From: Juho Lehmonen Date: Thu, 27 Jul 2023 09:27:58 +0300 Subject: [PATCH 01/21] PP-499: Enable fetching office holder decisions from elasticsearch. --- .../custom/paatokset_policymakers/paatokset_policymakers.module | 2 +- .../paatokset_submenus/src/Plugin/Block/AgendasSubmenuBlock.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/modules/custom/paatokset_policymakers/paatokset_policymakers.module b/public/modules/custom/paatokset_policymakers/paatokset_policymakers.module index a655b52cb..edd881a5e 100644 --- a/public/modules/custom/paatokset_policymakers/paatokset_policymakers.module +++ b/public/modules/custom/paatokset_policymakers/paatokset_policymakers.module @@ -168,7 +168,7 @@ function paatokset_policymakers_preprocess_node__policymaker(&$variables) { } else { // Get the two most recent decisions. - $recentDecisions = $policymakerService->getAgendasList(2, FALSE); + $recentDecisions = $policymakerService->getAgendasListFromElasticSearch(2, FALSE); if (!empty($recentDecisions)) { $variables['recent_decisions'] = $recentDecisions; $variables['all_decisions_link'] = $policymakerService->getDecisionsRoute(); diff --git a/public/modules/custom/paatokset_submenus/src/Plugin/Block/AgendasSubmenuBlock.php b/public/modules/custom/paatokset_submenus/src/Plugin/Block/AgendasSubmenuBlock.php index 2018c69c7..e71507fc0 100644 --- a/public/modules/custom/paatokset_submenus/src/Plugin/Block/AgendasSubmenuBlock.php +++ b/public/modules/custom/paatokset_submenus/src/Plugin/Block/AgendasSubmenuBlock.php @@ -35,7 +35,7 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition * Build the attributes. */ public function build() { - $list = $this->policymakerService->getAgendasList(NULL, TRUE); + $list = $this->policymakerService->getAgendasListFromElasticSearch(NULL, TRUE); $years = array_keys($list); return [ From 3fc7a2807a6c48f2f7c2c03ecbfcdd93a2e8c363 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Mon, 16 Oct 2023 06:26:02 +0300 Subject: [PATCH 02/21] UHF-8858 Add return types --- .../Plugin/QueueWorker/AhjoOrgChartQueueWorker.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php b/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php index c8fbb6be1..1a787e201 100644 --- a/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php +++ b/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php @@ -7,10 +7,12 @@ use Drupal\Component\Utility\Unicode; use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Queue\QueueInterface; use Drupal\Core\Queue\QueueWorkerBase; use Drupal\Core\Queue\SuspendQueueException; use Drupal\node\Entity\Node; use Drupal\node\NodeInterface; +use Drupal\paatokset_ahjo_proxy\AhjoProxy; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -35,19 +37,19 @@ class AhjoOrgChartQueueWorker extends QueueWorkerBase implements ContainerFactor * * @var \Drupal\paatokset_ahjo_proxy\AhjoProxy */ - protected $ahjoProxy; + protected AhjoProxy $ahjoProxy; /** * Ahjo organization chart queue. * * @var \Drupal\Core\Queue\QueueInterface */ - protected $queue; + protected QueueInterface $queue; /** * {@inheritdoc} */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static { $instance = new static($configuration, $plugin_id, $plugin_definition); $instance->ahjoProxy = $container->get('paatokset_ahjo_proxy'); $instance->logger = $container->get('logger.factory')->get('ahjo_api_org_queue'); @@ -180,10 +182,10 @@ public function processItem($item) { * @param string $langcode * Language for org data. * - * @return \Drupal\node\NodeInterface|null + * @return \Drupal\node\NodeInterface * Loaded or created node, if found. */ - private function findOrCreateOrg(string $id, string $title, string $langcode): ?NodeInterface { + private function findOrCreateOrg(string $id, string $title, string $langcode): NodeInterface { $query = \Drupal::entityQuery('node') ->condition('status', 1) ->range(0, 1) From 6d869285fe2c864ec503ed56b28e4394a2c1633c Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Mon, 16 Oct 2023 06:26:10 +0300 Subject: [PATCH 03/21] UHF-8858: Rename variables --- .../QueueWorker/AhjoOrgChartQueueWorker.php | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php b/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php index 1a787e201..77b70911a 100644 --- a/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php +++ b/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php @@ -61,11 +61,11 @@ public static function create(ContainerInterface $container, array $configuratio /** * {@inheritdoc} */ - public function processItem($item) { - $id = (string) $item['id']; - $step = (int) $item['step']; - $max_steps = (int) $item['max_steps']; - $langcode = (string) $item['langcode']; + public function processItem($data): void { + $id = (string) $data['id']; + $step = (int) $data['step']; + $max_steps = (int) $data['max_steps']; + $langcode = $data['langcode']; // Only allow finnish and swedish for now. $allowed_langs = ['fi', 'sv']; @@ -94,25 +94,25 @@ public function processItem($item) { $query_string = 'orgid=' . (string) $id . '&apireqlang=' . (string) $langcode; } - $data = $this->ahjoProxy->getData($url, $query_string); + $organization = $this->ahjoProxy->getData($url, $query_string); - // Local data is formatted a bit differently. - if (!empty($data['decisionMakers'][0]['Organization'])) { - $data = $data['decisionMakers'][0]['Organization']; + // Local organization is formatted a bit differently. + if (!empty($organization['decisionMakers'][0]['Organization'])) { + $organization = $organization['decisionMakers'][0]['Organization']; } - if (empty($data['ID'])) { + if (empty($organization['ID'])) { $this->logger->error('Data not found for @id', [ '@id' => $id, ]); return; } - $node = $this->findOrCreateOrg($id, $data['Name'], $langcode); - $node->set('field_organization_data', json_encode($data)); + $node = $this->findOrCreateOrg($id, $organization['Name'], $langcode); + $node->set('field_organization_data', json_encode($organization)); - if (!empty($data['OrganizationLevelAbove']['organizations'])) { - $above_org = reset($data['OrganizationLevelAbove']['organizations']); + if (!empty($organization['OrganizationLevelAbove']['organizations'])) { + $above_org = reset($organization['OrganizationLevelAbove']['organizations']); if (!$node->get('field_org_level_above_id')->isEmpty() && $node->get('field_org_level_above_id')->value !== $above_org['ID']) { $this->logger->warning('Duplicate ID with different parent: @id, (@parent_id, expecting @existing_parent).', [ @@ -126,7 +126,7 @@ public function processItem($item) { } } $below_ids = []; - foreach ($data['OrganizationLevelBelow']['organizations'] as $org_below) { + foreach ($organization['OrganizationLevelBelow']['organizations'] as $org_below) { if ($org_below['Existing'] !== 'true') { continue; } From 7f07e6b80262ae886f964dba5163ae9090ce3786 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Mon, 16 Oct 2023 06:26:16 +0300 Subject: [PATCH 04/21] UHF-8858: Make recursion depth parameter optional --- .../src/Commands/AhjoCallbackCommands.php | 19 +++++++++---------- .../QueueWorker/AhjoOrgChartQueueWorker.php | 12 +++++++++++- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php b/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php index e90d1f6c7..b03e45438 100644 --- a/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php +++ b/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php @@ -513,21 +513,22 @@ private function loadItem(string $queue_name, string $item_id) { * * @param string $start_id * Org ID to start from. - * @param int $max_steps - * Maximum amount of steps. + * @param ?int $max_steps + * Maximum amount of steps. Defaults to steps required to get the full + * organization chart. * @param string $langcode * Language to get org data with. * * @command ahjo-callback:start-org-queue * - * @usage ahjo-callback:start-org-queue 00001 3 - * Get first three levels of organization data. + * @usage ahjo-callback:start-org-queue 00001 + * Get full organization data. * @usage ahjo-callback:start-org-queue 00001 3 sv - * Get Swedish translations of the first three levels. + * Get first three levels of organization data only in swedish. * * @aliases ac:sorg */ - public function startOrgQueue(string $start_id, int $max_steps = 5, string $langcode = 'fi') { + public function startOrgQueue(string $start_id, ?int $max_steps = NULL, string $langcode = 'fi') { $data = [ 'id' => $start_id, 'step' => 0, @@ -538,12 +539,10 @@ public function startOrgQueue(string $start_id, int $max_steps = 5, string $lang $item_id = $this->orgQueue->createItem($data); if ($item_id) { - $this->writeln(sprintf('Started org queue from %s with %d steps.', $start_id, $max_steps)); - $this->logger->info('Added item to org chart queue: @id (@langcode), @step out of @max_steps).', [ + $this->writeln("Started org queue from $start_id."); + $this->logger->info('Added item to org chart queue: @id (@langcode).', [ '@id' => $start_id, '@langcode' => $langcode, - '@step' => 0, - '@max_steps' => $max_steps, ]); } else { diff --git a/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php b/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php index 77b70911a..0ce69e214 100644 --- a/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php +++ b/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php @@ -25,6 +25,16 @@ */ class AhjoOrgChartQueueWorker extends QueueWorkerBase implements ContainerFactoryPluginInterface { + /** + * Maximum allowed recursion depth. + * + * This will prevent infinite recursions in case the Ahjo API returns + * circular organization for any reason. + * + * As of october-2023, the maximum organization depth is 9. + */ + private const MAX_RECURSION_DEPTH = 20; + /** * The logger. * @@ -64,7 +74,7 @@ public static function create(ContainerInterface $container, array $configuratio public function processItem($data): void { $id = (string) $data['id']; $step = (int) $data['step']; - $max_steps = (int) $data['max_steps']; + $max_steps = (int) ($data['max_steps'] ?? self::MAX_RECURSION_DEPTH); $langcode = $data['langcode']; // Only allow finnish and swedish for now. From b45cbb0883bd27225643e58ae6d4eaa3c6bb525a Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Mon, 16 Oct 2023 06:26:32 +0300 Subject: [PATCH 05/21] UHF-8858: Make langcode parameter optional --- .../src/Commands/AhjoCallbackCommands.php | 11 ++--- .../QueueWorker/AhjoOrgChartQueueWorker.php | 44 ++++++++++++++++--- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php b/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php index b03e45438..48283d901 100644 --- a/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php +++ b/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php @@ -511,13 +511,15 @@ private function loadItem(string $queue_name, string $item_id) { /** * Initialize organization chart queue. * + * The root id of the whole organization is '00001'. + * * @param string $start_id * Org ID to start from. * @param ?int $max_steps * Maximum amount of steps. Defaults to steps required to get the full * organization chart. - * @param string $langcode - * Language to get org data with. + * @param ?string $langcode + * Language to get org data with. Defaults to all languages. * * @command ahjo-callback:start-org-queue * @@ -528,7 +530,7 @@ private function loadItem(string $queue_name, string $item_id) { * * @aliases ac:sorg */ - public function startOrgQueue(string $start_id, ?int $max_steps = NULL, string $langcode = 'fi') { + public function startOrgQueue(string $start_id, ?int $max_steps = NULL, ?string $langcode = NULL) { $data = [ 'id' => $start_id, 'step' => 0, @@ -540,9 +542,8 @@ public function startOrgQueue(string $start_id, ?int $max_steps = NULL, string $ if ($item_id) { $this->writeln("Started org queue from $start_id."); - $this->logger->info('Added item to org chart queue: @id (@langcode).', [ + $this->logger->info('Added item to org chart queue: @id', [ '@id' => $start_id, - '@langcode' => $langcode, ]); } else { diff --git a/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php b/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php index 0ce69e214..00851156e 100644 --- a/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php +++ b/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php @@ -35,6 +35,11 @@ class AhjoOrgChartQueueWorker extends QueueWorkerBase implements ContainerFactor */ private const MAX_RECURSION_DEPTH = 20; + /** + * Organization translations supported by Ahjo. + */ + private const ALLOWED_LANGCODES = ['fi', 'sv']; + /** * The logger. * @@ -75,14 +80,43 @@ public function processItem($data): void { $id = (string) $data['id']; $step = (int) $data['step']; $max_steps = (int) ($data['max_steps'] ?? self::MAX_RECURSION_DEPTH); - $langcode = $data['langcode']; + $langcode = $data['langcode'] ?? NULL; - // Only allow finnish and swedish for now. - $allowed_langs = ['fi', 'sv']; - if (!in_array($langcode, $allowed_langs)) { - $langcode = 'fi'; + // Process only one language. + if (!is_null($data['langcode'])) { + // Validate langcode. + if (!in_array($langcode, self::ALLOWED_LANGCODES)) { + $this->logger->error("Org: @id, refusing to process invalid language @langcode", [ + '@langcode' => $langcode, + ]); + + return; + } + + $this->processOrganization($id, $langcode, $step, $max_steps); } + else { + // Process all languages. Recursive items are added with the langcode + // parameter so this path only applies to the first item. + foreach (self::ALLOWED_LANGCODES as $langcode) { + $this->processOrganization($id, $langcode, $step, $max_steps); + } + } + } + /** + * Processes queued organization in one language. + * + * @param string $id + * Organization id. + * @param string $langcode + * Language to process. + * @param int $step + * Current recursion depth. + * @param int $max_steps + * Maximum allowed recursion depth. + */ + private function processOrganization(string $id, string $langcode, int $step, int $max_steps): void { $this->logger->info('Org: @id (@langcode), step @step out of @max_steps.', [ '@id' => $id, '@langcode' => $langcode, From eed069a7a1fac44641c280e3a4c7ac66ec5d11c0 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Mon, 16 Oct 2023 06:26:40 +0300 Subject: [PATCH 06/21] UHF-8858: Add description to organization content type --- conf/cmi/node.type.organization.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/cmi/node.type.organization.yml b/conf/cmi/node.type.organization.yml index 7f7222590..dd0afa3f9 100644 --- a/conf/cmi/node.type.organization.yml +++ b/conf/cmi/node.type.organization.yml @@ -24,7 +24,7 @@ third_party_settings: unpublish_revision: false name: Organization type: organization -description: '' +description: 'Organisation hierarchy from Ahjo API.' help: '' new_revision: false preview_mode: 1 From 7c0dca953cfc234a740a431fcb532e6b3a487241 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Mon, 16 Oct 2023 06:26:45 +0300 Subject: [PATCH 07/21] UHF-8858: Hide organization nodes from anonymous users --- .../paatokset_policymakers.module | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/public/modules/custom/paatokset_policymakers/paatokset_policymakers.module b/public/modules/custom/paatokset_policymakers/paatokset_policymakers.module index a655b52cb..6c3d919d3 100644 --- a/public/modules/custom/paatokset_policymakers/paatokset_policymakers.module +++ b/public/modules/custom/paatokset_policymakers/paatokset_policymakers.module @@ -7,11 +7,27 @@ declare(strict_types = 1); +use Drupal\Core\Access\AccessResult; use Drupal\Core\Render\Element; +use Drupal\Core\Session\AccountInterface; use Drupal\node\NodeInterface; use Drupal\paragraphs\Entity\Paragraph; use Drupal\paragraphs\ParagraphInterface; +/** + * Implements hook_node_access(). + */ +function paatokset_policymakers_node_access(NodeInterface $node, $op, AccountInterface $account) { + // Disable access to organization nodes from anonymous users. + // The organization nodes do not contain anything useful for now. + if ($account->isAnonymous() && $node->gettype() == 'organization') { + return AccessResult::forbidden()->cachePerUser()->addCacheableDependency($node); + } + + // No opinion. + return AccessResult::neutral(); +} + /** * Implements hook_theme(). */ From 0a5cc1e7b0759b7aaa2dbe26a34b9e15f5ff8114 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Mon, 16 Oct 2023 06:16:46 +0300 Subject: [PATCH 08/21] UHF-8858: Add admin view for organizations --- conf/cmi/views.view.organizations.yml | 762 ++++++++++++++++++++++++++ 1 file changed, 762 insertions(+) create mode 100644 conf/cmi/views.view.organizations.yml diff --git a/conf/cmi/views.view.organizations.yml b/conf/cmi/views.view.organizations.yml new file mode 100644 index 000000000..821047142 --- /dev/null +++ b/conf/cmi/views.view.organizations.yml @@ -0,0 +1,762 @@ +uuid: 11c9fa18-8c7b-41bf-b0f0-6a4caf4db7a0 +langcode: en +status: true +dependencies: + config: + - field.storage.node.field_policymaker_id + - node.type.organization + module: + - node + - user +id: organizations +label: Organizations +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: nid +display: + default: + id: default + display_title: Default + display_plugin: default + position: 0 + display_options: + title: Organisations + fields: + node_bulk_form: + id: node_bulk_form + table: node + field: node_bulk_form + relationship: none + group_type: group + admin_label: '' + entity_type: node + plugin_id: node_bulk_form + label: 'Solmujen bulkkitoimintojen lomake' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + action_title: Toiminto + include_exclude: exclude + selected_actions: { } + title: + id: title + table: node_field_data + field: title + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: title + plugin_id: field + label: Otsikko + exclude: false + alter: + alter_text: false + make_link: false + absolute: false + word_boundary: false + ellipsis: false + strip_tags: false + trim: false + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: true + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + field_policymaker_id: + id: field_policymaker_id + table: node__field_policymaker_id + field: field_policymaker_id + relationship: none + group_type: group + admin_label: '' + plugin_id: field + label: 'Organization ID' + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: string + settings: + link_to_entity: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + langcode: + id: langcode + table: node_field_data + field: langcode + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: langcode + plugin_id: field + label: Kieli + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + click_sort_column: value + type: language + settings: + link_to_entity: false + native_language: false + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + operations: + id: operations + table: node + field: operations + relationship: none + group_type: group + admin_label: '' + entity_type: node + plugin_id: entity_operations + label: Operations + exclude: false + alter: + alter_text: false + text: '' + make_link: false + path: '' + absolute: false + external: false + replace_spaces: false + path_case: none + trim_whitespace: false + alt: '' + rel: '' + link_class: '' + prefix: '' + suffix: '' + target: '' + nl2br: false + max_length: 0 + word_boundary: true + ellipsis: true + more_link: false + more_link_text: '' + more_link_path: '' + strip_tags: false + trim: false + preserve_tags: '' + html: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_empty: false + empty_zero: false + hide_alter_empty: true + destination: false + pager: + type: full + options: + offset: 0 + items_per_page: 50 + total_pages: null + id: 0 + tags: + next: ›› + previous: ‹‹ + first: '« Ensimmäinen' + last: 'Viimeinen »' + expose: + items_per_page: false + items_per_page_label: 'Merkintöjä sivua kohti' + items_per_page_options: '5, 10, 25, 50' + items_per_page_options_all: false + items_per_page_options_all_label: '- Kaikki -' + offset: false + offset_label: Offset + quantity: 9 + exposed_form: + type: basic + options: + submit_button: Käytä + reset_button: false + reset_button_label: Palauta + exposed_sorts_label: Lajittele + expose_sort_order: true + sort_asc_label: Nousevasti + sort_desc_label: Laskevasti + access: + type: perm + options: + perm: 'access content overview' + cache: + type: tag + options: { } + empty: { } + sorts: + changed: + id: changed + table: node_field_data + field: changed + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: changed + plugin_id: date + order: DESC + expose: + label: '' + field_identifier: changed + exposed: false + granularity: second + arguments: { } + filters: + type: + id: type + table: node_field_data + field: type + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: type + plugin_id: bundle + operator: in + value: + organization: organization + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + title: + id: title + table: node_field_data + field: title + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: title + plugin_id: string + operator: contains + value: '' + group: 1 + exposed: true + expose: + operator_id: title_op + label: Otsikko + description: '' + use_operator: false + operator: title_op + operator_limit_selection: false + operator_list: { } + identifier: title + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + admin: '0' + content_producer: '0' + placeholder: '' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + field_policymaker_id_value: + id: field_policymaker_id_value + table: node__field_policymaker_id + field: field_policymaker_id_value + relationship: none + group_type: group + admin_label: '' + plugin_id: string + operator: '=' + value: '' + group: 1 + exposed: true + expose: + operator_id: field_policymaker_id_value_op + label: 'Organization ID' + description: '' + use_operator: false + operator: field_policymaker_id_value_op + operator_limit_selection: false + operator_list: { } + identifier: field_policymaker_id_value + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + read_only: '0' + content_producer: '0' + editor: '0' + admin: '0' + api_user: '0' + elevated_api_user: '0' + placeholder: '' + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + langcode: + id: langcode + table: node_field_data + field: langcode + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: langcode + plugin_id: language + operator: in + value: + '***LANGUAGE_language_content***': '***LANGUAGE_language_content***' + group: 1 + exposed: true + expose: + operator_id: langcode_op + label: Kieli + description: '' + use_operator: false + operator: langcode_op + operator_limit_selection: false + operator_list: { } + identifier: langcode + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + anonymous: '0' + read_only: '0' + content_producer: '0' + editor: '0' + admin: '0' + api_user: '0' + elevated_api_user: '0' + reduce: false + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } + status: + id: status + table: node_field_data + field: status + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: status + plugin_id: boolean + operator: '=' + value: '1' + group: 1 + exposed: true + expose: + operator_id: '' + label: Julkaisutila + description: null + use_operator: false + operator: status_op + operator_limit_selection: false + operator_list: { } + identifier: status + required: true + remember: false + multiple: false + remember_roles: + authenticated: authenticated + is_grouped: true + group_info: + label: Julkaistu + description: '' + identifier: status + optional: true + widget: select + multiple: false + remember: false + default_group: '1' + default_group_multiple: { } + group_items: + 1: + title: 'True' + operator: '=' + value: '1' + 2: + title: 'False' + operator: '=' + value: '0' + filter_groups: + operator: AND + groups: + 1: AND + style: + type: table + options: + grouping: { } + row_class: '' + default_row_class: true + columns: + title: title + field_diary_number: field_diary_number + field_meeting_id: field_meeting_id + field_unique_id: field_unique_id + field_dm_org_name: field_dm_org_name + field_decision_date: field_decision_date + field_meeting_date: field_meeting_date + langcode: langcode + field_decision_content: field_decision_content + field_decision_motion: field_decision_motion + field_is_decision: field_is_decision + operations: operations + default: '-1' + info: + title: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + field_diary_number: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + field_meeting_id: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + field_unique_id: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + field_dm_org_name: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + field_decision_date: + sortable: true + default_sort_order: desc + align: '' + separator: '' + empty_column: false + responsive: '' + field_meeting_date: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + langcode: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + field_decision_content: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + field_decision_motion: + sortable: false + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + field_is_decision: + sortable: true + default_sort_order: asc + align: '' + separator: '' + empty_column: false + responsive: '' + operations: + align: '' + separator: '' + empty_column: false + responsive: '' + override: true + sticky: false + summary: '' + empty_table: false + caption: '' + description: '' + row: + type: fields + query: + type: views_query + options: + query_comment: '' + disable_sql_rewrite: false + distinct: false + replica: false + query_tags: { } + relationships: { } + header: { } + footer: { } + display_extenders: { } + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - 'user.node_grants:view' + - user.permissions + tags: + - 'config:field.storage.node.field_policymaker_id' + page_1: + id: page_1 + display_title: Page + display_plugin: page + position: 1 + display_options: + display_extenders: + metatag_display_extender: + metatags: { } + tokenize: false + path: admin/content/organizations + menu: + type: tab + title: Organizations + description: '' + weight: 50 + expanded: false + menu_name: admin + parent: system.admin_content + context: '0' + cache_metadata: + max-age: 0 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - url + - url.query_args + - 'user.node_grants:view' + - user.permissions + tags: + - 'config:field.storage.node.field_policymaker_id' From b6a53cff236bb1fc84347147d0c956991b190150 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Fri, 13 Oct 2023 08:15:19 +0300 Subject: [PATCH 09/21] UHF-8858: Link policymaker to organization with a reference --- ..._form_display.node.policymaker.default.yml | 46 ++++++--------- ..._view_display.node.policymaker.default.yml | 6 +- ...ld.node.policymaker.field_dm_org_above.yml | 21 ------- ...ld.node.policymaker.field_dm_org_below.yml | 21 ------- ...node.policymaker.field_dm_organization.yml | 29 ++++++++++ .../field.storage.node.field_dm_org_below.yml | 19 ------ ...ld.storage.node.field_dm_organization.yml} | 14 ++--- .../migrations/ahjo_decisionmakers.yml | 28 ++++----- .../paatokset_policymakers.install | 58 +++++++++++++++++++ 9 files changed, 125 insertions(+), 117 deletions(-) delete mode 100644 conf/cmi/field.field.node.policymaker.field_dm_org_above.yml delete mode 100644 conf/cmi/field.field.node.policymaker.field_dm_org_below.yml create mode 100644 conf/cmi/field.field.node.policymaker.field_dm_organization.yml delete mode 100644 conf/cmi/field.storage.node.field_dm_org_below.yml rename conf/cmi/{field.storage.node.field_dm_org_above.yml => field.storage.node.field_dm_organization.yml} (52%) create mode 100644 public/modules/custom/paatokset_policymakers/paatokset_policymakers.install diff --git a/conf/cmi/core.entity_form_display.node.policymaker.default.yml b/conf/cmi/core.entity_form_display.node.policymaker.default.yml index f52e61de7..a535e78ce 100644 --- a/conf/cmi/core.entity_form_display.node.policymaker.default.yml +++ b/conf/cmi/core.entity_form_display.node.policymaker.default.yml @@ -10,9 +10,8 @@ dependencies: - field.field.node.policymaker.field_custom_menu_links - field.field.node.policymaker.field_custom_organization_type - field.field.node.policymaker.field_decisions_description - - field.field.node.policymaker.field_dm_org_above - - field.field.node.policymaker.field_dm_org_below - field.field.node.policymaker.field_dm_org_name + - field.field.node.policymaker.field_dm_organization - field.field.node.policymaker.field_dm_sector - field.field.node.policymaker.field_documents_description - field.field.node.policymaker.field_first_name @@ -52,6 +51,7 @@ third_party_settings: - field_ahjo_title - field_policymaker_id - field_ahjo_summary + - field_dm_organization - field_organization_type - field_organization_type_id - field_dm_org_name @@ -61,8 +61,6 @@ third_party_settings: - field_policymaker_existing - field_is_decisionmaker - field_dm_sector - - field_dm_org_above - - field_dm_org_below label: 'Integration data' region: content parent_name: '' @@ -221,33 +219,27 @@ content: rows: 5 placeholder: '' third_party_settings: { } - field_dm_org_above: - type: json_textarea - weight: 16 - region: content - settings: - rows: 5 - placeholder: '' - third_party_settings: { } - field_dm_org_below: - type: json_textarea - weight: 17 + field_dm_org_name: + type: string_textfield + weight: 10 region: content settings: - rows: 5 + size: 60 placeholder: '' third_party_settings: { } - field_dm_org_name: - type: string_textfield - weight: 9 + field_dm_organization: + type: entity_reference_autocomplete + weight: 7 region: content settings: + match_operator: CONTAINS + match_limit: 10 size: 60 placeholder: '' third_party_settings: { } field_dm_sector: type: json_textarea - weight: 15 + weight: 16 region: content settings: rows: 5 @@ -271,7 +263,7 @@ content: third_party_settings: { } field_is_decisionmaker: type: boolean_checkbox - weight: 14 + weight: 15 region: content settings: display_label: true @@ -300,7 +292,7 @@ content: third_party_settings: { } field_organization_type: type: string_textfield - weight: 7 + weight: 8 region: content settings: size: 60 @@ -308,7 +300,7 @@ content: third_party_settings: { } field_organization_type_id: type: string_textfield - weight: 8 + weight: 9 region: content settings: size: 60 @@ -323,20 +315,20 @@ content: third_party_settings: { } field_policymaker_dissolved: type: datetime_default - weight: 12 + weight: 13 region: content settings: { } third_party_settings: { } field_policymaker_existing: type: boolean_checkbox - weight: 13 + weight: 14 region: content settings: display_label: true third_party_settings: { } field_policymaker_formed: type: datetime_default - weight: 11 + weight: 12 region: content settings: { } third_party_settings: { } @@ -375,7 +367,7 @@ content: third_party_settings: { } field_sector_name: type: string_textfield - weight: 10 + weight: 11 region: content settings: size: 60 diff --git a/conf/cmi/core.entity_view_display.node.policymaker.default.yml b/conf/cmi/core.entity_view_display.node.policymaker.default.yml index 08a702895..0e0022b76 100644 --- a/conf/cmi/core.entity_view_display.node.policymaker.default.yml +++ b/conf/cmi/core.entity_view_display.node.policymaker.default.yml @@ -10,9 +10,8 @@ dependencies: - field.field.node.policymaker.field_custom_menu_links - field.field.node.policymaker.field_custom_organization_type - field.field.node.policymaker.field_decisions_description - - field.field.node.policymaker.field_dm_org_above - - field.field.node.policymaker.field_dm_org_below - field.field.node.policymaker.field_dm_org_name + - field.field.node.policymaker.field_dm_organization - field.field.node.policymaker.field_dm_sector - field.field.node.policymaker.field_documents_description - field.field.node.policymaker.field_first_name @@ -163,8 +162,7 @@ content: hidden: field_contacts: true field_custom_menu_links: true - field_dm_org_above: true - field_dm_org_below: true + field_dm_organization: true field_dm_sector: true field_first_name: true field_is_decisionmaker: true diff --git a/conf/cmi/field.field.node.policymaker.field_dm_org_above.yml b/conf/cmi/field.field.node.policymaker.field_dm_org_above.yml deleted file mode 100644 index 1a222ce93..000000000 --- a/conf/cmi/field.field.node.policymaker.field_dm_org_above.yml +++ /dev/null @@ -1,21 +0,0 @@ -uuid: a40bef58-e5a5-4a60-99de-dc6b80dbd64e -langcode: fi -status: true -dependencies: - config: - - field.storage.node.field_dm_org_above - - node.type.policymaker - module: - - json_field -id: node.policymaker.field_dm_org_above -field_name: field_dm_org_above -entity_type: node -bundle: policymaker -label: 'Organization level above' -description: '' -required: false -translatable: true -default_value: { } -default_value_callback: '' -settings: { } -field_type: json_native diff --git a/conf/cmi/field.field.node.policymaker.field_dm_org_below.yml b/conf/cmi/field.field.node.policymaker.field_dm_org_below.yml deleted file mode 100644 index 447d009e2..000000000 --- a/conf/cmi/field.field.node.policymaker.field_dm_org_below.yml +++ /dev/null @@ -1,21 +0,0 @@ -uuid: 5c295bea-960e-4b9a-9929-c1712c6c96ad -langcode: fi -status: true -dependencies: - config: - - field.storage.node.field_dm_org_below - - node.type.policymaker - module: - - json_field -id: node.policymaker.field_dm_org_below -field_name: field_dm_org_below -entity_type: node -bundle: policymaker -label: 'Organization level below' -description: '' -required: false -translatable: true -default_value: { } -default_value_callback: '' -settings: { } -field_type: json_native diff --git a/conf/cmi/field.field.node.policymaker.field_dm_organization.yml b/conf/cmi/field.field.node.policymaker.field_dm_organization.yml new file mode 100644 index 000000000..2d577b820 --- /dev/null +++ b/conf/cmi/field.field.node.policymaker.field_dm_organization.yml @@ -0,0 +1,29 @@ +uuid: f47dded2-2ca3-41ef-831d-bd448bd4c80c +langcode: fi +status: true +dependencies: + config: + - field.storage.node.field_dm_organization + - node.type.organization + - node.type.policymaker +id: node.policymaker.field_dm_organization +field_name: field_dm_organization +entity_type: node +bundle: policymaker +label: Organisation +description: 'Reference to organisation.' +required: false +translatable: false +default_value: { } +default_value_callback: '' +settings: + handler: 'default:node' + handler_settings: + target_bundles: + organization: organization + sort: + field: _none + direction: ASC + auto_create: false + auto_create_bundle: '' +field_type: entity_reference diff --git a/conf/cmi/field.storage.node.field_dm_org_below.yml b/conf/cmi/field.storage.node.field_dm_org_below.yml deleted file mode 100644 index 7eb07c47c..000000000 --- a/conf/cmi/field.storage.node.field_dm_org_below.yml +++ /dev/null @@ -1,19 +0,0 @@ -uuid: 65bad5d6-b8f3-4374-aa45-83cd2128f5c1 -langcode: fi -status: true -dependencies: - module: - - json_field - - node -id: node.field_dm_org_below -field_name: field_dm_org_below -entity_type: node -type: json_native -settings: { } -module: json_field -locked: false -cardinality: 1 -translatable: true -indexes: { } -persist_with_no_fields: false -custom_storage: false diff --git a/conf/cmi/field.storage.node.field_dm_org_above.yml b/conf/cmi/field.storage.node.field_dm_organization.yml similarity index 52% rename from conf/cmi/field.storage.node.field_dm_org_above.yml rename to conf/cmi/field.storage.node.field_dm_organization.yml index cb9c70431..54e5b2701 100644 --- a/conf/cmi/field.storage.node.field_dm_org_above.yml +++ b/conf/cmi/field.storage.node.field_dm_organization.yml @@ -1,16 +1,16 @@ -uuid: 8caf5172-b997-45f4-8f2b-71baf42ccac0 +uuid: e44a9501-05f7-4c93-b3eb-d5b3a5e2ec26 langcode: fi status: true dependencies: module: - - json_field - node -id: node.field_dm_org_above -field_name: field_dm_org_above +id: node.field_dm_organization +field_name: field_dm_organization entity_type: node -type: json_native -settings: { } -module: json_field +type: entity_reference +settings: + target_type: node +module: core locked: false cardinality: 1 translatable: true diff --git a/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_decisionmakers.yml b/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_decisionmakers.yml index 2d81856d9..c4b39179f 100644 --- a/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_decisionmakers.yml +++ b/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_decisionmakers.yml @@ -63,10 +63,6 @@ source: name: organization_above label: Organization Level Above selector: Organization/OrganizationLevelAbove - - - name: organization_below - label: Organization Level Below - selector: Organization/OrganizationLevelBelow ids: decisionmaker_id: type: string @@ -127,13 +123,16 @@ process: - plugin: callback callable: json_encode - field_dm_org_above: - - - plugin: single_value - source: organization_above - - - plugin: callback - callable: json_encode + field_dm_organization: + - + plugin: entity_lookup + entity_type: node + bundle: organization + bundle_key: type + value_key: field_policymaker_id + source: decisionmaker_id + access_check: false + ignore_case: true field_dm_org_name: - plugin: array_shift @@ -142,13 +141,6 @@ process: plugin: extract index: - Name - field_dm_org_below: - - - plugin: single_value - source: organization_below - - - plugin: callback - callable: json_encode destination: plugin: 'entity:node' migration_dependencies: { } diff --git a/public/modules/custom/paatokset_policymakers/paatokset_policymakers.install b/public/modules/custom/paatokset_policymakers/paatokset_policymakers.install new file mode 100644 index 000000000..c28155073 --- /dev/null +++ b/public/modules/custom/paatokset_policymakers/paatokset_policymakers.install @@ -0,0 +1,58 @@ +getStorage('node'); + + // Load policymakers that are missing field_dm_organization. + $nids = $nodeStorage + ->getQuery() + ->accessCheck(FALSE) + ->condition('type', 'policymaker') + ->notExists('field_dm_organization') + ->execute(); + + foreach ($nids as $nid) { + if (is_null($policymaker = $nodeStorage->load($nid))) { + continue; + } + + $policymaker_id = $policymaker->get('field_policymaker_id')->getString(); + $organizations = $nodeStorage->loadByProperties([ + 'type' => 'organization', + 'field_policymaker_id' => $policymaker_id + ]); + + if ($organization = reset($organizations)) { + // Set organization reference to policymaker. + $policymaker->set('field_dm_organization', $organization); + } else { + // Organization not found. Try running org chart queue first. + throw new UpdateException("Organization with id $policymaker_id does not exists."); + } + } +} + + + From e65936168448449c47d1cb12d7667ed09e50bc33 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Mon, 16 Oct 2023 06:24:44 +0300 Subject: [PATCH 10/21] UHF-8858: Add service for querying organization hierarchy --- .../paatokset_policymakers.services.yml | 3 + .../src/Service/OrganizationService.php | 156 ++++++++++++++++++ 2 files changed, 159 insertions(+) create mode 100644 public/modules/custom/paatokset_policymakers/src/Service/OrganizationService.php diff --git a/public/modules/custom/paatokset_policymakers/paatokset_policymakers.services.yml b/public/modules/custom/paatokset_policymakers/paatokset_policymakers.services.yml index c958d0dd2..34d6657af 100644 --- a/public/modules/custom/paatokset_policymakers/paatokset_policymakers.services.yml +++ b/public/modules/custom/paatokset_policymakers/paatokset_policymakers.services.yml @@ -4,3 +4,6 @@ services: policymakers_lazy_builder: class: Drupal\paatokset_policymakers\Service\PolicymakerLazyBuilder arguments: ['@language_manager', '@entity_type.manager', '@paatokset_policymakers'] + Drupal\paatokset_policymakers\Service\OrganizationService: + class: Drupal\paatokset_policymakers\Service\OrganizationService + arguments: ['@language_manager', '@entity_type.manager', '@logger.factory'] diff --git a/public/modules/custom/paatokset_policymakers/src/Service/OrganizationService.php b/public/modules/custom/paatokset_policymakers/src/Service/OrganizationService.php new file mode 100644 index 000000000..616d9991d --- /dev/null +++ b/public/modules/custom/paatokset_policymakers/src/Service/OrganizationService.php @@ -0,0 +1,156 @@ +organizationStorage = $entityTypeManager->getStorage('node'); + $this->logger = $loggerChannelFactory->get('paatokset_policymakers'); + } + + /** + * Get policymaker organization. + * + * @param \Drupal\node\NodeInterface $policymaker + * Policymaker node. + * @param ?\Drupal\Core\Language\LanguageInterface $language + * Language for the organization. Defaults to current language. + * + * @returns ?NodeInterface + * Organizations of the given policymaker. Null if the policymaker does not + * belong to any organization (we get invalid data from API). + */ + public function getPolicymakerOrganization(NodeInterface $policymaker, ?LanguageInterface $language = NULL): ?NodeInterface { + if (is_null($language)) { + $language = $this->languageManager->getCurrentLanguage(); + } + + Assert::eq($policymaker->getType(), PolicymakerService::NODE_TYPE); + + $field = $policymaker->get('field_dm_organization'); + if ($field->isEmpty()) { + return NULL; + } + + $entity = $field->entity; + + /** @var \Drupal\node\NodeInterface $entity */ + Assert::isInstanceOf($entity, NodeInterface::class); + + if ($entity->hasTranslation($language->getId())) { + return $entity->getTranslation($language->getId()); + } + + return NULL; + } + + /** + * Get list of organization hierarchy from root up to the given organization. + * + * @param \Drupal\node\NodeInterface $organization + * Starting organization. + * @param ?\Drupal\Core\Language\LanguageInterface $language + * Language for organization hierarchy. Defaults to current language. + * + * @returns NodeInterface[] + * Organizations above the given organization and the given organization. + * Root organization is the first element. + */ + public function getOrganizationHierarchy(NodeInterface $organization, ?LanguageInterface $language = NULL): array { + if (is_null($language)) { + $language = $this->languageManager->getCurrentLanguage(); + } + + // Include the given organization. + $hierarchy = [$organization]; + + // Recursively load until the root organization is reached. + while (!is_null($organization = $this->getParentOrganization($organization, $language))) { + $hierarchy[] = $organization; + } + + return array_reverse($hierarchy); + } + + /** + * Get parent organization or NULL if root. + * + * @param \Drupal\node\NodeInterface $organization + * Current organization level. + * @param \Drupal\Core\Language\LanguageInterface $language + * Language. + * + * @returns \Drupal\node\NodeInterface + * Parent organization or NULL if current is root. + */ + private function getParentOrganization(NodeInterface $organization, LanguageInterface $language): ?NodeInterface { + Assert::eq($organization->getType(), self::ORGANIZATION_TYPE); + + if ($organization->get('field_org_level_above_id')->isEmpty()) { + return NULL; + } + + $nodes = $this->organizationStorage->loadByProperties([ + 'type' => self::ORGANIZATION_TYPE, + 'langcode' => $language->getId(), + 'field_policymaker_id' => $organization->get('field_org_level_above_id')->getString(), + ]); + + if ($node = reset($nodes)) { + return $node; + } + + // Should not happen. + $this->logger->warning("Missing parent organization for @org", [ + '@org' => $organization->get('field_org_level_above_id')->getString(), + ]); + + return NULL; + } + +} From 5aa3b1d6bd481d684095023b096dba7560e1aa08 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Fri, 13 Oct 2023 12:16:07 +0300 Subject: [PATCH 11/21] UHF-8858: Replace AhjoOrgChartQueueWorker with a migration --- .../migrations/ahjo_decisionmakers.yml | 16 +- .../migrations/ahjo_organization.yml | 48 ++++ .../paatokset_ahjo_api.module | 23 ++ .../src/Commands/AhjoCallbackCommands.php | 136 --------- .../QueueWorker/AhjoOrgChartQueueWorker.php | 271 ------------------ .../migrate/source/AhjoOrganizationSource.php | 158 ++++++++++ .../Plugin/migrate/source/AhjoSourceBase.php | 47 +++ 7 files changed, 283 insertions(+), 416 deletions(-) create mode 100644 public/modules/custom/paatokset_ahjo_api/migrations/ahjo_organization.yml delete mode 100644 public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php create mode 100644 public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoOrganizationSource.php create mode 100644 public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoSourceBase.php diff --git a/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_decisionmakers.yml b/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_decisionmakers.yml index c4b39179f..bb9185c31 100644 --- a/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_decisionmakers.yml +++ b/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_decisionmakers.yml @@ -125,14 +125,10 @@ process: callable: json_encode field_dm_organization: - - plugin: entity_lookup - entity_type: node - bundle: organization - bundle_key: type - value_key: field_policymaker_id - source: decisionmaker_id - access_check: false - ignore_case: true + plugin: migration_lookup + migration: ahjo_organizations + source: + - decisionmaker_id field_dm_org_name: - plugin: array_shift @@ -143,4 +139,6 @@ process: - Name destination: plugin: 'entity:node' -migration_dependencies: { } +migration_dependencies: + required: + - ahjo_organizations diff --git a/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_organization.yml b/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_organization.yml new file mode 100644 index 000000000..60ab9f602 --- /dev/null +++ b/public/modules/custom/paatokset_ahjo_api/migrations/ahjo_organization.yml @@ -0,0 +1,48 @@ +langcode: en +status: true +dependencies: + enforced: + module: + - paatokset_ahjo_api + - paatokset_ahjo_proxy +id: ahjo_organizations +migration_tags: + - ahjo_api + - ahjo_api_organizations +migration_group: ahjo_api +label: 'Ahjo API - Organizations' +source: + plugin: ahjo_api_organizations + root_org: '00001' + include_inactive: true + track_changes: true + languages: + - fi + - sv +process: + langcode: langcode + nid: + plugin: callback + callable: _paatokset_ahjo_api_lookup_organization_nid + source: response/ID + title: title + field_policymaker_id: response/ID + field_organization_data: + - + plugin: single_value + source: response + - + plugin: callback + callable: json_encode + field_org_level_above_id: + - + plugin: sub_process + source: response/OrganizationLevelAbove/organizations + process: + value: ID + field_org_level_below_ids: response/OrganizationLevelBelow/organizations/0/ID +destination: + plugin: 'entity:node' + translations: true + default_bundle: organization +migration_dependencies: { } diff --git a/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module b/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module index 286de2b0b..2bc5483ef 100644 --- a/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module +++ b/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module @@ -779,6 +779,29 @@ function _paatokset_ahjo_api_lookup_policymaker_nid(string $decisionmaker_id): ? return reset($ids); } +/** + * Lookup organization nodes by ID. + * + * @param string $decisionmaker_id + * Policymaker ID. + * + * @return string|null + * Existing nid, if found. + */ +function _paatokset_ahjo_api_lookup_organization_nid(string $decisionmaker_id): ?string { + $query = Drupal::entityQuery('node') + ->condition('type', 'organization') + ->condition('field_policymaker_id', $decisionmaker_id) + ->accessCheck(FALSE) + ->range(0, 1) + ->latestRevision(); + $ids = $query->execute(); + if (empty($ids)) { + return NULL; + } + return reset($ids); +} + /** * Truncate text value. * diff --git a/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php b/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php index 48283d901..5f87dfd49 100644 --- a/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php +++ b/public/modules/custom/paatokset_ahjo_api/src/Commands/AhjoCallbackCommands.php @@ -23,7 +23,6 @@ class AhjoCallbackCommands extends DrushCommands { private const AGGREGATION_QUEUE_NAME = 'ahjo_api_aggregation_queue'; private const RETRY_QUEUE_NAME = 'ahjo_api_retry_queue'; private const ERROR_QUEUE_NAME = 'ahjo_api_error_queue'; - private const ORG_QUEUE_NAME = 'ahjo_api_org_queue'; /** * Ahjo callback queue. @@ -53,13 +52,6 @@ class AhjoCallbackCommands extends DrushCommands { */ protected $errorQueue; - /** - * Ahjo organization chart queue. - * - * @var \Drupal\Core\Queue\QueueInterface - */ - protected $orgQueue; - /** * Ahjo proxy service. * @@ -106,7 +98,6 @@ public function __construct(QueueFactory $queue_factory, LoggerChannelFactoryInt $this->retryQueue = $this->queueFactory->get(self::RETRY_QUEUE_NAME); $this->aggregationQueue = $this->queueFactory->get(self::AGGREGATION_QUEUE_NAME); $this->errorQueue = $this->queueFactory->get(self::ERROR_QUEUE_NAME); - $this->orgQueue = $this->queueFactory->get(self::ORG_QUEUE_NAME); $this->logger = $logger_factory->get('ahjo_api_subscriber'); $this->database = $database; $this->ahjoProxy = $ahjo_proxy; @@ -508,131 +499,4 @@ private function loadItem(string $queue_name, string $item_id) { return $query->execute()->fetchObject(); } - /** - * Initialize organization chart queue. - * - * The root id of the whole organization is '00001'. - * - * @param string $start_id - * Org ID to start from. - * @param ?int $max_steps - * Maximum amount of steps. Defaults to steps required to get the full - * organization chart. - * @param ?string $langcode - * Language to get org data with. Defaults to all languages. - * - * @command ahjo-callback:start-org-queue - * - * @usage ahjo-callback:start-org-queue 00001 - * Get full organization data. - * @usage ahjo-callback:start-org-queue 00001 3 sv - * Get first three levels of organization data only in swedish. - * - * @aliases ac:sorg - */ - public function startOrgQueue(string $start_id, ?int $max_steps = NULL, ?string $langcode = NULL) { - $data = [ - 'id' => $start_id, - 'step' => 0, - 'max_steps' => $max_steps, - 'langcode' => $langcode, - ]; - - $item_id = $this->orgQueue->createItem($data); - - if ($item_id) { - $this->writeln("Started org queue from $start_id."); - $this->logger->info('Added item to org chart queue: @id', [ - '@id' => $start_id, - ]); - } - else { - $this->writeln('Could not start org chart queue'); - } - } - - /** - * List organization chart queue contents. - * - * @command ahjo-callback:list-org-queue - * - * @aliases ac:org - */ - public function listOrgQueue(): void { - $table = new Table($this->output()); - $table->setHeaders([ - 'OrgID', 'ID', 'Lang', 'Time', 'Step', 'Max steps', - ]); - - $count = 0; - $items = []; - $ids = []; - - while ($item = $this->orgQueue->claimItem()) { - $items[] = $item; - - $count++; - - if (isset($item->data['step'])) { - $step = $item->data['step']; - } - else { - $step = NULL; - } - - if (isset($item->data['max_steps'])) { - $max_steps = $item->data['max_steps']; - } - else { - $max_steps = NULL; - } - - if (!in_array($item->data['id'], $ids)) { - $ids[] = $item->data['id']; - } - - $table->addRow([ - $item->data['id'], - $item->item_id, - $item->data['langcode'], - date('Y-m-d H:i:s', (int) $item->created), - $step, - $max_steps, - ]); - } - - // Release claimed items. - foreach ($items as $item) { - $this->queue->releaseItem(($item)); - } - - $table->render(); - $this->writeln('Queue has ' . count($ids) . ' unique IDs.'); - $this->writeln('Total: ' . $count); - $this->writeln('Run with: drush queue:run ' . self::ORG_QUEUE_NAME); - } - - /** - * Clear organization chart queue contents. - * - * @command ahjo-callback:clear-org-queue - * - * @aliases ac:corg - */ - public function clearOrgQueue(): void { - $this->output()->writeln('Clearing organization chart queue.'); - - if (!$this->io()->confirm('Are you sure?')) { - return; - } - - $count = 0; - while ($item = $this->orgQueue->claimItem()) { - $this->orgQueue->deleteItem($item); - $count++; - } - - $this->output()->writeln('Deleted ' . $count . ' items.'); - } - } diff --git a/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php b/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php deleted file mode 100644 index 00851156e..000000000 --- a/public/modules/custom/paatokset_ahjo_api/src/Plugin/QueueWorker/AhjoOrgChartQueueWorker.php +++ /dev/null @@ -1,271 +0,0 @@ -ahjoProxy = $container->get('paatokset_ahjo_proxy'); - $instance->logger = $container->get('logger.factory')->get('ahjo_api_org_queue'); - $queue_factory = $container->get('queue'); - $instance->queue = $queue_factory->get('ahjo_api_org_queue'); - return $instance; - } - - /** - * {@inheritdoc} - */ - public function processItem($data): void { - $id = (string) $data['id']; - $step = (int) $data['step']; - $max_steps = (int) ($data['max_steps'] ?? self::MAX_RECURSION_DEPTH); - $langcode = $data['langcode'] ?? NULL; - - // Process only one language. - if (!is_null($data['langcode'])) { - // Validate langcode. - if (!in_array($langcode, self::ALLOWED_LANGCODES)) { - $this->logger->error("Org: @id, refusing to process invalid language @langcode", [ - '@langcode' => $langcode, - ]); - - return; - } - - $this->processOrganization($id, $langcode, $step, $max_steps); - } - else { - // Process all languages. Recursive items are added with the langcode - // parameter so this path only applies to the first item. - foreach (self::ALLOWED_LANGCODES as $langcode) { - $this->processOrganization($id, $langcode, $step, $max_steps); - } - } - } - - /** - * Processes queued organization in one language. - * - * @param string $id - * Organization id. - * @param string $langcode - * Language to process. - * @param int $step - * Current recursion depth. - * @param int $max_steps - * Maximum allowed recursion depth. - */ - private function processOrganization(string $id, string $langcode, int $step, int $max_steps): void { - $this->logger->info('Org: @id (@langcode), step @step out of @max_steps.', [ - '@id' => $id, - '@langcode' => $langcode, - '@step' => $step, - '@max_steps' => $max_steps, - ]); - - if (!$this->ahjoProxy->isOperational()) { - $this->logger->error('Ahjo Proxy is not operational, suspending.'); - throw new SuspendQueueException('Ahjo Proxy is not operational, suspending.'); - } - - if (!empty(getenv('AHJO_PROXY_BASE_URL'))) { - $url = 'organization/single/' . (string) $id . '?apireqlang=' . (string) $langcode; - $query_string = NULL; - } - else { - $url = 'organization'; - $query_string = 'orgid=' . (string) $id . '&apireqlang=' . (string) $langcode; - } - - $organization = $this->ahjoProxy->getData($url, $query_string); - - // Local organization is formatted a bit differently. - if (!empty($organization['decisionMakers'][0]['Organization'])) { - $organization = $organization['decisionMakers'][0]['Organization']; - } - - if (empty($organization['ID'])) { - $this->logger->error('Data not found for @id', [ - '@id' => $id, - ]); - return; - } - - $node = $this->findOrCreateOrg($id, $organization['Name'], $langcode); - $node->set('field_organization_data', json_encode($organization)); - - if (!empty($organization['OrganizationLevelAbove']['organizations'])) { - $above_org = reset($organization['OrganizationLevelAbove']['organizations']); - - if (!$node->get('field_org_level_above_id')->isEmpty() && $node->get('field_org_level_above_id')->value !== $above_org['ID']) { - $this->logger->warning('Duplicate ID with different parent: @id, (@parent_id, expecting @existing_parent).', [ - '@id' => $id, - '@parent_id' => $above_org['ID'], - '@existing_parent' => $node->get('field_org_level_above_id')->value, - ]); - } - if ($node->isDefaultTranslation()) { - $node->set('field_org_level_above_id', $above_org['ID']); - } - } - $below_ids = []; - foreach ($organization['OrganizationLevelBelow']['organizations'] as $org_below) { - if ($org_below['Existing'] !== 'true') { - continue; - } - $below_ids[] = $org_below['ID']; - } - - if ($node->isDefaultTranslation()) { - $node->set('field_org_level_below_ids', $below_ids); - } - - $node->save(); - - if (empty($below_ids)) { - return; - } - - // Check if max step amount has been reached yet. - if ($step >= $max_steps) { - $this->logger->info('Maximum amount of steps reached.'); - return; - } - - // Add child items to queue. - $next_step = $step + 1; - foreach ($below_ids as $child_id) { - $data = [ - 'id' => $child_id, - 'step' => $next_step, - 'max_steps' => $max_steps, - 'langcode' => $langcode, - ]; - - $item_id = $this->queue->createItem($data); - - if ($item_id) { - $this->logger->info('Added item to org chart queue: @id (@langcode), (@step out of @max_steps).', [ - '@id' => $child_id, - '@langcode' => $langcode, - '@step' => $next_step, - '@max_steps' => $max_steps, - ]); - } - } - } - - /** - * Find or create organization node based on ID. - * - * @param string $id - * Organization ID. - * @param string $title - * Organization's name. - * @param string $langcode - * Language for org data. - * - * @return \Drupal\node\NodeInterface - * Loaded or created node, if found. - */ - private function findOrCreateOrg(string $id, string $title, string $langcode): NodeInterface { - $query = \Drupal::entityQuery('node') - ->condition('status', 1) - ->range(0, 1) - ->condition('field_policymaker_id', $id) - ->condition('type', 'organization'); - - $ids = $query->execute(); - $found_node = NULL; - if (!empty($ids)) { - $found_node = Node::load(reset($ids)); - } - - $title = Unicode::truncate($title, '255', TRUE, TRUE); - - if (!$found_node instanceof NodeInterface) { - $found_node = Node::create([ - 'type' => 'organization', - 'langcode' => $langcode, - 'field_policymaker_id' => $id, - 'title' => $title, - ]); - } - else { - if ($found_node->hasTranslation($langcode)) { - $found_node = $found_node->getTranslation($langcode); - } - else { - $found_node = $found_node->addTranslation($langcode, [ - 'type' => 'organization', - 'title' => $title, - ]); - } - } - - $found_node->set('title', $title); - return $found_node; - } - -} diff --git a/public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoOrganizationSource.php b/public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoOrganizationSource.php new file mode 100644 index 000000000..1a1f9aacc --- /dev/null +++ b/public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoOrganizationSource.php @@ -0,0 +1,158 @@ + [ + 'type' => 'string', + ], + 'langcode' => [ + 'type' => 'string', + ], + ]; + } + + /** + * {@inheritDoc} + */ + protected function initializeIterator(): \Iterator { + // Using stack allows the iterator to keep track of much less information. + // The stack basically leads to Depth-first search instead of breadth-first. + $stack = new \SplStack(); + + $root = $this->configuration['root_org'] ?? self::ROOT_ORGANIZATION_ID; + $langcodes = $this->configuration['languages'] ?? self::ALL_LANGCODES; + + Assert::isArray($langcodes); + + // Iterate the org chart using Depth-first search starting from the root. + $stack->push($root); + + while (!$stack->isEmpty()) { + $id = $stack->pop(); + + // Traverse org char once for each langcode. + foreach ($langcodes as $langcode) { + $this->logger->info("Importing organization @id (@language)", [ + "@id" => $id, + "@language" => $langcode, + ]); + + $organization = $this->getOrganization($id, $langcode); + + $title = Unicode::truncate($organization['Name'], '255', TRUE, TRUE); + + // Some organizations don't have Name in Ahjo. + if (empty($title)) { + $title = $id; + } + + // Add organizations below this one to the stack. + foreach ($organization['OrganizationLevelBelow']['organizations'] as $org_below) { + $include_inactive = $this->configuration['include_inactive'] ?? FALSE; + if ($include_inactive !== TRUE && $org_below['Existing'] !== 'true') { + continue; + } + + $stack->push($org_below['ID']); + } + + yield [ + 'id' => $id, + 'response' => $organization, + 'title' => $title, + 'langcode' => $langcode, + ]; + } + } + } + + /** + * Get organization info from Ahjo. + */ + private function getOrganization(string $id, string $langcode): array { + if (!$this->ahjoProxy->isOperational()) { + $this->logger->error('Ahjo Proxy is not operational, exiting.'); + throw new MigrateException('Ahjo Proxy is not operational, exiting.'); + } + + if (!empty(getenv('AHJO_PROXY_BASE_URL'))) { + $url = 'organization/single/' . (string) $id . '?apireqlang=' . (string) $langcode; + $query_string = NULL; + } + else { + $url = 'organization'; + $query_string = 'orgid=' . (string) $id . '&apireqlang=' . (string) $langcode; + } + + $organization = $this->ahjoProxy->getData($url, $query_string); + + // Local organization is formatted a bit differently. + if (!empty($organization['decisionMakers'][0]['Organization'])) { + $organization = $organization['decisionMakers'][0]['Organization']; + } + + if (empty($organization['ID'])) { + $this->logger->error('Data not found for @id', [ + '@id' => $id, + ]); + throw new MigrateException("Data not found for $id"); + } + + return $organization; + } + + /** + * {@inheritDoc} + */ + public function __toString() { + return 'AhjoOrganizations'; + } + +} diff --git a/public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoSourceBase.php b/public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoSourceBase.php new file mode 100644 index 000000000..0eadc0ef4 --- /dev/null +++ b/public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoSourceBase.php @@ -0,0 +1,47 @@ +logger = $container->get('logger.factory')->get('paatokset_ahjo_api'); + $instance->ahjoProxy = $container->get('paatokset_ahjo_proxy'); + return $instance; + } + +} From 3537d0c6bf60761ff28080b65e5218112d11f3ac Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Mon, 16 Oct 2023 06:21:50 +0300 Subject: [PATCH 12/21] UHF-8858: Add organizations cron jobs --- docker/openshift/crons/run-aggregated-ahjo-integrations.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docker/openshift/crons/run-aggregated-ahjo-integrations.sh b/docker/openshift/crons/run-aggregated-ahjo-integrations.sh index 3917f2129..60969ca15 100644 --- a/docker/openshift/crons/run-aggregated-ahjo-integrations.sh +++ b/docker/openshift/crons/run-aggregated-ahjo-integrations.sh @@ -48,6 +48,9 @@ do drush migrate-import ahjo_trustees:all --update drush migrate-reset-status ahjo_trustees:all_sv drush migrate-import ahjo_trustees:all_sv --update + echo "Migrating organization chart" + drush migrate-reset-status ahjo_organizations + drush migrate-import ahjo_organizations echo "Migrating data for decisionmakers: $(date)" drush migrate-reset-status ahjo_decisionmakers:latest drush migrate-reset-status ahjo_decisionmakers:latest_sv From 9f578417b9d258bf729cf3afd26c468b2177c2f0 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Mon, 16 Oct 2023 07:36:42 +0300 Subject: [PATCH 13/21] UHF-8858: move update hook to drush command Update hook would not work, since the migration needs to be executed first. Wouldn't the deploy fail the hook is not run immediately. --- composer.json | 1 + composer.lock | 74 ++++++++++++++++++- .../src/Commands/AhjoAggregatorCommands.php | 64 ++++++++++++++++ .../paatokset_policymakers.install | 58 --------------- 4 files changed, 137 insertions(+), 60 deletions(-) delete mode 100644 public/modules/custom/paatokset_policymakers/paatokset_policymakers.install diff --git a/composer.json b/composer.json index 9503e717c..9fe102fcf 100644 --- a/composer.json +++ b/composer.json @@ -36,6 +36,7 @@ "dmore/chrome-mink-driver": "^2.8", "drupal/coder": "^8.3", "drupal/core-dev": "^9.3", + "drupal/migrate_tools": "^5.2", "mglaman/phpstan-drupal": "^1.0", "phpspec/prophecy-phpunit": "^2", "phpstan/extension-installer": "^1.1", diff --git a/composer.lock b/composer.lock index 0c0342ae1..712b37ea1 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": "a24058afc486263d95fac94cdc5896d3", + "content-hash": "3fb14139d66c80f430a392996cd31893", "packages": [ { "name": "asm89/stack-cors", @@ -13854,6 +13854,76 @@ }, "time": "2022-07-27T00:23:55+00:00" }, + { + "name": "drupal/migrate_tools", + "version": "5.2.0", + "source": { + "type": "git", + "url": "https://git.drupalcode.org/project/migrate_tools.git", + "reference": "8.x-5.2" + }, + "dist": { + "type": "zip", + "url": "https://ftp.drupal.org/files/projects/migrate_tools-8.x-5.2.zip", + "reference": "8.x-5.2", + "shasum": "e473c32780c567b62b3aa7dd92c2fb5227b9ee12" + }, + "require": { + "drupal/core": "^9.1", + "drupal/migrate_plus": "^5", + "php": ">=7.1" + }, + "require-dev": { + "drupal/migrate_source_csv": "^3.0", + "drush/drush": "^10" + }, + "suggest": { + "drush/drush": "^9 || ^10" + }, + "type": "drupal-module", + "extra": { + "drupal": { + "version": "8.x-5.2", + "datestamp": "1672425094", + "security-coverage": { + "status": "covered", + "message": "Covered by Drupal's security advisory policy" + } + }, + "drush": { + "services": { + "drush.services.yml": "^9 || ^10" + } + } + }, + "notification-url": "https://packages.drupal.org/8/downloads", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Mike Ryan", + "homepage": "https://www.drupal.org/u/mikeryan", + "role": "Maintainer" + }, + { + "name": "Lucas Hedding", + "homepage": "https://www.drupal.org/u/heddn", + "role": "Maintainer" + }, + { + "name": "mikeryan", + "homepage": "https://www.drupal.org/user/4420" + } + ], + "description": "Tools to assist in developing and running migrations.", + "homepage": "http://drupal.org/project/migrate_tools", + "support": { + "source": "https://git.drupalcode.org/project/migrate_tools", + "issues": "https://www.drupal.org/project/issues/migrate_tools", + "slack": "#migrate" + } + }, { "name": "easyrdf/easyrdf", "version": "1.1.1", @@ -17103,5 +17173,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/public/modules/custom/paatokset_ahjo_proxy/src/Commands/AhjoAggregatorCommands.php b/public/modules/custom/paatokset_ahjo_proxy/src/Commands/AhjoAggregatorCommands.php index 34cbb370e..85477bbf5 100644 --- a/public/modules/custom/paatokset_ahjo_proxy/src/Commands/AhjoAggregatorCommands.php +++ b/public/modules/custom/paatokset_ahjo_proxy/src/Commands/AhjoAggregatorCommands.php @@ -3129,4 +3129,68 @@ private function getListKey(string $endpoint): ?string { return $key; } + /** + * Fix policymaker node references to organizations. + * + * For some reason, the ahjo_decisionmakers:latest migration does not return + * all policymakers that exist in the production database. + * + * This command fixes the links and should be run on the production database + * once when UHF-8858 is deployed and the migration ahjo_organizations has + * been run. + * + * This should not be an issue once existing policymakers are treated, since + * new policymakers that are imported using the migration should get the + * reference automatically. + * + * @command ahjo-proxy:fix-decisionmaker-references + * + * @usage ahjo-proxy:store-static-files + * Stores default static files into filesystem (for debugging migrations). + */ + public function fixPolicymakerReferences(): void { + $nodeStorage = \Drupal::entityTypeManager() + ->getStorage('node'); + + // Load policymakers that are missing field_dm_organization. + $nids = $nodeStorage + ->getQuery() + ->accessCheck(FALSE) + ->condition('type', 'policymaker') + ->notExists('field_dm_organization') + ->execute(); + + $count = 0; + + foreach ($nids as $nid) { + if (is_null($policymaker = $nodeStorage->load($nid))) { + continue; + } + + $policymaker_id = $policymaker->get('field_policymaker_id')->getString(); + $organizations = $nodeStorage->loadByProperties([ + 'type' => 'organization', + 'field_policymaker_id' => $policymaker_id, + ]); + + if ($organization = reset($organizations)) { + // Set organization reference to policymaker. + $policymaker->set('field_dm_organization', $organization); + $policymaker->save(); + $count += 1; + } + else { + \Drupal::logger('paatokset_ahjo_proxy')->warning("Decisionmaker @dm: organization @id does not exist", [ + '@dm' => $policymaker->toUrl('edit-form')->toString(), + '@id' => $policymaker_id, + ]); + } + } + + \Drupal::logger('paatokset_ahjo_proxy')->info("Fixed @fixed of detected @all policymaers", [ + '@fixed' => $count, + '@all' => count($nids), + ]); + } + } diff --git a/public/modules/custom/paatokset_policymakers/paatokset_policymakers.install b/public/modules/custom/paatokset_policymakers/paatokset_policymakers.install deleted file mode 100644 index c28155073..000000000 --- a/public/modules/custom/paatokset_policymakers/paatokset_policymakers.install +++ /dev/null @@ -1,58 +0,0 @@ -getStorage('node'); - - // Load policymakers that are missing field_dm_organization. - $nids = $nodeStorage - ->getQuery() - ->accessCheck(FALSE) - ->condition('type', 'policymaker') - ->notExists('field_dm_organization') - ->execute(); - - foreach ($nids as $nid) { - if (is_null($policymaker = $nodeStorage->load($nid))) { - continue; - } - - $policymaker_id = $policymaker->get('field_policymaker_id')->getString(); - $organizations = $nodeStorage->loadByProperties([ - 'type' => 'organization', - 'field_policymaker_id' => $policymaker_id - ]); - - if ($organization = reset($organizations)) { - // Set organization reference to policymaker. - $policymaker->set('field_dm_organization', $organization); - } else { - // Organization not found. Try running org chart queue first. - throw new UpdateException("Organization with id $policymaker_id does not exists."); - } - } -} - - - From 839a78a56a793b32e3e19fdb63e7f17b5be57988 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Tue, 17 Oct 2023 12:04:23 +0300 Subject: [PATCH 14/21] UHF-9028: remove who_s_new and who_s_online views These views are not used anywhere. --- conf/cmi/language/fi/views.view.who_s_new.yml | 20 -- .../language/fi/views.view.who_s_online.yml | 30 --- conf/cmi/language/ru/views.view.who_s_new.yml | 20 -- .../language/ru/views.view.who_s_online.yml | 30 --- conf/cmi/language/sv/views.view.who_s_new.yml | 20 -- .../language/sv/views.view.who_s_online.yml | 30 --- conf/cmi/views.view.who_s_new.yml | 197 --------------- conf/cmi/views.view.who_s_online.yml | 226 ------------------ 8 files changed, 573 deletions(-) delete mode 100644 conf/cmi/language/fi/views.view.who_s_new.yml delete mode 100644 conf/cmi/language/fi/views.view.who_s_online.yml delete mode 100644 conf/cmi/language/ru/views.view.who_s_new.yml delete mode 100644 conf/cmi/language/ru/views.view.who_s_online.yml delete mode 100644 conf/cmi/language/sv/views.view.who_s_new.yml delete mode 100644 conf/cmi/language/sv/views.view.who_s_online.yml delete mode 100644 conf/cmi/views.view.who_s_new.yml delete mode 100644 conf/cmi/views.view.who_s_online.yml diff --git a/conf/cmi/language/fi/views.view.who_s_new.yml b/conf/cmi/language/fi/views.view.who_s_new.yml deleted file mode 100644 index e2521a8dd..000000000 --- a/conf/cmi/language/fi/views.view.who_s_new.yml +++ /dev/null @@ -1,20 +0,0 @@ -label: 'Uudet käyttäjät' -description: 'Näyttää listan sivuston uusimmista käyttäjätileistä.' -display: - default: - display_title: Oletus - display_options: - title: 'Uudet käyttäjät' - exposed_form: - options: - submit_button: Käytä - reset_button_label: Palauta - exposed_sorts_label: Lajittele - sort_asc_label: Asc - sort_desc_label: Desc - block_1: - display_title: 'Uudet käyttäjät' - display_options: - display_description: 'Lista uusista käyttäjistä' - block_description: 'Uudet käyttäjät' - block_category: Käyttäjä diff --git a/conf/cmi/language/fi/views.view.who_s_online.yml b/conf/cmi/language/fi/views.view.who_s_online.yml deleted file mode 100644 index 3d793934c..000000000 --- a/conf/cmi/language/fi/views.view.who_s_online.yml +++ /dev/null @@ -1,30 +0,0 @@ -label: 'Kuka on paikalla -lohko' -description: 'Näyttää viimeksi aktiivisina olleiden käyttäjien käyttäjätunnukset ja aktiivisten käyttäjien kokonaismäärän.' -display: - default: - display_title: Oletus - display_options: - title: 'Paikalla olevat käyttäjät' - exposed_form: - options: - submit_button: Käytä - reset_button_label: Palauta - exposed_sorts_label: Lajittele - sort_asc_label: Asc - sort_desc_label: Desc - empty: - area_text_custom: - content: 'Tällä hetkellä 0 käyttäjää on online.' - filters: - access: - expose: - label: 'Viimeksi paikalla' - description: 'Sen jäkeen kun käyttäjä viimeksi latasi sivun, hänen katsotaan olevan paikalla vielä näin kauan' - header: - result: - content: 'Tällä hetkellä @total käyttäjää on online.' - who_s_online_block: - display_title: 'Paikalla olevat käyttäjät' - display_options: - display_description: 'Lista käyttäjistä jotka ovat online.' - block_description: 'Paikalla olevat käyttäjät' diff --git a/conf/cmi/language/ru/views.view.who_s_new.yml b/conf/cmi/language/ru/views.view.who_s_new.yml deleted file mode 100644 index daf06478b..000000000 --- a/conf/cmi/language/ru/views.view.who_s_new.yml +++ /dev/null @@ -1,20 +0,0 @@ -label: 'Новые пользователи' -description: 'Показывает список новых учётных записей пользователей на сайте.' -display: - default: - display_title: 'По умолчанию' - display_options: - title: 'Новые пользователи' - exposed_form: - options: - submit_button: Применить - reset_button_label: Сбросить - exposed_sorts_label: 'Сортировать по' - sort_asc_label: 'По возрастанию' - sort_desc_label: 'По убыванию' - block_1: - display_title: 'Новые пользователи' - display_options: - display_description: 'Список новых пользователей' - block_description: 'Новые пользователи' - block_category: Пользователь diff --git a/conf/cmi/language/ru/views.view.who_s_online.yml b/conf/cmi/language/ru/views.view.who_s_online.yml deleted file mode 100644 index 729f66fe6..000000000 --- a/conf/cmi/language/ru/views.view.who_s_online.yml +++ /dev/null @@ -1,30 +0,0 @@ -label: 'Блок «Кто на сайте?»' -description: 'Показывает имена пользователей, которые были активными в последнее время, и общее число активных пользователей.' -display: - default: - display_title: 'По умолчанию' - display_options: - title: 'Сейчас на сайте' - exposed_form: - options: - submit_button: Применить - reset_button_label: Сбросить - exposed_sorts_label: 'Сортировать по' - sort_asc_label: 'По возрастанию' - sort_desc_label: 'По убыванию' - empty: - area_text_custom: - content: 'Сейчас 0 пользователей онлайн.' - filters: - access: - expose: - label: 'Последнее посещение' - description: 'Пользователь считается находящимся на сайте в течение этого периода, начиная со времени последнего просмотра им страницы.' - header: - result: - content: 'В данный момент пользователей онлайн: @total.' - who_s_online_block: - display_title: 'Сейчас на сайте' - display_options: - display_description: 'Список пользователей, авторизированных в данный момент.' - block_description: 'Сейчас на сайте' diff --git a/conf/cmi/language/sv/views.view.who_s_new.yml b/conf/cmi/language/sv/views.view.who_s_new.yml deleted file mode 100644 index baf10af6e..000000000 --- a/conf/cmi/language/sv/views.view.who_s_new.yml +++ /dev/null @@ -1,20 +0,0 @@ -label: 'Vilka är nya?' -description: 'Visar en lista över de senast användarkontona på webbplatsen.' -display: - default: - display_title: Förvald - display_options: - title: 'Vilka är nya?' - exposed_form: - options: - submit_button: Verkställ - reset_button_label: Återställ - exposed_sorts_label: 'Sortera efter' - sort_asc_label: Stigande - sort_desc_label: Fallande - block_1: - display_title: 'Vilka är nya?' - display_options: - display_description: 'En lista på nya användare' - block_description: 'Vilka är nya?' - block_category: Användare diff --git a/conf/cmi/language/sv/views.view.who_s_online.yml b/conf/cmi/language/sv/views.view.who_s_online.yml deleted file mode 100644 index f22a2955a..000000000 --- a/conf/cmi/language/sv/views.view.who_s_online.yml +++ /dev/null @@ -1,30 +0,0 @@ -label: 'Block för vilka som är inloggade' -description: 'Visar de användarnamnen för de senast aktiva användarna samt de totalt antal aktiva användare.' -display: - default: - display_title: Förvald - display_options: - title: 'Vilka är inloggade' - exposed_form: - options: - submit_button: Verkställ - reset_button_label: Återställ - exposed_sorts_label: 'Sortera efter' - sort_asc_label: Stigande - sort_desc_label: Fallande - empty: - area_text_custom: - content: 'För närvarande är 0 användare inloggade.' - filters: - access: - expose: - label: 'Senast åtkomst' - description: 'En användare anses vara inloggad så här länge efter att de senast tittat på en sida.' - header: - result: - content: 'För närvarande är @total användare inloggade.' - who_s_online_block: - display_title: 'Vilka är inloggade' - display_options: - display_description: 'En lista på användare som för närvarande är inloggade.' - block_description: 'Vilka är inloggade' diff --git a/conf/cmi/views.view.who_s_new.yml b/conf/cmi/views.view.who_s_new.yml deleted file mode 100644 index 5459a7109..000000000 --- a/conf/cmi/views.view.who_s_new.yml +++ /dev/null @@ -1,197 +0,0 @@ -uuid: 3cc290aa-1841-4cb9-9ea5-d3dcfc0cd7d6 -langcode: en -status: true -dependencies: - module: - - user -_core: - default_config_hash: nCa1oy25w2fh-nk_iQ7IJFQwQIcKxrV_5EQW2y8dzPc -id: who_s_new -label: 'Uudet käyttäjät' -module: user -description: 'Näyttää listan sivuston uusimmista käyttäjätileistä.' -tag: default -base_table: users_field_data -base_field: uid -display: - default: - id: default - display_title: Oletus - display_plugin: default - position: 0 - display_options: - title: 'Uudet käyttäjät' - fields: - name: - id: name - table: users_field_data - field: name - relationship: none - group_type: group - admin_label: '' - entity_type: user - entity_field: name - plugin_id: field - label: '' - exclude: false - alter: - alter_text: false - make_link: false - absolute: false - word_boundary: false - ellipsis: false - strip_tags: false - trim: false - html: false - element_type: '' - element_class: '' - element_label_type: '' - element_label_class: '' - element_label_colon: true - element_wrapper_type: '' - element_wrapper_class: '' - element_default_classes: true - empty: '' - hide_empty: false - empty_zero: false - hide_alter_empty: true - type: user_name - pager: - type: some - options: - offset: 0 - items_per_page: 5 - exposed_form: - type: basic - options: - submit_button: Käytä - reset_button: false - reset_button_label: Palauta - exposed_sorts_label: Lajittele - expose_sort_order: true - sort_asc_label: Nousevasti - sort_desc_label: Laskevasti - access: - type: perm - options: - perm: 'access content' - cache: - type: tag - options: { } - empty: { } - sorts: - created: - id: created - table: users_field_data - field: created - relationship: none - group_type: group - admin_label: '' - entity_type: user - entity_field: created - plugin_id: date - order: DESC - expose: - label: '' - field_identifier: created - exposed: false - granularity: second - arguments: { } - filters: - status: - id: status - table: users_field_data - field: status - entity_type: user - entity_field: status - plugin_id: boolean - value: '1' - group: 1 - expose: - operator: '0' - operator_limit_selection: false - operator_list: { } - access: - id: access - table: users_field_data - field: access - relationship: none - group_type: group - admin_label: '' - entity_type: user - entity_field: access - plugin_id: date - operator: '>' - value: - min: '' - max: '' - value: '1970-01-01' - type: date - group: 1 - exposed: false - expose: - operator_id: '0' - label: '' - description: '' - use_operator: false - operator: '' - operator_limit_selection: false - operator_list: { } - identifier: '' - required: false - remember: false - multiple: false - remember_roles: - authenticated: authenticated - is_grouped: false - group_info: - label: '' - description: '' - identifier: '' - optional: true - widget: select - multiple: false - remember: false - default_group: All - default_group_multiple: { } - group_items: { } - style: - type: html_list - row: - type: fields - query: - type: views_query - options: - query_comment: '' - disable_sql_rewrite: false - distinct: false - replica: false - query_tags: { } - relationships: { } - header: { } - footer: { } - display_extenders: { } - cache_metadata: - max-age: -1 - contexts: - - 'languages:language_content' - - 'languages:language_interface' - - user.permissions - tags: { } - block_1: - id: block_1 - display_title: 'Uudet käyttäjät' - display_plugin: block - position: 1 - display_options: - display_description: 'Lista uusista käyttäjistä' - display_extenders: { } - block_description: 'Uudet käyttäjät' - block_category: Käyttäjä - cache_metadata: - max-age: -1 - contexts: - - 'languages:language_content' - - 'languages:language_interface' - - user.permissions - tags: { } diff --git a/conf/cmi/views.view.who_s_online.yml b/conf/cmi/views.view.who_s_online.yml deleted file mode 100644 index fdf60dbda..000000000 --- a/conf/cmi/views.view.who_s_online.yml +++ /dev/null @@ -1,226 +0,0 @@ -uuid: c6624521-ee46-49e5-a664-3fd5720ef44a -langcode: en -status: true -dependencies: - module: - - user -_core: - default_config_hash: t9qu6R6PnnbZNOft0SpIMxwCg6VCfaX3aW2W-NjeFyc -id: who_s_online -label: 'Kuka on paikalla -lohko' -module: user -description: 'Näyttää viimeksi aktiivisina olleiden käyttäjien käyttäjätunnukset ja aktiivisten käyttäjien kokonaismäärän.' -tag: default -base_table: users_field_data -base_field: uid -display: - default: - id: default - display_title: Oletus - display_plugin: default - position: 0 - display_options: - title: 'Paikalla olevat käyttäjät' - fields: - name: - id: name - table: users_field_data - field: name - relationship: none - group_type: group - admin_label: '' - entity_type: user - entity_field: name - plugin_id: field - label: '' - exclude: false - alter: - alter_text: false - make_link: false - absolute: false - word_boundary: false - ellipsis: false - strip_tags: false - trim: false - html: false - element_type: '' - element_class: '' - element_label_type: '' - element_label_class: '' - element_label_colon: true - element_wrapper_type: '' - element_wrapper_class: '' - element_default_classes: true - empty: '' - hide_empty: false - empty_zero: false - hide_alter_empty: true - type: user_name - pager: - type: some - options: - offset: 0 - items_per_page: 10 - exposed_form: - type: basic - options: - submit_button: Käytä - reset_button: false - reset_button_label: Palauta - exposed_sorts_label: Lajittele - expose_sort_order: true - sort_asc_label: Nousevasti - sort_desc_label: Laskevasti - access: - type: perm - options: - perm: 'access user profiles' - cache: - type: tag - options: { } - empty: - area_text_custom: - id: area_text_custom - table: views - field: area_text_custom - relationship: none - group_type: group - admin_label: '' - plugin_id: text_custom - empty: true - content: 'Tällä hetkellä 0 käyttäjää on online.' - tokenize: false - sorts: - access: - id: access - table: users_field_data - field: access - relationship: none - group_type: group - admin_label: '' - entity_type: user - entity_field: access - plugin_id: date - order: DESC - expose: - label: '' - field_identifier: access - exposed: false - granularity: second - arguments: { } - filters: - status: - id: status - table: users_field_data - field: status - entity_type: user - entity_field: status - plugin_id: boolean - value: '1' - group: 1 - expose: - operator: '0' - operator_limit_selection: false - operator_list: { } - access: - id: access - table: users_field_data - field: access - relationship: none - group_type: group - admin_label: '' - entity_type: user - entity_field: access - plugin_id: date - operator: '>=' - value: - min: '' - max: '' - value: '-15 minutes' - type: offset - group: 1 - exposed: false - expose: - operator_id: access_op - label: 'Viimeksi paikalla' - description: 'Sen jäkeen kun käyttäjä viimeksi latasi sivun, hänen katsotaan olevan paikalla vielä näin kauan' - use_operator: false - operator: access_op - operator_limit_selection: false - operator_list: { } - identifier: access - required: false - remember: false - multiple: false - remember_roles: - authenticated: authenticated - anonymous: '0' - administrator: '0' - is_grouped: false - group_info: - label: '' - description: '' - identifier: '' - optional: true - widget: select - multiple: false - remember: false - default_group: All - default_group_multiple: { } - group_items: { } - style: - type: html_list - options: - grouping: { } - row_class: '' - default_row_class: true - type: ul - wrapper_class: item-list - class: '' - row: - type: fields - query: - type: views_query - options: - query_comment: '' - disable_sql_rewrite: false - distinct: false - replica: false - query_tags: { } - relationships: { } - header: - result: - id: result - table: views - field: result - relationship: none - group_type: group - admin_label: '' - plugin_id: result - empty: false - content: 'Tällä hetkellä @total käyttäjää on online.' - footer: { } - display_extenders: { } - cache_metadata: - max-age: -1 - contexts: - - 'languages:language_content' - - 'languages:language_interface' - - user.permissions - tags: { } - who_s_online_block: - id: who_s_online_block - display_title: 'Paikalla olevat käyttäjät' - display_plugin: block - position: 1 - display_options: - display_description: 'Lista käyttäjistä jotka ovat online.' - display_extenders: { } - block_description: 'Paikalla olevat käyttäjät' - cache_metadata: - max-age: -1 - contexts: - - 'languages:language_content' - - 'languages:language_interface' - - user.permissions - tags: { } From 7588d957f6b15952b6fddb41e75065a6a0139f90 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Tue, 17 Oct 2023 13:28:26 +0300 Subject: [PATCH 15/21] UHF-9028: Fix pager styles on taxonomy term view In view settings, this changes the pager from mini to full. The full pager uses is styled in hdbt. --- conf/cmi/views.view.taxonomy_term.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/conf/cmi/views.view.taxonomy_term.yml b/conf/cmi/views.view.taxonomy_term.yml index 5b07a95ca..1f76991dc 100644 --- a/conf/cmi/views.view.taxonomy_term.yml +++ b/conf/cmi/views.view.taxonomy_term.yml @@ -156,7 +156,7 @@ display: separator: ', ' field_api_classes: false pager: - type: mini + type: full options: offset: 0 items_per_page: 10 @@ -165,6 +165,8 @@ display: tags: next: 'Seuraava ›' previous: '‹ Edellinen' + first: '« Ensimmäinen' + last: 'Viimeinen »' expose: items_per_page: false items_per_page_label: 'Merkintöjä sivua kohti' @@ -173,6 +175,7 @@ display: items_per_page_options_all_label: '- Kaikki -' offset: false offset_label: Offset + quantity: 9 exposed_form: type: basic options: From 4462add105c5e3454e8b9d1a497c2b8430e26a11 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Wed, 18 Oct 2023 09:05:57 +0300 Subject: [PATCH 16/21] UHF-9028: remove unnecessary template variable --- .../custom/paatokset_ahjo_api/paatokset_ahjo_api.module | 9 +-------- .../src/Plugin/Block/ArticlesBlock.php | 2 ++ .../templates/block/block--all-articles.html.twig | 1 + 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module b/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module index 286de2b0b..068e85e05 100644 --- a/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module +++ b/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module @@ -376,7 +376,6 @@ function paatokset_ahjo_api_preprocess_block__all_articles(array &$variables): v $nodes = Node::loadMultiple($nids); - $years = []; $by_year = []; foreach ($nodes as $node) { if ($node->hasTranslation($currentLanguage)) { @@ -391,19 +390,13 @@ function paatokset_ahjo_api_preprocess_block__all_articles(array &$variables): v } $year = date('Y', $timestamp); - if (!in_array($year, $years)) { - $by_year[$year] = []; - $years[] = $year; - } - $by_year[$year][] = [ 'url' => $node->toUrl(), 'date' => $timestamp, - 'title' => $node->title->value, + 'title' => $node->getTitle(), ]; } - $variables['years'] = $years; $variables['articles'] = $by_year; // Helpful $content variable for templates. diff --git a/public/modules/custom/paatokset_ahjo_api/src/Plugin/Block/ArticlesBlock.php b/public/modules/custom/paatokset_ahjo_api/src/Plugin/Block/ArticlesBlock.php index 3941093f0..ad78bdd4a 100644 --- a/public/modules/custom/paatokset_ahjo_api/src/Plugin/Block/ArticlesBlock.php +++ b/public/modules/custom/paatokset_ahjo_api/src/Plugin/Block/ArticlesBlock.php @@ -17,6 +17,8 @@ class ArticlesBlock extends BlockBase { /** * Build the attributes. + * + * @see \paatokset_ahjo_api_preprocess_block__all_articles */ public function build() { return [ diff --git a/public/modules/custom/paatokset_ahjo_api/templates/block/block--all-articles.html.twig b/public/modules/custom/paatokset_ahjo_api/templates/block/block--all-articles.html.twig index 3183824fd..0d32f7e8f 100644 --- a/public/modules/custom/paatokset_ahjo_api/templates/block/block--all-articles.html.twig +++ b/public/modules/custom/paatokset_ahjo_api/templates/block/block--all-articles.html.twig @@ -6,6 +6,7 @@ %} {% if articles %}
+ {% set years = articles | keys %} {% if (years is not empty ) %}
From a422564d968b4169a049be7ca5488070e9c30849 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Wed, 18 Oct 2023 09:07:16 +0300 Subject: [PATCH 17/21] UHF-9028: ensure that taxonomy_term and all_artices block have the same query --- conf/cmi/views.view.taxonomy_term.yml | 62 ++++++++++++++++--- .../paatokset_ahjo_api.module | 3 + 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/conf/cmi/views.view.taxonomy_term.yml b/conf/cmi/views.view.taxonomy_term.yml index 1f76991dc..78c5edddd 100644 --- a/conf/cmi/views.view.taxonomy_term.yml +++ b/conf/cmi/views.view.taxonomy_term.yml @@ -195,31 +195,35 @@ display: options: { } empty: { } sorts: - sticky: - id: sticky - table: taxonomy_index + sticky_2: + id: sticky_2 + table: node_field_data field: sticky relationship: none group_type: group admin_label: '' + entity_type: node + entity_field: sticky plugin_id: standard order: DESC expose: label: '' - field_identifier: sticky + field_identifier: '' exposed: false - created: - id: created - table: taxonomy_index - field: created + published_at: + id: published_at + table: node_field_data + field: published_at relationship: none group_type: group admin_label: '' + entity_type: node + entity_field: published_at plugin_id: date order: DESC expose: label: '' - field_identifier: created + field_identifier: '' exposed: false granularity: second arguments: @@ -345,6 +349,46 @@ display: default_group: All default_group_multiple: { } group_items: { } + status_1: + id: status_1 + table: node_field_data + field: status + relationship: none + group_type: group + admin_label: '' + entity_type: node + entity_field: status + plugin_id: boolean + operator: '=' + value: '1' + group: 1 + exposed: false + expose: + operator_id: '' + label: '' + description: '' + use_operator: false + operator: '' + operator_limit_selection: false + operator_list: { } + identifier: '' + required: false + remember: false + multiple: false + remember_roles: + authenticated: authenticated + is_grouped: false + group_info: + label: '' + description: '' + identifier: '' + optional: true + widget: select + multiple: false + remember: false + default_group: All + default_group_multiple: { } + group_items: { } style: type: default options: diff --git a/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module b/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module index 068e85e05..02441fd95 100644 --- a/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module +++ b/public/modules/custom/paatokset_ahjo_api/paatokset_ahjo_api.module @@ -368,9 +368,12 @@ function paatokset_ahjo_api_preprocess_block__all_initiatives(array &$variables) function paatokset_ahjo_api_preprocess_block__all_articles(array &$variables): void { $currentLanguage = \Drupal::languageManager()->getCurrentLanguage()->getId(); $nids = \Drupal::entityQuery('node') + ->accessCheck(TRUE) ->condition('type', 'article') ->condition('langcode', $currentLanguage) ->condition('status', 1) + ->sort('sticky', 'DESC') + // Field defined by publication_date module. ->sort('published_at', 'DESC') ->execute(); From 8f963f67e5ab84e3321a5b8deb8a977440c20ecb Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Wed, 18 Oct 2023 09:58:46 +0300 Subject: [PATCH 18/21] UHF-9028: Use same field and date format for all_articles block and taxonomy_term view --- conf/cmi/views.view.taxonomy_term.yml | 8 ++++---- .../templates/block/block--all-articles.html.twig | 2 +- .../src/scss/06_components/content/_term-page.scss | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/conf/cmi/views.view.taxonomy_term.yml b/conf/cmi/views.view.taxonomy_term.yml index 78c5edddd..b26e88ccb 100644 --- a/conf/cmi/views.view.taxonomy_term.yml +++ b/conf/cmi/views.view.taxonomy_term.yml @@ -23,15 +23,15 @@ display: position: 0 display_options: fields: - created: - id: created + published_at: + id: published_at table: node_field_data - field: created + field: published_at relationship: none group_type: group admin_label: '' entity_type: node - entity_field: created + entity_field: published_at plugin_id: field label: '' exclude: false diff --git a/public/modules/custom/paatokset_ahjo_api/templates/block/block--all-articles.html.twig b/public/modules/custom/paatokset_ahjo_api/templates/block/block--all-articles.html.twig index 0d32f7e8f..ec5489a54 100644 --- a/public/modules/custom/paatokset_ahjo_api/templates/block/block--all-articles.html.twig +++ b/public/modules/custom/paatokset_ahjo_api/templates/block/block--all-articles.html.twig @@ -54,7 +54,7 @@
{% if document.date %} - {{ document.date|date("d.m.Y") }} + {{ document.date|format_date('publication_date_format') }} {% endif %}
diff --git a/public/themes/custom/hdbt_subtheme/src/scss/06_components/content/_term-page.scss b/public/themes/custom/hdbt_subtheme/src/scss/06_components/content/_term-page.scss index 0aa386d1b..9822ef435 100644 --- a/public/themes/custom/hdbt_subtheme/src/scss/06_components/content/_term-page.scss +++ b/public/themes/custom/hdbt_subtheme/src/scss/06_components/content/_term-page.scss @@ -8,7 +8,7 @@ border-top: 1px solid $color-black-20; } - .views-field-created { + .views-field-published-at { font-size: $fontsize-body-m; color: $color-black-light; margin-bottom: $spacing; From 45fa25d6d0e19b7c14d7d369f1357cfada241e51 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Wed, 18 Oct 2023 09:59:05 +0300 Subject: [PATCH 19/21] UHF-9028: build css --- public/themes/custom/hdbt_subtheme/dist/css/styles.min.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/themes/custom/hdbt_subtheme/dist/css/styles.min.css b/public/themes/custom/hdbt_subtheme/dist/css/styles.min.css index e84727bce..12080a929 100644 --- a/public/themes/custom/hdbt_subtheme/dist/css/styles.min.css +++ b/public/themes/custom/hdbt_subtheme/dist/css/styles.min.css @@ -1 +1 @@ -html{font-size:100%;height:100%;scroll-behavior:smooth}.dialog-off-canvas-main-canvas{background-color:#fff}body{height:100%;margin:0;padding:0}img{display:block;height:auto;max-width:100%}main{width:100%}.error-page .dialog-off-canvas-main-canvas{background:rgba(0,0,0,0)}.has-section-nav .layout-sidebar-first{display:none}@media(min-width: 992px){.has-section-nav .layout-sidebar-first{display:block}}html h1,html .page-title h1{margin-bottom:16px;font-size:3.25rem;font-weight:400}@media(min-width: 768px){html h1,html .page-title h1{margin-bottom:24px}}@media(min-width: 992px){html h1,html .page-title h1{font-size:4.5rem;line-height:4.5rem;margin-bottom:38px}}html blockquote{font-size:1.5rem;line-height:2.25rem;font-weight:400;border-left:5px solid #707070;color:#4a4a49;letter-spacing:0;margin:48px;padding-left:25px}html blockquote p{font-size:1.5rem;line-height:2.25rem;font-weight:400}body{font-size:18px}.paatokset-accordion .accordion-item__header .handorgel__header__button{color:#000;border:none;border-top:2px solid #ccc;background-color:#f7f7f8;padding:32px 32px 32px 0;display:flex;justify-content:space-between}.paatokset-accordion .accordion-item__header .accordion-item__icon{display:flex;align-items:center}.paatokset-accordion .accordion-item__header .accordion-item__icon span{min-width:30px;min-height:30px;width:30px;height:30px;transition:all .1s ease-in-out}.paatokset-accordion .handorgel__header--opened .accordion-item__icon span{transform:rotate(180deg)}.paatokset-accordion .handorgel__content{background-color:#f7f7f8;border:none}.paatokset-accordion .accordion-item__content__inner{padding:0;max-width:90vw}@media(min-width: 576px){.paatokset-accordion .accordion-item__content__inner{max-width:95vw}}@media(min-width: 768px){.paatokset-accordion .accordion-item__content__inner{max-width:100vw}}.paatokset-accordion .accordion__wrapper.handorgel{border:none}.paatokset-accordion .accordion-item__button--close,.paatokset-accordion .accordion-item__button--close-inner{display:flex;justify-content:right;padding:24px;cursor:pointer}.announcement.announcement--helsinki-kanava h2{font-weight:700;font-size:1.15rem;margin-top:1rem;margin-bottom:1rem}.announcement.announcement--helsinki-kanava p{font-size:18px}.announcement.announcement--helsinki-kanava .announcement__container{margin-left:0}@media(min-width: 768px){.announcement.announcement--helsinki-kanava .announcement__container{margin-left:0;margin-right:0}}.policymaker-summary .announcement.announcement--helsinki-kanava{padding-left:0;padding-right:0}.views--declarations-of-affiliation{margin-top:32px}.views--declarations-of-affiliation ul{padding-top:0;margin-bottom:32px}.decision-tree{margin-top:72px}.decision-tree__box{padding:24px;text-align:center;border:2px solid #1a1a1a;font-size:20px;font-weight:500;position:relative;-webkit-hyphens:auto;hyphens:auto;word-wrap:break-word;word-wrap:break-word}@media(min-width: 576px){.decision-tree__box{padding:28px;font-size:24px}}.decision-tree__box:not(.decision-tree__box:last-of-type){margin-bottom:24px}.decision-tree__box:not(.decision-tree__box:last-of-type)::after{content:"";height:30px;width:30px;border-bottom:2px solid #1a1a1a;border-right:2px solid #1a1a1a;position:absolute;left:0;right:0;margin:auto;bottom:-15.5px;transform:rotate(45deg);background-color:#fff}.decision-tree__upper-tree{margin:0 60px 72px 60px;position:relative;display:flex;flex-direction:column}.decision-tree__upper-tree .decision-tree__arrow{position:absolute}.decision-tree__upper-tree .arrow-left{left:-54px;top:23px;height:280px;width:55px}.decision-tree__upper-tree .arrow-right{right:-65px;bottom:23px;height:395px;width:65px}.decision-tree__upper-tree .decision-tree__box:nth-of-type(2),.decision-tree__upper-tree .decision-tree__box:nth-of-type(2)::after{background-color:#9fc9eb}.decision-tree__upper-tree .decision-tree__box:nth-of-type(3),.decision-tree__upper-tree .decision-tree__box:nth-of-type(3)::after{background-color:#dedfe1}.decision-tree__upper-tree .decision-tree__box:nth-of-type(4),.decision-tree__upper-tree .decision-tree__box:nth-of-type(4)::after{background-color:#00d7a7}.decision-tree__lower-tree{margin:0 60px 72px 60px;display:flex;flex-direction:column}.decision-tree__lower-tree .decision-tree__box:nth-of-type(2),.decision-tree__lower-tree .decision-tree__box:nth-of-type(2)::after{background-color:#f5a3c7}.decision-tree__info-text{font-size:36px;text-align:center;margin-bottom:36px}.container.frontpage-calendar__container{max-width:none;padding-left:0;padding-right:0;margin-top:64px;margin-bottom:64px}@media(min-width: 992px){.container.frontpage-calendar__container{margin-top:128px;margin-bottom:128px}}.frontpage-calendar{background-color:#f7f7f8;position:relative;margin-top:50px}.frontpage-calendar .hds-koros{position:absolute;top:-50px;right:0;left:0}.frontpage-calendar h2{padding:128px 0 0 0;margin-bottom:36px}@media(min-width: 576px){.frontpage-calendar h2{margin-bottom:48px}}@media(min-width: 768px){.frontpage-calendar h2{padding:60px 0 0}}.frontpage-calendar .container{padding-bottom:80px}.frontpage-calendar__link-container{display:flex;justify-content:right;padding:0 16px}@media(min-width: 576px){.frontpage-calendar__link-container{padding:0}}.frontpage-calendar__link-container i{width:36px}.frontpage-calendar__link-container a{display:flex;text-decoration:none;font-size:18px;font-weight:500;align-items:center}.frontpage-calendar__link-container a:hover,.frontpage-calendar__link-container a:focus,.frontpage-calendar__link-container a:active{text-decoration:underline}.frontpage-calendar__item-container{display:flex;flex-wrap:wrap}@media(min-width: 576px){.frontpage-calendar__item-container{margin:0 -12px 60px -12px}}.frontpage-calendar__item{width:100%;min-height:282px;padding:8px 0;text-decoration:none}.frontpage-calendar__item:hover .motions-link{text-decoration:underline}@media(min-width: 768px){.frontpage-calendar__item{padding:12px;width:50%}}@media(min-width: 992px){.frontpage-calendar__item{width:33.3%}}@media(min-width: 1248px){.frontpage-calendar__item{width:25%}}.frontpage-calendar__item .motions-link{font-size:16px;display:flex;align-items:center;text-decoration:none;font-weight:500}.frontpage-calendar__item .motions-link i{height:18px;width:18px;margin-right:12px}.frontpage-calendar__item .motions-link span{width:auto}.frontpage-calendar__item .color-line{height:8px}.frontpage-calendar__item .content-container{padding:24px;display:flex;flex-direction:column;height:100%}.frontpage-calendar__item .meeting-date{font-size:18px;margin-bottom:16px}.frontpage-calendar__item h3{flex-grow:1;font-size:1.25rem;font-weight:500;margin-top:0}@media(min-width: 576px){.frontpage-calendar__item h3{font-size:1.5rem}}.frontpage-calendar__item-inner{background-color:#fff;height:100%}.frontpage-calendar__notice{margin-bottom:24px;margin-top:-24px}.news-listing--latest-tiny-teasers .news-listing__title{margin-left:24px}.news-listing--latest-tiny-teasers .news-listing__title{font-size:18px;font-weight:400;line-height:1.5;margin-bottom:8px;margin-top:0}.news-listing--latest-tiny-teasers .news-listing__img{position:relative;flex-shrink:0;height:78px;width:78px;box-shadow:inset 0 0 0 1px #e5e5e5}.news-listing--latest-tiny-teasers .news-listing__img img{position:absolute;-o-object-fit:cover;object-fit:cover;width:100%;height:100%}.news-listing--latest-tiny-teasers .news-listing__img .image-placeholder{align-items:center;background-color:#e5e5e5;display:flex;height:100%;justify-content:center;padding-bottom:0;width:100%}.news-listing--latest-tiny-teasers .news-listing__img .image-placeholder:before{content:none}.meetings-calendar{margin-top:90px}.meetings-calendar .hds-loading-spinner{margin:90px auto;position:relative;top:auto;top:initial;left:auto;left:initial}.meetings-calendar ol{list-style:none}.meetings-calendar .calendar-header{display:flex;margin-bottom:65px;justify-content:center;align-items:center}.meetings-calendar .calendar-header h2{margin:0 15px;font-size:26px;min-width:190px;text-align:center;text-transform:capitalize}@media(min-width: 576px){.meetings-calendar .calendar-header h2{margin:0 30px;font-size:32px;min-width:235px}}.meetings-calendar .calendar-header .hel-icon,.meetings-calendar .calendar-header .icon-container{height:30px;min-width:30px;width:30px;cursor:pointer}.meetings-calendar .calendar-header .icon-container--disabled{color:#efefef}.meetings-calendar .days-grid{display:grid;grid-gap:30px;gap:30px;padding-left:0}@media(min-width: 992px){.meetings-calendar .days-grid{display:flex;flex-wrap:wrap;gap:0}}.meetings-calendar .calendar-day{flex:1;padding:16px;position:relative;margin-top:0}@media(min-width: 992px){.meetings-calendar .calendar-day{margin-bottom:60px;max-width:20%;min-width:20%}.meetings-calendar .calendar-day::after{content:"";height:8px;background-color:#c2a251;display:block;position:absolute;bottom:-32px;right:0;left:0;margin:0 16px}}.meetings-calendar .calendar-day .no-meetings{padding:16px;height:100%;background-color:#f7f7f8}@media(min-width: 992px){.meetings-calendar .calendar-day .no-meetings{height:calc(100% - 40px)}}.meetings-calendar .meeting-row{border-bottom:1px dashed #666;padding:16px 0;font-size:16px}.meetings-calendar .meeting-row a{display:flex;align-items:center}.meetings-calendar .meeting-row .hel-icon{width:16px;height:16px}.meetings-calendar .meeting-title{font-weight:700;margin-bottom:8px;margin-top:0;font-size:16px}.meetings-calendar .meeting-start-time{color:#666}.meetings-calendar .meeting-row--cancelled .meeting-title,.meetings-calendar .meeting-row--cancelled .meeting-start-time{text-decoration:line-through}.meetings-calendar .date-header{font-size:20px;font-weight:500;padding-bottom:8px;border-bottom:2px solid #000;justify-content:space-between;white-space:nowrap;display:flex}.meetings-calendar .calendar-day__today .meeting-row{padding:16px;background-color:#f7f2e4}.meetings-calendar .calendar-day__today .date-header{color:#c2a251;border-color:#c2a251}.meetings-calendar .calendar-day__no-meetings .date-header{color:#666;border-color:#666}:not(.has-sidebar) .paatokset__decision-tree-container{margin-left:auto;margin-right:auto;max-width:1264px}.paatokset__decision-tree-container .hidden{display:none}.paatokset__decision-tree-container .custom-select-wrapper{position:absolute;right:0}.paatokset__decision-tree-container .arrow i{width:16px;height:16px}.paatokset__decision-tree-container .custom-select .custom-options{display:none}.paatokset__decision-tree-container .custom-select.open .custom-options{display:block}.paatokset__decision-tree-container .decision-tree__title span{display:block;font-weight:500;font-size:1.5rem;margin-top:56px;margin-bottom:16px}.paatokset__decision-tree-container .decision-tree__title-container{display:flex;align-items:center;width:100%;max-width:994px;margin-bottom:20px}.paatokset__decision-tree-container .decistion-tree__item.open div{padding-left:14px}.paatokset__decision-tree-container button.accordion-item__button.accordion-item__button--toggle.tabbed-list__header__button{width:289px;height:24px;color:#1a1a1a;font-size:18px;font-weight:bold;line-height:24px}.paatokset__decision-tree-container .accordion-item__content__inner{position:relative;border-bottom:1px solid #000;display:flex;display:inline-flex;width:100%;justify-content:space-between}.paatokset__decision-tree-container .accordion-item__content__inner.tabbed-list__content__inner input{color:#060606;font-size:20px;font-weight:normal;letter-spacing:0;text-decoration:none;background:none;border:none;cursor:pointer}.paatokset__decision-tree-container .menu{overflow:auto}.paatokset__decision-tree-container .menu:scroll{display:none}.paatokset__decision-tree-container .menu .item{display:inline-block;color:#060606;font-size:20px;font-weight:bold;letter-spacing:.29px;text-decoration:none;margin-right:22px}.paatokset__decision-tree-container .menu .item.hidden{display:none}.paatokset__decision-tree-container .menu .item.selected{border-bottom:6px solid #000;padding-bottom:19px}.paatokset__decision-tree-container .container.accordion__container{padding:0}.policymakers-documents,.policymakers-decisions{display:none}.policymakers-documents.selected-year,.policymakers-decisions.selected-year{display:block}.custom-select{display:flex;flex-direction:column}.custom-select__trigger{position:relative;display:flex;align-items:center;-ms-flex-pack:justify;padding:0 10px;cursor:pointer;border:none;color:#060606;font-size:18px;font-weight:500;letter-spacing:0;padding-bottom:23px;margin:0}.custom-select__trigger .arrow i{width:24px;height:24px}.custom-options{position:absolute;display:block;opacity:0;visibility:hidden;pointer-events:none;z-index:99}.custom-select.open .custom-options{opacity:1;visibility:visible;pointer-events:all;margin-top:56px;border:1px solid #000;background-color:#fff;width:148px;text-align:center}.custom-option{position:relative;padding:0 22px 0 22px;font-size:22px;font-weight:300;color:#3b3b3b;line-height:60px;cursor:pointer;transition:all .5s}.custom-option:hover{cursor:pointer;background-color:#b2b2b2}.custom-option.selected{color:#fff;background-color:#305c91}@media(max-width: 544px){.desktopTd{display:none}}@media(min-width: 544px){.mobileTd{display:none}}.paatokset_download-link-container .paatokset__link-plain{display:flex;flex-wrap:wrap;align-items:center;margin-top:22px}.paatokset_download-link-container .paatokset__link-plain span{margin-right:12px}.policymaker-no-content{margin-top:24px}.policymaker-calendar h2{margin-bottom:24px}.policymaker-calendar__table{width:100%;max-width:none;max-width:initial;display:table;border:0;border-collapse:collapse}.policymaker-calendar__table thead{background-color:#fff}.policymaker-calendar__table th,.policymaker-calendar__table td{font-size:18px;background-color:#fff;color:#000;padding:24px 0;padding-right:24px;font-weight:400}@media(max-width: 576px){.policymaker-calendar__table th:nth-of-type(2){text-align:right}}.policymaker-calendar__table-header th{font-weight:500;padding-top:0}@media(max-width: 576px){.policymaker-calendar__table-header{border-bottom:2px solid #000}.policymaker-calendar__table-header th:last-of-type{display:none}}.policymaker-calendar__table-row{border-bottom:1px solid #ccc}.policymaker-calendar__table-row:hover{background-color:rgba(0,0,0,0)}.policymaker-calendar__table-row th:last-of-type{display:flex;align-items:center}@media(max-width: 576px){.policymaker-calendar__table-row{display:flex;flex-wrap:wrap;width:100%;padding:16px 0}.policymaker-calendar__table-row th{padding:8px}.policymaker-calendar__table-row td{border-bottom:none !important}.policymaker-calendar__table-row td{padding:8px}.policymaker-calendar__table-row td:first-of-type{font-weight:500}.policymaker-calendar__table-row td:last-of-type a{display:flex;align-items:center;color:#000;white-space:nowrap}.policymaker-calendar__table-row td:last-of-type a .hel-icon--angle-right{width:16px;height:16px}.policymaker-calendar__table-row th:nth-of-type(1),.policymaker-calendar__table-row th:nth-of-type(2),.policymaker-calendar__table-row td:nth-of-type(1),.policymaker-calendar__table-row td:nth-of-type(2){width:50%;padding-right:0}.policymaker-calendar__table-row td:nth-of-type(2){text-align:right}.policymaker-calendar__table-row th:nth-of-type(3),.policymaker-calendar__table-row th:nth-of-type(4),.policymaker-calendar__table-row td:nth-of-type(3),.policymaker-calendar__table-row td:nth-of-type(4){width:100%}}.policymaker-calendar__table-row--cancelled td:nth-child(1),.policymaker-calendar__table-row--cancelled td:nth-child(2){text-decoration:line-through}.policymaker-contacts{width:100%;font-size:1.125rem}@media(min-width: 992px){.policymaker-contacts h2{display:none}}.policymaker-contacts h3{margin-bottom:24px}.policymaker-contacts label.unit__contact-row__label{font-weight:700}.policymaker-contacts .hel-icon{--icon-size: 1.5rem}.policymaker-contacts article h3{margin-top:0}.policymaker-listing{background-color:#f7f7f8}.policymaker-listing .container{padding-top:65px;padding-bottom:65px}.policymaker-listing h2{margin-bottom:50px}.policymaker-card__container{margin-bottom:72px}@media(min-width: 576px){.policymaker-card__container{display:flex}}.policymaker-card__container .policymaker-card{text-decoration:none;display:flex;flex-direction:column;justify-content:space-between;padding-bottom:16px}@media(min-width: 576px){.policymaker-card__container .policymaker-card{width:50%;padding-bottom:0}.policymaker-card__container .policymaker-card:first-of-type{padding-right:8px}.policymaker-card__container .policymaker-card:last-of-type{padding-left:8px}}.policymaker-card__container .policymaker-card:hover .hel-icon{transform:translate(10px)}.policymaker-card__container .policymaker-card__color-title{text-align:center;font-weight:500;text-transform:uppercase;padding:4px 0}.policymaker-card__container .policymaker-card__title-icon{padding:25px;background-color:#fff}.policymaker-card__container .policymaker-card__title-icon h4{margin-top:0}.policymaker-card__container .hel-icon{width:30px;height:30px;min-width:30px;min-height:30px;transition:all .2s ease-in-out}.policymaker-row__link{padding:36px;display:flex;justify-content:space-between;background-color:#fff;margin-bottom:16px;position:relative;text-decoration:none;align-items:center}.policymaker-row__link:hover .hel-icon{transform:translate(10px)}.policymaker-row__link .hel-icon{min-width:30px;min-height:30px;width:10%;height:30px;transition:all .2s ease-in-out}.policymaker-row__link .policymaker-row__color{position:absolute;left:0;top:0;bottom:0;height:100%;width:16px}.policymaker-row__link .policymaker-row__title{font-size:24px;-webkit-hyphens:auto;hyphens:auto;width:90%;word-wrap:break-word;word-wrap:break-word;padding-right:16px}.policymaker-row__link .policymaker-row__sub-title{font-size:20px;color:#707070}.policymaker-row__link+h4{margin-top:64px !important}.policymaker-listing .accordion-item__content__inner h4{font-weight:500;margin-bottom:32px;margin-top:0}.load-more-btn{display:none}.policymaker-members h2{margin-bottom:32px}.policymaker-members__filters{display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:54px}.policymaker-members__filters input:not(input[type=checkbox]),.policymaker-members__filters select{width:100%;height:56px;padding:16px;border:2px solid #707070}.policymaker-members__filters select{-webkit-appearance:none;-moz-appearance:none;appearance:none}.policymaker-members__filters option{color:#000}.policymaker-members__filters .search-wrapper{width:100%;margin-bottom:36px;position:relative}.policymaker-members__filters .search-wrapper .hel-icon{position:absolute;left:20px;bottom:16px;width:24px;height:24px}.policymaker-members__filters .search-wrapper input{padding-left:56px !important}.policymaker-members__filters .form-item{width:100%;margin-bottom:36px}@media(min-width: 576px){.policymaker-members__filters .form-item{width:48%}}.policymaker-members__filters .form-item__dropdown{position:relative}.policymaker-members__filters .form-item__dropdown .hel-icon{width:24px;height:24px;position:absolute;right:20px;bottom:16px;pointer-events:none}.policymaker-members__filters .form-item--checkbox__item{list-style:none}.policymaker-members__filters .form-item--checkbox__item label{display:flex}.policymaker-members__filters .form-item--checkbox__item span{white-space:nowrap;padding-left:12px}.policymaker-members__filters .form-item--checkbox__item input{-moz-appearance:none;-webkit-appearance:none;-o-appearance:none;outline:none;content:none}.policymaker-members__filters .form-item--checkbox__item input::before{content:"";font-size:20px;display:flex;justify-content:center;align-items:center;width:24px;height:24px;max-width:24px;max-height:24px;border:2px solid #707070}.policymaker-members__filters .form-item--checkbox__item input:checked::before{content:"✓"}.policymaker-members__list{border-top:2px solid #000}.policymaker-members__list .member-row{display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #000;padding:32px 0;text-decoration:none}.policymaker-members__list .member-row:link:hover .member-name{text-decoration:underline}.policymaker-members__list .member-info>div{display:flex;flex-wrap:wrap}@media(min-width: 576px){.policymaker-members__list .member-info>div{flex-direction:row;align-items:center}}.policymaker-members__list .member-info{display:flex;flex-direction:column}.policymaker-members__list .member-info .deputy-of{margin-top:16px}.policymaker-members__list .member-image{height:75px;width:75px;min-height:75px;min-width:75px;border-radius:50%;overflow:hidden;margin-left:8px}@media(min-width: 576px){.policymaker-members__list .member-image{height:120px;width:120px;min-height:120px;min-width:120px}}.policymaker-members__list .member-name{font-size:20px;font-weight:500;line-height:29px;margin-bottom:0;margin-top:0}@media(min-width: 576px){.policymaker-members__list .member-name{font-size:24px}}.policymaker-members__list .member-role,.policymaker-members__list .member-party{color:#666;font-size:16px;line-height:24px}@media(min-width: 576px){.policymaker-members__list .member-role,.policymaker-members__list .member-party{font-size:18px;line-height:27px}}.policymaker-members__list .member-role::after{content:",";margin-right:4px}@media(min-width: 576px){.policymaker-members__list .member-role::after{display:none}}.policymaker-members__list .member-party{display:flex;align-items:center}@media(min-width: 576px){.policymaker-members__list .member-party::before{content:"";height:4px;width:4px;border-radius:50%;background-color:#000;display:inline-block;margin:0 8px}}.policymaker-members__list .no-results{margin:16px 0;display:flex;justify-content:center;align-items:center}.policymaker-side-menu--desktop{display:none}@media(min-width: 992px){.policymaker-side-menu--desktop{display:block}}.policymaker-side-menu.policymaker-side-menu--mobile{max-width:1328px;margin-left:auto;margin-right:auto;padding-left:16px;padding-right:16px;margin-bottom:-30px;margin-top:30px}@media(min-width: 768px){.policymaker-side-menu.policymaker-side-menu--mobile{padding-left:32px;padding-right:32px}}.policymaker-side-menu.policymaker-side-menu--mobile li+li{margin-top:0}@media(min-width: 992px){.policymaker-side-menu.policymaker-side-menu--mobile{display:none}}.policymaker-side-menu--desktop li,.sidebar-navigation li{width:100%}.policymaker-side-menu--desktop a,.sidebar-navigation a{text-decoration:none}.policymaker-side-menu--desktop .menu,.sidebar-navigation .menu{flex-direction:column}.policymaker-side-menu--desktop a[icon=angle-left],.sidebar-navigation a[icon=angle-left]{display:flex;align-items:center}.policymaker-side-menu--desktop a[icon=angle-left] svg,.sidebar-navigation a[icon=angle-left] svg{margin-right:8px}.policymaker-side-menu--desktop .active,.sidebar-navigation .active{font-weight:bold}.policymaker-side-menu--desktop #menu--level-0 li span.menu__link-wrapper,.sidebar-navigation #menu--level-0 li span.menu__link-wrapper{font-size:24px;padding-bottom:26px;border-bottom:2px solid #000}.policymaker-side-menu--desktop #menu--level-1 li span.menu__link-wrapper,.sidebar-navigation #menu--level-1 li span.menu__link-wrapper{padding:24px 0;border-bottom:1px solid #ccc;font-size:18px}.has-policymaker-nav.has-sidebar .before-content--in-main .page-title,.has-policymaker-nav .has-sidebar .before-content--in-main .page-title{margin-top:0}a.hds-button.hds-button--primary.hdbt-icon::before,a.hds-button.hds-button--secondary.hdbt-icon::before{margin-left:16px;margin-right:0}.policymaker-list-item--agenda-item>a,.policymaker-list-item--agenda-item>div{display:flex;flex-direction:column;align-items:flex-start}@media(min-width: 992px){.policymaker-list-item--agenda-item>a,.policymaker-list-item--agenda-item>div{flex-direction:row;align-items:flex-start}.policymaker-list-item--agenda-item>a .hel-icon,.policymaker-list-item--agenda-item>div .hel-icon{align-self:center;margin-left:auto;margin-right:8px}}.policymaker-list-item--agenda-item .agenda-item__index-number{font-weight:500;margin-right:32px;margin-bottom:6px;white-space:nowrap}@media(min-width: 992px){.policymaker-list-item--agenda-item .agenda-item__index-number{margin-bottom:0}}.policymaker-list-item--agenda-item .agenda-item__subject{margin-right:32px;margin-bottom:24px}@media(min-width: 992px){.policymaker-list-item--agenda-item .agenda-item__subject{margin-bottom:0}}.policymaker-list-item--agenda-item a{text-decoration:none}.policymaker-list-item--agenda-item a:hover .agenda-item__subject{text-decoration:underline}.policymaker-list-item--agenda-item .hel-icon{min-width:24px;min-height:24px}.policymaker-list-item--agenda-item.policymaker-list-item{border-bottom-color:#000}.policymaker-list-item--agenda-item.policymaker-list-item:first-child{border-top:2px solid #000}.policymaker-list-item--agenda-item.policymaker-list-item:last-child{border-bottom:2px solid #000}.node--type-article .content-author{font-size:1rem;color:#666}.node--type-article .keywords{margin-bottom:8px;display:flex}.node--type-article .keywords .hds-tag{margin:16px;margin-left:0}.node--type-article .keywords .hds-tag a{font-size:16px;border-radius:24px;background:#000;color:#fff;padding:6px 16px;text-decoration:none;display:flex;width:-moz-fit-content;width:fit-content;--outline-gutter: 2px;--outline-width: 3px;--focus-outline-color: #000;border:2px solid rgba(0,0,0,0)}.node--type-article .keywords .hds-tag a:hover,.node--type-article .keywords .hds-tag a:active,.node--type-article .keywords .hds-tag a:focus{transition-property:background-color,border-color,color;transition-duration:85ms;transition-timing-function:ease-out}.node--type-article .keywords .hds-tag a:hover{border-color:#000;color:#000;background-color:rgba(0,0,0,0)}.node--type-article .keywords .hds-tag a:focus,.node--type-article .keywords .hds-tag a:active{outline:var(--outline-width) solid var(--focus-outline-color);outline-offset:var(--outline-gutter);outline-offset:2px}.latest-articles__list{width:100%}.latest-articles__list .sidebar_block_heading{margin-top:0}.latest-articles__list a{text-decoration:none}.latest-articles__list a:hover{text-decoration:underline}:not(.has-sidebar) .all-articles{padding-left:32px;padding-right:32px}.node--type-imported-article .article__body{margin-top:64px}.node--type-imported-article p{font-size:1.125rem}.node--type-imported-article .preamble p{font-size:1.375rem}.node--type-imported-article .preamble::after{background:#000;content:"";display:block;height:2px;margin-bottom:32px;margin-top:32px;width:64px}.issue-header__container{border-bottom:2px solid #ccc;margin-bottom:27.5px}@media(min-width: 1248px){.issue-header__container{margin-bottom:32px}}.issue__title{margin-bottom:24px;font-size:32px;line-height:1.1;font-weight:normal}.issue__header .issue__title{margin-top:0}@media(min-width: 992px){.issue__title{font-size:52px}}.issue__diarynumber{font-size:16px;margin-bottom:32px}.issue__diarynumber label{display:block;font-weight:600}.issue-header__footer{margin-bottom:24px}.issue-header__footer .issue__category{margin-bottom:32px}@media(min-width: 1248px){.issue-header__footer{display:flex;align-items:center;flex-wrap:wrap}.issue-header__footer .issue__category{margin-bottom:0}}.issue__category{display:flex}.issue__category .hds-tag{margin-right:12px;font-size:16px;border-radius:24px;background:#000;color:#fff;padding:6px 16px;display:flex;width:-moz-fit-content;width:fit-content}.issue__category .hds-tag--confidential{background:var(--color-brick)}.issue__container h3{font-size:32px}@media(min-width: 1248px){.issue__container h3{font-size:36px}}.issue__container h3,.issue__container h4{margin-top:16px}.issue__container h3:first-child,.issue__container h4:first-child{margin-top:0}.issue__container .SisaltoSektio{margin-bottom:32px}.issue__container.issue__container--navigation{margin-bottom:32px}.issue__container .paatokset-accordion{margin-bottom:32px;border-bottom:2px solid #ccc}.issue__container .paatokset-accordion .handorgel__header__button,.issue__container .paatokset-accordion .handorgel__content{background:rgba(0,0,0,0)}.issue__container .voting-results-accordion{margin-bottom:-2px}@media(min-width: 1248px){.issue__container{display:flex}}@media(min-width: 1248px){.issue__left-column__container{width:65%;padding-right:125px}}.issue-right-column__container .issue__attachment{padding:24px 0;border-bottom:1px solid #979797;vertical-align:top;font-weight:600;line-height:24px;font-size:16px}.issue-right-column__container .issue__attachment>a,.issue-right-column__container .issue__attachment>div{display:flex}.issue-right-column__container .issue__attachment div:first-child{margin-right:16px}.issue-right-column__container .issue__attachment .hel-icon{width:var(--spacing-m);height:var(--spacing-m)}@media(min-width: 1248px){.issue-right-column__container{width:35%}}.issue__attachment__reason{font-size:16px}.issue-content__title h2{margin-top:16px;margin-bottom:32px;line-height:1.1;font-weight:normal;font-size:24px}@media(min-width: 992px){.issue-content__title h2{font-size:36px}}.issue-content__indices{font-size:20px;margin-bottom:8px}.issue-content__policymaker-label{text-align:left;text-transform:uppercase;font-weight:bold;padding:10px 48px;margin-bottom:36px;display:inline-block;max-width:100%;font-size:14px}.issue-content__policymaker-label.policymaker-label--small{display:inline-block;padding:10px 40px;font-size:14px}@media(min-width: 768px){.issue-content__policymaker-label{display:inline-block;padding:10px 55px}}.issue__favorite-button button.hds-button{color:#000;padding-left:0}.issue__favorite-button button.hds-button .hds-button__label{padding:0}.issue__favorite-button button.hds-button .hel-icon:first-of-type:not(:last-of-type){margin-left:0;margin-right:13px}.issue-content-top__container{margin-top:48px;margin-bottom:48px}.issue-content__section{margin-bottom:32px}.issue-content__section p,.issue-content__section ul{margin-top:0;padding-top:0}@media(min-width: 1248px){.issue-content__section{font-size:20px}}.issue__pdf{margin-bottom:32px}.issue__pdf.issue__pdf--desktop{display:none}.issue__decision-navigation{height:100%;display:flex;align-items:center;margin-top:8px;margin-bottom:45px}.issue__decision-navigation .decision-navigation-button--next span{margin-left:auto;margin-right:0;flex-basis:0}@media(min-width: 576px){.issue__decision-navigation .decision-navigation-button--next span{flex-basis:auto}}.issue__decision-navigation .decision-navigation-button--next .hel-icon{margin-right:0;margin-left:14px}.issue__meetings-labels label{font-weight:500}.issue__more-info{margin-top:64px;margin-bottom:64px}.issue__more-info div{margin:16px 0}.issue__more-info__content{padding-left:24px;border-left:5px solid var(--hdbt-color-palette--primary)}.issue-ajax-error__container{display:none}.issue__decision-date{margin-bottom:32px}.issue__container table{border:none}.issue-content__container td,.issue-content__container div{font-size:1.125rem}@media(min-width: 992px){.issue-content__container td,.issue-content__container div{font-size:1.25rem}}.issue-content__container del{text-decoration:line-through}.issue-content__container ins{text-decoration:none}.issue-content__container .SisaltoSektio ul,.issue-content__container .SisaltoSektio ol,.issue-content__container .accordion-item__content__inner ul,.issue-content__container .accordion-item__content__inner ol{padding-top:0;padding-left:1rem}.issue-content__container .SisaltoSektio div,.issue-content__container .accordion-item__content__inner div{margin:16px 0}.issue-content__container .SisaltoSektio table td,.issue-content__container .accordion-item__content__inner table td{display:block;background-color:#f1f1f1}.issue-content__container .SisaltoSektio table td div,.issue-content__container .accordion-item__content__inner table td div{margin:0}@media(min-width: 576px){.issue-content__container .SisaltoSektio table td,.issue-content__container .accordion-item__content__inner table td{display:table-cell}}.issue-content__container .accordion-item__content__inner>h3{font-size:30px;line-height:1.1;margin-top:48px}.issue-content__container .accordion-item__content__inner>h3:first-child{margin-top:0}h4.decision-history-title+h5.decision-history-title{margin-top:1rem}.voting-results-accordion .color-kupari{background-color:#00d7a7 !important}.voting-results-accordion .color-tiili{background-color:#bd2719 !important}.voting-results-accordion .color-tiili{color:#fff}.voting-results-accordion .color-sumu{background-color:#9fc9eb !important}.voting-results-accordion .color-gray-light{background-color:#efefef !important}.voting-results-accordion .accordion-item__content__inner>h3{font-size:24px;line-height:1.1}.voting-results-accordion__inner:first-of-type{margin-top:24px !important}.voting-results-accordion__inner .accordion-item__header .accordion-item__button{border:1px solid #000;align-items:center;padding:0}.voting-results-accordion__inner .accordion-item__header .accordion-item__button .result-key,.voting-results-accordion__inner .accordion-item__header .accordion-item__button .result-color{margin:0;font-size:18px;padding:16px;line-height:1.5}.voting-results-accordion__inner .accordion-item__header .accordion-item__button .result-color{min-width:54px;text-align:center}.voting-results-accordion__inner .accordion-item__header .accordion-item__button .accordion-item__icon{margin:0;padding-right:16px}.voting-results-accordion__inner .accordion-item__header .result-type{display:flex;margin:0}.voting-results-accordion__inner .accordion-item__header .result-type.ayes .result-color{background-color:#00d7a7}.voting-results-accordion__inner .accordion-item__header .result-type.noes .result-color{background-color:#bd2719;color:#fff}.voting-results-accordion__inner .accordion-item__header .result-type.blank .result-color{background-color:#9fc9eb}.voting-results-accordion__inner .accordion-item__header .result-type.absent .result-color{background-color:#efefef}.voting-results-accordion__inner .accordion-item__content{margin-top:-1px !important}.voting-results-accordion__inner .accordion-item__content{border:1px solid #000}.voting-results-accordion__inner .accordion-item__content__inner{margin:0 !important}.voting-results-accordion__inner .results-table{margin:0;max-width:none;max-width:initial}.voting-results-accordion__inner .results-table thead,.voting-results-accordion__inner .results-table tbody{width:100%}.voting-results-accordion__inner .results-table thead th,.voting-results-accordion__inner .results-table thead td,.voting-results-accordion__inner .results-table tbody th,.voting-results-accordion__inner .results-table tbody td{font-size:16px}.voting-results-accordion__inner .results-table thead .results-table__row{background-color:#efefef}.voting-results-accordion__inner .results-table thead .results-table__row th{color:#000}.voting-results-accordion__inner .results-table tbody .results-table__row{background-color:#fff}.voting-results-accordion__inner .results-table tbody .results-table__row td{background-color:#fff;display:table-cell}.voting-results-accordion__inner .results-table .results-table__row th{width:40%}.voting-results-accordion__inner .accordion-item__button--close-inner{font-size:16px}.results-by-party{margin-top:64px !important}.results-by-party .results-table{max-width:none;max-width:initial}.results-by-party .results-table thead .results-table__row th{min-width:0;min-width:initial;font-size:16px}.results-by-party .results-table thead .results-table__row th:first-of-type{width:100%;font-weight:600}.results-by-party .results-table thead .results-table__row th:not(:first-of-type){min-width:56px;width:56px;max-width:56px;font-size:14px;padding:6px;text-align:center}.results-by-party .results-table tbody .results-table__row td{background-color:#fff;min-width:0;min-width:initial;font-size:16px;display:table-cell}.results-by-party .results-table tbody .results-table__row td:not(:first-of-type){min-width:56px;width:56px;max-width:56px;padding:10px;text-align:center}.issue__hidden-message{margin-bottom:32px}.page-type--case .layout-content,.page-type--decision .layout-content{max-width:100vw;margin-left:auto;margin-right:auto;padding-left:16px;padding-right:16px}@media(min-width: 768px){.page-type--case .layout-content,.page-type--decision .layout-content{max-width:1328px;padding-left:32px;padding-right:32px}}.page-type--case .component.component--banner,.page-type--decision .component.component--banner{margin-top:48px}@media(min-width: 1248px){.page-type--case .component.component--banner,.page-type--decision .component.component--banner{width:65%}}.motion-tag{display:block;margin:0}.info-label,.warning-label{display:inline-block;padding:5px;padding-right:10px;margin-bottom:5px;margin-bottom:24px;display:inline-block}.info-label span,.warning-label span{font-size:16px;font-weight:700}.info-label.visible,.warning-label.visible{visibility:visible}@media(min-width: 992px){.info-label,.warning-label{margin-bottom:7px}}.info-label span,.warning-label span{margin-left:5px}.info-label{background-color:#e8f3fc}.warning-label{background-color:#ffd238}.info-label__container,.warning-label__container{display:flex;align-items:center}.meeting-video__video-container{position:relative;padding-bottom:56.25%;height:0;margin-bottom:16px;margin-top:16px}.meeting-video__video-container iframe{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden}.meeting-video__video-container iframe html{overflow:hidden;overflow-y:hidden}.meeting-video p{font-size:16px}.node--type-policymaker>section.policymaker-summary{margin-bottom:24px;--line-height:1.5555555556}@media(min-width: 768px){.node--type-policymaker>section.policymaker-summary{margin-bottom:40px}}.node--type-policymaker>section.policymaker-summary p{font-size:18px}.node--type-policymaker>section.policymaker-summary .issue-content__policymaker-label{margin-bottom:0}.node--type-policymaker>section.policymaker-summary .policymaker-summary__label{display:flex;margin-bottom:16px}.node--type-policymaker>section.policymaker-summary .issue__favorite-button{display:none}@media(min-width: 992px){.node--type-policymaker>section.policymaker-summary .issue__favorite-button{display:inline-block;margin-left:16px}}.node--type-policymaker>section.policymaker-summary .announcement h2{font-weight:700;font-size:1.15rem;margin-top:1rem;margin-bottom:1rem}@media(min-width: 768px){.node--type-policymaker>section.policymaker-summary .announcement{margin-left:0;margin-right:0}}.policymaker-image{margin-bottom:48px}.policymaker-image figure{margin:0}.policymaker-image img{-o-object-fit:cover;object-fit:cover;margin-bottom:8px;width:100%}.policymaker-meetings .warning-label{margin-top:16px}.node--type-policymaker .table-of-contents__container{position:relative;margin-bottom:64px}.table-of-contents+.policymaker-image{padding-top:48px}.content-menu__arrow{display:none}.content-menu__arrow.hel-icon--arrow-up{transform:rotate(180deg)}@media(min-width: 320px){.content-menu__arrow{display:block;height:111px;color:#fd4f00;width:90px;position:absolute;right:0}}.node--type-policymaker>section{margin-top:0;margin-bottom:64px}.node--type-policymaker>section .section-description{margin-bottom:32px}@media(min-width: 992px){.node--type-policymaker>section .section-description{margin-bottom:48px}}.view-all .paatokset-button-link{margin-top:32px}.view-all .paatokset-button-link span{margin-left:auto}.policymaker-list-item{border-bottom:1px solid #ccc;padding:24px 0;display:block}.policymaker-list-item:first-child{border-top:1px solid #ccc}.policymaker-list-item.policymaker-list-item--document,.policymaker-list-item .policymaker-list-item--document{display:block;border-color:#000;text-decoration:none}.policymaker-list-item.policymaker-list-item--document .subject__date,.policymaker-list-item .policymaker-list-item--document .subject__date{display:block}.policymaker-list-item .list-item__date{font-size:16px;color:#666;margin-bottom:16px}.policymaker-list-item .list-item__date--desktop{display:inline}.policymaker-list-item .list-item__subject{font-weight:500;font-size:24px}.policymaker-list-item .list-item__subject a{text-decoration:none}.policymaker-list-item .policymaker-list-item--document:hover .list-item__subject{text-decoration:underline}h1.minutes__header{margin-top:0;display:flex;flex-direction:column;margin-bottom:16px;gap:24px}h1.minutes__header .minutes__header-prefix{font-size:20px}h1.minutes__header .minutes__header-suffix{font-size:16px;color:#666}@media(min-width: 992px){h1.minutes__header{gap:0px}}h2.minutes-list__header{font-weight:500;font-size:24px;margin-bottom:24px}.minutes-list__wrapper{font-size:18px;margin-bottom:32px}.minutes-file__container label{display:block;margin-bottom:4px}.minutes-file__container .minutes__publish-date{position:relative;padding-bottom:24px;margin-bottom:32px}.minutes-file__container .minutes__publish-date:after{content:"";height:2px;background:#000;width:62px;position:absolute;bottom:0;left:0}.minutes-file__container .publish-date__date{font-size:20px;font-weight:700}.minutes__file-link{margin-bottom:8px}.policymaker-live-sream .view-all--recordings{display:none}.policymaker-label__tags{margin-bottom:32px}.policymaker-label__tags .hds-tag{font-size:16px;border-radius:24px;background:#000;color:#fff;padding:6px 16px;margin-right:12px;display:flex;width:-moz-fit-content;width:fit-content}.policymaker-label__tags .hds-tag__container{display:flex}.policymaker-label__tags:after{content:"";display:block;margin-top:24px;border-bottom:2px solid #000;width:90px}.minutes-decision__container{margin-top:64px}.minutes-decision__container .paatokset-accordion{margin-top:32px;margin-bottom:32px;border-bottom:2px solid #ccc}.minutes-decision__container .paatokset-accordion .handorgel__header__button,.minutes-decision__container .paatokset-accordion .handorgel__content{background:rgba(0,0,0,0)}.minutes-decision__container .paatokset-accordion .accordion-item__button{padding-top:20px;padding-bottom:20px}.minutes-decision__container .paatokset-accordion .accordion-item__header{font-size:1.5rem}.minutes-decision__meta{font-size:18px}.minutes-decision__meta .Kokousaika{font-weight:700}.minutes-decision__heading{margin-bottom:32px;line-height:1.1;font-weight:normal;font-size:32px}@media(min-width: 992px){.minutes-decision__heading{font-size:36px}}.paatokset-search-page--decisions .layout-content{margin:0}.paatokset-search-page--decisions .main-content{margin-top:0;background-color:#f7f7f8;padding-bottom:calc(50px + 48px) auto 0}@media(min-width: 992px){.paatokset-search-page--decisions .main-content{padding-bottom:calc(50px + 64px)}}.paatokset-search-page--decisions .footer{margin-top:0}.paatokset-search--frontpage .paatokset-search-wrapper{margin-left:-16px}@media(min-width: 576px){.paatokset-search--frontpage .paatokset-search-wrapper{margin-left:-32px}}.paatokset-search--decisions{margin-bottom:32px}.views--taxonomy-term .views-row{border-bottom:1px solid #ccc;padding:24px 0;display:block}.views--taxonomy-term .views-row:first-child{border-top:1px solid #ccc}.views--taxonomy-term .views-row .views-field-created{font-size:16px;color:#666;margin-bottom:16px}.views--taxonomy-term .views-row .views-field-title{font-weight:500;font-size:24px}.views--taxonomy-term .views-row .views-field-title a{text-decoration:none}.views--taxonomy-term .views-row .views-field-title a:hover{text-decoration:underline}.views--taxonomy-term .feed-icon{display:flex;align-items:center;margin-top:64px;text-decoration:none}.views--taxonomy-term .feed-icon i{margin-right:8px}.views--taxonomy-term .feed-icon:hover,.views--taxonomy-term .feed-icon:focus,.views--taxonomy-term .feed-icon:active{text-decoration:underline}.tpr-unit--view-mode-contact-card{margin-bottom:48px}.tpr-unit--view-mode-contact-card .unit__title{border-bottom:2px solid #000}.tpr-unit--view-mode-contact-card .unit__title h3{font-size:24px}.tpr-unit--view-mode-contact-card .unit-info{border-bottom:1px solid #ccc;padding:24px 0;display:flex}.tpr-unit--view-mode-contact-card label{font-weight:500;margin-bottom:4px}.tpr-unit--view-mode-contact-card .unit-info__icon{margin-right:16px}.tpr-unit--view-mode-contact-card a{display:block}.tpr-unit--view-mode-contact-card .paatokset-button-link{display:flex}.tpr-unit--view-mode-contact-card span.country{display:none}.page-type--trustee .page-title__container{max-width:none;max-width:initial}.trustee-information{background-color:#e8f3fc;padding:24px;margin-bottom:48px}.trustee-information .information-row{display:flex;flex-wrap:wrap;font-size:18px}.trustee-information .information-row:not(:last-of-type){margin-bottom:16px}.trustee-information .information-row.information-row--pm-declaration a{margin-left:.4rem}.trustee-information .information-row.information-row--doa a{display:inline-flex;align-items:center}.trustee-information .label{margin-right:8px;font-weight:500}.trustee-top-container{margin-bottom:24px}@media(min-width: 992px){.trustee-top-container{padding:0}}.trustee-top-container span{font-size:18px;color:#666}.trustee-top-container span:first-of-type::after{content:"•";margin:0 16px}.trustee-image{margin-bottom:24px}.node--type-trustee .accordion-item__header{font-size:1.5rem}.node--type-trustee .accordion-item__header .handorgel__header__button{color:#000;border:none;border-top:2px solid #ccc;padding:24px;display:flex;justify-content:space-between;align-items:center;padding:32px 32px 32px 0}.node--type-trustee .accordion-item__header .icon{min-width:30px;min-height:30px;width:30px;height:30px;transition:all .1s ease-in-out}.node--type-trustee .handorgel__header--open .icon{transform:rotate(180deg)}.node--type-trustee .handorgel__header--open .handorgel__header__button,.node--type-trustee .handorgel__header--opened .handorgel__header__button{background-color:#fff}.node--type-trustee .handorgel__content{border:none;padding:0}.node--type-trustee .accordion-item__content__inner{padding:0}.node--type-trustee .accordion__wrapper.handorgel{border:none}.node--type-trustee .accordion-item__button--close{display:flex;justify-content:right;padding:24px;cursor:pointer}.node--type-trustee .accordion-item__button--close .icon{margin-left:8px}.accordion_initiatives .accordion-item__content__inner>div,.accordion_resolutions .accordion-item__content__inner>div{margin-bottom:16px}.accordion_initiatives .date,.accordion_resolutions .date{font-size:16px;color:#666;margin-bottom:8px}.accordion_initiatives .title,.accordion_resolutions .title{display:block;margin-bottom:24px}.accordion_speaking-turn .accordion-item__content__inner>div{margin-bottom:16px}.accordion_speaking-turn .speaking-turn__group__title{font-size:1.5rem;margin-bottom:16px;margin-top:0}.accordion_speaking-turn .speaking-turn__group__title:not(:first-of-type){margin-top:40px}.accordion_speaking-turn .speaking-turn__link-container{display:flex;align-items:center}.accordion_speaking-turn .speaking-turn__link-container .icon{margin-right:16px}.section--content form{display:flex;flex-direction:column;padding-bottom:24px}.section--content form:not(.user-login-form){margin-bottom:24px}.section--content form.user-login-form .form-item{max-width:500px}.section--content form .container{border-bottom:1px solid #707070;margin-bottom:32px;padding-bottom:16px}.section--content form .fieldset-legend{font-size:1.125rem;line-height:1.625rem;font-weight:400;display:inline-block;margin-bottom:12px}.section--content form fieldset.form-item{margin:0 0 32px}.section--content form fieldset.form-item .form-checkboxes,.section--content form fieldset.form-item .form-radios{margin:0}.section--content form fieldset.form-item .form-checkboxes label,.section--content form fieldset.form-item .form-radios label{font-size:1.125rem;line-height:1.4375rem;font-weight:400}.section--content form details{font-size:1.125rem;line-height:1.6875rem;font-weight:400;background:#fff;border-radius:5px;letter-spacing:0;padding:16px;transition-duration:.2s;transition-property:all;width:100%}.section--content form details fieldset{border:0 none}.section--content form details fieldset .fieldset-wrapper .label{font-size:1.0625rem;line-height:1.5rem;font-weight:500}.section--content form details fieldset .fieldset-wrapper .container-inline{display:flex}.section--content form details fieldset .fieldset-wrapper .container-inline .form-item{flex:1 1 50%;padding:0 32px 16px 0}.section--content form .form-item{font-size:1rem;line-height:1.5rem;display:block;margin:0 0 16px;padding:0}.section--content form .form-item label:not(.visually-hidden){font-size:1.125rem;line-height:1.625rem;font-weight:400;color:#000;display:inline-block;letter-spacing:0;margin-bottom:12px;text-align:left;width:100%}.section--content form .form-item .description{font-size:.8125rem;line-height:1.25rem}.section--content form .form-item select,.section--content form .form-item textarea,.section--content form .form-item input[type=text],.section--content form .form-item input[type=tel],.section--content form .form-item input[type=password],.section--content form .form-item input[type=url],.section--content form .form-item input[type=email],.section--content form .form-item input[type=date],.section--content form .form-item .select2-container--default .select2-selection--single{font-size:1.125rem;line-height:1.6875rem;font-weight:400;background:#fff;border:1px solid #cecbbd;border-radius:5px;box-sizing:border-box;height:55px;letter-spacing:0;padding:16px;transition-duration:.2s;transition-property:all;width:100%}.section--content form .form-item select::-moz-placeholder, .section--content form .form-item textarea::-moz-placeholder, .section--content form .form-item input[type=text]::-moz-placeholder, .section--content form .form-item input[type=tel]::-moz-placeholder, .section--content form .form-item input[type=password]::-moz-placeholder, .section--content form .form-item input[type=url]::-moz-placeholder, .section--content form .form-item input[type=email]::-moz-placeholder, .section--content form .form-item input[type=date]::-moz-placeholder, .section--content form .form-item .select2-container--default .select2-selection--single::-moz-placeholder{color:#4a4a49}.section--content form .form-item select::placeholder,.section--content form .form-item textarea::placeholder,.section--content form .form-item input[type=text]::placeholder,.section--content form .form-item input[type=tel]::placeholder,.section--content form .form-item input[type=password]::placeholder,.section--content form .form-item input[type=url]::placeholder,.section--content form .form-item input[type=email]::placeholder,.section--content form .form-item input[type=date]::placeholder,.section--content form .form-item .select2-container--default .select2-selection--single::placeholder{color:#4a4a49}.section--content form .form-item select:focus,.section--content form .form-item textarea:focus,.section--content form .form-item input[type=text]:focus,.section--content form .form-item input[type=tel]:focus,.section--content form .form-item input[type=password]:focus,.section--content form .form-item input[type=url]:focus,.section--content form .form-item input[type=email]:focus,.section--content form .form-item input[type=date]:focus,.section--content form .form-item .select2-container--default .select2-selection--single:focus{border-color:rgba(0,0,0,0);box-shadow:none;color:#000;outline:#0061ad auto 3px}.section--content form .form-item select[disabled],.section--content form .form-item select[disabled]:active,.section--content form .form-item select[disabled]:focus,.section--content form .form-item select[disabled]:hover,.section--content form .form-item textarea[disabled],.section--content form .form-item textarea[disabled]:active,.section--content form .form-item textarea[disabled]:focus,.section--content form .form-item textarea[disabled]:hover,.section--content form .form-item input[type=text][disabled],.section--content form .form-item input[type=text][disabled]:active,.section--content form .form-item input[type=text][disabled]:focus,.section--content form .form-item input[type=text][disabled]:hover,.section--content form .form-item input[type=tel][disabled],.section--content form .form-item input[type=tel][disabled]:active,.section--content form .form-item input[type=tel][disabled]:focus,.section--content form .form-item input[type=tel][disabled]:hover,.section--content form .form-item input[type=password][disabled],.section--content form .form-item input[type=password][disabled]:active,.section--content form .form-item input[type=password][disabled]:focus,.section--content form .form-item input[type=password][disabled]:hover,.section--content form .form-item input[type=url][disabled],.section--content form .form-item input[type=url][disabled]:active,.section--content form .form-item input[type=url][disabled]:focus,.section--content form .form-item input[type=url][disabled]:hover,.section--content form .form-item input[type=email][disabled],.section--content form .form-item input[type=email][disabled]:active,.section--content form .form-item input[type=email][disabled]:focus,.section--content form .form-item input[type=email][disabled]:hover,.section--content form .form-item input[type=date][disabled],.section--content form .form-item input[type=date][disabled]:active,.section--content form .form-item input[type=date][disabled]:focus,.section--content form .form-item input[type=date][disabled]:hover,.section--content form .form-item .select2-container--default .select2-selection--single[disabled],.section--content form .form-item .select2-container--default .select2-selection--single[disabled]:active,.section--content form .form-item .select2-container--default .select2-selection--single[disabled]:focus,.section--content form .form-item .select2-container--default .select2-selection--single[disabled]:hover{background-color:pink}.section--content form .form-item select::-ms-clear,.section--content form .form-item textarea::-ms-clear,.section--content form .form-item input[type=text]::-ms-clear,.section--content form .form-item input[type=tel]::-ms-clear,.section--content form .form-item input[type=password]::-ms-clear,.section--content form .form-item input[type=url]::-ms-clear,.section--content form .form-item input[type=email]::-ms-clear,.section--content form .form-item input[type=date]::-ms-clear,.section--content form .form-item .select2-container--default .select2-selection--single::-ms-clear{display:none}.section--content form .form-item select::-ms-expand,.section--content form .form-item textarea::-ms-expand,.section--content form .form-item input[type=text]::-ms-expand,.section--content form .form-item input[type=tel]::-ms-expand,.section--content form .form-item input[type=password]::-ms-expand,.section--content form .form-item input[type=url]::-ms-expand,.section--content form .form-item input[type=email]::-ms-expand,.section--content form .form-item input[type=date]::-ms-expand,.section--content form .form-item .select2-container--default .select2-selection--single::-ms-expand{display:none}.section--content form .form-item .form-textarea-wrapper textarea{height:120px}.section--content form .form-item input[type=search]{font-size:1.125rem;line-height:1.6875rem;font-weight:400;background:#fff;border:0 none;height:55px;letter-spacing:0;padding:16px;transition-duration:.2s;transition-property:all;width:100%}.section--content form .form-item input[type=submit]{align-self:flex-end;height:2.5em}.section--content form .form-item .form-type-textarea+div{display:none}.section--content form .form-item.form-type-radio{cursor:pointer;display:inline;margin-bottom:32px;margin-right:24px}.section--content form .form-item.form-type-radio input[type=radio]{opacity:0}.section--content form .form-item.form-type-radio input[type=radio]+label:after{content:none}.section--content form .form-item.form-type-radio input[type=radio]:checked+label::after{content:""}.section--content form .form-item.form-type-radio input[type=radio]:focus+label::before{outline:#8ccdca auto 3px}.section--content form .form-item.form-type-radio label{cursor:pointer;display:inline;margin-left:-16px;padding-left:40px;position:relative}.section--content form .form-item.form-type-radio label:before{border:1px solid #cecbbd;border-radius:50%;content:"";display:inline-block;height:30px;left:0;position:absolute;top:-5px;width:30px}.section--content form .form-item.form-type-radio label:after{background-color:#8ccdca;border-radius:50%;content:"";display:inline-block;height:20px;left:5px;position:absolute;top:0;width:20px}.section--content form .form-item.form-type-checkbox{margin-bottom:16px}.section--content form .form-item.form-type-checkbox:last-of-type{margin-bottom:128px}.section--content form .form-item.form-type-checkbox input[type=checkbox]{opacity:0}.section--content form .form-item.form-type-checkbox input[type=checkbox]+label:after{content:none}.section--content form .form-item.form-type-checkbox input[type=checkbox]:checked+label::after{content:""}.section--content form .form-item.form-type-checkbox input[type=checkbox]:focus+label::before{outline:#8ccdca auto 3px}.section--content form .form-item.form-type-checkbox label{cursor:pointer;display:inline;margin-left:-16px;padding-left:40px;position:relative}.section--content form .form-item.form-type-checkbox label:before{border:1px solid #cecbbd;border-radius:5px;content:"";display:inline-block;height:30px;left:0;position:absolute;top:-5px;width:30px}.section--content form .form-item.form-type-checkbox label:after{background-color:#8ccdca;border-radius:3px;content:"";display:inline-block;height:20px;left:5px;position:absolute;top:0;width:20px}.section--content form .form-item.form-type-textarea{margin-bottom:32px}.section--content form .form__group{margin-bottom:32px}.section--content form .form__group h3{font-size:1.25rem}.section--content form .form__group.form__divider{border-top:1px solid #cecbbd;padding-top:16px}.paatokset-search--decisions h1,.paatokset-search--decisions label,.paatokset-search--decisions .container>p,.paatokset-search-wrapper h1,.paatokset-search-wrapper label,.paatokset-search-wrapper .container>p,.paatokset-search--frontpage h1,.paatokset-search--frontpage label,.paatokset-search--frontpage .container>p{color:#000}.paatokset-search--decisions button+ul li,.paatokset-search-wrapper button+ul li,.paatokset-search--frontpage button+ul li{font-size:16px;margin-top:0}.paatokset-search--decisions button+ul li[class*=Select-module_highlighted],.paatokset-search-wrapper button+ul li[class*=Select-module_highlighted],.paatokset-search--frontpage button+ul li[class*=Select-module_highlighted]{color:#fff !important;background-color:#000 !important}.paatokset-search--decisions button+ul li[class*=Select-module_highlighted] span,.paatokset-search-wrapper button+ul li[class*=Select-module_highlighted] span,.paatokset-search--frontpage button+ul li[class*=Select-module_highlighted] span{border-color:#fff !important;box-shadow:none !important}.paatokset-search--decisions button>span[class*=Select-module_buttonLabel],.paatokset-search-wrapper button>span[class*=Select-module_buttonLabel],.paatokset-search--frontpage button>span[class*=Select-module_buttonLabel]{color:#666}.paatokset-search--decisions .DateSelect__predefined-ranges-container+button,.paatokset-search-wrapper .DateSelect__predefined-ranges-container+button,.paatokset-search--frontpage .DateSelect__predefined-ranges-container+button{border-top-color:#ccc}.paatokset-search--decisions .DateSelect__predefined-ranges-container+button:hover,.paatokset-search-wrapper .DateSelect__predefined-ranges-container+button:hover,.paatokset-search--frontpage .DateSelect__predefined-ranges-container+button:hover{background-color:#000;border-color:#000}.paatokset-search--decisions .search-autocomplete,.paatokset-search-wrapper .search-autocomplete,.paatokset-search--frontpage .search-autocomplete{border:2px solid #000;border-top-color:#000;border-top-width:2px;border-top-color:#ccc;border-top-width:1px;position:absolute;left:0;right:0}.paatokset-search--decisions .search-autocomplete__wrapper,.paatokset-search-wrapper .search-autocomplete__wrapper,.paatokset-search--frontpage .search-autocomplete__wrapper{position:relative;z-index:10}.paatokset-search--decisions .search-autocomplete__item,.paatokset-search-wrapper .search-autocomplete__item,.paatokset-search--frontpage .search-autocomplete__item{font-size:16px;padding:.75rem 1rem;cursor:pointer}.paatokset-search--frontpage div[class*=SearchBarWrapper_SearchBarWrapper]{max-width:100%}.paatokset-search--frontpage button[class*=SubmitButton_SubmitButton__desktop]{margin-left:24px}.issue__wrapper .ajax-progress-throbber{display:none}.issue__meetings-container label{font-size:16px}.issue__meetings-dropdown{border:2px solid gray;margin-bottom:32px}.issue__meetings-dropdown .hds-button{position:relative;width:100%;border:none;color:#000;justify-content:flex-start;overflow:hidden}.issue__meetings-dropdown .hds-button:focus,.issue__meetings-dropdown .hds-button:hover{background-color:rgba(0,0,0,0)}.issue__meetings-dropdown .hds-button:focus:hover{color:#000}.issue__meetings-dropdown .hds-button[disabled] .hel-icon.hel-icon--angle-down{display:none}.issue__meetings-dropdown .hds-button .hel-icon.hel-icon--angle-down{margin-left:auto}.issue__meetings-dropdown .hds-button .hds-button__label{text-align:left;padding-left:22px}.issue__meetings-dropdown .hds-button::before{content:"";position:absolute;left:0;width:0;height:0;border-top:26px solid rgba(0,0,0,0);border-bottom:26px solid rgba(0,0,0,0);border-left:20px solid}.issue__meetings-dropdown .hds-button::after{content:none}.issue__meetings-dropdown:focus,.issue__meetings-dropdown[focus-within]{border:2px solid #000}.issue__meetings-dropdown:focus,.issue__meetings-dropdown:focus-within{border:2px solid #000}.issue__meetings-dropdown.open .hds-button{border-bottom:1px solid;border-color:gray}.issue__meetings-dropdown.open .hds-button .hel-icon.hel-icon--angle-down{transform:rotate(180deg)}.issue__meetings-dropdown .option{margin-top:0;font-size:16px;height:52px;display:flex;align-items:center;padding-left:30px;position:relative}.issue__meetings-dropdown .option a:hover{text-decoration:none}.issue__meetings-dropdown .option:before{content:"";position:absolute;left:0;width:0;height:0;border-top:26px solid rgba(0,0,0,0);border-bottom:26px solid rgba(0,0,0,0);border-left:20px solid #000}.issue__meetings-dropdown .option{cursor:pointer}.issue__meetings-dropdown .option:not(.selected):hover{background-color:#000}.issue__meetings-dropdown .option:not(.selected):hover a{color:#fff}.issue__meetings-dropdown .option:focus{border:2px solid #000}.issue__meetings-dropdown .option.selected{background-color:#ccc}.issue__meetings-select{width:100%;list-style:none;display:none;padding-top:0;margin-top:0;margin-bottom:0;padding-left:0;overflow-x:scroll;-ms-overflow-style:none;scrollbar-width:none;position:relative;z-index:2;background:#fff}.issue__meetings-select .paatokset__link-plain:hover{color:inherit}.issue__meetings-select::-webkit-scrollbar{display:none}.issue__meetings-labels{display:flex;flex-direction:column-reverse}@media(min-width: 992px){.issue__meetings-labels{flex-direction:row;align-items:center}}.new-handlings-warning__wrapper .warning-label{visibility:hidden}.new-handlings-warning__wrapper .warning-label.visible{visibility:visible}@media(min-width: 992px){.new-handlings-warning__wrapper{margin-left:auto}}.hero--paatokset-search-bar{margin-bottom:32px}@media(min-width: 1248px){.hero--paatokset-search-bar{margin-bottom:64px}}.hero--paatokset-search-bar .hero__text-content{padding-top:48px;padding-bottom:48px}.paatokset__search-form .hds-text-input__label{font-weight:bold}.paatokset__search-form .hds-text-input__input-wrapper{display:block}@media(min-width: 1248px){.paatokset__search-form .hds-text-input__input-wrapper{display:flex;align-items:flex-end}}.paatokset__search-form .hds-text-input__input-wrapper .form-item-hds-text-input__input{width:100%}.paatokset__search-form input[type=submit]{width:100%;margin-bottom:16px;height:var(--input-height);background-color:#000;background-image:none;text-shadow:none;--focus-outline-color: var(--color-coat-of-arms)}.paatokset__search-form input[type=submit]:hover{background-color:#fff;border-color:#000;color:#000}@media(min-width: 1248px){.paatokset__search-form input[type=submit]{max-width:258px;margin-left:24px}}.paatokset__search-form .advanced-search-link-container{display:flex;justify-content:flex-end;align-items:center}@media(min-width: 1248px){.paatokset__search-form .advanced-search-link-container{max-width:894px}}@media(min-width: 1248px){.paatokset__search-form .advanced-fields-container{display:flex;flex-wrap:wrap;justify-content:space-between;max-width:894px}}.paatokset__search-form .advanced-fields-container label{display:none}@media(min-width: 1248px){.paatokset__search-form .advanced-fields-container label{display:inline;font-weight:bold}}.paatokset__search-form .advanced-fields-container select{width:100%}@media(min-width: 1248px){.paatokset__search-form .advanced-fields-container select{max-width:282px}}.paatokset__search-form .advanced-search__tags-container{border-top:1px solid #000;display:flex;align-items:center;padding-top:10px}.paatokset__search-form .advanced-search__tags-container>*{margin-right:15px}.paatokset__search-form .advanced-search__tags-container .tags-container__title{display:none}@media(min-width: 1248px){.paatokset__search-form .advanced-search__tags-container .tags-container__title{display:inline;font-weight:500}}.paatokset__search-form .advanced-search__search-watcher{width:100%}.paragraph-content>*:last-child{margin-bottom:0}.hero__title+.hero__description{margin-top:56px}.news-liftups{margin-top:64px}@media(min-width: 992px){.news-liftups{margin-top:128px}}.news-liftups h2{margin-bottom:48px}.news-liftups a{text-decoration:none}.news-liftups a:hover h3{text-decoration:underline}.news-liftups a:hover .hel-icon{transform:translate(10px)}.news-liftups a .hel-icon{transition:all .2s ease-in-out}@media(min-width: 1248px){.news-liftups .liftups__wrapper{display:flex;justify-content:space-between}}.news-liftups .liftups-container--main{margin-bottom:16px}@media(min-width: 1248px){.news-liftups .liftups-container--main{max-width:600px}}.news-liftups .liftup--main h3{font-weight:500}.news-liftups .liftup--main .liftup--lead{margin-bottom:22px}.news-liftups .liftup--main img{margin-bottom:32px}.news-liftups .liftup--main .liftup__published-date{display:inline-block;margin-bottom:8px}.news-liftups .liftup--main i{display:block;width:48px;height:48px}.news-liftups .liftups-container--secondary h3{font-size:1.25rem;margin-bottom:8px;margin-top:0;font-weight:500}@media(min-width: 768px){.news-liftups .liftups-container--secondary h3{font-size:1.5rem}}@media(min-width: 1248px){.news-liftups .liftups-container--secondary{max-width:486px}}.news-liftups .liftup--secondary{border-top:1px solid #e2e2e2;padding-top:24px;padding-bottom:24px}.news-liftups .liftup__published-date{font-size:.875rem}@media(min-width: 768px){.tools__container{margin-top:16px}}@media(min-width: 768px){.breadcrumb__container+.tools__container{margin-bottom:20px;margin-top:-8px}}.ajax-progress,.ajax-progress-throbber,.ajax-progress-fullscreen{background:rgba(255,255,255,.6);border-radius:0;height:100%;left:0;margin:0;opacity:1;overflow:hidden;padding:0;position:fixed;text-indent:-99999em;top:0;width:100%;z-index:999999}.ajax-progress-throbber:before,.ajax-progress-fullscreen:before{animation:spin .8s infinite linear;border-color:#4a4a49 rgba(0,0,0,0) #4a4a49 rgba(0,0,0,0);border-radius:120px;border-style:solid;border-width:10px;bottom:0;content:" ";display:block;height:120px;left:0;margin:auto;overflow:hidden;position:absolute;right:0;text-indent:-99999em;top:0;width:120px}@keyframes spin{to{transform:rotate(360deg)}}.paatokset-button-link{color:#000;width:100%;font-weight:500;display:flex;align-items:center;text-decoration:none}.paatokset-button-link i,.paatokset-button-link span{margin-right:14px}.paatokset-button-link .hel-icon{width:var(--spacing-m);height:var(--spacing-m)}.paatokset-button-link:hover{text-decoration:underline}.paatokset__link-plain{color:#000;text-decoration:none}.paatokset__link-plain:hover{text-decoration:underline}.login-link{font-size:1rem;align-items:center;display:inline-flex;line-height:1;text-decoration:none}.login-link>svg{margin-right:8px}.login-link:hover,.login-link:focus{text-decoration:none}:root{--color-sumu: #9fc9eb;--color-hopea: #dedfe1;--color-suomenlinna: #f5a3c7;--color-kupari: #00d7a7}.issue-content__policymaker-label.color-sumu,.policymaker-row__color.color-sumu,.frontpage-calendar__item .color-line.color-sumu,.policymaker-card__color-title.color-sumu{background-color:#9fc9eb}.issue-content__policymaker-label.color-hopea,.policymaker-row__color.color-hopea,.frontpage-calendar__item .color-line.color-hopea,.policymaker-card__color-title.color-hopea{background-color:#dedfe1}.issue-content__policymaker-label.color-suomenlinna,.policymaker-row__color.color-suomenlinna,.frontpage-calendar__item .color-line.color-suomenlinna,.policymaker-card__color-title.color-suomenlinna{background-color:#f5a3c7}.issue-content__policymaker-label.color-engel,.policymaker-row__color.color-engel,.frontpage-calendar__item .color-line.color-engel,.policymaker-card__color-title.color-engel{background-color:#ffe977}.issue-content__policymaker-label.color-kupari,.policymaker-row__color.color-kupari,.frontpage-calendar__item .color-line.color-kupari,.policymaker-card__color-title.color-kupari{background-color:#00d7a7}.issue__meetings-dropdown .color-sumu::before{border-left-color:#9fc9eb}.issue__meetings-dropdown .color-hopea::before{border-left-color:#dedfe1}.issue__meetings-dropdown .color-suomenlinna::before{border-left-color:#f5a3c7}.issue__meetings-dropdown .color-engel::before{border-left-color:#ffe977}.issue__meetings-dropdown .color-kupari::before{border-left-color:#00d7a7}.search-link{font-size:1rem;align-items:center;display:inline-flex;line-height:1;text-decoration:none}.search-link>svg{margin-right:4px}.search-link:hover,.search-link:focus{text-decoration:none}.skip-link.focusable:focus{font-weight:500;background-color:#fff;border-radius:0 0 10px 10px;color:#0061ad;display:block;left:calc(50% - 75px);min-height:20px;min-width:150px;padding:5px 20px;position:absolute;text-align:center;text-decoration:none}.system-messages{border:2px solid;box-shadow:none;margin:2rem 0;padding:1.25rem}.system-messages li{margin-top:.25rem}.system-messages li:first-child{margin-top:0}.system-messages--error,.system-messages--status,.system-messages--warning,.system-messages a{color:#fff}.system-messages a{text-decoration:underline}.system-messages em{font-weight:500;font-style:normal}.system-messages--error{background:#e98491;border-color:#ed1a3b}.system-messages--error a:hover,.system-messages--error a:focus{color:#ed1a3b}.system-messages--status{background:#7dcdc8;border-color:#00a97a}.system-messages--status a:hover,.system-messages--status a:focus{color:#00a97a}.system-messages--warning{background:#f29869;border-color:#f26522}.system-messages--warning a:hover,.system-messages--warning a:focus{color:#f26522}.user-action{font-size:1rem;align-items:center;display:inline-flex;line-height:1;text-decoration:none;text-transform:capitalize}.user-action>svg{margin-right:4px}.user-action:hover,.user-action:focus{text-decoration:none}.breadcrumb__link{white-space:nowrap}@media screen and (max-width: 768px){.breadcrumb .breadcrumb__link:last-of-type{display:block;width:100%;overflow:hidden;text-overflow:ellipsis}}.breadcrumb__link:nth-child(6),.breadcrumb__current{text-overflow:ellipsis;overflow-x:hidden;white-space:nowrap}@media(min-width: 768px){.breadcrumb__link:nth-child(6),.breadcrumb__current{display:block}}.footer-top .menu{flex-direction:column}.local-tasks{display:flex;flex-wrap:wrap;list-style:none;margin:16px -5px;padding:0}.local-tasks .local-task{margin:0}.local-tasks .local-task a{font-size:.875rem;line-height:1.125rem;background-color:#fff;border:1px solid #4a4a49;box-shadow:0 3px 6px rgba(0,0,0,.1607843137);color:#000;display:flex;margin:10px 5px;padding:.3rem .75rem;position:relative;text-align:center;text-decoration:none;transform:perspective(1px) translateZ(0);transition-duration:.1s;transition-property:background-color;width:auto}@media screen and (min-width: 992px){.local-tasks .local-task a{display:flex;max-width:none;padding:.3rem 1.5rem}}.local-tasks .local-task a:hover{background-color:#707070;box-shadow:0 8px 6px -6px rgba(0,0,0,.1);color:#fff;cursor:pointer}.local-tasks .local-task a.is-active{background-color:#707070;box-shadow:0 0 0 rgba(0,0,0,0);color:#fff;cursor:default}.navigation.contextual-region{position:static}.navigation.navigation--main--desktop{z-index:100}@media(max-width: 944px){.navigation.navigation--main--desktop{display:none;visibility:hidden}}.menu{display:flex;list-style:none;margin:0;padding:0}@media(min-width: 944px){.menu.menu--main{height:100%}}@media(min-width: 944px){.menu--main .menu__item{align-items:center;display:inline-flex;height:100%}}@media(min-width: 944px){.menu--main .menu__item:not(:first-of-type){margin-left:32px}}.menu--main .menu__item.is-active{position:relative}.menu--main .menu__item.is-active:after{background-color:#000;bottom:-16px;content:"";height:3px;left:0;position:absolute;right:0;width:100%}.menu__link{display:inline-block}@media(min-width: 944px){.menu--main .menu__link{font-size:1rem;text-decoration:none}}[data-js]~* .cssmenu-toggle-button[aria-expanded=true]::before{-webkit-mask-image:var(--hel-icon--cross);mask-image:var(--hel-icon--cross)}.header-branding .cssmenu-menu{grid-template-areas:"lang" "back" "nav" "footer"}.mmenu__back{align-items:start;background-color:#fff;border:0;cursor:pointer;display:grid;grid-gap:8px;gap:8px;grid-template-areas:"icon label";grid-template-columns:40px auto;grid-template-rows:auto;justify-items:center;margin-top:-5px;padding:5px 12px;position:relative;width:100%;text-decoration:none}.mmenu__back .icon-wrapper{background:#f7f7f8;content:"";display:block;grid-area:icon;height:40px;width:40px}.mmenu__back .hel-icon--angle-right{width:32px;height:32px;transform:rotate(180deg);margin-left:3px;margin-top:3px}.mmenu__back:hover,.mmenu__back:active{text-decoration:underline}.mmenu__back:hover.hel-icon,.mmenu__back:active.hel-icon{transform:translateX(-4px)}.mmenu__back:focus,.mmenu__back:active{outline:3px solid #000;outline-offset:-3px}.mmenu__back:focus::before,.mmenu__back:active::before{transform:translateX(-4px)}.mmenu__back-wrapper{color:#000;grid-area:label;justify-self:start;margin-top:8px;font-weight:500;font-size:1rem;padding-left:10px} +html{font-size:100%;height:100%;scroll-behavior:smooth}.dialog-off-canvas-main-canvas{background-color:#fff}body{height:100%;margin:0;padding:0}img{display:block;height:auto;max-width:100%}main{width:100%}.error-page .dialog-off-canvas-main-canvas{background:rgba(0,0,0,0)}.has-section-nav .layout-sidebar-first{display:none}@media(min-width: 992px){.has-section-nav .layout-sidebar-first{display:block}}html h1,html .page-title h1{margin-bottom:16px;font-size:3.25rem;font-weight:400}@media(min-width: 768px){html h1,html .page-title h1{margin-bottom:24px}}@media(min-width: 992px){html h1,html .page-title h1{font-size:4.5rem;line-height:4.5rem;margin-bottom:38px}}html blockquote{font-size:1.5rem;line-height:2.25rem;font-weight:400;border-left:5px solid #707070;color:#4a4a49;letter-spacing:0;margin:48px;padding-left:25px}html blockquote p{font-size:1.5rem;line-height:2.25rem;font-weight:400}body{font-size:18px}.paatokset-accordion .accordion-item__header .handorgel__header__button{color:#000;border:none;border-top:2px solid #ccc;background-color:#f7f7f8;padding:32px 32px 32px 0;display:flex;justify-content:space-between}.paatokset-accordion .accordion-item__header .accordion-item__icon{display:flex;align-items:center}.paatokset-accordion .accordion-item__header .accordion-item__icon span{min-width:30px;min-height:30px;width:30px;height:30px;transition:all .1s ease-in-out}.paatokset-accordion .handorgel__header--opened .accordion-item__icon span{transform:rotate(180deg)}.paatokset-accordion .handorgel__content{background-color:#f7f7f8;border:none}.paatokset-accordion .accordion-item__content__inner{padding:0;max-width:90vw}@media(min-width: 576px){.paatokset-accordion .accordion-item__content__inner{max-width:95vw}}@media(min-width: 768px){.paatokset-accordion .accordion-item__content__inner{max-width:100vw}}.paatokset-accordion .accordion__wrapper.handorgel{border:none}.paatokset-accordion .accordion-item__button--close,.paatokset-accordion .accordion-item__button--close-inner{display:flex;justify-content:right;padding:24px;cursor:pointer}.announcement.announcement--helsinki-kanava h2{font-weight:700;font-size:1.15rem;margin-top:1rem;margin-bottom:1rem}.announcement.announcement--helsinki-kanava p{font-size:18px}.announcement.announcement--helsinki-kanava .announcement__container{margin-left:0}@media(min-width: 768px){.announcement.announcement--helsinki-kanava .announcement__container{margin-left:0;margin-right:0}}.policymaker-summary .announcement.announcement--helsinki-kanava{padding-left:0;padding-right:0}.views--declarations-of-affiliation{margin-top:32px}.views--declarations-of-affiliation ul{padding-top:0;margin-bottom:32px}.decision-tree{margin-top:72px}.decision-tree__box{padding:24px;text-align:center;border:2px solid #1a1a1a;font-size:20px;font-weight:500;position:relative;-webkit-hyphens:auto;hyphens:auto;word-wrap:break-word;word-wrap:break-word}@media(min-width: 576px){.decision-tree__box{padding:28px;font-size:24px}}.decision-tree__box:not(.decision-tree__box:last-of-type){margin-bottom:24px}.decision-tree__box:not(.decision-tree__box:last-of-type)::after{content:"";height:30px;width:30px;border-bottom:2px solid #1a1a1a;border-right:2px solid #1a1a1a;position:absolute;left:0;right:0;margin:auto;bottom:-15.5px;transform:rotate(45deg);background-color:#fff}.decision-tree__upper-tree{margin:0 60px 72px 60px;position:relative;display:flex;flex-direction:column}.decision-tree__upper-tree .decision-tree__arrow{position:absolute}.decision-tree__upper-tree .arrow-left{left:-54px;top:23px;height:280px;width:55px}.decision-tree__upper-tree .arrow-right{right:-65px;bottom:23px;height:395px;width:65px}.decision-tree__upper-tree .decision-tree__box:nth-of-type(2),.decision-tree__upper-tree .decision-tree__box:nth-of-type(2)::after{background-color:#9fc9eb}.decision-tree__upper-tree .decision-tree__box:nth-of-type(3),.decision-tree__upper-tree .decision-tree__box:nth-of-type(3)::after{background-color:#dedfe1}.decision-tree__upper-tree .decision-tree__box:nth-of-type(4),.decision-tree__upper-tree .decision-tree__box:nth-of-type(4)::after{background-color:#00d7a7}.decision-tree__lower-tree{margin:0 60px 72px 60px;display:flex;flex-direction:column}.decision-tree__lower-tree .decision-tree__box:nth-of-type(2),.decision-tree__lower-tree .decision-tree__box:nth-of-type(2)::after{background-color:#f5a3c7}.decision-tree__info-text{font-size:36px;text-align:center;margin-bottom:36px}.container.frontpage-calendar__container{max-width:none;padding-left:0;padding-right:0;margin-top:64px;margin-bottom:64px}@media(min-width: 992px){.container.frontpage-calendar__container{margin-top:128px;margin-bottom:128px}}.frontpage-calendar{background-color:#f7f7f8;position:relative;margin-top:50px}.frontpage-calendar .hds-koros{position:absolute;top:-50px;right:0;left:0}.frontpage-calendar h2{padding:128px 0 0 0;margin-bottom:36px}@media(min-width: 576px){.frontpage-calendar h2{margin-bottom:48px}}@media(min-width: 768px){.frontpage-calendar h2{padding:60px 0 0}}.frontpage-calendar .container{padding-bottom:80px}.frontpage-calendar__link-container{display:flex;justify-content:right;padding:0 16px}@media(min-width: 576px){.frontpage-calendar__link-container{padding:0}}.frontpage-calendar__link-container i{width:36px}.frontpage-calendar__link-container a{display:flex;text-decoration:none;font-size:18px;font-weight:500;align-items:center}.frontpage-calendar__link-container a:hover,.frontpage-calendar__link-container a:focus,.frontpage-calendar__link-container a:active{text-decoration:underline}.frontpage-calendar__item-container{display:flex;flex-wrap:wrap}@media(min-width: 576px){.frontpage-calendar__item-container{margin:0 -12px 60px -12px}}.frontpage-calendar__item{width:100%;min-height:282px;padding:8px 0;text-decoration:none}.frontpage-calendar__item:hover .motions-link{text-decoration:underline}@media(min-width: 768px){.frontpage-calendar__item{padding:12px;width:50%}}@media(min-width: 992px){.frontpage-calendar__item{width:33.3%}}@media(min-width: 1248px){.frontpage-calendar__item{width:25%}}.frontpage-calendar__item .motions-link{font-size:16px;display:flex;align-items:center;text-decoration:none;font-weight:500}.frontpage-calendar__item .motions-link i{height:18px;width:18px;margin-right:12px}.frontpage-calendar__item .motions-link span{width:auto}.frontpage-calendar__item .color-line{height:8px}.frontpage-calendar__item .content-container{padding:24px;display:flex;flex-direction:column;height:100%}.frontpage-calendar__item .meeting-date{font-size:18px;margin-bottom:16px}.frontpage-calendar__item h3{flex-grow:1;font-size:1.25rem;font-weight:500;margin-top:0}@media(min-width: 576px){.frontpage-calendar__item h3{font-size:1.5rem}}.frontpage-calendar__item-inner{background-color:#fff;height:100%}.frontpage-calendar__notice{margin-bottom:24px;margin-top:-24px}.news-listing--latest-tiny-teasers .news-listing__title{margin-left:24px}.news-listing--latest-tiny-teasers .news-listing__title{font-size:18px;font-weight:400;line-height:1.5;margin-bottom:8px;margin-top:0}.news-listing--latest-tiny-teasers .news-listing__img{position:relative;flex-shrink:0;height:78px;width:78px;box-shadow:inset 0 0 0 1px #e5e5e5}.news-listing--latest-tiny-teasers .news-listing__img img{position:absolute;-o-object-fit:cover;object-fit:cover;width:100%;height:100%}.news-listing--latest-tiny-teasers .news-listing__img .image-placeholder{align-items:center;background-color:#e5e5e5;display:flex;height:100%;justify-content:center;padding-bottom:0;width:100%}.news-listing--latest-tiny-teasers .news-listing__img .image-placeholder:before{content:none}.meetings-calendar{margin-top:90px}.meetings-calendar .hds-loading-spinner{margin:90px auto;position:relative;top:auto;top:initial;left:auto;left:initial}.meetings-calendar ol{list-style:none}.meetings-calendar .calendar-header{display:flex;margin-bottom:65px;justify-content:center;align-items:center}.meetings-calendar .calendar-header h2{margin:0 15px;font-size:26px;min-width:190px;text-align:center;text-transform:capitalize}@media(min-width: 576px){.meetings-calendar .calendar-header h2{margin:0 30px;font-size:32px;min-width:235px}}.meetings-calendar .calendar-header .hel-icon,.meetings-calendar .calendar-header .icon-container{height:30px;min-width:30px;width:30px;cursor:pointer}.meetings-calendar .calendar-header .icon-container--disabled{color:#efefef}.meetings-calendar .days-grid{display:grid;grid-gap:30px;gap:30px;padding-left:0}@media(min-width: 992px){.meetings-calendar .days-grid{display:flex;flex-wrap:wrap;gap:0}}.meetings-calendar .calendar-day{flex:1;padding:16px;position:relative;margin-top:0}@media(min-width: 992px){.meetings-calendar .calendar-day{margin-bottom:60px;max-width:20%;min-width:20%}.meetings-calendar .calendar-day::after{content:"";height:8px;background-color:#c2a251;display:block;position:absolute;bottom:-32px;right:0;left:0;margin:0 16px}}.meetings-calendar .calendar-day .no-meetings{padding:16px;height:100%;background-color:#f7f7f8}@media(min-width: 992px){.meetings-calendar .calendar-day .no-meetings{height:calc(100% - 40px)}}.meetings-calendar .meeting-row{border-bottom:1px dashed #666;padding:16px 0;font-size:16px}.meetings-calendar .meeting-row a{display:flex;align-items:center}.meetings-calendar .meeting-row .hel-icon{width:16px;height:16px}.meetings-calendar .meeting-title{font-weight:700;margin-bottom:8px;margin-top:0;font-size:16px}.meetings-calendar .meeting-start-time{color:#666}.meetings-calendar .meeting-row--cancelled .meeting-title,.meetings-calendar .meeting-row--cancelled .meeting-start-time{text-decoration:line-through}.meetings-calendar .date-header{font-size:20px;font-weight:500;padding-bottom:8px;border-bottom:2px solid #000;justify-content:space-between;white-space:nowrap;display:flex}.meetings-calendar .calendar-day__today .meeting-row{padding:16px;background-color:#f7f2e4}.meetings-calendar .calendar-day__today .date-header{color:#c2a251;border-color:#c2a251}.meetings-calendar .calendar-day__no-meetings .date-header{color:#666;border-color:#666}:not(.has-sidebar) .paatokset__decision-tree-container{margin-left:auto;margin-right:auto;max-width:1264px}.paatokset__decision-tree-container .hidden{display:none}.paatokset__decision-tree-container .custom-select-wrapper{position:absolute;right:0}.paatokset__decision-tree-container .arrow i{width:16px;height:16px}.paatokset__decision-tree-container .custom-select .custom-options{display:none}.paatokset__decision-tree-container .custom-select.open .custom-options{display:block}.paatokset__decision-tree-container .decision-tree__title span{display:block;font-weight:500;font-size:1.5rem;margin-top:56px;margin-bottom:16px}.paatokset__decision-tree-container .decision-tree__title-container{display:flex;align-items:center;width:100%;max-width:994px;margin-bottom:20px}.paatokset__decision-tree-container .decistion-tree__item.open div{padding-left:14px}.paatokset__decision-tree-container button.accordion-item__button.accordion-item__button--toggle.tabbed-list__header__button{width:289px;height:24px;color:#1a1a1a;font-size:18px;font-weight:bold;line-height:24px}.paatokset__decision-tree-container .accordion-item__content__inner{position:relative;border-bottom:1px solid #000;display:flex;display:inline-flex;width:100%;justify-content:space-between}.paatokset__decision-tree-container .accordion-item__content__inner.tabbed-list__content__inner input{color:#060606;font-size:20px;font-weight:normal;letter-spacing:0;text-decoration:none;background:none;border:none;cursor:pointer}.paatokset__decision-tree-container .menu{overflow:auto}.paatokset__decision-tree-container .menu:scroll{display:none}.paatokset__decision-tree-container .menu .item{display:inline-block;color:#060606;font-size:20px;font-weight:bold;letter-spacing:.29px;text-decoration:none;margin-right:22px}.paatokset__decision-tree-container .menu .item.hidden{display:none}.paatokset__decision-tree-container .menu .item.selected{border-bottom:6px solid #000;padding-bottom:19px}.paatokset__decision-tree-container .container.accordion__container{padding:0}.policymakers-documents,.policymakers-decisions{display:none}.policymakers-documents.selected-year,.policymakers-decisions.selected-year{display:block}.custom-select{display:flex;flex-direction:column}.custom-select__trigger{position:relative;display:flex;align-items:center;-ms-flex-pack:justify;padding:0 10px;cursor:pointer;border:none;color:#060606;font-size:18px;font-weight:500;letter-spacing:0;padding-bottom:23px;margin:0}.custom-select__trigger .arrow i{width:24px;height:24px}.custom-options{position:absolute;display:block;opacity:0;visibility:hidden;pointer-events:none;z-index:99}.custom-select.open .custom-options{opacity:1;visibility:visible;pointer-events:all;margin-top:56px;border:1px solid #000;background-color:#fff;width:148px;text-align:center}.custom-option{position:relative;padding:0 22px 0 22px;font-size:22px;font-weight:300;color:#3b3b3b;line-height:60px;cursor:pointer;transition:all .5s}.custom-option:hover{cursor:pointer;background-color:#b2b2b2}.custom-option.selected{color:#fff;background-color:#305c91}@media(max-width: 544px){.desktopTd{display:none}}@media(min-width: 544px){.mobileTd{display:none}}.paatokset_download-link-container .paatokset__link-plain{display:flex;flex-wrap:wrap;align-items:center;margin-top:22px}.paatokset_download-link-container .paatokset__link-plain span{margin-right:12px}.policymaker-no-content{margin-top:24px}.policymaker-calendar h2{margin-bottom:24px}.policymaker-calendar__table{width:100%;max-width:none;max-width:initial;display:table;border:0;border-collapse:collapse}.policymaker-calendar__table thead{background-color:#fff}.policymaker-calendar__table th,.policymaker-calendar__table td{font-size:18px;background-color:#fff;color:#000;padding:24px 0;padding-right:24px;font-weight:400}@media(max-width: 576px){.policymaker-calendar__table th:nth-of-type(2){text-align:right}}.policymaker-calendar__table-header th{font-weight:500;padding-top:0}@media(max-width: 576px){.policymaker-calendar__table-header{border-bottom:2px solid #000}.policymaker-calendar__table-header th:last-of-type{display:none}}.policymaker-calendar__table-row{border-bottom:1px solid #ccc}.policymaker-calendar__table-row:hover{background-color:rgba(0,0,0,0)}.policymaker-calendar__table-row th:last-of-type{display:flex;align-items:center}@media(max-width: 576px){.policymaker-calendar__table-row{display:flex;flex-wrap:wrap;width:100%;padding:16px 0}.policymaker-calendar__table-row th{padding:8px}.policymaker-calendar__table-row td{border-bottom:none !important}.policymaker-calendar__table-row td{padding:8px}.policymaker-calendar__table-row td:first-of-type{font-weight:500}.policymaker-calendar__table-row td:last-of-type a{display:flex;align-items:center;color:#000;white-space:nowrap}.policymaker-calendar__table-row td:last-of-type a .hel-icon--angle-right{width:16px;height:16px}.policymaker-calendar__table-row th:nth-of-type(1),.policymaker-calendar__table-row th:nth-of-type(2),.policymaker-calendar__table-row td:nth-of-type(1),.policymaker-calendar__table-row td:nth-of-type(2){width:50%;padding-right:0}.policymaker-calendar__table-row td:nth-of-type(2){text-align:right}.policymaker-calendar__table-row th:nth-of-type(3),.policymaker-calendar__table-row th:nth-of-type(4),.policymaker-calendar__table-row td:nth-of-type(3),.policymaker-calendar__table-row td:nth-of-type(4){width:100%}}.policymaker-calendar__table-row--cancelled td:nth-child(1),.policymaker-calendar__table-row--cancelled td:nth-child(2){text-decoration:line-through}.policymaker-contacts{width:100%;font-size:1.125rem}@media(min-width: 992px){.policymaker-contacts h2{display:none}}.policymaker-contacts h3{margin-bottom:24px}.policymaker-contacts label.unit__contact-row__label{font-weight:700}.policymaker-contacts .hel-icon{--icon-size: 1.5rem}.policymaker-contacts article h3{margin-top:0}.policymaker-listing{background-color:#f7f7f8}.policymaker-listing .container{padding-top:65px;padding-bottom:65px}.policymaker-listing h2{margin-bottom:50px}.policymaker-card__container{margin-bottom:72px}@media(min-width: 576px){.policymaker-card__container{display:flex}}.policymaker-card__container .policymaker-card{text-decoration:none;display:flex;flex-direction:column;justify-content:space-between;padding-bottom:16px}@media(min-width: 576px){.policymaker-card__container .policymaker-card{width:50%;padding-bottom:0}.policymaker-card__container .policymaker-card:first-of-type{padding-right:8px}.policymaker-card__container .policymaker-card:last-of-type{padding-left:8px}}.policymaker-card__container .policymaker-card:hover .hel-icon{transform:translate(10px)}.policymaker-card__container .policymaker-card__color-title{text-align:center;font-weight:500;text-transform:uppercase;padding:4px 0}.policymaker-card__container .policymaker-card__title-icon{padding:25px;background-color:#fff}.policymaker-card__container .policymaker-card__title-icon h4{margin-top:0}.policymaker-card__container .hel-icon{width:30px;height:30px;min-width:30px;min-height:30px;transition:all .2s ease-in-out}.policymaker-row__link{padding:36px;display:flex;justify-content:space-between;background-color:#fff;margin-bottom:16px;position:relative;text-decoration:none;align-items:center}.policymaker-row__link:hover .hel-icon{transform:translate(10px)}.policymaker-row__link .hel-icon{min-width:30px;min-height:30px;width:10%;height:30px;transition:all .2s ease-in-out}.policymaker-row__link .policymaker-row__color{position:absolute;left:0;top:0;bottom:0;height:100%;width:16px}.policymaker-row__link .policymaker-row__title{font-size:24px;-webkit-hyphens:auto;hyphens:auto;width:90%;word-wrap:break-word;word-wrap:break-word;padding-right:16px}.policymaker-row__link .policymaker-row__sub-title{font-size:20px;color:#707070}.policymaker-row__link+h4{margin-top:64px !important}.policymaker-listing .accordion-item__content__inner h4{font-weight:500;margin-bottom:32px;margin-top:0}.load-more-btn{display:none}.policymaker-members h2{margin-bottom:32px}.policymaker-members__filters{display:flex;flex-wrap:wrap;justify-content:space-between;margin-bottom:54px}.policymaker-members__filters input:not(input[type=checkbox]),.policymaker-members__filters select{width:100%;height:56px;padding:16px;border:2px solid #707070}.policymaker-members__filters select{-webkit-appearance:none;-moz-appearance:none;appearance:none}.policymaker-members__filters option{color:#000}.policymaker-members__filters .search-wrapper{width:100%;margin-bottom:36px;position:relative}.policymaker-members__filters .search-wrapper .hel-icon{position:absolute;left:20px;bottom:16px;width:24px;height:24px}.policymaker-members__filters .search-wrapper input{padding-left:56px !important}.policymaker-members__filters .form-item{width:100%;margin-bottom:36px}@media(min-width: 576px){.policymaker-members__filters .form-item{width:48%}}.policymaker-members__filters .form-item__dropdown{position:relative}.policymaker-members__filters .form-item__dropdown .hel-icon{width:24px;height:24px;position:absolute;right:20px;bottom:16px;pointer-events:none}.policymaker-members__filters .form-item--checkbox__item{list-style:none}.policymaker-members__filters .form-item--checkbox__item label{display:flex}.policymaker-members__filters .form-item--checkbox__item span{white-space:nowrap;padding-left:12px}.policymaker-members__filters .form-item--checkbox__item input{-moz-appearance:none;-webkit-appearance:none;-o-appearance:none;outline:none;content:none}.policymaker-members__filters .form-item--checkbox__item input::before{content:"";font-size:20px;display:flex;justify-content:center;align-items:center;width:24px;height:24px;max-width:24px;max-height:24px;border:2px solid #707070}.policymaker-members__filters .form-item--checkbox__item input:checked::before{content:"✓"}.policymaker-members__list{border-top:2px solid #000}.policymaker-members__list .member-row{display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #000;padding:32px 0;text-decoration:none}.policymaker-members__list .member-row:link:hover .member-name{text-decoration:underline}.policymaker-members__list .member-info>div{display:flex;flex-wrap:wrap}@media(min-width: 576px){.policymaker-members__list .member-info>div{flex-direction:row;align-items:center}}.policymaker-members__list .member-info{display:flex;flex-direction:column}.policymaker-members__list .member-info .deputy-of{margin-top:16px}.policymaker-members__list .member-image{height:75px;width:75px;min-height:75px;min-width:75px;border-radius:50%;overflow:hidden;margin-left:8px}@media(min-width: 576px){.policymaker-members__list .member-image{height:120px;width:120px;min-height:120px;min-width:120px}}.policymaker-members__list .member-name{font-size:20px;font-weight:500;line-height:29px;margin-bottom:0;margin-top:0}@media(min-width: 576px){.policymaker-members__list .member-name{font-size:24px}}.policymaker-members__list .member-role,.policymaker-members__list .member-party{color:#666;font-size:16px;line-height:24px}@media(min-width: 576px){.policymaker-members__list .member-role,.policymaker-members__list .member-party{font-size:18px;line-height:27px}}.policymaker-members__list .member-role::after{content:",";margin-right:4px}@media(min-width: 576px){.policymaker-members__list .member-role::after{display:none}}.policymaker-members__list .member-party{display:flex;align-items:center}@media(min-width: 576px){.policymaker-members__list .member-party::before{content:"";height:4px;width:4px;border-radius:50%;background-color:#000;display:inline-block;margin:0 8px}}.policymaker-members__list .no-results{margin:16px 0;display:flex;justify-content:center;align-items:center}.policymaker-side-menu--desktop{display:none}@media(min-width: 992px){.policymaker-side-menu--desktop{display:block}}.policymaker-side-menu.policymaker-side-menu--mobile{max-width:1328px;margin-left:auto;margin-right:auto;padding-left:16px;padding-right:16px;margin-bottom:-30px;margin-top:30px}@media(min-width: 768px){.policymaker-side-menu.policymaker-side-menu--mobile{padding-left:32px;padding-right:32px}}.policymaker-side-menu.policymaker-side-menu--mobile li+li{margin-top:0}@media(min-width: 992px){.policymaker-side-menu.policymaker-side-menu--mobile{display:none}}.policymaker-side-menu--desktop li,.sidebar-navigation li{width:100%}.policymaker-side-menu--desktop a,.sidebar-navigation a{text-decoration:none}.policymaker-side-menu--desktop .menu,.sidebar-navigation .menu{flex-direction:column}.policymaker-side-menu--desktop a[icon=angle-left],.sidebar-navigation a[icon=angle-left]{display:flex;align-items:center}.policymaker-side-menu--desktop a[icon=angle-left] svg,.sidebar-navigation a[icon=angle-left] svg{margin-right:8px}.policymaker-side-menu--desktop .active,.sidebar-navigation .active{font-weight:bold}.policymaker-side-menu--desktop #menu--level-0 li span.menu__link-wrapper,.sidebar-navigation #menu--level-0 li span.menu__link-wrapper{font-size:24px;padding-bottom:26px;border-bottom:2px solid #000}.policymaker-side-menu--desktop #menu--level-1 li span.menu__link-wrapper,.sidebar-navigation #menu--level-1 li span.menu__link-wrapper{padding:24px 0;border-bottom:1px solid #ccc;font-size:18px}.has-policymaker-nav.has-sidebar .before-content--in-main .page-title,.has-policymaker-nav .has-sidebar .before-content--in-main .page-title{margin-top:0}a.hds-button.hds-button--primary.hdbt-icon::before,a.hds-button.hds-button--secondary.hdbt-icon::before{margin-left:16px;margin-right:0}.policymaker-list-item--agenda-item>a,.policymaker-list-item--agenda-item>div{display:flex;flex-direction:column;align-items:flex-start}@media(min-width: 992px){.policymaker-list-item--agenda-item>a,.policymaker-list-item--agenda-item>div{flex-direction:row;align-items:flex-start}.policymaker-list-item--agenda-item>a .hel-icon,.policymaker-list-item--agenda-item>div .hel-icon{align-self:center;margin-left:auto;margin-right:8px}}.policymaker-list-item--agenda-item .agenda-item__index-number{font-weight:500;margin-right:32px;margin-bottom:6px;white-space:nowrap}@media(min-width: 992px){.policymaker-list-item--agenda-item .agenda-item__index-number{margin-bottom:0}}.policymaker-list-item--agenda-item .agenda-item__subject{margin-right:32px;margin-bottom:24px}@media(min-width: 992px){.policymaker-list-item--agenda-item .agenda-item__subject{margin-bottom:0}}.policymaker-list-item--agenda-item a{text-decoration:none}.policymaker-list-item--agenda-item a:hover .agenda-item__subject{text-decoration:underline}.policymaker-list-item--agenda-item .hel-icon{min-width:24px;min-height:24px}.policymaker-list-item--agenda-item.policymaker-list-item{border-bottom-color:#000}.policymaker-list-item--agenda-item.policymaker-list-item:first-child{border-top:2px solid #000}.policymaker-list-item--agenda-item.policymaker-list-item:last-child{border-bottom:2px solid #000}.node--type-article .content-author{font-size:1rem;color:#666}.node--type-article .keywords{margin-bottom:8px;display:flex}.node--type-article .keywords .hds-tag{margin:16px;margin-left:0}.node--type-article .keywords .hds-tag a{font-size:16px;border-radius:24px;background:#000;color:#fff;padding:6px 16px;text-decoration:none;display:flex;width:-moz-fit-content;width:fit-content;--outline-gutter: 2px;--outline-width: 3px;--focus-outline-color: #000;border:2px solid rgba(0,0,0,0)}.node--type-article .keywords .hds-tag a:hover,.node--type-article .keywords .hds-tag a:active,.node--type-article .keywords .hds-tag a:focus{transition-property:background-color,border-color,color;transition-duration:85ms;transition-timing-function:ease-out}.node--type-article .keywords .hds-tag a:hover{border-color:#000;color:#000;background-color:rgba(0,0,0,0)}.node--type-article .keywords .hds-tag a:focus,.node--type-article .keywords .hds-tag a:active{outline:var(--outline-width) solid var(--focus-outline-color);outline-offset:var(--outline-gutter);outline-offset:2px}.latest-articles__list{width:100%}.latest-articles__list .sidebar_block_heading{margin-top:0}.latest-articles__list a{text-decoration:none}.latest-articles__list a:hover{text-decoration:underline}:not(.has-sidebar) .all-articles{padding-left:32px;padding-right:32px}.node--type-imported-article .article__body{margin-top:64px}.node--type-imported-article p{font-size:1.125rem}.node--type-imported-article .preamble p{font-size:1.375rem}.node--type-imported-article .preamble::after{background:#000;content:"";display:block;height:2px;margin-bottom:32px;margin-top:32px;width:64px}.issue-header__container{border-bottom:2px solid #ccc;margin-bottom:27.5px}@media(min-width: 1248px){.issue-header__container{margin-bottom:32px}}.issue__title{margin-bottom:24px;font-size:32px;line-height:1.1;font-weight:normal}.issue__header .issue__title{margin-top:0}@media(min-width: 992px){.issue__title{font-size:52px}}.issue__diarynumber{font-size:16px;margin-bottom:32px}.issue__diarynumber label{display:block;font-weight:600}.issue-header__footer{margin-bottom:24px}.issue-header__footer .issue__category{margin-bottom:32px}@media(min-width: 1248px){.issue-header__footer{display:flex;align-items:center;flex-wrap:wrap}.issue-header__footer .issue__category{margin-bottom:0}}.issue__category{display:flex}.issue__category .hds-tag{margin-right:12px;font-size:16px;border-radius:24px;background:#000;color:#fff;padding:6px 16px;display:flex;width:-moz-fit-content;width:fit-content}.issue__category .hds-tag--confidential{background:var(--color-brick)}.issue__container h3{font-size:32px}@media(min-width: 1248px){.issue__container h3{font-size:36px}}.issue__container h3,.issue__container h4{margin-top:16px}.issue__container h3:first-child,.issue__container h4:first-child{margin-top:0}.issue__container .SisaltoSektio{margin-bottom:32px}.issue__container.issue__container--navigation{margin-bottom:32px}.issue__container .paatokset-accordion{margin-bottom:32px;border-bottom:2px solid #ccc}.issue__container .paatokset-accordion .handorgel__header__button,.issue__container .paatokset-accordion .handorgel__content{background:rgba(0,0,0,0)}.issue__container .voting-results-accordion{margin-bottom:-2px}@media(min-width: 1248px){.issue__container{display:flex}}@media(min-width: 1248px){.issue__left-column__container{width:65%;padding-right:125px}}.issue-right-column__container .issue__attachment{padding:24px 0;border-bottom:1px solid #979797;vertical-align:top;font-weight:600;line-height:24px;font-size:16px}.issue-right-column__container .issue__attachment>a,.issue-right-column__container .issue__attachment>div{display:flex}.issue-right-column__container .issue__attachment div:first-child{margin-right:16px}.issue-right-column__container .issue__attachment .hel-icon{width:var(--spacing-m);height:var(--spacing-m)}@media(min-width: 1248px){.issue-right-column__container{width:35%}}.issue__attachment__reason{font-size:16px}.issue-content__title h2{margin-top:16px;margin-bottom:32px;line-height:1.1;font-weight:normal;font-size:24px}@media(min-width: 992px){.issue-content__title h2{font-size:36px}}.issue-content__indices{font-size:20px;margin-bottom:8px}.issue-content__policymaker-label{text-align:left;text-transform:uppercase;font-weight:bold;padding:10px 48px;margin-bottom:36px;display:inline-block;max-width:100%;font-size:14px}.issue-content__policymaker-label.policymaker-label--small{display:inline-block;padding:10px 40px;font-size:14px}@media(min-width: 768px){.issue-content__policymaker-label{display:inline-block;padding:10px 55px}}.issue__favorite-button button.hds-button{color:#000;padding-left:0}.issue__favorite-button button.hds-button .hds-button__label{padding:0}.issue__favorite-button button.hds-button .hel-icon:first-of-type:not(:last-of-type){margin-left:0;margin-right:13px}.issue-content-top__container{margin-top:48px;margin-bottom:48px}.issue-content__section{margin-bottom:32px}.issue-content__section p,.issue-content__section ul{margin-top:0;padding-top:0}@media(min-width: 1248px){.issue-content__section{font-size:20px}}.issue__pdf{margin-bottom:32px}.issue__pdf.issue__pdf--desktop{display:none}.issue__decision-navigation{height:100%;display:flex;align-items:center;margin-top:8px;margin-bottom:45px}.issue__decision-navigation .decision-navigation-button--next span{margin-left:auto;margin-right:0;flex-basis:0}@media(min-width: 576px){.issue__decision-navigation .decision-navigation-button--next span{flex-basis:auto}}.issue__decision-navigation .decision-navigation-button--next .hel-icon{margin-right:0;margin-left:14px}.issue__meetings-labels label{font-weight:500}.issue__more-info{margin-top:64px;margin-bottom:64px}.issue__more-info div{margin:16px 0}.issue__more-info__content{padding-left:24px;border-left:5px solid var(--hdbt-color-palette--primary)}.issue-ajax-error__container{display:none}.issue__decision-date{margin-bottom:32px}.issue__container table{border:none}.issue-content__container td,.issue-content__container div{font-size:1.125rem}@media(min-width: 992px){.issue-content__container td,.issue-content__container div{font-size:1.25rem}}.issue-content__container del{text-decoration:line-through}.issue-content__container ins{text-decoration:none}.issue-content__container .SisaltoSektio ul,.issue-content__container .SisaltoSektio ol,.issue-content__container .accordion-item__content__inner ul,.issue-content__container .accordion-item__content__inner ol{padding-top:0;padding-left:1rem}.issue-content__container .SisaltoSektio div,.issue-content__container .accordion-item__content__inner div{margin:16px 0}.issue-content__container .SisaltoSektio table td,.issue-content__container .accordion-item__content__inner table td{display:block;background-color:#f1f1f1}.issue-content__container .SisaltoSektio table td div,.issue-content__container .accordion-item__content__inner table td div{margin:0}@media(min-width: 576px){.issue-content__container .SisaltoSektio table td,.issue-content__container .accordion-item__content__inner table td{display:table-cell}}.issue-content__container .accordion-item__content__inner>h3{font-size:30px;line-height:1.1;margin-top:48px}.issue-content__container .accordion-item__content__inner>h3:first-child{margin-top:0}h4.decision-history-title+h5.decision-history-title{margin-top:1rem}.voting-results-accordion .color-kupari{background-color:#00d7a7 !important}.voting-results-accordion .color-tiili{background-color:#bd2719 !important}.voting-results-accordion .color-tiili{color:#fff}.voting-results-accordion .color-sumu{background-color:#9fc9eb !important}.voting-results-accordion .color-gray-light{background-color:#efefef !important}.voting-results-accordion .accordion-item__content__inner>h3{font-size:24px;line-height:1.1}.voting-results-accordion__inner:first-of-type{margin-top:24px !important}.voting-results-accordion__inner .accordion-item__header .accordion-item__button{border:1px solid #000;align-items:center;padding:0}.voting-results-accordion__inner .accordion-item__header .accordion-item__button .result-key,.voting-results-accordion__inner .accordion-item__header .accordion-item__button .result-color{margin:0;font-size:18px;padding:16px;line-height:1.5}.voting-results-accordion__inner .accordion-item__header .accordion-item__button .result-color{min-width:54px;text-align:center}.voting-results-accordion__inner .accordion-item__header .accordion-item__button .accordion-item__icon{margin:0;padding-right:16px}.voting-results-accordion__inner .accordion-item__header .result-type{display:flex;margin:0}.voting-results-accordion__inner .accordion-item__header .result-type.ayes .result-color{background-color:#00d7a7}.voting-results-accordion__inner .accordion-item__header .result-type.noes .result-color{background-color:#bd2719;color:#fff}.voting-results-accordion__inner .accordion-item__header .result-type.blank .result-color{background-color:#9fc9eb}.voting-results-accordion__inner .accordion-item__header .result-type.absent .result-color{background-color:#efefef}.voting-results-accordion__inner .accordion-item__content{margin-top:-1px !important}.voting-results-accordion__inner .accordion-item__content{border:1px solid #000}.voting-results-accordion__inner .accordion-item__content__inner{margin:0 !important}.voting-results-accordion__inner .results-table{margin:0;max-width:none;max-width:initial}.voting-results-accordion__inner .results-table thead,.voting-results-accordion__inner .results-table tbody{width:100%}.voting-results-accordion__inner .results-table thead th,.voting-results-accordion__inner .results-table thead td,.voting-results-accordion__inner .results-table tbody th,.voting-results-accordion__inner .results-table tbody td{font-size:16px}.voting-results-accordion__inner .results-table thead .results-table__row{background-color:#efefef}.voting-results-accordion__inner .results-table thead .results-table__row th{color:#000}.voting-results-accordion__inner .results-table tbody .results-table__row{background-color:#fff}.voting-results-accordion__inner .results-table tbody .results-table__row td{background-color:#fff;display:table-cell}.voting-results-accordion__inner .results-table .results-table__row th{width:40%}.voting-results-accordion__inner .accordion-item__button--close-inner{font-size:16px}.results-by-party{margin-top:64px !important}.results-by-party .results-table{max-width:none;max-width:initial}.results-by-party .results-table thead .results-table__row th{min-width:0;min-width:initial;font-size:16px}.results-by-party .results-table thead .results-table__row th:first-of-type{width:100%;font-weight:600}.results-by-party .results-table thead .results-table__row th:not(:first-of-type){min-width:56px;width:56px;max-width:56px;font-size:14px;padding:6px;text-align:center}.results-by-party .results-table tbody .results-table__row td{background-color:#fff;min-width:0;min-width:initial;font-size:16px;display:table-cell}.results-by-party .results-table tbody .results-table__row td:not(:first-of-type){min-width:56px;width:56px;max-width:56px;padding:10px;text-align:center}.issue__hidden-message{margin-bottom:32px}.page-type--case .layout-content,.page-type--decision .layout-content{max-width:100vw;margin-left:auto;margin-right:auto;padding-left:16px;padding-right:16px}@media(min-width: 768px){.page-type--case .layout-content,.page-type--decision .layout-content{max-width:1328px;padding-left:32px;padding-right:32px}}.page-type--case .component.component--banner,.page-type--decision .component.component--banner{margin-top:48px}@media(min-width: 1248px){.page-type--case .component.component--banner,.page-type--decision .component.component--banner{width:65%}}.motion-tag{display:block;margin:0}.info-label,.warning-label{display:inline-block;padding:5px;padding-right:10px;margin-bottom:5px;margin-bottom:24px;display:inline-block}.info-label span,.warning-label span{font-size:16px;font-weight:700}.info-label.visible,.warning-label.visible{visibility:visible}@media(min-width: 992px){.info-label,.warning-label{margin-bottom:7px}}.info-label span,.warning-label span{margin-left:5px}.info-label{background-color:#e8f3fc}.warning-label{background-color:#ffd238}.info-label__container,.warning-label__container{display:flex;align-items:center}.meeting-video__video-container{position:relative;padding-bottom:56.25%;height:0;margin-bottom:16px;margin-top:16px}.meeting-video__video-container iframe{position:absolute;top:0;left:0;width:100%;height:100%;overflow:hidden}.meeting-video__video-container iframe html{overflow:hidden;overflow-y:hidden}.meeting-video p{font-size:16px}.node--type-policymaker>section.policymaker-summary{margin-bottom:24px;--line-height:1.5555555556}@media(min-width: 768px){.node--type-policymaker>section.policymaker-summary{margin-bottom:40px}}.node--type-policymaker>section.policymaker-summary p{font-size:18px}.node--type-policymaker>section.policymaker-summary .issue-content__policymaker-label{margin-bottom:0}.node--type-policymaker>section.policymaker-summary .policymaker-summary__label{display:flex;margin-bottom:16px}.node--type-policymaker>section.policymaker-summary .issue__favorite-button{display:none}@media(min-width: 992px){.node--type-policymaker>section.policymaker-summary .issue__favorite-button{display:inline-block;margin-left:16px}}.node--type-policymaker>section.policymaker-summary .announcement h2{font-weight:700;font-size:1.15rem;margin-top:1rem;margin-bottom:1rem}@media(min-width: 768px){.node--type-policymaker>section.policymaker-summary .announcement{margin-left:0;margin-right:0}}.policymaker-image{margin-bottom:48px}.policymaker-image figure{margin:0}.policymaker-image img{-o-object-fit:cover;object-fit:cover;margin-bottom:8px;width:100%}.policymaker-meetings .warning-label{margin-top:16px}.node--type-policymaker .table-of-contents__container{position:relative;margin-bottom:64px}.table-of-contents+.policymaker-image{padding-top:48px}.content-menu__arrow{display:none}.content-menu__arrow.hel-icon--arrow-up{transform:rotate(180deg)}@media(min-width: 320px){.content-menu__arrow{display:block;height:111px;color:#fd4f00;width:90px;position:absolute;right:0}}.node--type-policymaker>section{margin-top:0;margin-bottom:64px}.node--type-policymaker>section .section-description{margin-bottom:32px}@media(min-width: 992px){.node--type-policymaker>section .section-description{margin-bottom:48px}}.view-all .paatokset-button-link{margin-top:32px}.view-all .paatokset-button-link span{margin-left:auto}.policymaker-list-item{border-bottom:1px solid #ccc;padding:24px 0;display:block}.policymaker-list-item:first-child{border-top:1px solid #ccc}.policymaker-list-item.policymaker-list-item--document,.policymaker-list-item .policymaker-list-item--document{display:block;border-color:#000;text-decoration:none}.policymaker-list-item.policymaker-list-item--document .subject__date,.policymaker-list-item .policymaker-list-item--document .subject__date{display:block}.policymaker-list-item .list-item__date{font-size:16px;color:#666;margin-bottom:16px}.policymaker-list-item .list-item__date--desktop{display:inline}.policymaker-list-item .list-item__subject{font-weight:500;font-size:24px}.policymaker-list-item .list-item__subject a{text-decoration:none}.policymaker-list-item .policymaker-list-item--document:hover .list-item__subject{text-decoration:underline}h1.minutes__header{margin-top:0;display:flex;flex-direction:column;margin-bottom:16px;gap:24px}h1.minutes__header .minutes__header-prefix{font-size:20px}h1.minutes__header .minutes__header-suffix{font-size:16px;color:#666}@media(min-width: 992px){h1.minutes__header{gap:0px}}h2.minutes-list__header{font-weight:500;font-size:24px;margin-bottom:24px}.minutes-list__wrapper{font-size:18px;margin-bottom:32px}.minutes-file__container label{display:block;margin-bottom:4px}.minutes-file__container .minutes__publish-date{position:relative;padding-bottom:24px;margin-bottom:32px}.minutes-file__container .minutes__publish-date:after{content:"";height:2px;background:#000;width:62px;position:absolute;bottom:0;left:0}.minutes-file__container .publish-date__date{font-size:20px;font-weight:700}.minutes__file-link{margin-bottom:8px}.policymaker-live-sream .view-all--recordings{display:none}.policymaker-label__tags{margin-bottom:32px}.policymaker-label__tags .hds-tag{font-size:16px;border-radius:24px;background:#000;color:#fff;padding:6px 16px;margin-right:12px;display:flex;width:-moz-fit-content;width:fit-content}.policymaker-label__tags .hds-tag__container{display:flex}.policymaker-label__tags:after{content:"";display:block;margin-top:24px;border-bottom:2px solid #000;width:90px}.minutes-decision__container{margin-top:64px}.minutes-decision__container .paatokset-accordion{margin-top:32px;margin-bottom:32px;border-bottom:2px solid #ccc}.minutes-decision__container .paatokset-accordion .handorgel__header__button,.minutes-decision__container .paatokset-accordion .handorgel__content{background:rgba(0,0,0,0)}.minutes-decision__container .paatokset-accordion .accordion-item__button{padding-top:20px;padding-bottom:20px}.minutes-decision__container .paatokset-accordion .accordion-item__header{font-size:1.5rem}.minutes-decision__meta{font-size:18px}.minutes-decision__meta .Kokousaika{font-weight:700}.minutes-decision__heading{margin-bottom:32px;line-height:1.1;font-weight:normal;font-size:32px}@media(min-width: 992px){.minutes-decision__heading{font-size:36px}}.paatokset-search-page--decisions .layout-content{margin:0}.paatokset-search-page--decisions .main-content{margin-top:0;background-color:#f7f7f8;padding-bottom:calc(50px + 48px) auto 0}@media(min-width: 992px){.paatokset-search-page--decisions .main-content{padding-bottom:calc(50px + 64px)}}.paatokset-search-page--decisions .footer{margin-top:0}.paatokset-search--frontpage .paatokset-search-wrapper{margin-left:-16px}@media(min-width: 576px){.paatokset-search--frontpage .paatokset-search-wrapper{margin-left:-32px}}.paatokset-search--decisions{margin-bottom:32px}.views--taxonomy-term .views-row{border-bottom:1px solid #ccc;padding:24px 0;display:block}.views--taxonomy-term .views-row:first-child{border-top:1px solid #ccc}.views--taxonomy-term .views-row .views-field-published-at{font-size:16px;color:#666;margin-bottom:16px}.views--taxonomy-term .views-row .views-field-title{font-weight:500;font-size:24px}.views--taxonomy-term .views-row .views-field-title a{text-decoration:none}.views--taxonomy-term .views-row .views-field-title a:hover{text-decoration:underline}.views--taxonomy-term .feed-icon{display:flex;align-items:center;margin-top:64px;text-decoration:none}.views--taxonomy-term .feed-icon i{margin-right:8px}.views--taxonomy-term .feed-icon:hover,.views--taxonomy-term .feed-icon:focus,.views--taxonomy-term .feed-icon:active{text-decoration:underline}.tpr-unit--view-mode-contact-card{margin-bottom:48px}.tpr-unit--view-mode-contact-card .unit__title{border-bottom:2px solid #000}.tpr-unit--view-mode-contact-card .unit__title h3{font-size:24px}.tpr-unit--view-mode-contact-card .unit-info{border-bottom:1px solid #ccc;padding:24px 0;display:flex}.tpr-unit--view-mode-contact-card label{font-weight:500;margin-bottom:4px}.tpr-unit--view-mode-contact-card .unit-info__icon{margin-right:16px}.tpr-unit--view-mode-contact-card a{display:block}.tpr-unit--view-mode-contact-card .paatokset-button-link{display:flex}.tpr-unit--view-mode-contact-card span.country{display:none}.page-type--trustee .page-title__container{max-width:none;max-width:initial}.trustee-information{background-color:#e8f3fc;padding:24px;margin-bottom:48px}.trustee-information .information-row{display:flex;flex-wrap:wrap;font-size:18px}.trustee-information .information-row:not(:last-of-type){margin-bottom:16px}.trustee-information .information-row.information-row--pm-declaration a{margin-left:.4rem}.trustee-information .information-row.information-row--doa a{display:inline-flex;align-items:center}.trustee-information .label{margin-right:8px;font-weight:500}.trustee-top-container{margin-bottom:24px}@media(min-width: 992px){.trustee-top-container{padding:0}}.trustee-top-container span{font-size:18px;color:#666}.trustee-top-container span:first-of-type::after{content:"•";margin:0 16px}.trustee-image{margin-bottom:24px}.node--type-trustee .accordion-item__header{font-size:1.5rem}.node--type-trustee .accordion-item__header .handorgel__header__button{color:#000;border:none;border-top:2px solid #ccc;padding:24px;display:flex;justify-content:space-between;align-items:center;padding:32px 32px 32px 0}.node--type-trustee .accordion-item__header .icon{min-width:30px;min-height:30px;width:30px;height:30px;transition:all .1s ease-in-out}.node--type-trustee .handorgel__header--open .icon{transform:rotate(180deg)}.node--type-trustee .handorgel__header--open .handorgel__header__button,.node--type-trustee .handorgel__header--opened .handorgel__header__button{background-color:#fff}.node--type-trustee .handorgel__content{border:none;padding:0}.node--type-trustee .accordion-item__content__inner{padding:0}.node--type-trustee .accordion__wrapper.handorgel{border:none}.node--type-trustee .accordion-item__button--close{display:flex;justify-content:right;padding:24px;cursor:pointer}.node--type-trustee .accordion-item__button--close .icon{margin-left:8px}.accordion_initiatives .accordion-item__content__inner>div,.accordion_resolutions .accordion-item__content__inner>div{margin-bottom:16px}.accordion_initiatives .date,.accordion_resolutions .date{font-size:16px;color:#666;margin-bottom:8px}.accordion_initiatives .title,.accordion_resolutions .title{display:block;margin-bottom:24px}.accordion_speaking-turn .accordion-item__content__inner>div{margin-bottom:16px}.accordion_speaking-turn .speaking-turn__group__title{font-size:1.5rem;margin-bottom:16px;margin-top:0}.accordion_speaking-turn .speaking-turn__group__title:not(:first-of-type){margin-top:40px}.accordion_speaking-turn .speaking-turn__link-container{display:flex;align-items:center}.accordion_speaking-turn .speaking-turn__link-container .icon{margin-right:16px}.section--content form{display:flex;flex-direction:column;padding-bottom:24px}.section--content form:not(.user-login-form){margin-bottom:24px}.section--content form.user-login-form .form-item{max-width:500px}.section--content form .container{border-bottom:1px solid #707070;margin-bottom:32px;padding-bottom:16px}.section--content form .fieldset-legend{font-size:1.125rem;line-height:1.625rem;font-weight:400;display:inline-block;margin-bottom:12px}.section--content form fieldset.form-item{margin:0 0 32px}.section--content form fieldset.form-item .form-checkboxes,.section--content form fieldset.form-item .form-radios{margin:0}.section--content form fieldset.form-item .form-checkboxes label,.section--content form fieldset.form-item .form-radios label{font-size:1.125rem;line-height:1.4375rem;font-weight:400}.section--content form details{font-size:1.125rem;line-height:1.6875rem;font-weight:400;background:#fff;border-radius:5px;letter-spacing:0;padding:16px;transition-duration:.2s;transition-property:all;width:100%}.section--content form details fieldset{border:0 none}.section--content form details fieldset .fieldset-wrapper .label{font-size:1.0625rem;line-height:1.5rem;font-weight:500}.section--content form details fieldset .fieldset-wrapper .container-inline{display:flex}.section--content form details fieldset .fieldset-wrapper .container-inline .form-item{flex:1 1 50%;padding:0 32px 16px 0}.section--content form .form-item{font-size:1rem;line-height:1.5rem;display:block;margin:0 0 16px;padding:0}.section--content form .form-item label:not(.visually-hidden){font-size:1.125rem;line-height:1.625rem;font-weight:400;color:#000;display:inline-block;letter-spacing:0;margin-bottom:12px;text-align:left;width:100%}.section--content form .form-item .description{font-size:.8125rem;line-height:1.25rem}.section--content form .form-item select,.section--content form .form-item textarea,.section--content form .form-item input[type=text],.section--content form .form-item input[type=tel],.section--content form .form-item input[type=password],.section--content form .form-item input[type=url],.section--content form .form-item input[type=email],.section--content form .form-item input[type=date],.section--content form .form-item .select2-container--default .select2-selection--single{font-size:1.125rem;line-height:1.6875rem;font-weight:400;background:#fff;border:1px solid #cecbbd;border-radius:5px;box-sizing:border-box;height:55px;letter-spacing:0;padding:16px;transition-duration:.2s;transition-property:all;width:100%}.section--content form .form-item select::-moz-placeholder, .section--content form .form-item textarea::-moz-placeholder, .section--content form .form-item input[type=text]::-moz-placeholder, .section--content form .form-item input[type=tel]::-moz-placeholder, .section--content form .form-item input[type=password]::-moz-placeholder, .section--content form .form-item input[type=url]::-moz-placeholder, .section--content form .form-item input[type=email]::-moz-placeholder, .section--content form .form-item input[type=date]::-moz-placeholder, .section--content form .form-item .select2-container--default .select2-selection--single::-moz-placeholder{color:#4a4a49}.section--content form .form-item select::placeholder,.section--content form .form-item textarea::placeholder,.section--content form .form-item input[type=text]::placeholder,.section--content form .form-item input[type=tel]::placeholder,.section--content form .form-item input[type=password]::placeholder,.section--content form .form-item input[type=url]::placeholder,.section--content form .form-item input[type=email]::placeholder,.section--content form .form-item input[type=date]::placeholder,.section--content form .form-item .select2-container--default .select2-selection--single::placeholder{color:#4a4a49}.section--content form .form-item select:focus,.section--content form .form-item textarea:focus,.section--content form .form-item input[type=text]:focus,.section--content form .form-item input[type=tel]:focus,.section--content form .form-item input[type=password]:focus,.section--content form .form-item input[type=url]:focus,.section--content form .form-item input[type=email]:focus,.section--content form .form-item input[type=date]:focus,.section--content form .form-item .select2-container--default .select2-selection--single:focus{border-color:rgba(0,0,0,0);box-shadow:none;color:#000;outline:#0061ad auto 3px}.section--content form .form-item select[disabled],.section--content form .form-item select[disabled]:active,.section--content form .form-item select[disabled]:focus,.section--content form .form-item select[disabled]:hover,.section--content form .form-item textarea[disabled],.section--content form .form-item textarea[disabled]:active,.section--content form .form-item textarea[disabled]:focus,.section--content form .form-item textarea[disabled]:hover,.section--content form .form-item input[type=text][disabled],.section--content form .form-item input[type=text][disabled]:active,.section--content form .form-item input[type=text][disabled]:focus,.section--content form .form-item input[type=text][disabled]:hover,.section--content form .form-item input[type=tel][disabled],.section--content form .form-item input[type=tel][disabled]:active,.section--content form .form-item input[type=tel][disabled]:focus,.section--content form .form-item input[type=tel][disabled]:hover,.section--content form .form-item input[type=password][disabled],.section--content form .form-item input[type=password][disabled]:active,.section--content form .form-item input[type=password][disabled]:focus,.section--content form .form-item input[type=password][disabled]:hover,.section--content form .form-item input[type=url][disabled],.section--content form .form-item input[type=url][disabled]:active,.section--content form .form-item input[type=url][disabled]:focus,.section--content form .form-item input[type=url][disabled]:hover,.section--content form .form-item input[type=email][disabled],.section--content form .form-item input[type=email][disabled]:active,.section--content form .form-item input[type=email][disabled]:focus,.section--content form .form-item input[type=email][disabled]:hover,.section--content form .form-item input[type=date][disabled],.section--content form .form-item input[type=date][disabled]:active,.section--content form .form-item input[type=date][disabled]:focus,.section--content form .form-item input[type=date][disabled]:hover,.section--content form .form-item .select2-container--default .select2-selection--single[disabled],.section--content form .form-item .select2-container--default .select2-selection--single[disabled]:active,.section--content form .form-item .select2-container--default .select2-selection--single[disabled]:focus,.section--content form .form-item .select2-container--default .select2-selection--single[disabled]:hover{background-color:pink}.section--content form .form-item select::-ms-clear,.section--content form .form-item textarea::-ms-clear,.section--content form .form-item input[type=text]::-ms-clear,.section--content form .form-item input[type=tel]::-ms-clear,.section--content form .form-item input[type=password]::-ms-clear,.section--content form .form-item input[type=url]::-ms-clear,.section--content form .form-item input[type=email]::-ms-clear,.section--content form .form-item input[type=date]::-ms-clear,.section--content form .form-item .select2-container--default .select2-selection--single::-ms-clear{display:none}.section--content form .form-item select::-ms-expand,.section--content form .form-item textarea::-ms-expand,.section--content form .form-item input[type=text]::-ms-expand,.section--content form .form-item input[type=tel]::-ms-expand,.section--content form .form-item input[type=password]::-ms-expand,.section--content form .form-item input[type=url]::-ms-expand,.section--content form .form-item input[type=email]::-ms-expand,.section--content form .form-item input[type=date]::-ms-expand,.section--content form .form-item .select2-container--default .select2-selection--single::-ms-expand{display:none}.section--content form .form-item .form-textarea-wrapper textarea{height:120px}.section--content form .form-item input[type=search]{font-size:1.125rem;line-height:1.6875rem;font-weight:400;background:#fff;border:0 none;height:55px;letter-spacing:0;padding:16px;transition-duration:.2s;transition-property:all;width:100%}.section--content form .form-item input[type=submit]{align-self:flex-end;height:2.5em}.section--content form .form-item .form-type-textarea+div{display:none}.section--content form .form-item.form-type-radio{cursor:pointer;display:inline;margin-bottom:32px;margin-right:24px}.section--content form .form-item.form-type-radio input[type=radio]{opacity:0}.section--content form .form-item.form-type-radio input[type=radio]+label:after{content:none}.section--content form .form-item.form-type-radio input[type=radio]:checked+label::after{content:""}.section--content form .form-item.form-type-radio input[type=radio]:focus+label::before{outline:#8ccdca auto 3px}.section--content form .form-item.form-type-radio label{cursor:pointer;display:inline;margin-left:-16px;padding-left:40px;position:relative}.section--content form .form-item.form-type-radio label:before{border:1px solid #cecbbd;border-radius:50%;content:"";display:inline-block;height:30px;left:0;position:absolute;top:-5px;width:30px}.section--content form .form-item.form-type-radio label:after{background-color:#8ccdca;border-radius:50%;content:"";display:inline-block;height:20px;left:5px;position:absolute;top:0;width:20px}.section--content form .form-item.form-type-checkbox{margin-bottom:16px}.section--content form .form-item.form-type-checkbox:last-of-type{margin-bottom:128px}.section--content form .form-item.form-type-checkbox input[type=checkbox]{opacity:0}.section--content form .form-item.form-type-checkbox input[type=checkbox]+label:after{content:none}.section--content form .form-item.form-type-checkbox input[type=checkbox]:checked+label::after{content:""}.section--content form .form-item.form-type-checkbox input[type=checkbox]:focus+label::before{outline:#8ccdca auto 3px}.section--content form .form-item.form-type-checkbox label{cursor:pointer;display:inline;margin-left:-16px;padding-left:40px;position:relative}.section--content form .form-item.form-type-checkbox label:before{border:1px solid #cecbbd;border-radius:5px;content:"";display:inline-block;height:30px;left:0;position:absolute;top:-5px;width:30px}.section--content form .form-item.form-type-checkbox label:after{background-color:#8ccdca;border-radius:3px;content:"";display:inline-block;height:20px;left:5px;position:absolute;top:0;width:20px}.section--content form .form-item.form-type-textarea{margin-bottom:32px}.section--content form .form__group{margin-bottom:32px}.section--content form .form__group h3{font-size:1.25rem}.section--content form .form__group.form__divider{border-top:1px solid #cecbbd;padding-top:16px}.paatokset-search--decisions h1,.paatokset-search--decisions label,.paatokset-search--decisions .container>p,.paatokset-search-wrapper h1,.paatokset-search-wrapper label,.paatokset-search-wrapper .container>p,.paatokset-search--frontpage h1,.paatokset-search--frontpage label,.paatokset-search--frontpage .container>p{color:#000}.paatokset-search--decisions button+ul li,.paatokset-search-wrapper button+ul li,.paatokset-search--frontpage button+ul li{font-size:16px;margin-top:0}.paatokset-search--decisions button+ul li[class*=Select-module_highlighted],.paatokset-search-wrapper button+ul li[class*=Select-module_highlighted],.paatokset-search--frontpage button+ul li[class*=Select-module_highlighted]{color:#fff !important;background-color:#000 !important}.paatokset-search--decisions button+ul li[class*=Select-module_highlighted] span,.paatokset-search-wrapper button+ul li[class*=Select-module_highlighted] span,.paatokset-search--frontpage button+ul li[class*=Select-module_highlighted] span{border-color:#fff !important;box-shadow:none !important}.paatokset-search--decisions button>span[class*=Select-module_buttonLabel],.paatokset-search-wrapper button>span[class*=Select-module_buttonLabel],.paatokset-search--frontpage button>span[class*=Select-module_buttonLabel]{color:#666}.paatokset-search--decisions .DateSelect__predefined-ranges-container+button,.paatokset-search-wrapper .DateSelect__predefined-ranges-container+button,.paatokset-search--frontpage .DateSelect__predefined-ranges-container+button{border-top-color:#ccc}.paatokset-search--decisions .DateSelect__predefined-ranges-container+button:hover,.paatokset-search-wrapper .DateSelect__predefined-ranges-container+button:hover,.paatokset-search--frontpage .DateSelect__predefined-ranges-container+button:hover{background-color:#000;border-color:#000}.paatokset-search--decisions .search-autocomplete,.paatokset-search-wrapper .search-autocomplete,.paatokset-search--frontpage .search-autocomplete{border:2px solid #000;border-top-color:#000;border-top-width:2px;border-top-color:#ccc;border-top-width:1px;position:absolute;left:0;right:0}.paatokset-search--decisions .search-autocomplete__wrapper,.paatokset-search-wrapper .search-autocomplete__wrapper,.paatokset-search--frontpage .search-autocomplete__wrapper{position:relative;z-index:10}.paatokset-search--decisions .search-autocomplete__item,.paatokset-search-wrapper .search-autocomplete__item,.paatokset-search--frontpage .search-autocomplete__item{font-size:16px;padding:.75rem 1rem;cursor:pointer}.paatokset-search--frontpage div[class*=SearchBarWrapper_SearchBarWrapper]{max-width:100%}.paatokset-search--frontpage button[class*=SubmitButton_SubmitButton__desktop]{margin-left:24px}.issue__wrapper .ajax-progress-throbber{display:none}.issue__meetings-container label{font-size:16px}.issue__meetings-dropdown{border:2px solid gray;margin-bottom:32px}.issue__meetings-dropdown .hds-button{position:relative;width:100%;border:none;color:#000;justify-content:flex-start;overflow:hidden}.issue__meetings-dropdown .hds-button:focus,.issue__meetings-dropdown .hds-button:hover{background-color:rgba(0,0,0,0)}.issue__meetings-dropdown .hds-button:focus:hover{color:#000}.issue__meetings-dropdown .hds-button[disabled] .hel-icon.hel-icon--angle-down{display:none}.issue__meetings-dropdown .hds-button .hel-icon.hel-icon--angle-down{margin-left:auto}.issue__meetings-dropdown .hds-button .hds-button__label{text-align:left;padding-left:22px}.issue__meetings-dropdown .hds-button::before{content:"";position:absolute;left:0;width:0;height:0;border-top:26px solid rgba(0,0,0,0);border-bottom:26px solid rgba(0,0,0,0);border-left:20px solid}.issue__meetings-dropdown .hds-button::after{content:none}.issue__meetings-dropdown:focus,.issue__meetings-dropdown[focus-within]{border:2px solid #000}.issue__meetings-dropdown:focus,.issue__meetings-dropdown:focus-within{border:2px solid #000}.issue__meetings-dropdown.open .hds-button{border-bottom:1px solid;border-color:gray}.issue__meetings-dropdown.open .hds-button .hel-icon.hel-icon--angle-down{transform:rotate(180deg)}.issue__meetings-dropdown .option{margin-top:0;font-size:16px;height:52px;display:flex;align-items:center;padding-left:30px;position:relative}.issue__meetings-dropdown .option a:hover{text-decoration:none}.issue__meetings-dropdown .option:before{content:"";position:absolute;left:0;width:0;height:0;border-top:26px solid rgba(0,0,0,0);border-bottom:26px solid rgba(0,0,0,0);border-left:20px solid #000}.issue__meetings-dropdown .option{cursor:pointer}.issue__meetings-dropdown .option:not(.selected):hover{background-color:#000}.issue__meetings-dropdown .option:not(.selected):hover a{color:#fff}.issue__meetings-dropdown .option:focus{border:2px solid #000}.issue__meetings-dropdown .option.selected{background-color:#ccc}.issue__meetings-select{width:100%;list-style:none;display:none;padding-top:0;margin-top:0;margin-bottom:0;padding-left:0;overflow-x:scroll;-ms-overflow-style:none;scrollbar-width:none;position:relative;z-index:2;background:#fff}.issue__meetings-select .paatokset__link-plain:hover{color:inherit}.issue__meetings-select::-webkit-scrollbar{display:none}.issue__meetings-labels{display:flex;flex-direction:column-reverse}@media(min-width: 992px){.issue__meetings-labels{flex-direction:row;align-items:center}}.new-handlings-warning__wrapper .warning-label{visibility:hidden}.new-handlings-warning__wrapper .warning-label.visible{visibility:visible}@media(min-width: 992px){.new-handlings-warning__wrapper{margin-left:auto}}.hero--paatokset-search-bar{margin-bottom:32px}@media(min-width: 1248px){.hero--paatokset-search-bar{margin-bottom:64px}}.hero--paatokset-search-bar .hero__text-content{padding-top:48px;padding-bottom:48px}.paatokset__search-form .hds-text-input__label{font-weight:bold}.paatokset__search-form .hds-text-input__input-wrapper{display:block}@media(min-width: 1248px){.paatokset__search-form .hds-text-input__input-wrapper{display:flex;align-items:flex-end}}.paatokset__search-form .hds-text-input__input-wrapper .form-item-hds-text-input__input{width:100%}.paatokset__search-form input[type=submit]{width:100%;margin-bottom:16px;height:var(--input-height);background-color:#000;background-image:none;text-shadow:none;--focus-outline-color: var(--color-coat-of-arms)}.paatokset__search-form input[type=submit]:hover{background-color:#fff;border-color:#000;color:#000}@media(min-width: 1248px){.paatokset__search-form input[type=submit]{max-width:258px;margin-left:24px}}.paatokset__search-form .advanced-search-link-container{display:flex;justify-content:flex-end;align-items:center}@media(min-width: 1248px){.paatokset__search-form .advanced-search-link-container{max-width:894px}}@media(min-width: 1248px){.paatokset__search-form .advanced-fields-container{display:flex;flex-wrap:wrap;justify-content:space-between;max-width:894px}}.paatokset__search-form .advanced-fields-container label{display:none}@media(min-width: 1248px){.paatokset__search-form .advanced-fields-container label{display:inline;font-weight:bold}}.paatokset__search-form .advanced-fields-container select{width:100%}@media(min-width: 1248px){.paatokset__search-form .advanced-fields-container select{max-width:282px}}.paatokset__search-form .advanced-search__tags-container{border-top:1px solid #000;display:flex;align-items:center;padding-top:10px}.paatokset__search-form .advanced-search__tags-container>*{margin-right:15px}.paatokset__search-form .advanced-search__tags-container .tags-container__title{display:none}@media(min-width: 1248px){.paatokset__search-form .advanced-search__tags-container .tags-container__title{display:inline;font-weight:500}}.paatokset__search-form .advanced-search__search-watcher{width:100%}.paragraph-content>*:last-child{margin-bottom:0}.hero__title+.hero__description{margin-top:56px}.news-liftups{margin-top:64px}@media(min-width: 992px){.news-liftups{margin-top:128px}}.news-liftups h2{margin-bottom:48px}.news-liftups a{text-decoration:none}.news-liftups a:hover h3{text-decoration:underline}.news-liftups a:hover .hel-icon{transform:translate(10px)}.news-liftups a .hel-icon{transition:all .2s ease-in-out}@media(min-width: 1248px){.news-liftups .liftups__wrapper{display:flex;justify-content:space-between}}.news-liftups .liftups-container--main{margin-bottom:16px}@media(min-width: 1248px){.news-liftups .liftups-container--main{max-width:600px}}.news-liftups .liftup--main h3{font-weight:500}.news-liftups .liftup--main .liftup--lead{margin-bottom:22px}.news-liftups .liftup--main img{margin-bottom:32px}.news-liftups .liftup--main .liftup__published-date{display:inline-block;margin-bottom:8px}.news-liftups .liftup--main i{display:block;width:48px;height:48px}.news-liftups .liftups-container--secondary h3{font-size:1.25rem;margin-bottom:8px;margin-top:0;font-weight:500}@media(min-width: 768px){.news-liftups .liftups-container--secondary h3{font-size:1.5rem}}@media(min-width: 1248px){.news-liftups .liftups-container--secondary{max-width:486px}}.news-liftups .liftup--secondary{border-top:1px solid #e2e2e2;padding-top:24px;padding-bottom:24px}.news-liftups .liftup__published-date{font-size:.875rem}@media(min-width: 768px){.tools__container{margin-top:16px}}@media(min-width: 768px){.breadcrumb__container+.tools__container{margin-bottom:20px;margin-top:-8px}}.ajax-progress,.ajax-progress-throbber,.ajax-progress-fullscreen{background:rgba(255,255,255,.6);border-radius:0;height:100%;left:0;margin:0;opacity:1;overflow:hidden;padding:0;position:fixed;text-indent:-99999em;top:0;width:100%;z-index:999999}.ajax-progress-throbber:before,.ajax-progress-fullscreen:before{animation:spin .8s infinite linear;border-color:#4a4a49 rgba(0,0,0,0) #4a4a49 rgba(0,0,0,0);border-radius:120px;border-style:solid;border-width:10px;bottom:0;content:" ";display:block;height:120px;left:0;margin:auto;overflow:hidden;position:absolute;right:0;text-indent:-99999em;top:0;width:120px}@keyframes spin{to{transform:rotate(360deg)}}.paatokset-button-link{color:#000;width:100%;font-weight:500;display:flex;align-items:center;text-decoration:none}.paatokset-button-link i,.paatokset-button-link span{margin-right:14px}.paatokset-button-link .hel-icon{width:var(--spacing-m);height:var(--spacing-m)}.paatokset-button-link:hover{text-decoration:underline}.paatokset__link-plain{color:#000;text-decoration:none}.paatokset__link-plain:hover{text-decoration:underline}.login-link{font-size:1rem;align-items:center;display:inline-flex;line-height:1;text-decoration:none}.login-link>svg{margin-right:8px}.login-link:hover,.login-link:focus{text-decoration:none}:root{--color-sumu: #9fc9eb;--color-hopea: #dedfe1;--color-suomenlinna: #f5a3c7;--color-kupari: #00d7a7}.issue-content__policymaker-label.color-sumu,.policymaker-row__color.color-sumu,.frontpage-calendar__item .color-line.color-sumu,.policymaker-card__color-title.color-sumu{background-color:#9fc9eb}.issue-content__policymaker-label.color-hopea,.policymaker-row__color.color-hopea,.frontpage-calendar__item .color-line.color-hopea,.policymaker-card__color-title.color-hopea{background-color:#dedfe1}.issue-content__policymaker-label.color-suomenlinna,.policymaker-row__color.color-suomenlinna,.frontpage-calendar__item .color-line.color-suomenlinna,.policymaker-card__color-title.color-suomenlinna{background-color:#f5a3c7}.issue-content__policymaker-label.color-engel,.policymaker-row__color.color-engel,.frontpage-calendar__item .color-line.color-engel,.policymaker-card__color-title.color-engel{background-color:#ffe977}.issue-content__policymaker-label.color-kupari,.policymaker-row__color.color-kupari,.frontpage-calendar__item .color-line.color-kupari,.policymaker-card__color-title.color-kupari{background-color:#00d7a7}.issue__meetings-dropdown .color-sumu::before{border-left-color:#9fc9eb}.issue__meetings-dropdown .color-hopea::before{border-left-color:#dedfe1}.issue__meetings-dropdown .color-suomenlinna::before{border-left-color:#f5a3c7}.issue__meetings-dropdown .color-engel::before{border-left-color:#ffe977}.issue__meetings-dropdown .color-kupari::before{border-left-color:#00d7a7}.search-link{font-size:1rem;align-items:center;display:inline-flex;line-height:1;text-decoration:none}.search-link>svg{margin-right:4px}.search-link:hover,.search-link:focus{text-decoration:none}.skip-link.focusable:focus{font-weight:500;background-color:#fff;border-radius:0 0 10px 10px;color:#0061ad;display:block;left:calc(50% - 75px);min-height:20px;min-width:150px;padding:5px 20px;position:absolute;text-align:center;text-decoration:none}.system-messages{border:2px solid;box-shadow:none;margin:2rem 0;padding:1.25rem}.system-messages li{margin-top:.25rem}.system-messages li:first-child{margin-top:0}.system-messages--error,.system-messages--status,.system-messages--warning,.system-messages a{color:#fff}.system-messages a{text-decoration:underline}.system-messages em{font-weight:500;font-style:normal}.system-messages--error{background:#e98491;border-color:#ed1a3b}.system-messages--error a:hover,.system-messages--error a:focus{color:#ed1a3b}.system-messages--status{background:#7dcdc8;border-color:#00a97a}.system-messages--status a:hover,.system-messages--status a:focus{color:#00a97a}.system-messages--warning{background:#f29869;border-color:#f26522}.system-messages--warning a:hover,.system-messages--warning a:focus{color:#f26522}.user-action{font-size:1rem;align-items:center;display:inline-flex;line-height:1;text-decoration:none;text-transform:capitalize}.user-action>svg{margin-right:4px}.user-action:hover,.user-action:focus{text-decoration:none}.breadcrumb__link{white-space:nowrap}@media screen and (max-width: 768px){.breadcrumb .breadcrumb__link:last-of-type{display:block;width:100%;overflow:hidden;text-overflow:ellipsis}}.breadcrumb__link:nth-child(6),.breadcrumb__current{text-overflow:ellipsis;overflow-x:hidden;white-space:nowrap}@media(min-width: 768px){.breadcrumb__link:nth-child(6),.breadcrumb__current{display:block}}.footer-top .menu{flex-direction:column}.local-tasks{display:flex;flex-wrap:wrap;list-style:none;margin:16px -5px;padding:0}.local-tasks .local-task{margin:0}.local-tasks .local-task a{font-size:.875rem;line-height:1.125rem;background-color:#fff;border:1px solid #4a4a49;box-shadow:0 3px 6px rgba(0,0,0,.1607843137);color:#000;display:flex;margin:10px 5px;padding:.3rem .75rem;position:relative;text-align:center;text-decoration:none;transform:perspective(1px) translateZ(0);transition-duration:.1s;transition-property:background-color;width:auto}@media screen and (min-width: 992px){.local-tasks .local-task a{display:flex;max-width:none;padding:.3rem 1.5rem}}.local-tasks .local-task a:hover{background-color:#707070;box-shadow:0 8px 6px -6px rgba(0,0,0,.1);color:#fff;cursor:pointer}.local-tasks .local-task a.is-active{background-color:#707070;box-shadow:0 0 0 rgba(0,0,0,0);color:#fff;cursor:default}.navigation.contextual-region{position:static}.navigation.navigation--main--desktop{z-index:100}@media(max-width: 944px){.navigation.navigation--main--desktop{display:none;visibility:hidden}}.menu{display:flex;list-style:none;margin:0;padding:0}@media(min-width: 944px){.menu.menu--main{height:100%}}@media(min-width: 944px){.menu--main .menu__item{align-items:center;display:inline-flex;height:100%}}@media(min-width: 944px){.menu--main .menu__item:not(:first-of-type){margin-left:32px}}.menu--main .menu__item.is-active{position:relative}.menu--main .menu__item.is-active:after{background-color:#000;bottom:-16px;content:"";height:3px;left:0;position:absolute;right:0;width:100%}.menu__link{display:inline-block}@media(min-width: 944px){.menu--main .menu__link{font-size:1rem;text-decoration:none}}[data-js]~* .cssmenu-toggle-button[aria-expanded=true]::before{-webkit-mask-image:var(--hel-icon--cross);mask-image:var(--hel-icon--cross)}.header-branding .cssmenu-menu{grid-template-areas:"lang" "back" "nav" "footer"}.mmenu__back{align-items:start;background-color:#fff;border:0;cursor:pointer;display:grid;grid-gap:8px;gap:8px;grid-template-areas:"icon label";grid-template-columns:40px auto;grid-template-rows:auto;justify-items:center;margin-top:-5px;padding:5px 12px;position:relative;width:100%;text-decoration:none}.mmenu__back .icon-wrapper{background:#f7f7f8;content:"";display:block;grid-area:icon;height:40px;width:40px}.mmenu__back .hel-icon--angle-right{width:32px;height:32px;transform:rotate(180deg);margin-left:3px;margin-top:3px}.mmenu__back:hover,.mmenu__back:active{text-decoration:underline}.mmenu__back:hover.hel-icon,.mmenu__back:active.hel-icon{transform:translateX(-4px)}.mmenu__back:focus,.mmenu__back:active{outline:3px solid #000;outline-offset:-3px}.mmenu__back:focus::before,.mmenu__back:active::before{transform:translateX(-4px)}.mmenu__back-wrapper{color:#000;grid-area:label;justify-self:start;margin-top:8px;font-weight:500;font-size:1rem;padding-left:10px} From a9fd686bfbe14f069a4fac795a4f18ec06f62226 Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Tue, 24 Oct 2023 12:33:04 +0300 Subject: [PATCH 20/21] UHF-8858: fix typo --- .../src/Commands/AhjoAggregatorCommands.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/modules/custom/paatokset_ahjo_proxy/src/Commands/AhjoAggregatorCommands.php b/public/modules/custom/paatokset_ahjo_proxy/src/Commands/AhjoAggregatorCommands.php index 85477bbf5..b7fe33fdf 100644 --- a/public/modules/custom/paatokset_ahjo_proxy/src/Commands/AhjoAggregatorCommands.php +++ b/public/modules/custom/paatokset_ahjo_proxy/src/Commands/AhjoAggregatorCommands.php @@ -3187,7 +3187,7 @@ public function fixPolicymakerReferences(): void { } } - \Drupal::logger('paatokset_ahjo_proxy')->info("Fixed @fixed of detected @all policymaers", [ + \Drupal::logger('paatokset_ahjo_proxy')->info("Fixed @fixed of detected @all policymakers", [ '@fixed' => $count, '@all' => count($nids), ]); From 02a02cbd66f1463fa2169b0a53d6c6b69e0954aa Mon Sep 17 00:00:00 2001 From: Santeri Hurnanen Date: Tue, 24 Oct 2023 12:58:20 +0300 Subject: [PATCH 21/21] UHF-8858: do not crash migration if ahjo returns invalid organization --- .../Plugin/migrate/source/AhjoOrganizationSource.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoOrganizationSource.php b/public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoOrganizationSource.php index 1a1f9aacc..6c595172d 100644 --- a/public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoOrganizationSource.php +++ b/public/modules/custom/paatokset_ahjo_api/src/Plugin/migrate/source/AhjoOrganizationSource.php @@ -85,6 +85,9 @@ protected function initializeIterator(): \Iterator { ]); $organization = $this->getOrganization($id, $langcode); + if ($organization === NULL) { + continue; + } $title = Unicode::truncate($organization['Name'], '255', TRUE, TRUE); @@ -115,8 +118,11 @@ protected function initializeIterator(): \Iterator { /** * Get organization info from Ahjo. + * + * @return ?array + * NULL if received invalid data from Ahjo. */ - private function getOrganization(string $id, string $langcode): array { + private function getOrganization(string $id, string $langcode): ?array { if (!$this->ahjoProxy->isOperational()) { $this->logger->error('Ahjo Proxy is not operational, exiting.'); throw new MigrateException('Ahjo Proxy is not operational, exiting.'); @@ -142,7 +148,7 @@ private function getOrganization(string $id, string $langcode): array { $this->logger->error('Data not found for @id', [ '@id' => $id, ]); - throw new MigrateException("Data not found for $id"); + return NULL; } return $organization;