Skip to content

Commit f08ab19

Browse files
authored
Merge pull request #115 from VSEphpbb/status
Update status change UX
2 parents 6b913ec + ff5f779 commit f08ab19

7 files changed

Lines changed: 131 additions & 52 deletions

File tree

config/services.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ services:
8181
- '@controller.helper'
8282
- '@user_loader'
8383

84+
phpbb.ideas.twig.extension.ideas_status_icon:
85+
class: phpbb\ideas\template\twig\extension\ideas_status_icon
86+
tags:
87+
- { name: twig.extension }
88+
8489
# ----- Cron tasks -----
8590
phpbb.ideas.cron.task.prune_orphaned_ideas:
8691
class: phpbb\ideas\cron\prune_orphaned_ideas

language/en/common.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@
8484
'TITLE_TOO_SHORT' => 'You must specify a subject when posting a new idea.',
8585
'TOP' => 'Top',
8686
'TOP_IDEAS' => 'Top Ideas',
87-
'TOTAL_IDEAS' => array(
87+
'TOTAL_IDEAS' => [
8888
1 => '%d idea',
8989
2 => '%d ideas',
90-
),
91-
'TOTAL_POINTS' => array(
90+
],
91+
'TOTAL_POINTS' => [
9292
1 => '%s point.',
9393
2 => '%s points.',
94-
),
94+
],
9595

9696
'UPDATED_VOTE' => 'Successfully updated vote!',
9797

