Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
UX overhaul for dashboard. Bug 586921.
Browse files Browse the repository at this point in the history
  • Loading branch information
Fred Wenzel committed Aug 13, 2010
1 parent ed44617 commit 2f6de9e
Show file tree
Hide file tree
Showing 19 changed files with 378 additions and 93 deletions.
1 change: 1 addition & 0 deletions apps/dashboard/forms.py
Expand Up @@ -5,6 +5,7 @@
from tower import ugettext_lazy as _


# TODO deprecated. Remove this once unused in views.py
DASHBOARD_PERIODS = (
('1d', _(u'1 day', 'dashboard_period')),
('1w', _(u'1 week', 'dashboard_period')),
Expand Down
68 changes: 68 additions & 0 deletions apps/dashboard/helpers.py
@@ -0,0 +1,68 @@
import datetime

from jingo import register
import jinja2


def new_context(context, **kw):
"""Helper adding variables to the existing context."""
c = dict(context.items())
c.update(kw)
return c


@register.inclusion_tag('dashboard/locales.html')
@jinja2.contextfunction
def locales_block(context, locales, total, defaults=None):
return new_context(**locals())


@register.inclusion_tag('dashboard/message_list.html')
@jinja2.contextfunction
def message_list(context, opinions, defaults=None):
"""A list of messages."""
return new_context(**locals())


@register.inclusion_tag('dashboard/platforms.html')
@jinja2.contextfunction
def platforms_block(context, platforms, total, defaults=None):
return new_context(**locals())


@register.inclusion_tag('dashboard/sentiments.html')
@jinja2.contextfunction
def sentiment_block(context, sent, defaults=None):
return new_context(**locals())


@register.inclusion_tag('dashboard/sites.html')
@jinja2.contextfunction
def themes_block(context, sites, defaults=None):
"""Sidebar block for frequently mentioned sites."""
return new_context(**locals())


@register.inclusion_tag('dashboard/themes.html')
@jinja2.contextfunction
def themes_block(context, themes, defaults=None):
"""Sidebar block for frequently used terms."""
return new_context(**locals())


@register.inclusion_tag('dashboard/versions.html')
@jinja2.contextfunction
def versions_block(context, versions, defaults=None):
return new_context(**locals())


@register.inclusion_tag('dashboard/when.html')
@jinja2.contextfunction
def when_block(context, defaults=None):
return new_context(**locals())


@register.function
def date_ago(**kwargs):
"""Returns the date for the given timedelta from now."""
return datetime.date.today() - datetime.timedelta(**kwargs)
104 changes: 75 additions & 29 deletions apps/dashboard/templates/dashboard/dashboard.html
@@ -1,40 +1,86 @@
{% extends "search_base.html" %}
{% extends "base.html" %}

{% block body_id %}dashboard{% endblock %}

{% block content %}
<div id="search_box" class="clearfix">
{% include "search/search_form.html" %}
</div>

<noscript>
<div class="container">
<h2>{{ _('Please enable JavaScript to view this page.') }}</h2>
<div class="col left">
<div id="big-count" class="count block">
<h3>{# L10n: Title text for a complete message count. #}
{{ _('Messages') }}</h3>
<p>{{ opinion_count|numberfmt }}</p>
</div>
</noscript>

<div id="overview">
<div id="sentiment" class="container clearfix">
<div id="period">{{ period.period|safe }}</div>
<h2>{{ _('Overview') }}</h2>
<div class="ajaxy"></div>
</div>
<div id="trends" class="container">
<h2>{{ _('Trends') }}</h2>
<div class="ajaxy terms"></div>
<form id="filters" class="filters segments block" method="get" action="{{ url('search') }}">

<input type="hidden" name="product" value="{{ request.default_app.short }}" />

{{ when_block() }}

{{ sentiment_block(sentiments) }}

{#
<div class="filter collapsible collapsed">
<h3>{{ _('URL Provided?') }}</h3>
<a class="toggle" href="#" title="{{ _('Show/Hide Options') }}"><span>{{ _('Toggle') }}</span></a>
<ul class="bars" data-total="10000">
<li>

<input id="f21" name="f21" type="checkbox" />
<label for="f21" class="bar" data-value="2000">
{# L10n: Refers to messages that *have* a URL provided }
<strong>{{ _('Provided') }}</strong>
</label>
</li>

<li>
<input id="f21" name="f21" type="checkbox" />
<label for="f21" class="bar" data-value="8000">
{# L10n: Refers to messages that *do not* have a URL provided }
<strong>{{ _('Not Provided') }}</strong>
</label>
</li>
</ul>
</div>
#}

{{ versions_block(versions) }}

{{ platforms_block(demo.os, opinion_count) }}

{{ locales_block(demo.locale, opinion_count) }}

</form>
</div><!--
--><div class="col middle wide">
<div id="messages" class="block">
<h2>{{ _('Latest Feedback') }}</h2>

<form id="kw-search" method="get" action="{{ url('search') }}">
<input type="hidden" name="product" value="{{ request.default_app.short }}" />
{{ search_form.q|safe }}
</form>

{{ message_list(opinions) }}

<div class="pager">
<a class="next" href="{{ search_url() }}">{{ _('&laquo; Older Messages')|safe }}</a>
<span class="prev inactive">{{ _('Newer Messages &raquo;')|safe }}</span>
</div>
</div>
<div id="demo" class="container">
<h2>{{ _('Demographics') }}</h2>
<div class="ajaxy"></div>
</div><!--
--><div class="col right">

<div id="trends" class="trends segments block">

{{ themes_block(terms) }}

{# TODO fetch and show sites
{{ sites_block(sites) }}
#}

</div>
</div>

<div id="messages" class="container">
<a href="{{ search_url() }}" class="more">
{# L10n: Link on the dashboard to show more messages. #}
{{ _('Show more') }}
</a>
<h2>{{ _('Last {count} Messages')|f(count=messages_count) }}</h2>
<div class="ajaxy"></div>
</div>
{% endblock %}
19 changes: 0 additions & 19 deletions apps/dashboard/templates/dashboard/demographics.html

This file was deleted.

16 changes: 16 additions & 0 deletions apps/dashboard/templates/dashboard/locales.html
@@ -0,0 +1,16 @@
<div class="filter collapsible">
<h3>{{ _('Locale') }}</h3>
{% include "includes/filter_box_toggle.html" %}
<ul class="bars" data-total="{{ total }}">
{% for item in locales %}
<li>
<input id="loc_{{ item.locale }}" name="locale" type="checkbox"
title="{{ locale_name(item.locale, native=True, default='') }}"
value="{{ item.locale|default('unknown', True) }}" />
<label for="loc_{{ item.locale }}" class="bar" data-value="{{ item.count }}">
<strong>{{ locale_name(item.locale) }}</strong>
</label>
</li>
{% endfor %}
</ul>
</div>
37 changes: 37 additions & 0 deletions apps/dashboard/templates/dashboard/message_list.html
@@ -0,0 +1,37 @@
{% if opinions %}
<ul class="messages">
{% for opinion in opinions %}
<li class="message">
{% if opinion.positive %}
<p class="type praise" title="{{ _('Praise') }}"><span>{{ _('Praise') }}</span></p>
{% else %}
<p class="type issue" title="{{ _('Issue') }}"><span>{{ _('Issue') }}</span></p>
{% endif %}
<p class="body">{{ opinion.description }}</p>
<ul class="meta">
<li>
<a href="{{ opinion.get_url_path() }}">
{# L10n: {0} is a time delta, e.g.: 2 weeks #}
<time title="{{ opinion.created|isotime }}">{{ _('{0} ago')|f(opinion.created|timesince) }}</time>
</a>
</li>
<li><a href="{{ search_url(os=opinion.os) }}">{{ os_name(opinion.os) }}</a></li>
<li><a href="{{ search_url(locale=opinion.locale) }}">{{ locale_name(opinion.locale) }}</li>
{% if opinion.url %}
{# TODO redirect via outgoing? #}
<li><a href="{{ opinion.url }}" rel="nofollow">{{ opinion.url|extract_domain }}</a></li>
{% endif %}
</ul>
<div class="options">
<a href="#"><span>{{ _('More Options') }}</span></a>
<ul>
{# TODO copy user agent functionality #}
<!--<li><a href="#">{{ _('Copy User Agent') }}</a></li>-->
{# L10n: Link to Google Translator #}
<li><a href="{{ 'http://translate.google.com/'|urlparams(sl='auto', q=opinion.description) }}">{{ _('Translate Message') }}</a></li>
</ul>
</div>
</li>
{% endfor %}
</ul>
{% endif %}
15 changes: 15 additions & 0 deletions apps/dashboard/templates/dashboard/platforms.html
@@ -0,0 +1,15 @@
<div class="filter collapsible">
<h3>{{ _('Platform') }}</h3>
{% include "includes/filter_box_toggle.html" %}
<ul class="bars" data-total="{{ total }}">

{% for item in platforms %}
<li>
<input id="os_{{ item.os }}" name="os" type="checkbox" />
<label for="os_{{ item.os }}" class="bar" data-value="{{ item.count }}">
<strong>{{ item.name }}</strong>
</label>
</li>
{% endfor %}
</ul>
</div>
56 changes: 20 additions & 36 deletions apps/dashboard/templates/dashboard/sentiments.html
@@ -1,37 +1,21 @@
{% macro bar(name, desc, cnt, total, link=None): %}
{% with perc = cnt / total * 100 if total > 0 else 0 %}
<div class="response {{ name }}">
<div class="lbl">
{% if link %}
<a href="{{ link }}">{{ desc }}</a>
{% else %}
{{ name }}
{% endif %}
</div>
<div class="barwrapper">
<div class="bar" style="width: {{ perc }}%">
{% if perc > 5 %}{{ cnt|numberfmt }}{% endif %}&nbsp;
</div>
{% if perc <= 5 %}<div class="out-cnt">{{ cnt|numberfmt }}</div>{% endif %}
</div>
<div class="filter collapsible">
<h3>{{ _('Type of Feedback') }}</h3>
{% include "includes/filter_box_toggle.html" %}
<ul class="bars" data-total="{{ sent.total }}">
<li>
<input id="praise_bar" name="sentiment" value="happy" type="checkbox" />
<label for="praise_bar" class="bar" data-value="{{ sent.happy }}">
{# L10n: Formerly called "happy" #}
<strong>{{ _('Praise') }}</strong>
</label>
</li>

<div class="perc">{{ perc|int }}%</div>
</div>
{% endwith %}
{% endmacro %}

{% with defaults = form.data if form else None %}
{% if sent.total > 0 %}
{{ bar('happy', _('Praise'), sent.happy, sent.total,
search_url(defaults=defaults, sentiment='happy')) }}
{{ bar('sad', _('Issues'), sent.sad, sent.total,
search_url(defaults=defaults, sentiment='sad')) }}
{% endif %}
<p>
{# L10n: Total refers to a message count. #}
{% trans url=search_url(defaults=defaults),
count=sent.total|numberfmt %}
<a href="{{ url }}">Total</a>: {{ count }}
{% endtrans %}
</p>
{% endwith %}
<li>
<input id="issue_bar" name="sentiment" value="sad" type="checkbox" />
<label for="issue_bar" class="bar" data-value="{{ sent.sad }}">
{# L10n: Formerly called "sad" #}
<strong>{{ _('Issues') }}</strong>
</label>
</li>
</ul>
</div>
15 changes: 15 additions & 0 deletions apps/dashboard/templates/dashboard/sites.html
@@ -0,0 +1,15 @@
<div class="trend collapsible">
{# L10n: Refers to sites that were reported in feedback. #}
<h3>{{ _('While Visiting') }}</h3>
{% include "includes/filter_box_toggle.html %}
<ul class="bars">
{% for site in sites %}
<li>
<a href="search.html" class="bar" data-value="4500">
<strong>lorem.com</strong>

</a>
</li>
{% endfor %}
</ul>
</div>
15 changes: 15 additions & 0 deletions apps/dashboard/templates/dashboard/themes.html
@@ -0,0 +1,15 @@
<div class="trend collapsible">
{# L10n: Refers to terms often mentioned in feedback. #}
<h3>{{ _('Often Mentioned') }}</h3>
{% include "includes/filter_box_toggle.html" %}
<ul class="bars">
{% for item in themes %}
<li>
<a href="{{ search_url(defaults=defaults, q=item.term) }}"
class="bar" data-value="{{ item.count }}">
<strong>{{ item.term }}</strong>
</a>
</li>
{% endfor %}
</ul>
</div>
14 changes: 14 additions & 0 deletions apps/dashboard/templates/dashboard/versions.html
@@ -0,0 +1,14 @@
<div class="filter collapsible collapsed">
<h3>{{ _('Version') }}</h3>

{% include "includes/filter_box_toggle.html" %}

<div>
<select id="version" name="version">
{# TODO use defaults if specified #}
{% for val, name in versions %}
<option value="{{ val }}">{{ name }}</option>
{% endfor %}
</select>
</div>
</div>

0 comments on commit 2f6de9e

Please sign in to comment.