Skip to content

Commit 3d1b47e

Browse files
malleziedrunken-monkey
mallezie
authored andcommitted
Issue #2641388 by mallezie, drunken monkey, borisson_, janusman: Added various UX improvements for the "Fields" tab.
1 parent 5765121 commit 3d1b47e

11 files changed

+281
-117
lines changed

Diff for: CHANGELOG.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
Search API 1.x, dev (xxxx-xx-xx):
22
---------------------------------
3+
- #2641388 by mallezie, drunken monkey, borisson_, janusman: Added various UX
4+
improvements for the "Fields" tab.
35
- #2861587 by alexpott: Fixed the DB/Defaults integration tests.
46
- #2855758 by StryKaizer, drunken monkey: Fixed "is rendered" checks for Views
57
block displays.

Diff for: search_api.links.action.yml

-5
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,3 @@ search_api.execute_tasks:
1313
title: 'Execute pending tasks'
1414
appears_on:
1515
- search_api.overview
16-
entity.search_api_index.add_fields:
17-
route_name: entity.search_api_index.add_fields
18-
title: 'Add fields'
19-
appears_on:
20-
- entity.search_api_index.fields

Diff for: search_api.routing.yml

+15-3
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,19 @@ entity.search_api_index.fields:
124124
_entity_access: 'search_api_index.fields'
125125

126126
entity.search_api_index.add_fields:
127-
path: '/admin/config/search/search-api/index/{search_api_index}/fields/add'
127+
path: '/admin/config/search/search-api/index/{search_api_index}/fields/add/nojs'
128+
options:
129+
parameters:
130+
search_api_index:
131+
tempstore: TRUE
132+
type: 'entity:search_api_index'
133+
defaults:
134+
_entity_form: 'search_api_index.add_fields'
135+
requirements:
136+
_entity_access: 'search_api_index.fields'
137+
138+
entity.search_api_index.add_fields_ajax:
139+
path: '/admin/config/search/search-api/index/{search_api_index}/fields/add/ajax'
128140
options:
129141
parameters:
130142
search_api_index:
@@ -136,7 +148,7 @@ entity.search_api_index.add_fields:
136148
_entity_access: 'search_api_index.fields'
137149

138150
entity.search_api_index.field_config:
139-
path: '/admin/config/search/search-api/index/{search_api_index}/fields/{field_id}/edit'
151+
path: '/admin/config/search/search-api/index/{search_api_index}/fields/edit/{field_id}'
140152
options:
141153
parameters:
142154
search_api_index:
@@ -149,7 +161,7 @@ entity.search_api_index.field_config:
149161
_entity_access: 'search_api_index.fields'
150162

151163
entity.search_api_index.remove_field:
152-
path: '/admin/config/search/search-api/index/{search_api_index}/fields/{field_id}/remove'
164+
path: '/admin/config/search/search-api/index/{search_api_index}/fields/remove/{field_id}'
153165
options:
154166
parameters:
155167
search_api_index:

Diff for: search_api.theme.inc

+11-8
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,14 @@ function theme_search_api_admin_fields_table($variables) {
3636
$row[] = $cell;
3737
}
3838
}
39-
if (empty($form['fields'][$name]['description']['#value'])) {
40-
$rows[] = Utility::deepCopy($row);
41-
}
42-
else {
43-
$rows[] = array(
44-
'data' => $row,
45-
'title' => strip_tags($form['fields'][$name]['description']['#value']),
46-
);
39+
$row = array(
40+
'data' => $row,
41+
'data-field-row-id' => $name,
42+
);
43+
if (!empty($form['fields'][$name]['description']['#value'])) {
44+
$row['title'] = strip_tags($form['fields'][$name]['description']['#value']);
4745
}
46+
$rows[] = $row;
4847
}
4948
}
5049

@@ -61,6 +60,7 @@ function theme_search_api_admin_fields_table($variables) {
6160
'#theme' => 'table',
6261
'#header' => $form['#header'],
6362
'#rows' => $rows,
63+
'#empty' => t('No fields have been added for this datasource.'),
6464
);
6565

