Issue #3202579 by paul121, pcambra, mstenta: Map asset details

This commit is contained in:
Michael Stenta 2021-06-09 11:55:36 -04:00
commit 46c70131ff
14 changed files with 555 additions and 26 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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 `<a href="${url}">${name}</a>`;
}
// 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 !== '') {

View File

@ -0,0 +1,9 @@
langcode: en
status: true
dependencies:
module:
- asset
id: asset.map_popup
label: 'Map popup'
targetEntityType: asset
cache: true

View File

@ -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

View File

@ -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' => '<p>' . implode(' | ', $links) . '</p>',
'#weight' => -100,
];
return $build;
}

View File

@ -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

View File

@ -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();
});
}
});
}
};
}());

View File

@ -0,0 +1,40 @@
<?php
namespace Drupal\farm_ui_map\Controller;
use Drupal\asset\Entity\AssetInterface;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\Response;
/**
* Returns response for the map popup.
*/
class MapPopup extends ControllerBase {
/**
* Set the display mode used.
*
* @var string
*/
protected string $displayMode = 'map_popup';
/**
* Display an asset entity standalone in the map popup.
*
* @param \Drupal\asset\Entity\AssetInterface $asset
* The asset entity.
*
* @return \Symfony\Component\HttpFoundation\Response
* The response to display in the popup.
*/
public function display(AssetInterface $asset) : Response {
$response = new Response();
$view_builder = $this->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;
}
}

View File

@ -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().
*/