nodebb-plugin-poll 2.0.5 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +7 -7
- package/LICENSE +20 -20
- package/README.md +31 -31
- package/languages/cs/poll.json +47 -47
- package/languages/en_GB/poll.json +46 -46
- package/languages/en_US/poll.json +46 -46
- package/languages/es/poll.json +39 -39
- package/languages/fr/poll.json +38 -38
- package/languages/gl/poll.json +38 -38
- package/languages/he/poll.json +47 -47
- package/languages/pl/poll.json +39 -39
- package/languages/pt-PT/poll.json +41 -41
- package/languages/ro/poll.json +39 -39
- package/languages/ru/poll.json +0 -0
- package/languages/tr/poll.json +47 -47
- package/lib/config.js +0 -0
- package/lib/hooks.js +0 -0
- package/lib/nodebb.js +0 -0
- package/lib/poll.js +0 -0
- package/lib/scheduler.js +0 -0
- package/lib/serializer.js +2 -1
- package/lib/sockets.js +0 -0
- package/lib/vote.js +0 -0
- package/library.js +0 -0
- package/package.json +2 -2
- package/plugin.json +3 -3
- package/public/js/admin.js +0 -0
- package/public/js/poll/creator.js +0 -0
- package/public/js/poll/main.js +1 -0
- package/public/js/poll/serializer.js +4 -16
- package/public/js/poll/sockets.js +0 -0
- package/public/js/poll/view.js +1 -1
- package/public/{less/style.less → scss/style.scss} +1 -9
- package/templates/admin/plugins/poll.tpl +57 -58
- package/templates/poll/creator.tpl +19 -20
- package/templates/poll/view/details.tpl +6 -10
- package/templates/poll/view/messages.tpl +2 -2
- package/templates/poll/view/results.tpl +14 -14
- package/templates/poll/view/voting.tpl +16 -16
- package/templates/poll/view.tpl +28 -28
- package/upgrades/fix_incorrect_poll_privilege.js +15 -15
- package/package-lock.json +0 -1669
|
File without changes
|
package/public/js/poll/view.js
CHANGED
|
@@ -229,7 +229,7 @@
|
|
|
229
229
|
var el = this.dom.resultsPanel.find('[data-poll-option-id=' + option.id + ']');
|
|
230
230
|
el.find('.poll-result-votecount span').text(option.voteCount);
|
|
231
231
|
el.find('.poll-result-progressbar').css('width', option.percentage + '%')
|
|
232
|
-
.find('span').text(option.percentage);
|
|
232
|
+
.find('span.percent').text(option.percentage);
|
|
233
233
|
}, this);
|
|
234
234
|
};
|
|
235
235
|
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
margin-top: 0;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
.
|
|
11
|
+
.card-title {
|
|
12
12
|
display: inline-block;
|
|
13
13
|
}
|
|
14
14
|
|
|
@@ -24,14 +24,6 @@
|
|
|
24
24
|
min-width: 2em;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
.poll-result-avatar {
|
|
28
|
-
width: 50px;
|
|
29
|
-
height: 50px;
|
|
30
|
-
font-size: 3rem;
|
|
31
|
-
vertical-align: middle;
|
|
32
|
-
margin-bottom: 3px;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
27
|
.poll-result-details:hover {
|
|
36
28
|
text-decoration: none;
|
|
37
29
|
}
|
|
@@ -1,59 +1,58 @@
|
|
|
1
|
-
<div class="row">
|
|
2
|
-
<div class="col-lg-9">
|
|
3
|
-
<form class="form poll-settings">
|
|
4
|
-
<div class="
|
|
5
|
-
<div class="
|
|
6
|
-
<div class="
|
|
7
|
-
<div class="row">
|
|
8
|
-
<div class="col-lg-6">
|
|
9
|
-
<
|
|
10
|
-
<div class="
|
|
11
|
-
<div class="
|
|
12
|
-
<label>
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<div class="
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<div class="
|
|
53
|
-
|
|
54
|
-
<button id="
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
</div>
|
|
1
|
+
<div class="row">
|
|
2
|
+
<div class="col-lg-9">
|
|
3
|
+
<form class="form poll-settings">
|
|
4
|
+
<div class="card">
|
|
5
|
+
<div class="card-header">[[poll:poll]]</div>
|
|
6
|
+
<div class="card-body">
|
|
7
|
+
<div class="row">
|
|
8
|
+
<div class="col-lg-6">
|
|
9
|
+
<h6>[[poll:toggles]]</h6>
|
|
10
|
+
<div class="mb-3">
|
|
11
|
+
<div class="form-check">
|
|
12
|
+
<label class="form-check-label">[[poll:allow_guests]]</label>
|
|
13
|
+
<input class="form-check-input" type="checkbox" data-key="toggles.allowAnon" data-trim="false">
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
<div class="col-lg-6">
|
|
18
|
+
<h6>[[poll:limits]]</h6>
|
|
19
|
+
<div>
|
|
20
|
+
<label class="form-label" for="maxPollOptions">[[poll:max_options]]</label>
|
|
21
|
+
<input type="number" class="form-control" id="maxPollOptions" placeholder="10" min="1" max="100" data-key="limits.maxOptions">
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div class="card">
|
|
29
|
+
<div class="card-header">[[poll:defaults]]</div>
|
|
30
|
+
<div class="card-body">
|
|
31
|
+
<div class="row">
|
|
32
|
+
<div class="col-lg-6">
|
|
33
|
+
<div class="mb-3">
|
|
34
|
+
<label class="form-label" for="defaultsTitle">[[poll:default_title]]</label>
|
|
35
|
+
<input type="text" class="form-control" id="defaultsTitle" placeholder="Poll" data-key="defaults.title">
|
|
36
|
+
</div>
|
|
37
|
+
<div>
|
|
38
|
+
<label class="form-label" for="defaultsMaxVotes">[[poll:max_votes]]</label>
|
|
39
|
+
<input type="number" class="form-control" id="defaultsMaxVotes" placeholder="1" min="1" max="100" data-key="defaults.maxvotes">
|
|
40
|
+
<p class="form-text">[[poll:info_choices]]</p>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
</form>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<div class="col-lg-3">
|
|
50
|
+
<div class="card">
|
|
51
|
+
<div class="card-header">[[poll:settings]]</div>
|
|
52
|
+
<div class="card-body">
|
|
53
|
+
<button id="save" class="btn btn-primary btn-block">[[poll:save]]</button>
|
|
54
|
+
<button id="reset" class="btn btn-warning btn-block">[[poll:reset]]</button>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
59
58
|
</div>
|
|
@@ -1,51 +1,50 @@
|
|
|
1
1
|
<form class="form" id="pollCreator">
|
|
2
2
|
<div id="pollErrorBox" class="alert alert-danger hidden"></div>
|
|
3
3
|
|
|
4
|
-
<div class="
|
|
5
|
-
<label for="pollInputTitle">[[poll:poll_title]]</label>
|
|
4
|
+
<div class="mb-3">
|
|
5
|
+
<label class="form-label" for="pollInputTitle">[[poll:poll_title]]</label>
|
|
6
6
|
<input type="text" name="settings.title" id="pollInputTitle" value="{poll.settings.title}" placeholder="[[poll:poll_title_placeholder]]" class="form-control">
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
|
-
<div class="
|
|
10
|
-
<label for="pollInputOptions">[[poll:options_title]]</label>
|
|
9
|
+
<div class="mb-3">
|
|
10
|
+
<label class="form-label" for="pollInputOptions">[[poll:options_title]]</label>
|
|
11
11
|
<!-- IF poll.options.length -->
|
|
12
12
|
<!-- BEGIN poll.options -->
|
|
13
|
-
<input type="text" name="options" id="pollInputOptions" value="{@value}" class="form-control"/>
|
|
13
|
+
<input type="text" name="options" id="pollInputOptions" value="{@value}" class="form-control mb-2"/>
|
|
14
14
|
<!-- END poll.options -->
|
|
15
15
|
<!-- ELSE -->
|
|
16
|
-
<input type="text" name="options" id="pollInputOptions" class="form-control"/>
|
|
16
|
+
<input type="text" name="options" id="pollInputOptions" class="form-control mb-2"/>
|
|
17
17
|
<!-- ENDIF poll.options.length -->
|
|
18
18
|
<button type="button" id="pollAddOption" class="btn btn-primary btn-sm btn-block">[[poll:options_add]]</button>
|
|
19
19
|
</div>
|
|
20
20
|
|
|
21
21
|
<hr>
|
|
22
22
|
|
|
23
|
-
<div class="
|
|
24
|
-
<label for="pollInputAmount">[[poll:max_votes]]</label>
|
|
23
|
+
<div class="mb-3">
|
|
24
|
+
<label class="form-label" for="pollInputAmount">[[poll:max_votes]]</label>
|
|
25
25
|
<input type="number" name="settings.maxvotes" id="pollInputAmount" value="{poll.settings.maxvotes}"
|
|
26
26
|
min="1" max="10" step="1" placeholder="[[poll:max_votes_placeholder]]" class="form-control">
|
|
27
27
|
</div>
|
|
28
28
|
|
|
29
|
-
<div class="
|
|
30
|
-
<
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
</
|
|
29
|
+
<div class="mb-3">
|
|
30
|
+
<div class="form-check">
|
|
31
|
+
<label class="form-check-label" for="pollDisallowVoteUpdate">[[poll:disallow_vote_update]]</label>
|
|
32
|
+
<input class="form-check-input" type="checkbox" name="settings.disallowVoteUpdate" id="pollDisallowVoteUpdate" {{{if poll.settings.disallowVoteUpdate}}}checked{{{end}}}>
|
|
33
|
+
</div>
|
|
34
34
|
</div>
|
|
35
35
|
|
|
36
|
-
<div class="
|
|
37
|
-
<label for="pollInputEnd">[[poll:auto_end_title]]</label>
|
|
38
|
-
|
|
36
|
+
<div class="mb-3">
|
|
37
|
+
<label class="form-label" for="pollInputEnd">[[poll:auto_end_title]]</label>
|
|
39
38
|
<div class="input-group date flatpickr">
|
|
40
39
|
<input id="pollInputEnd" placeholder="[[poll:auto_end_placeholder]]" name="settings.end" class="form-control" value="{poll.settings.end}" data-input>
|
|
41
|
-
<a class="input-group-
|
|
40
|
+
<a class="input-group-text" data-toggle><i class="fa fa-calendar"></i></a>
|
|
42
41
|
</div>
|
|
43
|
-
<p class="
|
|
42
|
+
<p class="form-text">[[poll:auto_end_help]]</p>
|
|
44
43
|
</div>
|
|
45
44
|
|
|
46
|
-
|
|
45
|
+
{{{ if isRedactor }}}
|
|
47
46
|
<div class="alert alert-warning" role="alert">
|
|
48
47
|
[[poll:warning.redactor]]
|
|
49
48
|
</div>
|
|
50
|
-
|
|
49
|
+
{{{ end }}}
|
|
51
50
|
</form>
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
<h2>{voteCount} [[poll:vote_count]]</h2>
|
|
2
|
-
<!-- BEGIN votes -->
|
|
3
|
-
<a href="{config.relative_path}/user/{votes.userslug}" class="poll-result-details">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
<div class="poll-result-avatar user-icon" title="{votes.username}" style="background-color: {votes.icon:bgColor};">{votes.icon:text}</div>
|
|
8
|
-
<!-- ENDIF votes.picture -->
|
|
9
|
-
</a>
|
|
10
|
-
<!-- END votes -->
|
|
1
|
+
<h2>{voteCount} [[poll:vote_count]]</h2>
|
|
2
|
+
<!-- BEGIN votes -->
|
|
3
|
+
<a href="{config.relative_path}/user/{votes.userslug}" class="poll-result-details">
|
|
4
|
+
{buildAvatar(votes, "24px", true)}
|
|
5
|
+
</a>
|
|
6
|
+
<!-- END votes -->
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
<h3>{title}</h3>
|
|
2
|
-
<p>{content}</p>
|
|
1
|
+
<h3>{title}</h3>
|
|
2
|
+
<p>{content}</p>
|
|
3
3
|
<hr>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
<!-- BEGIN poll.options -->
|
|
2
|
-
<div class="poll-result" data-poll-option-id="{poll.options.id}">
|
|
3
|
-
<strong>{poll.options.title}</strong>
|
|
4
|
-
<small class="pull-right">
|
|
5
|
-
<a class="poll-result-votecount" href="#">
|
|
6
|
-
<span>{poll.options.voteCount}</span> [[poll:votes]]
|
|
7
|
-
</a>
|
|
8
|
-
</small>
|
|
9
|
-
<div class="progress">
|
|
10
|
-
<div class="progress-bar poll-result-progressbar" role="progressbar" aria-valuenow="{poll.options.percentage}" aria-valuemin="0" aria-valuemax="100" style="width: {poll.options.percentage}%;">
|
|
11
|
-
<span>{poll.options.percentage}</span
|
|
12
|
-
</div>
|
|
13
|
-
</div>
|
|
14
|
-
</div>
|
|
1
|
+
<!-- BEGIN poll.options -->
|
|
2
|
+
<div class="poll-result" data-poll-option-id="{poll.options.id}">
|
|
3
|
+
<strong>{poll.options.title}</strong>
|
|
4
|
+
<small class="pull-right">
|
|
5
|
+
<a class="poll-result-votecount" href="#">
|
|
6
|
+
<span>{poll.options.voteCount}</span> [[poll:votes]]
|
|
7
|
+
</a>
|
|
8
|
+
</small>
|
|
9
|
+
<div class="progress">
|
|
10
|
+
<div class="progress-bar poll-result-progressbar" role="progressbar" aria-valuenow="{poll.options.percentage}" aria-valuemin="0" aria-valuemax="100" style="width: {poll.options.percentage}%;">
|
|
11
|
+
<span><span class="percent">{poll.options.percentage}</span>%</span>
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
15
|
<!-- END poll.options -->
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
<form role="form" class="poll-voting-form">
|
|
2
|
-
<!-- BEGIN poll.options -->
|
|
3
|
-
<div class="poll-view-option {poll.optionType}" data-poll-option-id="{poll.options.id}">
|
|
4
|
-
<label>
|
|
5
|
-
<input type="{poll.optionType}" name="pollVoteSelection" value="{poll.options.id}">
|
|
6
|
-
{poll.options.title}
|
|
7
|
-
</label>
|
|
8
|
-
</div>
|
|
9
|
-
<!-- END poll.options -->
|
|
10
|
-
</form>
|
|
11
|
-
|
|
12
|
-
<!-- IF poll.settings.disallowVoteUpdate -->
|
|
13
|
-
<div class="alert alert-warning" role="alert">
|
|
14
|
-
[[poll:vote_is_final]]
|
|
15
|
-
</div>
|
|
16
|
-
<!-- ENDIF poll.settings.disallowVoteUpdate -->
|
|
1
|
+
<form role="form" class="poll-voting-form">
|
|
2
|
+
<!-- BEGIN poll.options -->
|
|
3
|
+
<div class="poll-view-option {poll.optionType}" data-poll-option-id="{poll.options.id}">
|
|
4
|
+
<label>
|
|
5
|
+
<input type="{poll.optionType}" name="pollVoteSelection" value="{poll.options.id}">
|
|
6
|
+
{poll.options.title}
|
|
7
|
+
</label>
|
|
8
|
+
</div>
|
|
9
|
+
<!-- END poll.options -->
|
|
10
|
+
</form>
|
|
11
|
+
|
|
12
|
+
<!-- IF poll.settings.disallowVoteUpdate -->
|
|
13
|
+
<div class="alert alert-warning" role="alert">
|
|
14
|
+
[[poll:vote_is_final]]
|
|
15
|
+
</div>
|
|
16
|
+
<!-- ENDIF poll.settings.disallowVoteUpdate -->
|
package/templates/poll/view.tpl
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
<div class="poll-view" data-poll-id="{poll.info.pollId}">
|
|
2
|
-
<div class="
|
|
3
|
-
<div class="
|
|
4
|
-
<h3 class="
|
|
5
|
-
<div class="btn-group
|
|
6
|
-
<a href="#" class="poll-button-edit">
|
|
7
|
-
<span class="fa fa-pencil"></span>
|
|
8
|
-
</a>
|
|
9
|
-
</div>
|
|
10
|
-
</div>
|
|
11
|
-
<div class="
|
|
12
|
-
<div class="poll-view-messages hidden"></div>
|
|
13
|
-
<div class="poll-view-voting <!-- IF poll.hasVoted -->hidden<!-- ENDIF poll.hasVoted -->">
|
|
14
|
-
<!-- IMPORT poll/view/voting.tpl -->
|
|
15
|
-
</div>
|
|
16
|
-
<div class="poll-view-results <!-- IF !poll.hasVoted -->hidden<!-- ENDIF !poll.hasVoted -->">
|
|
17
|
-
<!-- IMPORT poll/view/results.tpl -->
|
|
18
|
-
</div>
|
|
19
|
-
|
|
20
|
-
<div class="poll-view-buttons">
|
|
21
|
-
<button type="button" class="btn btn-primary poll-button-vote hidden">[[poll:vote]]</button>
|
|
22
|
-
<button type="button" class="btn btn-primary poll-button-update-vote hidden">[[poll:update_vote]]</button>
|
|
23
|
-
<button type="button" class="btn btn-danger poll-button-remove-vote hidden">[[poll:remove_vote]]</button>
|
|
24
|
-
<button type="button" class="btn btn-link poll-button-results hidden">[[poll:to_results]]</button>
|
|
25
|
-
<button type="button" class="btn btn-link poll-button-voting hidden">[[poll:to_voting]]</button>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
</div>
|
|
1
|
+
<div class="poll-view" data-poll-id="{poll.info.pollId}">
|
|
2
|
+
<div class="card">
|
|
3
|
+
<div class="card-header">
|
|
4
|
+
<h3 class="card-title">{poll.settings.title}</h3>
|
|
5
|
+
<div class="btn-group float-end hidden">
|
|
6
|
+
<a href="#" class="poll-button-edit">
|
|
7
|
+
<span class="fa fa-pencil"></span>
|
|
8
|
+
</a>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="card-body">
|
|
12
|
+
<div class="poll-view-messages hidden"></div>
|
|
13
|
+
<div class="poll-view-voting <!-- IF poll.hasVoted -->hidden<!-- ENDIF poll.hasVoted -->">
|
|
14
|
+
<!-- IMPORT poll/view/voting.tpl -->
|
|
15
|
+
</div>
|
|
16
|
+
<div class="poll-view-results <!-- IF !poll.hasVoted -->hidden<!-- ENDIF !poll.hasVoted -->">
|
|
17
|
+
<!-- IMPORT poll/view/results.tpl -->
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<div class="poll-view-buttons">
|
|
21
|
+
<button type="button" class="btn btn-primary poll-button-vote hidden">[[poll:vote]]</button>
|
|
22
|
+
<button type="button" class="btn btn-primary poll-button-update-vote hidden">[[poll:update_vote]]</button>
|
|
23
|
+
<button type="button" class="btn btn-danger poll-button-remove-vote hidden">[[poll:remove_vote]]</button>
|
|
24
|
+
<button type="button" class="btn btn-link poll-button-results hidden">[[poll:to_results]]</button>
|
|
25
|
+
<button type="button" class="btn btn-link poll-button-voting hidden">[[poll:to_voting]]</button>
|
|
26
|
+
</div>
|
|
27
|
+
</div>
|
|
28
|
+
</div>
|
|
29
29
|
</div>
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const db = require.main.require('./src/database');
|
|
4
|
-
const privileges = require.main.require('./src/privileges');
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
name: 'Fix incorrectly given poll privilege',
|
|
8
|
-
timestamp: Date.UTC(2020, 9, 29),
|
|
9
|
-
method: async () => {
|
|
10
|
-
const cids = await db.getSortedSetRange('categories:cid', 0, -1);
|
|
11
|
-
await Promise.all(cids.map(async (cid) => {
|
|
12
|
-
await privileges.categories.rescind(['poll:create'], cid, ['registered-users']);
|
|
13
|
-
}));
|
|
14
|
-
},
|
|
15
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const db = require.main.require('./src/database');
|
|
4
|
+
const privileges = require.main.require('./src/privileges');
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
name: 'Fix incorrectly given poll privilege',
|
|
8
|
+
timestamp: Date.UTC(2020, 9, 29),
|
|
9
|
+
method: async () => {
|
|
10
|
+
const cids = await db.getSortedSetRange('categories:cid', 0, -1);
|
|
11
|
+
await Promise.all(cids.map(async (cid) => {
|
|
12
|
+
await privileges.categories.rescind(['poll:create'], cid, ['registered-users']);
|
|
13
|
+
}));
|
|
14
|
+
},
|
|
15
|
+
};
|