diff --git a/modules/asset/animal/config/optional/core.entity_view_display.asset.animal.map_popup.yml b/modules/asset/animal/config/optional/core.entity_view_display.asset.animal.map_popup.yml new file mode 100644 index 000000000..9f5d11050 --- /dev/null +++ b/modules/asset/animal/config/optional/core.entity_view_display.asset.animal.map_popup.yml @@ -0,0 +1,60 @@ +langcode: en +status: true +dependencies: + config: + - asset.type.animal + - core.entity_view_mode.asset.map_popup + module: + - options + - text +id: asset.animal.map_popup +targetEntityType: asset +bundle: animal +mode: map_popup +content: + animal_type: + label: inline + type: entity_reference_label + weight: 1 + settings: + link: false + region: content + third_party_settings: { } + flag: + label: inline + type: list_default + weight: 0 + region: content + settings: { } + third_party_settings: { } + location: + type: entity_reference_label + weight: 3 + region: content + label: inline + settings: + link: true + third_party_settings: { } + notes: + label: inline + type: text_default + weight: 2 + region: content + settings: { } + third_party_settings: { } +hidden: + birthdate: true + data: true + file: true + geometry: true + id_tag: true + image: true + intrinsic_geometry: true + is_castrated: true + is_fixed: true + is_location: true + nickname: true + parent: true + sex: true + status: true + uid: true diff --git a/modules/asset/equipment/config/optional/core.entity_view_display.asset.equipment.map_popup.yml b/modules/asset/equipment/config/optional/core.entity_view_display.asset.equipment.map_popup.yml new file mode 100644 index 000000000..1bec970aa --- /dev/null +++ b/modules/asset/equipment/config/optional/core.entity_view_display.asset.equipment.map_popup.yml @@ -0,0 +1,72 @@ +langcode: en +status: true +dependencies: + config: + - asset.type.equipment + - core.entity_view_mode.asset.map_popup + module: + - options + - text +id: asset.equipment.map_popup +targetEntityType: asset +bundle: equipment +mode: map_popup +content: + flag: + label: inline + type: list_default + weight: 0 + region: content + settings: { } + third_party_settings: { } + location: + type: entity_reference_label + weight: 5 + region: content + label: inline + settings: + link: true + third_party_settings: { } + manufacturer: + label: inline + type: string + weight: 1 + region: content + settings: + link_to_entity: false + third_party_settings: { } + model: + label: inline + type: string + weight: 2 + region: content + settings: + link_to_entity: false + third_party_settings: { } + notes: + label: inline + type: text_default + weight: 4 + region: content + settings: { } + third_party_settings: { } + serial_number: + label: inline + type: string + weight: 3 + region: content + settings: + link_to_entity: false + third_party_settings: { } +hidden: + data: true + file: true + geometry: true + id_tag: true + image: true + intrinsic_geometry: true + is_fixed: true + is_location: true + parent: true + status: true + uid: true diff --git a/modules/asset/land/config/optional/core.entity_view_display.asset.land.map_popup.yml b/modules/asset/land/config/optional/core.entity_view_display.asset.land.map_popup.yml new file mode 100644 index 000000000..f052faa8d --- /dev/null +++ b/modules/asset/land/config/optional/core.entity_view_display.asset.land.map_popup.yml @@ -0,0 +1,55 @@ +langcode: en +status: true +dependencies: + config: + - asset.type.land + - core.entity_view_mode.asset.map_popup + module: + - options + - text +id: asset.land.map_popup +targetEntityType: asset +bundle: land +mode: map_popup +content: + flag: + label: inline + type: list_default + weight: 0 + region: content + settings: { } + third_party_settings: { } + land_type: + label: inline + type: list_default + weight: 1 + region: content + settings: { } + third_party_settings: { } + location: + type: entity_reference_label + weight: 3 + region: content + label: inline + settings: + link: true + third_party_settings: { } + notes: + label: inline + type: text_default + weight: 2 + region: content + settings: { } + third_party_settings: { } +hidden: + data: true + file: true + geometry: true + id_tag: true + image: true + intrinsic_geometry: true + is_fixed: true + is_location: true + parent: true + status: true + uid: true diff --git a/modules/asset/plant/config/optional/core.entity_view_display.asset.plant.map_popup.yml b/modules/asset/plant/config/optional/core.entity_view_display.asset.plant.map_popup.yml new file mode 100644 index 000000000..1f8d6f3e5 --- /dev/null +++ b/modules/asset/plant/config/optional/core.entity_view_display.asset.plant.map_popup.yml @@ -0,0 +1,57 @@ +langcode: en +status: true +dependencies: + config: + - asset.type.plant + - core.entity_view_mode.asset.map_popup + module: + - options + - text +id: asset.plant.map_popup +targetEntityType: asset +bundle: plant +mode: map_popup +content: + flag: + label: inline + type: list_default + weight: 0 + region: content + settings: { } + third_party_settings: { } + location: + type: entity_reference_label + weight: 3 + region: content + label: inline + settings: + link: true + third_party_settings: { } + notes: + label: inline + type: text_default + weight: 2 + region: content + settings: { } + third_party_settings: { } + plant_type: + label: inline + type: entity_reference_label + weight: 1 + settings: + link: false + region: content + third_party_settings: { } +hidden: + data: true + file: true + geometry: true + id_tag: true + image: true + intrinsic_geometry: true + is_fixed: true + is_location: true + parent: true + season: true + status: true + uid: true diff --git a/modules/asset/structure/config/optional/core.entity_view_display.asset.structure.map_popup.yml b/modules/asset/structure/config/optional/core.entity_view_display.asset.structure.map_popup.yml new file mode 100644 index 000000000..4126beb51 --- /dev/null +++ b/modules/asset/structure/config/optional/core.entity_view_display.asset.structure.map_popup.yml @@ -0,0 +1,55 @@ +langcode: en +status: true +dependencies: + config: + - asset.type.structure + - core.entity_view_mode.asset.map_popup + module: + - options + - text +id: asset.structure.map_popup +targetEntityType: asset +bundle: structure +mode: map_popup +content: + flag: + label: inline + type: list_default + weight: 0 + region: content + settings: { } + third_party_settings: { } + location: + type: entity_reference_label + weight: 3 + region: content + label: inline + settings: + link: true + third_party_settings: { } + notes: + label: inline + type: text_default + weight: 2 + region: content + settings: { } + third_party_settings: { } + structure_type: + label: inline + type: list_default + weight: 1 + region: content + settings: { } + third_party_settings: { } +hidden: + data: true + file: true + geometry: true + id_tag: true + image: true + intrinsic_geometry: true + is_fixed: true + is_location: true + parent: true + status: true + uid: true diff --git a/modules/core/location/config/optional/views.view.farm_asset_geojson.yml b/modules/core/location/config/optional/views.view.farm_asset_geojson.yml index 58f16751c..1c81f9f8d 100644 --- a/modules/core/location/config/optional/views.view.farm_asset_geojson.yml +++ b/modules/core/location/config/optional/views.view.farm_asset_geojson.yml @@ -278,6 +278,59 @@ display: field_api_classes: false entity_type: asset plugin_id: asset_geometry + view_asset: + id: view_asset + table: asset + field: view_asset + relationship: none + group_type: group + admin_label: '' + label: url + 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 + text: view + output_url_as_text: true + absolute: false + entity_type: asset + plugin_id: entity_link filters: { } sorts: { } header: { } @@ -561,6 +614,59 @@ display: field_api_classes: false entity_type: asset plugin_id: asset_geometry + view_asset: + id: view_asset + table: asset + field: view_asset + relationship: none + group_type: group + admin_label: '' + label: url + 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 + text: view + output_url_as_text: true + absolute: false + entity_type: asset + plugin_id: entity_link defaults: fields: false cache_metadata: diff --git a/modules/core/map/js/farmOS.map.behaviors.popup.js b/modules/core/map/js/farmOS.map.behaviors.popup.js index 44efeab62..d7b20c3de 100644 --- a/modules/core/map/js/farmOS.map.behaviors.popup.js +++ b/modules/core/map/js/farmOS.map.behaviors.popup.js @@ -2,6 +2,18 @@ farmOS.map.behaviors.popup = { attach: function (instance) { + // Helper function to build the feature name as a link. + const featureName = function (feature) { + // Bail if either the name or url aren't defined. + const name = feature.get('name'); + const url = feature.get('url'); + if (name === undefined || url === undefined) { + return name; + } + // Build a link with the url and name. + return `${name}`; + } + // Create a popup and add it to the instance for future reference. instance.popup = instance.addPopup(function (event) { var content = ''; @@ -14,8 +26,9 @@ if (features !== undefined) { var names = []; features.forEach(function (item) { - if (item.get('name') !== undefined) { - names.push(item.get('name')); + const name = featureName(item); + if (name !== undefined) { + names.push(name); } }); if (names.length !== 0) { @@ -24,7 +37,7 @@ feature.set('name', names.length + ' item(s):'); } - var name = feature.get('name') || ''; + var name = featureName(feature) || ''; var description = feature.get('description') || ''; var measurement = instance.measureGeometry(feature.getGeometry(), instance.units); if (name !== '' || measurement !== '' || description !== '') { diff --git a/modules/ui/map/config/install/core.entity_view_mode.asset.map_popup.yml b/modules/ui/map/config/install/core.entity_view_mode.asset.map_popup.yml new file mode 100644 index 000000000..26dbea65f --- /dev/null +++ b/modules/ui/map/config/install/core.entity_view_mode.asset.map_popup.yml @@ -0,0 +1,9 @@ +langcode: en +status: true +dependencies: + module: + - asset +id: asset.map_popup +label: 'Map popup' +targetEntityType: asset +cache: true diff --git a/modules/ui/map/farm_ui_map.libraries.yml b/modules/ui/map/farm_ui_map.libraries.yml index 0830a819c..276e6f79e 100644 --- a/modules/ui/map/farm_ui_map.libraries.yml +++ b/modules/ui/map/farm_ui_map.libraries.yml @@ -2,4 +2,5 @@ behavior_asset_type_layers: js: js/farmOS.map.behaviors.asset_type_layers.js: { } dependencies: + - farm_map/behavior_popup - farm_map/farm_map diff --git a/modules/ui/map/farm_ui_map.module b/modules/ui/map/farm_ui_map.module index c2f4d4d89..9a4b7a358 100644 --- a/modules/ui/map/farm_ui_map.module +++ b/modules/ui/map/farm_ui_map.module @@ -5,6 +5,10 @@ * The farmOS UI Map module. */ +use Drupal\Core\Entity\Display\EntityViewDisplayInterface; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Link; + /** * Implements hook_farm_dashboard_panes(). */ @@ -30,3 +34,45 @@ function farm_ui_map_module_implements_alter(&$implementations, $hook) { $implementations = array_merge([$module => $group], $implementations); } } + +/** + * Implements hook_ENTITY_TYPE_view(). + */ +function farm_ui_map_asset_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) { + /** @var \Drupal\farm_entity\Plugin\Asset\AssetType\AssetTypeInterface $entity */ + + // Bail if not the map_popup view mode. + if ($view_mode !== 'map_popup') { + return $build; + } + + // The default view mode is used if a map_popup view mode is not provided. + // Alter the default view mode to only include common fields. + $view_mode_options = \Drupal::service('entity_display.repository')->getViewModeOptionsByBundle('asset', $entity->bundle()); + if (!array_key_exists($view_mode, $view_mode_options)) { + $common_fields = ['name', 'type', 'flag', 'notes', 'location']; + $build = array_filter($build, function ($key) use ($common_fields) { + return strpos($key, '#') === 0 || in_array($key, $common_fields); + }, ARRAY_FILTER_USE_KEY); + } + + // Build links. + $links = []; + + // Build link to view assets located here. + // Only show this link on location assets. + if (\Drupal::service('asset.location')->isLocation($entity)) { + $links[] = Link::createFromRoute(t('View assets in this location'), 'view.farm_asset.page_location', ['asset' => $entity->id()])->toString(); + } + + // Build link to view logs referencing the asset. + $links[] = Link::createFromRoute(t('View logs'), 'view.farm_log.page_asset', ['asset' => $entity->id(), 'log_type' => 'all'])->toString(); + + // Render links in a list. + $build['links'] = [ + '#markup' => '

' . implode(' | ', $links) . '

', + '#weight' => -100, + ]; + + return $build; +} diff --git a/modules/ui/map/farm_ui_map.routing.yml b/modules/ui/map/farm_ui_map.routing.yml new file mode 100644 index 000000000..b9ff10739 --- /dev/null +++ b/modules/ui/map/farm_ui_map.routing.yml @@ -0,0 +1,11 @@ +farm_ui_map.asset.map_popup: + path: '/asset/{asset}/map-popup' + defaults: + _controller: '\Drupal\farm_ui_map\Controller\MapPopup::display' + requirements: + _entity_access: asset.view + asset: \d+ + options: + parameters: + asset: + type: entity:asset diff --git a/modules/ui/map/js/farmOS.map.behaviors.asset_type_layers.js b/modules/ui/map/js/farmOS.map.behaviors.asset_type_layers.js index bdf116228..af8ec6ce9 100644 --- a/modules/ui/map/js/farmOS.map.behaviors.asset_type_layers.js +++ b/modules/ui/map/js/farmOS.map.behaviors.asset_type_layers.js @@ -59,30 +59,23 @@ }); } - // @todo: Display area details in popup. // Load area details via AJAX when an area popup is displayed. - // instance.popup.on('farmOS-map.popup', function (event) { - // var area_details = jQuery('.ol-popup-description .area-details'); - // if (area_details.attr('id') === undefined) { - // return; - // } - // area_details.html('test!'); - // var area_id = area_details.attr('id').replace('area-details-', ''); - // if (area_id) { - // area_details.html('Loading area details...'); - // jQuery.getJSON(Drupal.settings.farm_map.base_path + 'farm/area/' + area_id + '/details', function(data) { - // if (data) { - // area_details.html(data); - // var position = event.target.getPosition(); - // event.target.setPosition(); - // event.target.setPosition(position); - // } - // else { - // area_details.html(''); - // } - // }); - // } - // }); + instance.popup.on('farmOS-map.popup', function (event) { + var link = event.target.element.querySelector('.ol-popup-name a'); + if (link) { + var assetLink = link.getAttribute('href') + var description = event.target.element.querySelector('.ol-popup-description'); + description.innerHTML = 'Loading asset details...'; + fetch(assetLink + '/map-popup') + .then((response) => { + return response.text(); + }) + .then((html) => { + description.innerHTML = html; + instance.popup.panIntoView(); + }); + } + }); } }; }()); diff --git a/modules/ui/map/src/Controller/MapPopup.php b/modules/ui/map/src/Controller/MapPopup.php new file mode 100644 index 000000000..ab64aff3b --- /dev/null +++ b/modules/ui/map/src/Controller/MapPopup.php @@ -0,0 +1,40 @@ +entityTypeManager()->getViewBuilder($asset->getEntityTypeId()); + $build = $view_builder->view($asset, $this->displayMode); + // Render already exposes cache metadata, so no need to do it twice. + $response->setContent(render($build)); + return $response; + } + +} diff --git a/modules/ui/theme/farm_ui_theme.module b/modules/ui/theme/farm_ui_theme.module index 99cf87eb4..bddddc96e 100644 --- a/modules/ui/theme/farm_ui_theme.module +++ b/modules/ui/theme/farm_ui_theme.module @@ -25,6 +25,17 @@ function farm_ui_theme_preprocess_block(&$variables) { } } +/** + * Implements hook_preprocess_HOOK(). + */ +function farm_ui_theme_preprocess_farm_map(&$variables) { + + // We need to add the flag CSS to pages with maps in them because a user MAY + // click a popup which MAY have flags in it. Otherwise the flags do not get + // styled. + $variables['#attached']['library'] = 'farm_ui_theme/flag'; +} + /** * Implements hook_preprocess_HOOK(). */