Perform location hierarchy changes in form submit instead of AJAX.
This commit is contained in:
parent
3fd2f9c893
commit
662f7801e0
|
@ -39,171 +39,25 @@
|
|||
|
||||
var changes = {}
|
||||
tree.on('node.drop', function(event, source, target, index) {
|
||||
var destination = (target === null) ? settings.asset_parent : target.uuid
|
||||
var new_parent = (target === null) ? settings.asset_parent : target.asset_id
|
||||
if (!changes.hasOwnProperty(source.id)) {
|
||||
if (source.original_parent !== destination) {
|
||||
if (source.original_parent !== new_parent) {
|
||||
changes[source.id] = {
|
||||
'uuid': source.uuid,
|
||||
'asset_id': source.asset_id,
|
||||
'original_parent': source.original_parent,
|
||||
'original_type': source.original_type,
|
||||
'destination': destination,
|
||||
'type': (target === null) ? settings.asset_parent_type : target.type,
|
||||
'new_parent': new_parent,
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (changes[source.id].original_parent !== destination) {
|
||||
changes[source.id].destination = destination
|
||||
if (changes[source.id].original_parent !== new_parent) {
|
||||
changes[source.id].new_parent = new_parent
|
||||
}
|
||||
else {
|
||||
delete changes[source.id]
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
$('input#edit-reset').on('click', function(event) {
|
||||
event.preventDefault()
|
||||
// Reset the changes so nothing is pushed accidentally.
|
||||
changes = {}
|
||||
// Reset the tree to the original status.
|
||||
tree.reload()
|
||||
tree.nodes().expand()
|
||||
domTree.clearSelection()
|
||||
})
|
||||
|
||||
$('input#edit-save').on('click', function(event) {
|
||||
event.preventDefault()
|
||||
var button = $(this)
|
||||
var messages = new Drupal.Message()
|
||||
messages.clear()
|
||||
|
||||
var entries = Object.entries(changes)
|
||||
if (entries.length <= 0) {
|
||||
messages.add(Drupal.t('No changes to save'), { type: 'status' })
|
||||
return
|
||||
}
|
||||
|
||||
button.attr('disabled',true)
|
||||
|
||||
var token = ''
|
||||
$.ajax({
|
||||
async: false,
|
||||
url: Drupal.url('session/token'),
|
||||
success(data) {
|
||||
if (data) {
|
||||
token = data
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
// Build an array of ajax requests.
|
||||
var requests = [];
|
||||
for (var [treeUuid, item] of entries) {
|
||||
if (item.destination === '' && item.original_parent !== '') {
|
||||
var deleteItem = {
|
||||
'data': [
|
||||
{
|
||||
'type': 'asset--' + item.original_type,
|
||||
'id': item.original_parent,
|
||||
}
|
||||
]
|
||||
}
|
||||
requests.push($.ajax({
|
||||
type: 'DELETE',
|
||||
cache: false,
|
||||
headers: {
|
||||
'X-CSRF-Token': token,
|
||||
},
|
||||
url: '/api/asset/' + item.original_type + '/' + item.uuid + '/relationships/parent',
|
||||
data: JSON.stringify(deleteItem),
|
||||
contentType: 'application/vnd.api+json',
|
||||
success: function success(data) {
|
||||
messages.clear()
|
||||
messages.add(Drupal.t('Locations have been saved'), { type: 'status' })
|
||||
button.attr('disabled',false)
|
||||
delete changes.treeUuid
|
||||
},
|
||||
error: function error(xmlhttp) {
|
||||
var e = new Drupal.AjaxError(xmlhttp)
|
||||
messages.clear()
|
||||
messages.add(e.message, { type: 'error' })
|
||||
button.attr('disabled',false)
|
||||
}
|
||||
}));
|
||||
}
|
||||
else {
|
||||
var patch = {
|
||||
'data': [
|
||||
{
|
||||
'type': 'asset--' + item.type,
|
||||
'id': item.destination,
|
||||
}
|
||||
]
|
||||
}
|
||||
requests.push($.ajax({
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
headers: {
|
||||
'X-CSRF-Token': token,
|
||||
},
|
||||
url: '/api/asset/' + item.type + '/' + item.uuid + '/relationships/parent',
|
||||
data: JSON.stringify(patch),
|
||||
contentType: 'application/vnd.api+json',
|
||||
success: function success(data) {
|
||||
if (item.original_parent !== settings.asset_parent) {
|
||||
var deleteItem = {
|
||||
'data': [
|
||||
{
|
||||
'type': 'asset--' + item.original_type,
|
||||
'id': item.original_parent,
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
requests.push($.ajax({
|
||||
type: 'DELETE',
|
||||
cache: false,
|
||||
headers: {
|
||||
'X-CSRF-Token': token,
|
||||
},
|
||||
url: '/api/asset/' + item.original_type + '/' + item.uuid + '/relationships/parent',
|
||||
data: JSON.stringify(deleteItem),
|
||||
contentType: 'application/vnd.api+json',
|
||||
success: function success(data) {
|
||||
messages.clear()
|
||||
messages.add(Drupal.t('Locations have been saved'), { type: 'status' })
|
||||
button.attr('disabled',false)
|
||||
delete changes.treeUuid
|
||||
},
|
||||
error: function error(xmlhttp) {
|
||||
var e = new Drupal.AjaxError(xmlhttp)
|
||||
messages.clear()
|
||||
messages.add(e.message, { type: 'error' })
|
||||
button.attr('disabled',false)
|
||||
}
|
||||
}))
|
||||
}
|
||||
else {
|
||||
messages.clear()
|
||||
messages.add(Drupal.t('Locations have been saved'), { type: 'status' })
|
||||
button.attr('disabled',false)
|
||||
}
|
||||
},
|
||||
error: function error(xmlhttp) {
|
||||
var e = new Drupal.AjaxError(xmlhttp)
|
||||
messages.clear()
|
||||
messages.add(e.message, { type: 'error' })
|
||||
button.attr('disabled',false)
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// Refresh the page once all requests are completed.
|
||||
$.when.apply($, requests).done(function () {
|
||||
location.reload();
|
||||
})
|
||||
$('input[name=changes]').val(JSON.stringify(changes))
|
||||
})
|
||||
|
||||
tree.on('node.click', function(event, node) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\farm_ui_location\Form;
|
||||
|
||||
use Drupal\asset\Entity\AssetInterface;
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Core\Access\AccessResult;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Form\FormBase;
|
||||
|
@ -116,6 +117,11 @@ class LocationHierarchyForm extends FormBase {
|
|||
],
|
||||
];
|
||||
|
||||
// Create a hidden field to store hierarchy changes recorded client-side.
|
||||
$form['changes'] = [
|
||||
'#type' => 'hidden',
|
||||
];
|
||||
|
||||
// Add buttons for toggling drag and drop, saving, and resetting.
|
||||
$form['actions'] = ['#type' => 'actions'];
|
||||
$form['actions']['toggle'] = [
|
||||
|
@ -150,16 +156,14 @@ class LocationHierarchyForm extends FormBase {
|
|||
$form['#attached']['library'][] = 'farm_ui_location/locations-drag-and-drop';
|
||||
$tree = [
|
||||
[
|
||||
'uuid' => !empty($asset) ? $asset->uuid() : '',
|
||||
'asset_id' => !empty($asset) ? $asset->id() : '',
|
||||
'text' => !empty($asset) ? $asset->label() : $this->t('All locations'),
|
||||
'children' => !empty($asset) ? $this->buildTree($asset) : $this->buildTree(),
|
||||
'type' => !empty($asset) ? $asset->bundle() : '',
|
||||
'url' => !empty($asset) ? $asset->toUrl('canonical', ['absolute' => TRUE])->toString() : '/locations',
|
||||
],
|
||||
];
|
||||
$form['#attached']['drupalSettings']['asset_tree'] = $tree;
|
||||
$form['#attached']['drupalSettings']['asset_parent'] = !empty($asset) ? $asset->uuid() : '';
|
||||
$form['#attached']['drupalSettings']['asset_parent_type'] = !empty($asset) ? $asset->bundle() : '';
|
||||
$form['#attached']['drupalSettings']['asset_parent'] = !empty($asset) ? $asset->id() : '';
|
||||
|
||||
// Return the form.
|
||||
return $form;
|
||||
|
@ -184,14 +188,12 @@ class LocationHierarchyForm extends FormBase {
|
|||
if ($locations) {
|
||||
foreach ($locations as $location) {
|
||||
$element = [
|
||||
'uuid' => $location->uuid(),
|
||||
'asset_id' => $location->id(),
|
||||
'text' => $location->label(),
|
||||
'children' => $this->buildTree($location),
|
||||
'type' => $location->bundle(),
|
||||
'url' => $location->toUrl('canonical', ['absolute' => TRUE])->toString(),
|
||||
];
|
||||
$element['original_parent'] = $asset ? $asset->uuid() : '';
|
||||
$element['original_type'] = $asset ? $asset->bundle() : '';
|
||||
$element['original_parent'] = $asset ? $asset->id() : '';
|
||||
$tree[] = $element;
|
||||
}
|
||||
}
|
||||
|
@ -238,4 +240,77 @@ class LocationHierarchyForm extends FormBase {
|
|||
return $assets;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function submitForm(array &$form, FormStateInterface $form_state) {
|
||||
|
||||
// Only process the form if the "Save" button was clicked.
|
||||
if ($form_state->getTriggeringElement()['#id'] != 'edit-save') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load hierarchy changes. If there are none, do nothing.
|
||||
$changes = Json::decode($form_state->getValue('changes'));
|
||||
if (empty($changes)) {
|
||||
$this->messenger()->addStatus($this->t('No changes were made.'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Get asset storage.
|
||||
$storage = $this->entityTypeManager->getStorage('asset');
|
||||
|
||||
// Maintain a list of assets that need to be saved.
|
||||
$save_assets = [];
|
||||
|
||||
// Iterate through the changes.
|
||||
foreach ($changes as $change) {
|
||||
|
||||
// Load the asset.
|
||||
$asset = $storage->load($change['asset_id']);
|
||||
|
||||
// Remove the original parent.
|
||||
if (!empty($asset->get('parent'))) {
|
||||
/** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $parent */
|
||||
foreach ($asset->get('parent') as $delta => $parent) {
|
||||
$parent_id = $parent->getValue()['target_id'];
|
||||
if ($change['original_parent'] == $parent_id) {
|
||||
unset($asset->get('parent')[$delta]);
|
||||
if (!array_key_exists($asset->id(), $save_assets)) {
|
||||
$save_assets[$asset->id()] = $asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the new parent, if applicable.
|
||||
if (!empty($change['new_parent'])) {
|
||||
$asset->get('parent')[] = ['target_id' => $change['new_parent']];
|
||||
if (!array_key_exists($asset->id(), $save_assets)) {
|
||||
$save_assets[$asset->id()] = $asset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save assets with a revision message.
|
||||
/** @var \Drupal\asset\Entity\AssetInterface[] $save_assets */
|
||||
foreach ($save_assets as $asset) {
|
||||
$message = $this->t('Parents removed via the Locations drag and drop editor.');
|
||||
$parent_names = [];
|
||||
foreach ($asset->get('parent') as $parent) {
|
||||
$parent_names[] = $storage->load($parent->getValue()['target_id'])->label();
|
||||
}
|
||||
if (!empty($parent_names)) {
|
||||
$message = $this->t('Parents changed to %parents via the Locations drag and drop editor.', ['%parents' => implode(', ', $parent_names)]);
|
||||
}
|
||||
$asset->setNewRevision(TRUE);
|
||||
$asset->setRevisionLogMessage($message);
|
||||
$asset->save();
|
||||
}
|
||||
|
||||
// Show a summary of the results.
|
||||
$message = $this->formatPlural(count($save_assets), 'Updated the parent hierarchy of %count asset.', 'Updated the parent hierarchy of %count assets.', ['%count' => count($save_assets)]);
|
||||
$this->messenger()->addStatus($message);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue