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:
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user