UI: Execution pagination on client side

* added execution list
  client side pagination
  which rely on the server api
* both next and previous iteration
  are supported
* items per page are coherent to
  user settings

Screenshots:
http://pasteboard.co/2p5A512S.png
http://pasteboard.co/2p5Cd1qW.png

Partially implements blueprint: mistral-dashboard-executions-screen

Change-Id: If13482d8fe62e4989dd1a62874c88c08c3e43d54
This commit is contained in:
Gal Margalit 2015-11-25 16:21:32 +00:00
parent 977e0aeafc
commit 87a74ece9d
2 changed files with 95 additions and 6 deletions

View File

@ -14,8 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import itertools
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from horizon.utils import functions as utils
from horizon.utils import memoized
from mistralclient.api import client as mistral_client
@ -51,10 +55,50 @@ def execution_create(request, **data):
@handle_errors(_("Unable to retrieve executions."), [])
def execution_list(request):
"""Returns all executions."""
def execution_list(request, marker='', sort_keys='',
sort_dirs='', paginate=False):
"""Retrieve a listing of executions.
return mistralclient(request).executions.list()
:param request: Request data
:param marker: Pagination marker for large data sets: execution id
:param sort_keys: Columns to sort results by. Default: created_at
:param sort_dirs: Sorting Directions (asc/desc). Default:asc
:param paginate: If true will perform pagination based on settings
"""
limit = getattr(settings, 'API_RESULT_LIMIT', 1000)
page_size = utils.get_page_size(request)
if paginate:
request_size = page_size + 1
else:
request_size = limit
executions_iter = mistralclient(request).executions.list(
marker, limit, sort_keys, sort_dirs
)
has_prev_data = has_more_data = False
if paginate:
executions = list(itertools.islice(executions_iter, request_size))
# first and middle page condition
if len(executions) > page_size:
executions.pop(-1)
has_more_data = True
# middle page condition
if marker is not None:
has_prev_data = True
# first page condition when reached via prev back
elif sort_dirs == 'asc' and marker is not None:
has_more_data = True
# last page condition
elif marker is not None:
has_prev_data = True
else:
executions = list(executions_iter)
return executions, has_more_data, has_prev_data
def execution_get(request, execution_id):
@ -67,14 +111,14 @@ def execution_get(request, execution_id):
def execution_update(request, execution_id, field, value):
"""update specific execution field, either state or description
"""update specific execution field, either state or description.
:param request: Request data
:param execution_id: Execution ID
:param field: flag - either Execution state or description
:param value: new update value
"""
if field == "state":
return mistralclient(request).\
executions.update(execution_id, value)

View File

@ -74,8 +74,53 @@ class IndexView(tables.DataTableView):
table_class = ExecutionsTable
template_name = 'mistral/executions/index.html'
def has_prev_data(self, table):
return self._prev
def has_more_data(self, table):
return self._more
def get_data(self):
return api.execution_list(self.request)
executions = []
prev_marker = self.request.GET.get(
ExecutionsTable._meta.prev_pagination_param,
None
)
if prev_marker is not None:
sort_dir = 'asc'
marker = prev_marker
else:
sort_dir = 'desc'
marker = self.request.GET.get(
ExecutionsTable._meta.pagination_param,
None
)
try:
executions, self._more, self._prev = api.execution_list(
request=self.request,
marker=marker,
sort_dirs=sort_dir,
paginate=True
)
if prev_marker is not None:
executions = sorted(
executions,
key=lambda execution: getattr(
execution, 'created_at'
),
reverse=True
)
except Exception:
self._prev = False
self._more = False
msg = _('Unable to retrieve executions list.')
exceptions.handle(self.request, msg)
return executions
class DetailView(generic.TemplateView):