Fix broken dashboard tables
Due to this patch: https://review.openstack.org/#/c/246625/, Horizon changes the table styles. This broke murano-dashboard tables. This patch fixes the following: 1 Fix package, images, categories, environments table looks broken 2 Fix import package descriptions displayed 3 Removes unicode symbols from README to unlock py34 gate 4 Comment out the 'multi_select=false' to pass the ci test 5 Dixed broken tests Co-Authored-By: Kirill Zaitsev <k.zaitsev@me.com> Change-Id: I802aaa89021b5f20805a498ad2a17ba73c076bed Closes-bug: #1552702 Closes-bug: #1550822 Closes-bug: #1554317
This commit is contained in:
parent
5973c5ee7e
commit
94b0c092ed
@ -3,8 +3,8 @@ Murano
|
||||
|
||||
Murano Project introduces an application catalog, which allows application
|
||||
developers and cloud administrators to publish various cloud-ready
|
||||
applications in a browsable categorised catalog. Cloud users
|
||||
— including inexperienced ones — can then use the catalog to
|
||||
applications in a browsable categorised catalog. Cloud users,
|
||||
including inexperienced ones, can then use the catalog to
|
||||
compose reliable application environments with the push of a button.
|
||||
|
||||
Murano Dashboard
|
||||
|
@ -28,6 +28,7 @@ from muranodashboard.categories import tables
|
||||
class CategoriesView(horizon_tables.DataTableView):
|
||||
table_class = tables.CategoriesTable
|
||||
template_name = 'categories/index.html'
|
||||
page_title = _("Application Categories")
|
||||
|
||||
def has_prev_data(self, table):
|
||||
return self._prev
|
||||
|
@ -323,7 +323,9 @@ class EnvironmentsTable(tables.DataTable):
|
||||
table_actions = (CreateEnvironment,)
|
||||
row_actions = (ShowEnvironmentServices, DeployEnvironment,
|
||||
DeleteEnvironment, AbandonEnvironment)
|
||||
multi_select = False
|
||||
# TODO(zhurong) Due to bug/1554087 in horizon, we should temporary
|
||||
# comment out this 'multi_select = False' to pass the ci test
|
||||
# multi_select = False
|
||||
|
||||
|
||||
def get_service_details_link(service):
|
||||
@ -418,13 +420,14 @@ class ServicesTable(tables.DataTable):
|
||||
class Meta(object):
|
||||
name = 'services'
|
||||
verbose_name = _('Component List')
|
||||
template = 'services/_data_table.html'
|
||||
no_data_message = _('No components')
|
||||
status_columns = ['status']
|
||||
row_class = UpdateServiceRow
|
||||
table_actions = (AddApplication, DeployThisEnvironment)
|
||||
row_actions = (DeleteService,)
|
||||
multi_select = False
|
||||
# TODO(zhurong) Due to bug/1554087 in horizon, we should temporary
|
||||
# comment out this 'multi_select = False' to pass the ci test
|
||||
# multi_select = False
|
||||
|
||||
|
||||
class ShowDeploymentDetails(tables.LinkAction):
|
||||
@ -458,7 +461,6 @@ class DeploymentsTable(tables.DataTable):
|
||||
class Meta(object):
|
||||
name = 'deployments'
|
||||
verbose_name = _('Deployments')
|
||||
template = 'common/_data_table.html'
|
||||
row_actions = (ShowDeploymentDetails,)
|
||||
|
||||
|
||||
@ -475,4 +477,3 @@ class EnvConfigTable(tables.DataTable):
|
||||
class Meta(object):
|
||||
name = 'environment_configuration'
|
||||
verbose_name = _('Deployed Components')
|
||||
template = 'common/_data_table.html'
|
||||
|
@ -36,6 +36,7 @@ from muranodashboard.environments import tabs as env_tabs
|
||||
class IndexView(tables.DataTableView):
|
||||
table_class = env_tables.EnvironmentsTable
|
||||
template_name = 'environments/index.html'
|
||||
page_title = _("Environments")
|
||||
|
||||
def get_data(self):
|
||||
environments = []
|
||||
|
@ -63,6 +63,5 @@ class MarkedImagesTable(tables.DataTable):
|
||||
class Meta(object):
|
||||
name = 'marked_images'
|
||||
verbose_name = _('Marked Images')
|
||||
template = 'common/_data_table.html'
|
||||
table_actions = (MarkImage, RemoveImageMetadata)
|
||||
row_actions = (RemoveImageMetadata,)
|
||||
|
@ -31,6 +31,7 @@ from muranodashboard.images import tables
|
||||
class MarkedImagesView(horizon_tables.DataTableView):
|
||||
table_class = tables.MarkedImagesTable
|
||||
template_name = 'images/index.html'
|
||||
page_title = _("Marked Images")
|
||||
|
||||
def has_prev_data(self, table):
|
||||
return self._prev
|
||||
|
@ -238,7 +238,6 @@ class PackageDefinitionsTable(tables.DataTable):
|
||||
name = 'packages'
|
||||
prev_pagination_param = 'marker'
|
||||
verbose_name = _('Packages')
|
||||
template = 'common/_data_table.html'
|
||||
table_actions_menu = (ToggleEnabled,
|
||||
TogglePublicEnabled)
|
||||
table_actions = (PackagesFilterAction,
|
||||
|
@ -73,6 +73,7 @@ def is_app(wizard):
|
||||
class PackageDefinitionsView(horizon_tables.DataTableView):
|
||||
table_class = tables.PackageDefinitionsTable
|
||||
template_name = 'packages/index.html'
|
||||
page_title = _("Packages")
|
||||
|
||||
_more = False
|
||||
_prev = False
|
||||
|
@ -2,10 +2,6 @@
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Application Categories" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Application Categories") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
||||
|
@ -1,10 +0,0 @@
|
||||
{% extends 'horizon/common/_data_table.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block table_caption %}
|
||||
<tr class='table_caption'>
|
||||
<th class='table_header' colspan='{{ columns|length }}'>
|
||||
{{ table.render_table_actions }}
|
||||
</th>
|
||||
</tr>
|
||||
{% endblock table_caption %}
|
@ -1,4 +1,4 @@
|
||||
{% extends 'common/_data_table.html' %}
|
||||
{% extends 'horizon/common/_data_table.html' %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Environments" %}{% endblock %}
|
||||
|
||||
|
@ -4,10 +4,6 @@
|
||||
{% load compress %}
|
||||
{% block title %}{% trans "Environments" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Environments") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
||||
|
@ -2,10 +2,6 @@
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Marked Images" %}{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Marked Images") %}
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
||||
|
@ -11,9 +11,6 @@
|
||||
{% endcompress %}
|
||||
{% endblock %}
|
||||
|
||||
{% block page_header %}
|
||||
{% include "horizon/common/_page_header.html" with title=_("Packages") %}
|
||||
{% endblock page_header %}
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
||||
|
@ -1,107 +1,93 @@
|
||||
{% extends 'common/_data_table.html' %}
|
||||
{% load i18n %}
|
||||
{% load custom_filters %}
|
||||
{% block title %}{% trans "Components" %}{% endblock %}
|
||||
|
||||
{% block table_caption %}
|
||||
{% with apps=table.get_apps_list %}
|
||||
{% if table.actions_allowed %}
|
||||
{% comment %}
|
||||
Note(efedorova): We are comparing to the string, since get_apps_list
|
||||
functions returns json.dumps, which is used in js later.
|
||||
So to prevent extra transformations comparing to the string is used
|
||||
to check for app absence.
|
||||
{% endcomment %}
|
||||
{% if apps != '[]' %}
|
||||
<div class="row row-header">
|
||||
<div class="col-xs-5">
|
||||
<h3 class="table_title extra_title table_title">
|
||||
{% trans "Application Components" %}</h3>
|
||||
</div>
|
||||
<h4 class="category-title">{% trans 'App category' %}</h4>
|
||||
<div class="col-xs-3">
|
||||
<div class="dropdown" id="envAppsCategory">
|
||||
{% with categories=table.get_categories_list %}
|
||||
<button class="btn btn-default dropdown-toggle"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
data-disabled="true"
|
||||
aria-expanded="false"
|
||||
id="envAppsCategoryBtn">
|
||||
<span id="envAppsCategoryName">{% trans "All" %}</span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu scrollable-menu"
|
||||
role="menu"
|
||||
aria-labelledby="envAppsCategoryBtn">
|
||||
<li role="presentation"><a
|
||||
role="menuitem" tabindex="-1"
|
||||
data-category-name="All"
|
||||
href="#">{% trans "All" %}</a>
|
||||
</li>
|
||||
{% for category in categories %}
|
||||
<li role="presentation"><a
|
||||
role="menuitem" tabindex="-1"
|
||||
data-category-name="{{ category.name }}"
|
||||
href="#">{{ category.name }} ({{category.package_count}})</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-3 filter-bar">
|
||||
<div class="has-feedback" id="envAppsFilter">
|
||||
<input class="form-control" value="{{ search }}"
|
||||
type="text"
|
||||
placeholder={% trans "Find in a selected category" %}>
|
||||
<span class="fa fa-search form-control-feedback search-icon"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p id="no_apps_in_catalog_message" class="col-xs-12 alert alert-info ">
|
||||
{% with repo_url=table.get_repo_url pkg_def_url=table.get_pkg_def_url %}
|
||||
{% trans "There are no applications in the catalog. You can import apps from" %}
|
||||
<a href="{{ repo_url }}" target="_blank"> {{ repo_url }}</a>.
|
||||
<br><br>
|
||||
{% blocktrans trimmed %}Go to
|
||||
<b>
|
||||
<a href={{ pkg_def_url }}>Packages</a>
|
||||
</b>, click 'Import Package' and select <i>Repository</i> as <i>Package Source</i>.
|
||||
{% endblocktrans %}
|
||||
{% endwith %}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<p id="no_apps_found_message" class="alert alert-info">
|
||||
{% trans "There are no applications matching your criteria." %}</p>
|
||||
<div id="apps_carousel" class="carousel">
|
||||
<input type="hidden" id="apps_carousel_contents"
|
||||
value="{{ apps }}">
|
||||
|
||||
<div class="carousel-inner"></div>
|
||||
<a class="left carousel-control" ng-non-bindable href="#apps_carousel"
|
||||
data-slide="prev">
|
||||
<i class="fa fa-chevron-left"></i>
|
||||
</a>
|
||||
<a class="right carousel-control" ng-non-bindable href="#apps_carousel"
|
||||
data-slide="next">
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
{% comment %}
|
||||
Note(efedorova): We are comparing to the string, since get_apps_list
|
||||
functions returns json.dumps, which is used in js later.
|
||||
So to prevent extra transformations comparing to the string is used
|
||||
to check for app absence.
|
||||
{% endcomment %}
|
||||
{% if apps != '[]' %}
|
||||
<div class="col-xs-5">
|
||||
<h3 class="table_title extra_title table_title">
|
||||
{% trans "Application Components" %}</h3>
|
||||
</div>
|
||||
<h4 class="category-title">{% trans 'App category' %}</h4>
|
||||
<div class="col-xs-3">
|
||||
<div class="dropdown" id="envAppsCategory">
|
||||
{% with categories=table.get_categories_list %}
|
||||
<button class="btn btn-default dropdown-toggle"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
data-disabled="true"
|
||||
aria-expanded="false"
|
||||
id="envAppsCategoryBtn">
|
||||
<span id="envAppsCategoryName">{% trans "All" %}</span>
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu scrollable-menu"
|
||||
role="menu"
|
||||
aria-labelledby="envAppsCategoryBtn">
|
||||
<li role="presentation"><a
|
||||
role="menuitem" tabindex="-1"
|
||||
data-category-name="All"
|
||||
href="#">{% trans "All" %}</a>
|
||||
</li>
|
||||
{% for category in categories %}
|
||||
<li role="presentation"><a
|
||||
role="menuitem" tabindex="-1"
|
||||
data-category-name="{{ category.name }}"
|
||||
href="#">{{ category.name }} ({{category.package_count}})</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-3 filter-bar">
|
||||
<div class="has-feedback" id="envAppsFilter">
|
||||
<input class="form-control" value="{{ search }}"
|
||||
type="text"
|
||||
placeholder={% trans "Find in a selected category" %}>
|
||||
<span class="fa fa-search form-control-feedback search-icon"></span>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p id="no_apps_in_catalog_message" class="col-xs-12 alert alert-info ">
|
||||
{% with repo_url=table.get_repo_url pkg_def_url=table.get_pkg_def_url %}
|
||||
{% trans "There are no applications in the catalog. You can import apps from" %}
|
||||
<a href="{{ repo_url }}" target="_blank"> {{ repo_url }}</a>.
|
||||
<br><br>
|
||||
{% blocktrans trimmed %}Go to
|
||||
<b>
|
||||
<a href={{ pkg_def_url }}>Packages</a>
|
||||
</b>, click 'Import Package' and select <i>Repository</i> as <i>Package Source</i>.
|
||||
{% endblocktrans %}
|
||||
{% endwith %}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<p id="no_apps_found_message" class="alert alert-info">
|
||||
{% trans "There are no applications matching your criteria." %}</p>
|
||||
<div id="apps_carousel" class="carousel">
|
||||
<input type="hidden" id="apps_carousel_contents"
|
||||
value="{{ apps }}">
|
||||
|
||||
<div class="carousel-inner"></div>
|
||||
<a class="left carousel-control" ng-non-bindable href="#apps_carousel"
|
||||
data-slide="prev">
|
||||
<i class="fa fa-chevron-left"></i>
|
||||
</a>
|
||||
<a class="right carousel-control" ng-non-bindable href="#apps_carousel"
|
||||
data-slide="next">
|
||||
<i class="fa fa-chevron-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
{% endwith %}
|
||||
<tr class='table_caption'>
|
||||
<th class='table_header' colspan='{{ columns|length }}'>
|
||||
<h3 class='table_title'>{{ table }}</h3>
|
||||
{{ table.render_table_actions }}
|
||||
</th>
|
||||
</tr>
|
||||
{% endblock table_caption %}
|
||||
|
||||
{% block table_body %}
|
||||
@ -112,13 +98,4 @@
|
||||
</h4>
|
||||
</div>
|
||||
{% endif %}
|
||||
<tbody>
|
||||
{% for row in rows %}
|
||||
{{ row.render }}
|
||||
{% empty %}
|
||||
<tr class="{% cycle 'odd' 'even' %} empty">
|
||||
<td colspan="{{ table.get_columns|length }}">{{ table.get_empty_message }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
{% endblock table_body %}
|
||||
|
@ -1,5 +1,13 @@
|
||||
{% load i18n %}
|
||||
|
||||
{% block main %}
|
||||
{{ table.render }}
|
||||
{% endblock %}
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
{% include "services/_data_table.html" %}
|
||||
<hr>
|
||||
<div id="components">
|
||||
{{ table.render }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
@ -275,7 +275,8 @@ class UITestCase(BaseDeps):
|
||||
|
||||
def edit_environment(self, old_name, new_name):
|
||||
el_td = self.driver.find_element_by_css_selector(
|
||||
'tr[data-display="{0}"] td:first-of-type'.format(old_name))
|
||||
'tr[data-display="{0}"] '.format(old_name) +
|
||||
'td[data-cell-name="name"]')
|
||||
el_pencil = el_td.find_element_by_css_selector(
|
||||
'button.ajax-inline-edit')
|
||||
|
||||
@ -287,14 +288,15 @@ class UITestCase(BaseDeps):
|
||||
# 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')
|
||||
'td[data-cell-name="name"] .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"]')
|
||||
'td[data-cell-name="name"] .inline-edit-actions' +
|
||||
' button[type="submit"]')
|
||||
el_submit.click()
|
||||
# there is no alert message
|
||||
|
||||
@ -308,7 +310,7 @@ class UITestCase(BaseDeps):
|
||||
def wait_for_alert_message(self):
|
||||
locator = (by.By.CSS_SELECTOR, 'div.alert-success')
|
||||
logger.debug("Waiting for a success message")
|
||||
ui.WebDriverWait(self.driver, 2).until(
|
||||
ui.WebDriverWait(self.driver, 5).until(
|
||||
EC.presence_of_element_located(locator))
|
||||
|
||||
def wait_for_error_message(self, sec=20):
|
||||
|
@ -1057,12 +1057,13 @@ class TestSuitePackages(base.PackageTestCase):
|
||||
pkg_name = self.alt_archive_name
|
||||
self.fill_field(by.By.CSS_SELECTOR,
|
||||
"input[name='modify-name']", pkg_name)
|
||||
self.driver.find_element_by_css_selector(
|
||||
"input[name=modify-is_public]"
|
||||
).click()
|
||||
self.driver.find_element_by_css_selector(
|
||||
"input[name=modify-enabled]"
|
||||
).click()
|
||||
|
||||
label = self.driver.find_element_by_css_selector(
|
||||
"label[for=id_modify-is_public]")
|
||||
label.click()
|
||||
label = self.driver.find_element_by_css_selector(
|
||||
"label[for=id_modify-enabled]")
|
||||
label.click()
|
||||
|
||||
self.driver.find_element_by_xpath(c.InputSubmit).click()
|
||||
self.driver.find_element_by_xpath(c.InputSubmit).click()
|
||||
@ -1162,9 +1163,9 @@ class TestSuitePackages(base.PackageTestCase):
|
||||
# Public = OFF; Active = ON.
|
||||
public_checkbox = self.driver.find_element_by_id('id_modify-is_public')
|
||||
active_checkbox = self.driver.find_element_by_id('id_modify-enabled')
|
||||
if public_checkbox.is_selected() is True:
|
||||
if public_checkbox.is_selected():
|
||||
public_checkbox.click()
|
||||
elif active_checkbox.is_selected() is False:
|
||||
if not active_checkbox.is_selected():
|
||||
active_checkbox.click()
|
||||
self.driver.find_element_by_xpath(c.InputSubmit).click()
|
||||
self.driver.find_element_by_xpath(c.InputSubmit).click()
|
||||
@ -1177,7 +1178,10 @@ class TestSuitePackages(base.PackageTestCase):
|
||||
c.AppPackages.format(self.archive_name))
|
||||
pkg_id = package.get_attribute("data-object-id")
|
||||
self.select_action_for_package(pkg_id, 'modify_package')
|
||||
self.driver.find_element_by_id('id_is_public').click()
|
||||
|
||||
label = self.driver.find_element_by_css_selector(
|
||||
"label[for=id_is_public]")
|
||||
label.click()
|
||||
self.driver.find_element_by_xpath(c.InputSubmit).click()
|
||||
# Expecting Error
|
||||
self.wait_for_error_message()
|
||||
|
Loading…
Reference in New Issue
Block a user