styles/prosilver/template/idea_body.html

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,30 @@
4747
</div>
4848
</dd>
4949
<dt class="idealabel">{{ lang('STATUS') ~ lang('COLON') }}</dt>
50-
<dd>
51-
<a href="{{ IDEA_STATUS_LINK }}" class="status-badge status-{{ IDEA_STATUS_ID }}">{{ IDEA_STATUS_NAME }}</a>
52-
{% if STATUS_ARY %}&nbsp; <select id="status" data-url="{{ U_CHANGE_STATUS }}">
53-
<option value="0">{{ lang('CHANGE_STATUS') }}</option>
54-
{% for status, id in STATUS_ARY %}<option value="{{ id }}">{{ lang(status) }}</option>{% endfor %}
55-
</select>{% endif %}
50+
<dd class="status-dropdown-container dropdown-container">
51+
<span class="status-badge status-{{ IDEA_STATUS_ID }}">
52+
<a href="{{ IDEA_STATUS_LINK }}" id="status-link"><i class="icon fa-fw {{ ideas_status_icon(IDEA_STATUS_ID) }}"></i>{{ IDEA_STATUS_NAME }}</a>
53+
{% if STATUS_ARY %}
54+
<a href="#" class="dropdown-trigger"><i class="icon fa-fw fa-caret-down"></i></a>
55+
{% endif %}
56+
</span>
57+
{% if STATUS_ARY %}
58+
<div class="status-dropdown dropdown">
59+
<div class="pointer"><div class="pointer-inner"></div></div>
60+
<ul class="dropdown-contents">
61+
{% for status, id in STATUS_ARY %}
62+
<li>
63+
<a href="{{ U_CHANGE_STATUS }}" data-status="{{ id }}" class="change-status"><i class="icon fa-fw {{ ideas_status_icon(id) }}"></i>{{ lang(status) }}</a>
64+
</li>
65+
{% endfor %}
66+
</ul>
67+
</div>
68+
{% endif %}
5669
</dd>
5770
{% if IDEA_RFC %}
5871
<dt class="idealabel">{{ lang('RFC') ~ lang('COLON') }}</dt>
5972
<dd>
60-
<a id="rfclink" class="ideamodbtn" href="{{ IDEA_RFC }}"{% if not IDEA_RFC %} style="display:none"{% endif %}>{{ IDEA_RFC }}</a>
73+
<a id="rfclink" href="{{ IDEA_RFC }}"{% if not IDEA_RFC %} style="display:none"{% endif %}>{{ IDEA_RFC }}</a>
6174
{% if S_CAN_EDIT %}
6275
<a href="{{ U_EDIT_RFC }}" id="rfcedit" data-l-add="{{ lang('ADD') }}" data-l-edit="{{ lang('EDIT') }}">{% if IDEA_RFC %}<i class="icon fa-fw fa-pencil"></i>{{ lang('EDIT') }}{% else %}<i class="icon fa-fw fa-plus-circle"></i>{{ lang('ADD') }}{% endif %}</a>
6376
<input type="text" id="rfceditinput" class="ideainput" value="{{ IDEA_RFC }}" data-l-err="{{ lang('ERROR') }}" data-l-msg="{{ lang('RFC_ERROR') }}" />
@@ -67,7 +80,7 @@
6780
{% if IDEA_TICKET or S_CAN_EDIT %}
6881
<dt class="idealabel">{{ lang('TICKET') ~ lang('COLON') }}</dt>
6982
<dd>
70-
<a id="ticketlink" class="ideamodbtn" {% if IDEA_TICKET %}href="https://tracker.phpbb.com/browse/PHPBB3-{{ IDEA_TICKET }}">PHPBB3-{{ IDEA_TICKET }}{% else %}style="display:none">{% endif %}</a>
83+
<a id="ticketlink" {% if IDEA_TICKET %}href="https://tracker.phpbb.com/browse/PHPBB3-{{ IDEA_TICKET }}">PHPBB3-{{ IDEA_TICKET }}{% else %}style="display:none">{% endif %}</a>
7184
{% if S_CAN_EDIT %}
7285
<a href="{{ U_EDIT_TICKET }}" id="ticketedit" data-l-add="{{ lang('ADD') }}" data-l-edit="{{ lang('EDIT') }}">{% if IDEA_TICKET %}<i class="icon fa-fw fa-pencil"></i>{{ lang('EDIT') }}{% else %}<i class="icon fa-fw fa-plus-circle"></i>{{ lang('ADD') }}{% endif %}</a>
7386
<input type="text" id="ticketeditinput" class="ideainput"{% if IDEA_TICKET %} value="PHPBB3-{{ IDEA_TICKET }}"{% endif %} placeholder="PHPBB3-#####" data-l-err="{{ lang('ERROR') }}" data-l-msg="{{ lang('TICKET_ERROR') }}" />
@@ -77,7 +90,7 @@
7790
{% if IDEA_DUPLICATE or S_IS_MOD %}
7891
<dt class="duplicatetoggle idealabel"{% if IDEA_STATUS_ID != STATUS_ARY.DUPLICATE %} style="display:none"{% endif %}>{{ lang('DUPLICATE') ~ lang('COLON') }}</dt>
7992
<dd class="duplicatetoggle" {% if IDEA_STATUS_ID != STATUS_ARY.DUPLICATE %}style="display:none"{% endif %}>
80-
<a id="duplicatelink" class="ideamodbtn" data-link="{{ U_IDEA_DUPLICATE }}" data-l-msg="{{ lang('IDEA_NUM') }}" {% if IDEA_DUPLICATE %}href="{{ U_IDEA_DUPLICATE }}">{{ lang('IDEA_NUM') ~ IDEA_DUPLICATE }}{% else %}style="display:none">{% endif %}</a>
93+
<a id="duplicatelink" data-link="{{ U_IDEA_DUPLICATE }}" data-l-msg="{{ lang('IDEA_NUM') }}" {% if IDEA_DUPLICATE %}href="{{ U_IDEA_DUPLICATE }}">{{ lang('IDEA_NUM') ~ IDEA_DUPLICATE }}{% else %}style="display:none">{% endif %}</a>
8194
{% if S_IS_MOD %}
8295
<a href="{{ U_EDIT_DUPLICATE }}" id="duplicateedit" data-l-add="{{ lang('ADD') }}" data-l-edit="{{ lang('EDIT') }}">{% if IDEA_DUPLICATE %}<i class="icon fa-fw fa-pencil"></i>{{ lang('EDIT') }}{% else %}<i class="icon fa-fw fa-plus-circle"></i>{{ lang('ADD') }}{% endif %}</a>
8396
<input type="text" id="duplicateeditinput" class="ideainput"{% if IDEA_DUPLICATE %} value="{{ IDEA_DUPLICATE }}"{% endif %} placeholder="###" data-l-err="{{ lang('ERROR') }}" data-l-msg="{{ lang('TICKET_ERROR_DUP') }}" />