6666
$output .= render($build);
@@ -161,6 +161,9 @@ function theme_search_api_form_item_list(array $variables) {
161161
$build = array(
162162
'#theme' => 'item_list',
163163
);
164+
if (!empty($element['#title'])) {
165+
$build['#title'] = $element['#title'];
166+
}
164167
foreach (Element::children($element) as $key) {
165168
$build['#items'][$key] = $element[$key];
166169
}

Diff for: src/Controller/IndexController.php

+65-1
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,72 @@
33
namespace Drupal\search_api\Controller;
44

55
use Drupal\Component\Render\FormattableMarkup;
6+
use Drupal\Core\Ajax\AjaxResponse;
7+
use Drupal\Core\Ajax\RemoveCommand;
68
use Drupal\Core\Controller\ControllerBase;
9+
use Drupal\Core\EventSubscriber\AjaxResponseSubscriber;
710
use Drupal\search_api\IndexInterface;
811
use Drupal\search_api\SearchApiException;
12+
use Symfony\Component\DependencyInjection\ContainerInterface;
13+
use Symfony\Component\HttpFoundation\RequestStack;
914
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
1015

1116
/**
1217
* Provides route responses for search indexes.
1318
*/
1419
class IndexController extends ControllerBase {
1520

21+
/**
22+
* The request stack.
23+
*
24+
* @var \Symfony\Component\HttpFoundation\RequestStack|null
25+
*/
26+
protected $requestStack;
27+
28+
/**
29+
* {@inheritdoc}
30+
*/
31+
public static function create(ContainerInterface $container) {
32+
/** @var static $controller */
33+
$controller = parent::create($container);
34+
35+
$controller->setRequestStack($container->get('request_stack'));
36+
37+
return $controller;
38+
}
39+
40+
/**
41+
* Retrieves the request stack.
42+
*
43+
* @return \Symfony\Component\HttpFoundation\RequestStack
44+
* The request stack.
45+
*/
46+
public function getRequestStack() {
47+
return $this->requestStack ?: \Drupal::service('request_stack');
48+
}
49+
50+
/**
51+
* Retrieves the current request.
52+
*
53+
* @return \Symfony\Component\HttpFoundation\Request|null
54+
*/
55+
public function getRequest() {
56+
return $this->getRequestStack()->getCurrentRequest();
57+
}
58+
59+
/**
60+
* Sets the request stack.
61+
*
62+
* @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
63+
* The new request stack.
64+
*
65+
* @return $this
66+
*/
67+
public function setRequestStack(RequestStack $request_stack) {
68+
$this->requestStack = $request_stack;
69+
return $this;
70+
}
71+
1672
/**
1773
* Displays information about a search index.
1874
*
@@ -96,10 +152,12 @@ public function indexBypassEnable(IndexInterface $search_api_index) {
96152
*/
97153
public function removeField(IndexInterface $search_api_index, $field_id) {
98154
$fields = $search_api_index->getFields();
155+
$success = FALSE;
99156
if (isset($fields[$field_id])) {
100157
try {
101158
$search_api_index->removeField($field_id);
102159
$search_api_index->save();
160+
$success = TRUE;
103161
}
104162
catch (SearchApiException $e) {
105163
$args['%field'] = $fields[$field_id]->getLabel();
@@ -110,7 +168,13 @@ public function removeField(IndexInterface $search_api_index, $field_id) {
110168
throw new NotFoundHttpException();
111169
}
112170

113-
// Redirect to the index's "View" page.
171+
// If this is an AJAX request, just remove the row in question.
172+
if ($success && $this->getRequest()->request->get(AjaxResponseSubscriber::AJAX_REQUEST_PARAMETER)) {
173+
$response = new AjaxResponse();
174+
$response->addCommand(new RemoveCommand("tr[data-field-row-id='$field_id']"));
175+
return $response;
176+
}
177+
// Redirect to the index's "Fields" page.
114178
$url = $search_api_index->toUrl('fields');
115179
return $this->redirect($url->getRouteName(), $url->getRouteParameters());
116180
}

Diff for: src/Entity/Index.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@
7878
* "add-form" = "/admin/config/search/search-api/add-index",
7979
* "edit-form" = "/admin/config/search/search-api/index/{search_api_index}/edit",
8080
* "fields" = "/admin/config/search/search-api/index/{search_api_index}/fields",
81-
* "add-fields" = "/admin/config/search/search-api/index/{search_api_index}/fields/add",
81+
* "add-fields" = "/admin/config/search/search-api/index/{search_api_index}/fields/add/nojs",
82+
* "add-fields-ajax" = "/admin/config/search/search-api/index/{search_api_index}/fields/add/ajax",
8283
* "break-lock-form" = "/admin/config/search/search-api/index/{search_api_index}/fields/break-lock",
8384
* "processors" = "/admin/config/search/search-api/index/{search_api_index}/processors",
8485
* "delete-form" = "/admin/config/search/search-api/index/{search_api_index}/delete",

Diff for: src/Form/FieldConfigurationForm.php

+45-9
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@
22

33
namespace Drupal\search_api\Form;
44

5+
use Drupal\Component\Render\FormattableMarkup;
6+
use Drupal\Component\Utility\Html;
57
use Drupal\Core\Datetime\DateFormatterInterface;
68
use Drupal\Core\Entity\EntityForm;
79
use Drupal\Core\Entity\EntityTypeManagerInterface;
10+
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
811
use Drupal\Core\Form\FormStateInterface;
912
use Drupal\Core\Render\RendererInterface;
1013
use Drupal\search_api\Processor\ConfigurablePropertyInterface;
@@ -32,6 +35,13 @@ class FieldConfigurationForm extends EntityForm {
3235
*/
3336
protected $field;
3437

38+
/**
39+
* The "id" attribute of the generated form.
40+
*
41+
* @var string
42+
*/
43+
protected $formIdAttribute;
44+
3545
/**
3646
* {@inheritdoc}
3747
*/
@@ -76,9 +86,6 @@ public static function create(ContainerInterface $container) {
7686
public function buildForm(array $form, FormStateInterface $form_state) {
7787
$field = $this->getField();
7888

79-
$args['%field'] = $field->getLabel();
80-
$form['#title'] = $this->t('Edit field %field', $args);
81-
8289
if (!$field) {
8390
$args['@id'] = $this->getRequest()->attributes->get('field_id');
8491
$form['message'] = array(
@@ -87,6 +94,21 @@ public function buildForm(array $form, FormStateInterface $form_state) {
8794
return $form;
8895
}
8996

97+
$args['%field'] = $field->getLabel();
98+
$form['#title'] = $this->t('Edit field %field', $args);
99+
100+
if ($this->getRequest()->query->get('modal_redirect')) {
101+
$form['title']['#markup'] = new FormattableMarkup('<h2>@title</h2>', ['@title' => $form['#title']]);
102+
Html::setIsAjax(TRUE);
103+
}
104+
105+
$this->formIdAttribute = Html::getUniqueId($this->getFormId());
106+
$form['#id'] = $this->formIdAttribute;
107+
108+
$form['messages'] = [
109+
'#type' => 'status_messages',
110+
];
111+
90112
$property = $field->getDataDefinition();
91113
if (!($property instanceof ConfigurablePropertyInterface)) {
92114
$args['%field'] = $field->getLabel();
@@ -123,11 +145,16 @@ protected function actions(array $form, FormStateInterface $form_state) {
123145
$actions = parent::actions($form, $form_state);
124146
unset($actions['delete']);
125147

126-
$actions['cancel'] = array(
127-
'#type' => 'link',
128-
'#title' => $this->t('Cancel'),
129-
'#url' => $this->entity->toUrl('fields'),
130-
);
148+
if ($this->getRequest()->query->get('modal_redirect')) {
149+
$actions['submit']['#ajax']['wrapper'] = $this->formIdAttribute;
150+
}
151+
else {
152+
$actions['cancel'] = array(
153+
'#type' => 'link',
154+
'#title' => $this->t('Cancel'),
155+
'#url' => $this->entity->toUrl('fields'),
156+
);
157+
}
131158

132159
return $actions;
133160
}
@@ -152,7 +179,16 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
152179
$property->submitConfigurationForm($field, $form, $form_state);
153180

154181
drupal_set_message($this->t('The field configuration was successfully saved.'));
155-
$form_state->setRedirectUrl($this->entity->toUrl('fields'));
182+
if ($this->getRequest()->query->get('modal_redirect')) {
183+
$url = $this->entity->toUrl('add-fields-ajax')
184+
->setOption('query', [
185+
MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax',
186+
]);
187+
$form_state->setRedirectUrl($url);
188+
}
189+
else {
190+
$form_state->setRedirectUrl($this->entity->toUrl('fields'));
191+
}
156192
}
157193

158194
/**

0 commit comments

Comments
 (0)