Relation Manager Customisation Improvements (#4444)

This change allows for easy customisation of the relation manager titles and toolbar buttons.

For buttons - define your custom strings directly in the standard `toolbarButtons` syntax...

```
toolbarButtons:
    create: acme.blog::lang.subcategory.CreateButtonText
    delete: # omit the string to fall back to the default button text
```

...and the old syntax still works...

```
toolbarButtons: create|delete
```

For titles - define different strings for each mode (form, list or pivot)...

```
title:
    form: acme.blog::lang.subcategory.FormTitle
    list: acme.blog::lang.subcategory.ListTitle
```

This feature provides developer convenience, for example in this situation where I have a relation manager that is used to assign user permissions to a project:
Before
![Screenshot 2019-07-10 at 09 28 22](https://user-images.githubusercontent.com/41773797/60953626-6bc0de80-a2f5-11e9-8001-04e816ad6967.png)
After
![Screenshot 2019-07-10 at 09 32 51](https://user-images.githubusercontent.com/41773797/60953773-b9d5e200-a2f5-11e9-93a9-69238ea696aa.png)

This PR contains no breaking changes.
This commit is contained in:
Dan Harrin 2020-03-27 18:56:07 +00:00 committed by GitHub
parent 3fe1c26e66
commit cd86c62b94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 103 additions and 47 deletions

View File

@ -1477,39 +1477,79 @@ class RelationController extends ControllerBehavior
/**
* Determine the default buttons based on the model relationship type.
* @return string
* @return array|null
*/
protected function evalToolbarButtons()
{
$buttons = $this->getConfig('view[toolbarButtons]');
if ($buttons === false) {
return null;
}
elseif (is_string($buttons)) {
return array_map('trim', explode('|', $buttons));
}
elseif (is_array($buttons)) {
return $buttons;
if (!is_array($buttons)) {
if ($buttons === false) {
return null;
} elseif (is_string($buttons)) {
$buttons = array_map('trim', explode('|', $buttons));
} elseif ($this->manageMode === 'pivot') {
$buttons = ['add', 'remove'];
} else {
switch ($this->relationType) {
case 'hasMany':
case 'morphMany':
case 'morphToMany':
case 'morphedByMany':
case 'belongsToMany':
return ['create', 'add', 'delete', 'remove'];
case 'hasOne':
case 'morphOne':
case 'belongsTo':
return ['create', 'update', 'link', 'delete', 'unlink'];
}
}
}
if ($this->manageMode == 'pivot') {
return ['add', 'remove'];
$buttonText = [];
foreach ($buttons as $type => $text) {
if (is_numeric($type) || !$text) {
if (is_numeric($type) && $text) {
$type = $text;
}
switch ($type) {
case 'create':
$text = 'backend::lang.relation.create_name';
break;
case 'update':
$text = 'backend::lang.relation.update_name';
break;
case 'delete':
$text = 'backend::lang.relation.delete';
break;
case 'add':
$text = 'backend::lang.relation.add_name';
break;
case 'remove':
$text = 'backend::lang.relation.remove';
break;
case 'link':
$text = 'backend::lang.relation.link_name';
break;
case 'unlink':
$text = 'backend::lang.relation.unlink';
break;
}
}
$buttonText[$type] = $text;
}
switch ($this->relationType) {
case 'hasMany':
case 'morphMany':
case 'morphToMany':
case 'morphedByMany':
case 'belongsToMany':
return ['create', 'add', 'delete', 'remove'];
case 'hasOne':
case 'morphOne':
case 'belongsTo':
return ['create', 'update', 'link', 'delete', 'unlink'];
}
return $buttonText;
}
/**
@ -1543,28 +1583,41 @@ class RelationController extends ControllerBehavior
*/
protected function evalManageTitle()
{
if ($customTitle = $this->getConfig('manage[title]')) {
$customTitle = $this->getConfig('manage[title]');
if (is_string($customTitle)) {
return $customTitle;
}
$customTitles = is_array($customTitle) ? $customTitle : [];
switch ($this->manageMode) {
case 'pivot':
if (array_key_exists('pivot', $customTitles)) {
return $customTitles['pivot'];
} elseif ($this->eventTarget === 'button-link') {
return 'backend::lang.relation.link_a_new';
}
return 'backend::lang.relation.add_a_new';
case 'list':
if ($this->eventTarget == 'button-link') {
if (array_key_exists('list', $customTitles)) {
return $customTitles['list'];
} elseif ($this->eventTarget === 'button-link') {
return 'backend::lang.relation.link_a_new';
}
return 'backend::lang.relation.add_a_new';
case 'form':
if ($this->readOnly) {
if (array_key_exists('form', $customTitles)) {
return $customTitles['form'];
} elseif ($this->readOnly) {
return 'backend::lang.relation.preview_name';
}
elseif ($this->manageId) {
} elseif ($this->manageId) {
return 'backend::lang.relation.update_name';
}
else {
return 'backend::lang.relation.create_name';
}
return 'backend::lang.relation.create_name';
}
}

View File

@ -4,5 +4,5 @@
data-handler="onRelationButtonAdd"
href="javascript:;"
class="btn btn-sm btn-secondary oc-icon-plus">
<?= e(trans('backend::lang.relation.add_name', ['name'=>trans($relationLabel)])) ?>
<?= e(trans($text, ['name' => trans($relationLabel)])) ?>
</a>

View File

@ -4,5 +4,5 @@
data-handler="onRelationButtonCreate"
href="javascript:;"
class="btn btn-sm btn-secondary oc-icon-file">
<?= e(trans('backend::lang.relation.create_name', ['name'=>trans($relationLabel)])) ?>
<?= e(trans($text, ['name' => trans($relationLabel)])) ?>
</a>

View File

@ -5,7 +5,7 @@
data-request-confirm="<?= e(trans('backend::lang.relation.delete_confirm')) ?>"
data-request-success="$.oc.relationBehavior.changed('<?= e($this->vars['relationField']) ?>', 'deleted')"
data-stripe-load-indicator>
<?= e(trans('backend::lang.relation.delete')) ?>
<?= e(trans($text)) ?>
</button>
<?php else: ?>
<button
@ -21,6 +21,6 @@
data-trigger="#<?= $this->relationGetId('view') ?> .control-list input[type=checkbox]"
data-trigger-condition="checked"
data-stripe-load-indicator>
<?= e(trans('backend::lang.relation.delete')) ?>
<?= e(trans($text)) ?>
</button>
<?php endif ?>
<?php endif ?>

View File

@ -4,5 +4,5 @@
data-handler="onRelationButtonLink"
href="javascript:;"
class="btn btn-sm btn-secondary oc-icon-link">
<?= e(trans('backend::lang.relation.link_name', ['name'=>trans($relationLabel)])) ?>
<?= e(trans($text, ['name' => trans($relationLabel)])) ?>
</a>

View File

@ -4,7 +4,7 @@
data-request="onRelationButtonRemove"
data-request-success="$.oc.relationBehavior.changed('<?= e($this->vars['relationField']) ?>', 'removed')"
data-stripe-load-indicator>
<?= e(trans('backend::lang.relation.remove')) ?>
<?= e(trans($text)) ?>
</button>
<?php else: ?>
<button
@ -19,6 +19,6 @@
data-trigger="#<?= $this->relationGetId('view') ?> .control-list input[type=checkbox]"
data-trigger-condition="checked"
data-stripe-load-indicator>
<?= e(trans('backend::lang.relation.remove')) ?>
<?= e(trans($text)) ?>
</button>
<?php endif ?>
<?php endif ?>

View File

@ -5,5 +5,5 @@
data-request-success="$.oc.relationBehavior.changed('<?= e($this->vars['relationField']) ?>', 'removed')"
data-request-confirm="<?= e(trans('backend::lang.relation.unlink_confirm')) ?>"
data-stripe-load-indicator>
<?= e(trans('backend::lang.relation.unlink')) ?>
<?= e(trans($text)) ?>
</a>

View File

@ -5,5 +5,5 @@
data-request-data="manage_id: '<?= $relationManageId ?>'"
href="javascript:;"
class="btn btn-sm btn-secondary oc-icon-pencil">
<?= e(trans('backend::lang.relation.update_name', ['name'=>trans($relationLabel)])) ?>
<?= e(trans($text, ['name' => trans($relationLabel)])) ?>
</a>

View File

@ -1,13 +1,16 @@
<div data-control="toolbar">
<?php foreach ($relationToolbarButtons as $button): ?>
<?php foreach ($relationToolbarButtons as $type => $text): ?>
<?php if ($button == 'update'): ?>
<?php if ($type === 'update'): ?>
<?= $this->relationMakePartial('button_update', [
'relationManageId' => $relationViewModel->getKey()
'relationManageId' => $relationViewModel->getKey(),
'text' => $text
]) ?>
<?php else: ?>
<?= $this->relationMakePartial('button_'.$button) ?>
<?= $this->relationMakePartial('button_' . $type, [
'text' => $text
]) ?>
<?php endif ?>
<?php endforeach ?>