styles/prosilver/template/ideas.js

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
implementedVersion: $('#implementedversion'),
2525
implementedToggle: $('.implementedtoggle'),
2626
removeVote: $('.removevote'),
27-
status: $('#status'),
27+
status: $('.change-status'),
28+
statusLink: $('#status-link'),
2829
successVoted: $('.successvoted'),
2930
userVoted: $('.user-voted'),
3031
votes: $('.votes'),
@@ -110,34 +111,33 @@
110111
}).fail(voteFailure).always(hideLoadingIndicator);
111112
});
112113

113-
$obj.status.on('change', function() {
114+
$obj.status.on('click', function(e) {
115+
e.preventDefault();
116+
114117
var $this = $(this),
115118
data = {
116-
mode: 'status',
117-
status: $this.val()
119+
status: $this.attr('data-status')
118120
};
119121

120122
if (!data.status) {
121123
return;
122124
}
123125

124126
showLoadingIndicator();
125-
$.get($this.attr('data-url'), data, function(res) {
127+
$.get($this.attr('href'), data, function(res) {
126128
if (res) {
127-
var anchor = $this.prev('a'),
128-
href = anchor.attr('href');
129-
130-
href = href.replace(/status=\d/, 'status=' + data.status);
129+
var href = $obj.statusLink.attr('href').replace(/status=\d/, 'status=' + data.status);
131130

132-
anchor.attr('href', href)
133-
.text($this.find(':selected').text())
131+
$obj.statusLink.attr('href', href)
132+
.html($this.html())
133+
.closest('span')
134134
.removeClass()
135-
.addClass('status-badge status-' + $this.find(':selected').val());
135+
.addClass('status-badge status-' + data.status);
136136

137-
$obj.duplicateToggle.toggle(idea_is_duplicate());
138-
$obj.implementedToggle.toggle(idea_is_implemented());
137+
$obj.duplicateToggle.toggle(data.status === '4');
138+
$obj.implementedToggle.toggle(data.status === '3');
139139
}
140-
}).always(hideLoadingIndicator);
140+
}).always([hideLoadingIndicator, hideStatusDropDown]);
141141
});
142142

143143
$obj.rfcEdit.on('click', function(e) {
@@ -360,20 +360,8 @@
360360
})).show();
361361
};
362362

