Allow inline name editing

Replaces EditEnvironment row action with inline name editing.
Also adds styling, to inline edits, that mimics inline creation form.
Also updated corresponding test, to check against inline capabilities.

Closes-Bug: #1476427

Change-Id: I0fb8602e9ddc9b2697a9f4de4420b736eb93d41e
This commit is contained in:
Kirill Zaitsev
2015-07-21 02:22:52 +03:00
parent 39bdff2354
commit c2e120f277
5 changed files with 92 additions and 26 deletions

View File

@@ -21,15 +21,17 @@ from django.template import defaultfilters
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import forms
from horizon import messages
from horizon import tables
from muranodashboard import api as api_utils
from muranodashboard.api import packages as pkg_api
from muranodashboard.catalog import views as catalog_views
from muranodashboard.environments import api
from muranodashboard.environments import consts
from muranodashboard import api as api_utils
from muranodashboard.api import packages as pkg_api
from muranoclient.common import exceptions as exc
LOG = logging.getLogger(__name__)
@@ -135,21 +137,6 @@ class AbandonEnvironment(tables.DeleteAction):
exceptions.handle(request, msg, redirect=redirect)
class EditEnvironment(tables.LinkAction):
name = 'edit'
verbose_name = _('Edit Environment')
url = 'horizon:murano:environments:update_environment'
classes = ('ajax-modal', 'btn-edit')
icon = 'edit'
def allowed(self, request, environment):
"""Allow edit environment only when status not deploying and deleting.
"""
status = getattr(environment, 'status', None)
return status not in [consts.STATUS_ID_DEPLOYING,
consts.STATUS_ID_DELETING]
class DeleteService(tables.DeleteAction):
data_type_singular = _('Component')
data_type_plural = _('Components')
@@ -270,10 +257,36 @@ class UpdateServiceRow(tables.Row):
return api.service_get(request, environment_id, service_id)
class UpdateName(tables.UpdateAction):
def update_cell(self, request, datum, obj_id, cell_name, new_cell_value):
try:
mc = api_utils.muranoclient(request)
mc.environments.update(datum.id, name=new_cell_value)
except exc.HTTPConflict:
message = _("This name is already taken.")
messages.warning(request, message)
LOG.warning(_("Couldn't update environment. Reason: ") + message)
# FIXME(kzaitsev): There is a bug in horizon and inline error
# icons are missing. This means, that if we return 400 here, by
# raising django.core.exceptions.ValidationError(message) the UI
# will break a little. Until the bug is fixed this will raise 500
# bug link: https://bugs.launchpad.net/horizon/+bug/1359399
# Alternatively this could somehow raise 409, which would result
# in the same behaviour.
raise ValueError(message)
except Exception:
exceptions.handle(request, ignore=True)
return False
return True
class EnvironmentsTable(tables.DataTable):
name = tables.Column('name',
link='horizon:murano:environments:services',
verbose_name=_('Name'))
verbose_name=_('Name'),
form_field=forms.CharField(),
update_action=UpdateName)
status = tables.Column('status',
verbose_name=_('Status'),
@@ -290,7 +303,7 @@ class EnvironmentsTable(tables.DataTable):
no_data_message = _('NO ENVIRONMENTS')
table_actions = (CreateEnvironment,)
row_actions = (ShowEnvironmentServices, DeployEnvironment,
EditEnvironment, DeleteEnvironment, AbandonEnvironment)
DeleteEnvironment, AbandonEnvironment)
multi_select = False

View File

@@ -1,3 +1,35 @@
table#murano div.table_cell_wrapper div.inline-edit-form input {
/*
* overrides from form-control, to make inline edit consistent
* with the rest of UI
*/
display: block;
height: 32px;
font-size: 13px;
line-height: 1.42857;
color: #555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
-o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
/* Additional styles, not present in form-control */
margin: 7px 7px 0 7px;
width: calc(100% - 14px);
}
table#murano div.table_cell_wrapper div.inline-edit-form input:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
}
.table_header.catalog {
border-bottom: 2px solid #e5e5e5;
padding-bottom:5px;

View File

@@ -12,11 +12,11 @@
{% endblock %}
{% block css %}
{% include "_stylesheets.html" %}
{{ block.super }}
<link href='{{ STATIC_URL }}muranodashboard/css/catalog.css' type='text/css' media='screen' rel='stylesheet' />
{% endblock %}
{% block js %}
{% include 'horizon/_scripts.html' %}
<script src="{% static 'muranodashboard/js/environments-in-place.js' %}"></script>
{% endblock %}
{% endblock %}

View File

@@ -23,6 +23,7 @@ from keystoneclient.v2_0 import client as ksclient
from muranoclient import client as mclient
from selenium.common import exceptions as exc
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import selenium.webdriver.common.by as by
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support import ui
@@ -195,10 +196,29 @@ class UITestCase(BaseDeps):
self.wait_for_alert_message()
def edit_environment(self, old_name, new_name):
self.select_action_for_environment(old_name, 'edit')
self.fill_field(by.By.ID, 'id_name', new_name)
self.driver.find_element_by_xpath(consts.InputSubmit).click()
self.wait_for_alert_message()
el_td = self.driver.find_element_by_css_selector(
'tr[data-display="{0}"] td:first-of-type'.format(old_name))
el_pencil = el_td.find_element_by_css_selector(
'button.ajax-inline-edit')
# hover to make pencil visible
hover = ActionChains(self.driver).move_to_element(el_td)
hover.perform()
el_pencil.click()
# fill in inline input
el_inline_input = self.driver.find_element_by_css_selector(
'tr[data-display="{0}"] '.format(old_name) +
'td:first-of-type .inline-edit-form input')
el_inline_input.clear()
el_inline_input.send_keys(new_name)
# click submit
el_submit = self.driver.find_element_by_css_selector(
'tr[data-display="{0}"] '.format(old_name) +
'td:first-of-type .inline-edit-actions button[type="submit"]')
el_submit.click()
# there is no alert message
def select_action_for_environment(self, env_name, action):
element_id = self.get_element_id(env_name)

View File

@@ -74,9 +74,10 @@ class TestSuiteEnvironment(base.ApplicationTestCase):
self.go_to_submenu('Environments')
self.create_environment('test_edit_env')
self.go_to_submenu('Environments')
self.driver.find_element_by_link_text('test_edit_env')
self.edit_environment(old_name='test_edit_env', new_name='edited_env')
self.go_to_submenu('Environments')
self.check_element_on_page(by.By.LINK_TEXT, 'edited_env')
self.check_element_not_on_page(by.By.LINK_TEXT, 'test_edit_env')