363-
/**
364-
* Returns true if idea is a duplicate. Bit hacky.
365-
*/
366-
function idea_is_duplicate() {
367-
var href = $obj.status.prev('a').attr('href');
368-
return href && href.indexOf('status=4') !== -1;
369-
}
370-
371-
/**
372-
* Returns true if idea is implemented. Bit hacky.
373-
*/
374-
function idea_is_implemented() {
375-
var href = $obj.status.prev('a').attr('href');
376-
return href && href.indexOf('status=3') !== -1;
363+
function hideStatusDropDown() {
364+
$('.status-dropdown').hide();
377365
}
378366

379367
function displayVoters(data) {

styles/prosilver/theme/ideas.css

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ dd.topics {
55
padding-left: 10px !important;
66
}
77

8-
.ideamodbtn {
9-
margin: 0 5px 0 0;
10-
}
11-
128
.fa-lightbulb-o {
139
font-weight: 400 !important;
1410
}
@@ -176,13 +172,26 @@ dd.topics {
176172
.status-badge {
177173
border-radius: 3px;
178174
color: #ffffff;
175+
display: inline-block;
179176
padding: 3px 6px;
180177
}
181178

182-
.status-badge:hover {
179+
.status-badge a {
180+
color: #ffffff;
181+
}
182+
183+
.status-badge a:hover {
183184
color: #ffffff;
184185
}
185186

187+
.status-dropdown-container {
188+
overflow: visible !important;
189+
}
190+
191+
.status-dropdown {
192+
margin-top: 8px;
193+
}
194+
186195
.status-1 {
187196
background-color: #6495ed;
188197
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/**
3+
*
4+
* This file is part of the phpBB Forum Software package.
5+
*
6+
* @copyright (c) phpBB Limited <https://www.phpbb.com>
7+
* @license GNU General Public License, version 2 (GPL-2.0)
8+
*
9+
* For full copyright and license information, please see
10+
* the docs/CREDITS.txt file.
11+
*
12+
*/
13+
14+
namespace phpbb\ideas\template\twig\extension;
15+
16+
class ideas_status_icon extends \Twig_Extension
17+
{
18+
/**
19+
* Get the name of this extension
20+
*
21+
* @return string
22+
*/
23+
public function getName()
24+
{
25+
return 'ideas_status_icon';
26+
}
27+
28+
/**
29+
* {@inheritDoc}
30+
*/
31+
public function getFunctions()
32+
{
33+
return [
34+
new \Twig_SimpleFunction('ideas_status_icon', [$this, 'get_status_icon']),
35+
];
36+
}
37+
38+
/**
39+
* Generate a Font Awesome icon class name given an integer input
40+
* representing one of the Ideas Statuses.
41+
*
42+
* @return string Status class name or empty string if no match found.
43+
*/
44+
public function get_status_icon()
45+
{
46+
$args = func_get_args();
47+
48+
$icons = [
49+
\phpbb\ideas\factory\ideas::$statuses['NEW'] => 'fa-lightbulb-o',
50+
\phpbb\ideas\factory\ideas::$statuses['IN_PROGRESS'] => 'fa-code-fork',
51+
\phpbb\ideas\factory\ideas::$statuses['IMPLEMENTED'] => 'fa-check',
52+
\phpbb\ideas\factory\ideas::$statuses['DUPLICATE'] => 'fa-files-o',
53+
\phpbb\ideas\factory\ideas::$statuses['INVALID'] => 'fa-ban',
54+
];
55+
56+
return isset($icons[$args[0]]) ? $icons[$args[0]] : '';
57+
}
58+
}

tests/ui/ideas_test.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
namespace phpbb\ideas\tests\ui;
1212

13+
use Facebook\WebDriver\WebDriverBy;
1314
use Facebook\WebDriver\WebDriverKeys;
1415

1516
/**
@@ -58,13 +59,18 @@ public function test_js_actions()
5859

5960
// test changing the status
6061
$this->assertEquals('New', $this->find_element('className', 'status-badge')->getText());
61-
$elements = $this->find_element('cssSelector', 'select#status')
62-
->findElements(\Facebook\WebDriver\WebDriverBy::tagName('option'));
63-
foreach ($elements as $element)
62+
$dropdown_container = $this->find_element('className', 'status-dropdown-container');
63+
$dropdown = $dropdown_container->findElement(WebDriverBy::className('dropdown'));
64+
$this->assertEmpty($dropdown->getText());
65+
$dropdown_container->findElement(WebDriverBy::className('dropdown-toggle'))->click();
66+
$this->assertNotNull($dropdown->getText());
67+
$statuses = $dropdown->findElements(WebDriverBy::className('change-status'));
68+
foreach ($statuses as $status)
6469
{
65-
if ($element->getText() === 'In Progress')
70+
if ($status->getText() === 'In Progress')
6671
{
67-
$element->click();
72+
$status->click();
73+
break;
6874
}
6975
}
7076
$this->waitForAjax();

0 commit comments

Comments
 (0)