nodebb-theme-persona 15.0.0-beta.1 → 15.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.
Files changed (43) hide show
  1. package/lib/controllers.js +2 -2
  2. package/library.js +2 -2
  3. package/package.json +3 -4
  4. package/public/admin.js +1 -1
  5. package/public/persona.js +18 -20
  6. package/scss/account.scss +0 -139
  7. package/scss/persona.scss +0 -1
  8. package/templates/account/categories.tpl +1 -1
  9. package/templates/account/consent.tpl +2 -0
  10. package/templates/account/info.tpl +2 -2
  11. package/templates/account/posts.tpl +1 -1
  12. package/templates/account/profile.tpl +69 -23
  13. package/templates/account/settings.tpl +3 -3
  14. package/templates/account/tags.tpl +1 -1
  15. package/templates/account/topics.tpl +1 -1
  16. package/templates/account/uploads.tpl +1 -1
  17. package/templates/partials/account/header.tpl +10 -10
  18. package/templates/partials/categories/lastpost.tpl +1 -1
  19. package/templates/partials/categories/link.tpl +5 -5
  20. package/templates/partials/category/tags.tpl +1 -1
  21. package/templates/partials/cookie-consent.tpl +2 -2
  22. package/templates/partials/menu.tpl +4 -4
  23. package/templates/partials/notifications_list.tpl +1 -1
  24. package/templates/partials/posts_list_item.tpl +2 -2
  25. package/templates/partials/search-filters.tpl +9 -9
  26. package/templates/partials/search-results.tpl +2 -2
  27. package/templates/partials/tags_list.tpl +4 -1
  28. package/templates/partials/topic/icon.tpl +4 -0
  29. package/templates/partials/topic/post.tpl +2 -2
  30. package/templates/partials/topic/tag.tpl +1 -1
  31. package/templates/partials/topics_list.tpl +3 -3
  32. package/templates/topic.tpl +1 -1
  33. package/scss/groups.scss +0 -111
  34. package/templates/groups/details.tpl +0 -114
  35. package/templates/groups/list.tpl +0 -46
  36. package/templates/groups/members.tpl +0 -6
  37. package/templates/partials/groups/admin.tpl +0 -96
  38. package/templates/partials/groups/badge.tpl +0 -1
  39. package/templates/partials/groups/invited.tpl +0 -33
  40. package/templates/partials/groups/list.tpl +0 -21
  41. package/templates/partials/groups/memberlist.tpl +0 -45
  42. package/templates/partials/groups/pending.tpl +0 -28
  43. package/templates/partials/toast.tpl +0 -19
@@ -5,7 +5,7 @@
5
5
  </a>
6
6
 
7
7
  <div component="post/content" class="content mb-3">
8
- {{../content}}
8
+ {{txEscape(../content)}}
9
9
  </div>
10
10
 
11
11
  <div class="mb-3">
@@ -15,7 +15,7 @@
15
15
  {{{ if ../topic.tags.length }}}
16
16
  <span class="tag-list">
17
17
  {{{ each ../topic.tags }}}
18
- <a href="{config.relative_path}/tags/{topic.tags.valueEncoded}"><span class="tag tag-item tag-class-{topic.tags.class}">{topic.tags.valueEscaped}</span></a>
18
+ <a href="{config.relative_path}/tags/{topic.tags.valueEncoded}"><span class="tag tag-item tag-class-{topic.tags.class}">{topic.tags.value}</span></a>
19
19
  {{{ end }}}
20
20
  </span>
21
21
  {{{ end }}}
@@ -3,7 +3,7 @@
3
3
  <div class="post-search-item">
4
4
  <div component="category/filter" class="dropdown" data-filter-name="category">
5
5
  <a component="category/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.categories.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
6
- <span class="filter-label">{{{ if filters.categories.active }}}{filters.categories.label}{{{ else }}}[[search:categories]]{{{ end }}}</span>
6
+ <span class="filter-label">{{{ if filters.categories.active }}}{tx(filters.categories.label)}{{{ else }}}[[search:categories]]{{{ end }}}</span>
7
7
  <span class="caret text-primary opacity-75"></span>
8
8
  </a>
9
9
 
@@ -29,7 +29,7 @@
29
29
  <div class="post-search-item">
30
30
  <div component="tag/filter" class="dropdown" data-filter-name="tag">
31
31
  <a component="tag/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.tags.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
32
- <span class="filter-label">{{{ if filters.tags.active }}}{filters.tags.label}{{{ else }}}[[search:tags]]{{{ end }}}</span>
32
+ <span class="filter-label">{{{ if filters.tags.active }}}{tx(filters.tags.label)}{{{ else }}}[[search:tags]]{{{ end }}}</span>
33
33
  <span class="caret text-primary opacity-75"></span>
34
34
  </a>
35
35
 
@@ -39,15 +39,15 @@
39
39
  <div component="tag/filter/selected" class="d-flex flex-wrap gap-2">
40
40
  {{{ each tagFilterSelected }}}
41
41
  <div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
42
- <div>{./valueEscaped}</div>
43
- <button component="tag/filter/delete" data-tag="{./valueEscaped}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
42
+ <div>{./value}</div>
43
+ <button component="tag/filter/delete" data-tag="{./value}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
44
44
  </div>
45
45
  {{{ end }}}
46
46
  </div>
47
47
  <hr class="my-2"/>
48
48
  <div component="tag/filter/results" class="d-flex flex-wrap gap-2">
49
49
  {{{ each tagFilterResults }}}
50
- <button class="btn btn-light btn-sm border" data-tag="{./valueEscaped}">{./valueEscaped}</button>
50
+ <button class="btn btn-light btn-sm border" data-tag="{./value}">{./value}</button>
51
51
  {{{ end }}}
52
52
  </div>
53
53
  </li>
@@ -59,7 +59,7 @@
59
59
  <div class="post-search-item">
60
60
  <div component="user/filter" class="dropdown" data-filter-name="user">
61
61
  <a component="user/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.users.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
62
- <span class="filter-label">{{{ if filters.users.active }}}{filters.users.label}{{{ else }}}[[search:posted-by]]{{{ end }}}</span>
62
+ <span class="filter-label">{{{ if filters.users.active }}}{tx(filters.users.label)}{{{ else }}}[[search:posted-by]]{{{ end }}}</span>
63
63
  <span class="caret text-primary opacity-75"></span>
64
64
  </a>
65
65
 
@@ -90,7 +90,7 @@
90
90
  <div class="post-search-item">
91
91
  <div class="dropdown" data-filter-name="replies">
92
92
  <a id="reply-count-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.replies.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
93
- <span class="filter-label">{{{ if filters.replies.active }}}{filters.replies.label}{{{ else }}}[[search:replies]]{{{ end }}}</span>
93
+ <span class="filter-label">{{{ if filters.replies.active }}}{tx(filters.replies.label)}{{{ else }}}[[search:replies]]{{{ end }}}</span>
94
94
  <span class="caret text-primary opacity-75"></span>
95
95
  </a>
96
96
 
@@ -110,7 +110,7 @@
110
110
  <div class="post-search-item">
111
111
  <div class="dropdown" data-filter-name="time">
112
112
  <a id="post-time-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.time.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
113
- <span class="filter-label">{{{ if filters.time.active }}}{filters.time.label}{{{ else }}}[[search:time]]{{{ end }}}</span>
113
+ <span class="filter-label">{{{ if filters.time.active }}}{tx(filters.time.label)}{{{ else }}}[[search:time]]{{{ end }}}</span>
114
114
  <span class="caret text-primary opacity-75"></span>
115
115
  </a>
116
116
 
@@ -139,7 +139,7 @@
139
139
  <div class="post-search-item">
140
140
  <div class="dropdown" data-filter-name="sort">
141
141
  <a id="sort-by-button" class="filter-btn btn btn-light btn-sm border {{{ if filters.sort.active }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
142
- <span class="filter-label">{{{ if filters.sort.active }}}{filters.sort.label}{{{ else }}}[[search:sort]]{{{ end }}}</span>
142
+ <span class="filter-label">{{{ if filters.sort.active }}}{tx(filters.sort.label)}{{{ else }}}[[search:sort]]{{{ end }}}</span>
143
143
  <span class="caret text-primary opacity-75"></span>
144
144
  </a>
145
145
 
@@ -1,6 +1,6 @@
1
1
  <div id="results" class="search-results col-md-12" data-search-query="{search_query}">
2
2
  {{{ if matchCount }}}
3
- <div class="alert alert-info">[[search:results-matching, {matchCount}, {txEscape(search_query)}, {time}]] </div>
3
+ <div class="alert alert-info">{{tx("search:results-matching", matchCount, txEscape(search_query), time)}}</div>
4
4
  {{{ else }}}
5
5
  {{{ if search_query }}}
6
6
  <div class="alert alert-warning">[[search:no-matches]]</div>
@@ -25,7 +25,7 @@
25
25
  <a href="{config.relative_path}/category/{./category.slug}">
26
26
  <div class="category-item d-inline-block">
27
27
  {{buildCategoryIcon(./category, "24px", "rounded-circle")}}
28
- {./category.name}
28
+ {tx(./category.name)}
29
29
  </div>
30
30
  </a> &bull;
31
31
  <span class="timeago" title="{./timestampISO}"></span>
@@ -1,5 +1,8 @@
1
1
  {{{each tags}}}
2
2
  <h5 class="float-start tag-container me-5 mb-5 fw-bold">
3
- <a href="{config.relative_path}/tags/{tags.valueEncoded}" data-tag="{tags.valueEscaped}"><span class="tag-item text-muted text-uppercase text-nowrap tag-class-{tags.class} me-2" data-tag="{tags.valueEscaped}">{tags.valueEscaped}</span><span class="tag-topic-count text-primary text-nowrap" title="{tags.score}">{formattedNumber(tags.score)}</span></a>
3
+ <a href="{config.relative_path}/tags/{./valueEncoded}" data-tag="{./value}">
4
+ <span class="tag-item text-muted text-uppercase text-nowrap tag-class-{tags.class} me-2" data-tag="{tags.value}">{./value}</span>
5
+ <span class="tag-topic-count text-primary text-nowrap" title="{./score}">{tx("global:x-topics", formattedNumber(./score))}</span>
6
+ </a>
4
7
  </h5>
5
8
  {{{end}}}
@@ -0,0 +1,4 @@
1
+ <span class="badge border {./classes}">
2
+ {{{ if ./icon }}}<i class="fa {./icon}"></i>{{{ end }}}
3
+ {{{ if ./label }}}<span> {tx(./label)}</span>{{{ end }}}
4
+ </span>
@@ -77,7 +77,7 @@
77
77
 
78
78
  <div class="post-footer">
79
79
  {{{ if posts.user.signature }}}
80
- <div component="post/signature" data-uid="{posts.user.uid}" class="post-signature">{{posts.user.signature}}</div>
80
+ <div component="post/signature" data-uid="{posts.user.uid}" class="post-signature">{{txEscape(posts.user.signature)}}</div>
81
81
  {{{ end }}}
82
82
 
83
83
  <div class="clearfix">
@@ -92,7 +92,7 @@
92
92
  {{{ end }}}
93
93
  </span>
94
94
 
95
- <span class="replies-count small" component="post/reply-count/text" data-replies="{posts.replies.count}">{posts.replies.text}</span>
95
+ <span class="replies-count small" component="post/reply-count/text" data-replies="{posts.replies.count}">{tx(posts.replies.text)}</span>
96
96
  <span class="replies-last hidden-xs small">[[topic:last-reply-time]] <span class="timeago" title="{posts.replies.timestampISO}"></span></span>
97
97
 
98
98
  <i class="fa fa-fw fa-chevron-down" component="post/replies/open"></i>
@@ -1 +1 @@
1
- <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="badge border border-gray-300 fw-normal tag tag-class-{./class}" data-tag="{./value}">{./valueEscaped}</span></a>
1
+ <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="badge border border-gray-300 fw-normal tag tag-class-{./class}" data-tag="{./value}">{./value}</span></a>
@@ -48,7 +48,7 @@
48
48
  <i class="fa fa-arrow-circle-right"></i>
49
49
  <span>[[topic:moved]]</span>
50
50
  </span>
51
- {{{each ./icons}}}<span class="lh-1">{@value}</span>{{{end}}}
51
+ {{{ each ./icons }}}<!-- IMPORT partials/topic/icon.tpl -->{{{ end }}}
52
52
 
53
53
  {{{ if (!template.category || (cid != ./cid)) }}}
54
54
  {{buildCategoryLabel(./category, "a", "border")}}
@@ -56,7 +56,7 @@
56
56
 
57
57
  <span data-tid="{./tid}" component="topic/tags" class="lh-1 tag-list d-flex flex-wrap gap-1 {{{ if !./tags.length }}}hidden{{{ end }}}">
58
58
  {{{ each ./tags }}}
59
- <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="badge border border-gray-300 fw-normal tag tag-class-{./class}" data-tag="{./value}">{./valueEscaped}</span></a>
59
+ <a href="{config.relative_path}/tags/{./valueEncoded}"><span class="badge border border-gray-300 fw-normal tag tag-class-{./class}" data-tag="{./value}">{./value}</span></a>
60
60
  {{{ end }}}
61
61
  </span>
62
62
 
@@ -119,7 +119,7 @@
119
119
  </div>
120
120
  <div class="post-content text-xs ps-2 line-clamp-sm-2 lh-sm text-break position-relative flex-fill">
121
121
  <a class="stretched-link" tabindex="-1" href="{config.relative_path}/topic/{./slug}/{./teaser.index}" aria-label="[[global:lastpost]]"></a>
122
- {{./teaser.content}}
122
+ {{txEscape(./teaser.content)}}
123
123
  </div>
124
124
  {{{ end }}}
125
125
  {{{ end }}}
@@ -30,7 +30,7 @@
30
30
  <a component="topic/moved" href="{config.relative_path}/category/{oldCid}" class="badge badge border border-gray-300 text-body text-decoration-none {{{ if !oldCid }}}hidden{{{ end }}}">
31
31
  <i class="fa fa-arrow-circle-right"></i> {{{ if privileges.isAdminOrMod }}}[[topic:moved-from, {oldCategory.name}]]{{{ else }}}[[topic:moved]]{{{ end }}}
32
32
  </a>
33
- {{{each icons}}}<span class="lh-1">{@value}</span>{{{end}}}
33
+ {{{ each ./icons }}}<!-- IMPORT partials/topic/icon.tpl -->{{{ end }}}
34
34
  </span>
35
35
  {{buildCategoryLabel(category, "a", "border")}}
36
36
  <div data-tid="{./tid}" component="topic/tags" class="lh-1 tags tag-list d-flex flex-wrap hidden-xs hidden-empty gap-2"><!-- IMPORT partials/topic/tags.tpl --></div>
package/scss/groups.scss DELETED
@@ -1,111 +0,0 @@
1
- .groups.details {
2
- margin-top: 200px;
3
-
4
- [component="groups/cover"] {
5
- background-size: cover;
6
- background-repeat: no-repeat;
7
- background-origin: content-box;
8
-
9
- min-height: 200px;
10
- width: 100%;
11
- margin-bottom: 1em;
12
- padding-left: 0;
13
- padding-right: 0;
14
-
15
- position: absolute;
16
- top: var(--panel-offset);
17
- right: 0;
18
- left: auto;
19
-
20
- &:hover {
21
- .controls {
22
- opacity: 0.8;
23
- }
24
- }
25
-
26
- .controls {
27
- text-align: center;
28
- min-height: 200px;
29
- line-height: 200px;
30
- opacity: 0;
31
- @include transition(opacity .15s linear);
32
- cursor: pointer;
33
- pointer-events: none;
34
-
35
- > * {
36
- pointer-events: all;
37
- }
38
-
39
- .fa {
40
- color: white;
41
- background-color: #333;
42
- opacity: 1;
43
- margin: 15px;
44
- padding: 5px;
45
- }
46
- }
47
-
48
- &.active {
49
- &:hover {
50
- cursor: move;
51
- }
52
-
53
- .controls {
54
- > * {
55
- display: none;
56
- }
57
- }
58
-
59
- .save {
60
- display: inline-block;
61
- }
62
- }
63
-
64
- &.saving {
65
- .save {
66
- display: none;
67
- }
68
-
69
- .indicator {
70
- display: inline-block;
71
- }
72
- }
73
-
74
- .save, .indicator {
75
- display: inline-block;
76
- position: absolute;
77
- top: 1em;
78
- right: 2em;
79
- opacity: 1;
80
- background-color: $primary;
81
- color: $gray-200;
82
- padding: 0.5em;
83
- font-weight: bold;
84
-
85
- &:hover {
86
- cursor: pointer;
87
- }
88
- }
89
-
90
- .save {
91
- display: none;
92
- }
93
-
94
- .indicator {
95
- display: none;
96
- }
97
- }
98
-
99
- @include media-breakpoint-up(md) {
100
- margin-top: 300px;
101
-
102
- [component="groups/cover"] {
103
- min-height: 300px;
104
-
105
- .controls {
106
- min-height: 300px;
107
- line-height: 300px;
108
- }
109
- }
110
- }
111
- }
@@ -1,114 +0,0 @@
1
- <div component="groups/container" class="groups details">
2
-
3
- <div component="groups/cover" style="background-image: url({group.cover:url}?{config.cache-buster}); background-position: {group.cover:position};">
4
- {{{ if group.isOwner }}}
5
- <div class="controls">
6
- <span class="upload"><i class="fa fa-fw fa-4x fa-upload"></i></span>
7
- <span class="resize"><i class="fa fa-fw fa-4x fa-arrows"></i></span>
8
- <span class="remove"><i class="fa fa-fw fa-4x fa-times"></i></span>
9
- </div>
10
- <div class="save">[[groups:cover-save]] <i class="fa fa-fw fa-floppy-o"></i></div>
11
- <div class="indicator">[[groups:cover-saving]] <i class="fa fa-fw fa-refresh fa-spin"></i></div>
12
- {{{ end }}}
13
- </div>
14
-
15
- <div>
16
- <!-- IMPORT partials/breadcrumbs.tpl -->
17
- </div>
18
-
19
- <div class="d-flex flex-column flex-md-row justify-content-md-between pb-2 mb-4 mt-2 border-bottom gap-3">
20
- <div class="d-flex flex-column gap-2">
21
- <div class="d-flex flex-column flex-md-row align-items-md-center gap-2">
22
- <h3 class="mb-0 text-capitalize">{generateGroupDisplayName(group)}</h3>
23
- <div>
24
- {{{ if group.private }}}<span class="badge text-bg-light border border-1">[[groups:details.private]]</span>{{{ end }}}
25
- {{{ if group.hidden }}}<span class="badge text-bg-light border border-1">[[groups:details.hidden]]</span>{{{ end }}}
26
- </div>
27
- </div>
28
- <div>
29
- {{group.descriptionParsed}}
30
- </div>
31
- </div>
32
- <div class="d-flex gap-2 align-items-start">
33
- {{{ if loggedIn }}}
34
- {{membershipBtn(group)}}
35
- {{{ end }}}
36
- {{{ if isAdmin }}}
37
- <a href="{config.relative_path}/admin/manage/groups/{group.slug}" target="_blank" class="btn btn-light text-nowrap"><i class="fa fa-gear"></i> [[user:edit]]</a>
38
- {{{ end }}}
39
- </div>
40
- </div>
41
-
42
- <div class="text-sm mb-3 nav d-flex flex-row flex-wrap gap-1 justify-content-end">
43
- <button data-bs-toggle="tab" data-bs-target="#groups-posts" class="btn btn-ghost btn-sm text-start d-flex align-items-center ff-secondary fw-semibold {{{ if template.groups/details }}}active{{{ end }}}">
44
- <div class="flex-grow-1">[[global:posts]]</div>
45
- </button>
46
- <button data-bs-toggle="tab" data-bs-target="#groups-members" class="btn btn-ghost btn-sm text-start d-flex align-items-center ff-secondary fw-semibold gap-2">
47
- <div class="flex-grow-1">[[groups:members]]</div>
48
- <span component="group/member/count" class="flex-shrink-0 text-xs" title="{group.memberCount}">{humanReadableNumber(group.memberCount)}</span>
49
- </button>
50
-
51
- {{{ if group.isOwner }}}
52
- <button data-bs-toggle="tab" data-bs-target="#groups-pending" class="btn btn-ghost btn-sm text-start d-flex align-items-center ff-secondary fw-semibold gap-2">
53
- <div class="flex-grow-1">[[groups:details.pending]]</div>
54
- <span component="group/pending/count" class="flex-shrink-0 text-xs" title="{group.pending.length}">{humanReadableNumber(group.pending.length)}</span>
55
- </button>
56
-
57
- <button data-bs-toggle="tab" data-bs-target="#groups-invited" class="btn btn-ghost btn-sm text-start d-flex align-items-center ff-secondary fw-semibold gap-2">
58
- <div class="flex-grow-1">[[groups:details.invited]]</div>
59
- <span component="group/invited/count" class="flex-shrink-0 text-xs" title="{group.invited.length}">{humanReadableNumber(group.invited.length)}</span>
60
- </button>
61
-
62
- <button data-bs-toggle="tab" data-bs-target="#groups-admin" class="btn btn-ghost btn-sm text-start d-flex align-items-center ff-secondary fw-semibold">
63
- <div class="flex-grow-1">[[global:header.admin]]</div>
64
- </button>
65
- {{{ end }}}
66
- </div>
67
-
68
- <div class="d-flex flex-column flex-md-row">
69
- <div data-widget-area="left">
70
- {{{each widgets.left}}}
71
- {{widgets.left.html}}
72
- {{{end}}}
73
- </div>
74
-
75
- <div class="flex-grow-1" style="min-width:0;">
76
- <div class="tab-content">
77
- <div class="tab-pane fade show active" id="groups-posts" role="tabpanel">
78
- <h3 class="fw-semibold fs-5">[[global:posts]]</h3>
79
- {{{ if !posts.length }}}
80
- <div class="alert alert-info my-2">[[groups:details.has-no-posts]]</div>
81
- {{{ end }}}
82
- <!-- IMPORT partials/posts_list.tpl -->
83
- </div>
84
- <div class="tab-pane fade" id="groups-members" role="tabpanel">
85
- <h3 class="fw-semibold fs-5 mb-3">[[groups:details.members]]</h3>
86
-
87
- <!-- IMPORT partials/groups/memberlist.tpl -->
88
- </div>
89
- {{{ if group.isOwner }}}
90
- <div class="tab-pane fade" id="groups-pending" role="tabpanel">
91
- <h3 class="fw-semibold fs-5 mb-3">[[groups:details.pending]]</h3>
92
- <!-- IMPORT partials/groups/pending.tpl -->
93
- </div>
94
-
95
- <div class="tab-pane fade" id="groups-invited" role="tabpanel">
96
- <h3 class="fw-semibold fs-5 mb-3">[[groups:details.invited]]</h3>
97
- <!-- IMPORT partials/groups/invited.tpl -->
98
- </div>
99
-
100
- <div class="tab-pane fade" id="groups-admin" role="tabpanel">
101
- <h3 class="fw-semibold fs-5 mb-3">[[groups:details.owner-options]]</h3>
102
- <!-- IMPORT partials/groups/admin.tpl -->
103
- </div>
104
- {{{ end }}}
105
- </div>
106
- </div>
107
-
108
- <div data-widget-area="right">
109
- {{{each widgets.right}}}
110
- {{widgets.right.html}}
111
- {{{end}}}
112
- </div>
113
- </div>
114
- </div>
@@ -1,46 +0,0 @@
1
- <!-- IMPORT partials/breadcrumbs.tpl -->
2
- <div data-widget-area="header">
3
- {{{each widgets.header}}}
4
- {{widgets.header.html}}
5
- {{{end}}}
6
- </div>
7
- <div class="groups list">
8
- <div class="d-flex justify-content-between align-items-center gap-3 flex-wrap">
9
- <div>
10
- {{{ if allowGroupCreation }}}
11
- <button class="btn btn-sm btn-primary" data-action="new"><i class="fa fa-plus"></i> [[groups:new-group]]</button>
12
- {{{ end }}}
13
- </div>
14
-
15
- <div class="d-flex gap-3 align-items-center">
16
- <select class="form-select form-select-sm" id="search-sort">
17
- <option value="alpha">[[groups:details.group-name]]</option>
18
- <option value="count">[[groups:details.member-count]]</option>
19
- <option value="date">[[groups:details.creation-date]]</option>
20
- </select>
21
-
22
- <div class="input-group">
23
- <input type="text" class="form-control form-control-sm" placeholder="[[global:search]]" name="query" value="" id="search-text">
24
- <button id="search-button" class="btn btn-sm btn-primary">
25
- <i class="fa fa-search"></i>
26
- </button>
27
- </div>
28
- </div>
29
- </div>
30
-
31
- <hr />
32
-
33
- <div component="groups/container" class="row" id="groups-list">
34
- {{{ if groups.length }}}
35
- <!-- IMPORT partials/groups/list.tpl -->
36
- {{{ else }}}
37
- <div class="col-12">
38
- <div class="alert alert-warning">
39
- [[groups:no-groups-found]]
40
- </div>
41
- </div>
42
- {{{ end }}}
43
- </div>
44
-
45
- <!-- IMPORT partials/paginator.tpl -->
46
- </div>
@@ -1,6 +0,0 @@
1
- <!-- IMPORT partials/breadcrumbs.tpl -->
2
- <div class="users">
3
- <!-- IMPORT partials/users_list.tpl -->
4
-
5
- <!-- IMPORT partials/paginator.tpl -->
6
- </div>
@@ -1,96 +0,0 @@
1
- <form component="groups/settings" role="form">
2
- <div class="mb-3">
3
- <label class="form-label" for="name">[[groups:details.group-name]]</label>
4
- <input <!-- IF group.system -->readonly<!-- ENDIF group.system --> class="form-control" name="name" id="name" type="text" value="{group.displayName}" />
5
- </div>
6
- <div class="mb-3">
7
- <label class="form-label" for="description">[[groups:details.description]]</label>
8
- <textarea class="form-control" name="description" id="description" type="text" maxlength="255">{group.description}</textarea>
9
- </div>
10
-
11
- <hr />
12
- <div class="mb-3">
13
- <label class="form-label" for="memberPostCids">[[groups:details.member-post-cids]]</label>
14
- <div class="row">
15
- <div class="col-md-6">
16
- <input id="memberPostCids" type="text" class="form-control" value="{group.memberPostCids}">
17
- </div>
18
- <div class="col-md-6 member-post-cids-selector">
19
- <!-- IMPORT partials/category/selector-dropdown-left.tpl -->
20
- </div>
21
- </div>
22
- </div>
23
-
24
- <hr />
25
-
26
- <div class="mb-3 user-title-option">
27
- <label class="form-label" for="userTitle">[[groups:details.badge-text]]</label>
28
- <div class="d-flex gap-2">
29
- <input component="groups/userTitleOption" class="form-control" name="userTitle" id="userTitle" type="text" maxlength="40" value="{group.userTitle}"<!-- IF !group.userTitleEnabled --> disabled<!-- ENDIF !group.userTitleEnabled --> />
30
- <button component="groups/userTitleOption" type="button" class="btn btn-outline-secondary btn-sm text-nowrap" data-action="icon-select"<!-- IF !group.userTitleEnabled --> disabled<!-- ENDIF !group.userTitleEnabled -->>[[groups:details.change-icon]]</button>
31
- </div>
32
- </div>
33
-
34
- <div class="mb-3 user-title-option">
35
- <div class="d-flex align-items-center gap-3">
36
- <label class="form-label mb-0">[[groups:details.badge-preview]]</label>
37
- <span class="badge rounded-1 text-uppercase text-truncate rounded-1 d-flex align-items-center gap-1 {{{ if !group.userTitleEnabled }}} hide{{{ end }}}" style="max-width:150px; color: {group.textColor}; background-color: {group.labelColor}"><i class="fa {{{ if (group.icon && (group.icon != "fa-nbb-none")) }}}{group.icon}{{{ else }}}hidden{{{ end }}}"></i><span class="badge-text">{{{ if group.userTitle }}}{group.userTitle}{{{ end }}}</span></span>
38
- </div>
39
- <hr/>
40
- <div class="d-flex flex-column gap-2">
41
- <div class="d-flex align-items-center gap-2">
42
- <label class="form-label mb-0" for="labelColor" class="badge-color-label">[[groups:details.change-label-colour]]</label>
43
- <input component="groups/userTitleOption" type="color" name="labelColor" id="labelColor" value="<!-- IF group.labelColor -->{group.labelColor}<!-- ENDIF group.labelColor -->" />
44
- </div>
45
- <div class="d-flex align-items-center gap-2">
46
- <label class="form-label mb-0" for="textColor" class="badge-color-label">[[groups:details.change-text-colour]]</label>
47
- <input component="groups/userTitleOption" type="color" name="textColor" id="textColor" value="<!-- IF group.textColor -->{group.textColor}<!-- ENDIF group.textColor -->" />
48
- </div>
49
- <input type="hidden" name="icon" value="<!-- IF group.icon -->{group.icon}<!-- ENDIF group.icon -->" />
50
- </div>
51
- <div id="icons" class="hidden">
52
- <div class="icon-container">
53
- <div class="row nbb-fa-icons">
54
- <!-- IMPORT partials/fontawesome.tpl -->
55
- </div>
56
- </div>
57
- </div>
58
- </div>
59
- <hr />
60
- <div class="form-check">
61
- <label class="form-check-label" for="userTitleEnabled">[[groups:details.userTitleEnabled]]</label>
62
- <input class="form-check-input" name="userTitleEnabled" id="userTitleEnabled" type="checkbox"<!-- IF group.userTitleEnabled --> checked<!-- ENDIF group.userTitleEnabled -->>
63
- </div>
64
- <div class="form-check">
65
- <label class="form-check-label" for="private">[[groups:details.private]]</label>
66
- <input class="form-check-input" name="private" id="private" type="checkbox"<!-- IF group.private --> checked<!-- ENDIF group.private -->>
67
- <!-- IF !allowPrivateGroups -->
68
- <p class="form-text">
69
- [[groups:details.private-system-help]]
70
- </p>
71
- <!-- ENDIF !allowPrivateGroups -->
72
- <p class="form-text">
73
- [[groups:details.private-help]]
74
- </p>
75
- </div>
76
- <div class="form-check">
77
- <label class="form-check-label" for="disableJoinRequests">[[groups:details.disableJoinRequests]]</label>
78
- <input class="form-check-input" name="disableJoinRequests" id="disableJoinRequests" type="checkbox"<!-- IF group.disableJoinRequests --> checked<!-- ENDIF group.disableJoinRequests -->>
79
- </div>
80
- <div class="form-check">
81
- <label class="form-check-label" for="disableLeave">[[groups:details.disableLeave]]</label>
82
- <input class="form-check-input" name="disableLeave" id="disableLeave" type="checkbox"{{{if group.disableLeave}}} checked{{{end}}}>
83
- </div>
84
- <div class="form-check">
85
- <label class="form-check-label" for="hidden">[[groups:details.hidden]]</label>
86
- <input class="form-check-input" name="hidden" id="hidden" type="checkbox"<!-- IF group.hidden --> checked<!-- ENDIF group.hidden -->>
87
- <p class="form-text">
88
- [[groups:details.hidden-help]]
89
- </p>
90
- </div>
91
-
92
- <div class="d-flex justify-content-end gap-2">
93
- <button class="btn btn-link text-danger" type="button" data-action="delete">[[groups:details.delete-group]]</button>
94
- <button class="btn btn-primary" type="button" data-action="update">[[global:save-changes]]</button>
95
- </div>
96
- </form>
@@ -1 +0,0 @@
1
- <a href="{config.relative_path}/groups/{./slug}" class="badge rounded-1 text-uppercase text-truncate text-decoration-none d-flex align-items-center gap-1" style="line-height: normal; 150px;color:{./textColor};background-color: {./labelColor};"><i class="fa {{{ if (./icon && (./icon != "fa-nbb-none")) }}}{./icon}{{{else}}}hidden{{{ end }}}"></i><span class="badge-text">{{{ if ./userTitle }}}{./userTitle}{{{ end }}}</span></a>
@@ -1,33 +0,0 @@
1
- <label class="text-xs text-muted">[[groups:invited.search]]</label>
2
- <div class="input-group mb-2">
3
- <input class="form-control" type="text" component="groups/members/invite"/>
4
- <span class="input-group-text search-button"><i class="fa fa-search"></i></span>
5
- </div>
6
-
7
- <div class="mb-2">
8
- <label class="text-xs text-muted">[[groups:bulk-invite-instructions]]</label>
9
- <textarea class="form-control" component="groups/members/bulk-invite"></textarea>
10
- </div>
11
-
12
- <div class="mb-2 clearfix">
13
- <button type="button" class="btn btn-primary btn-sm float-end" component="groups/members/bulk-invite-button">[[groups:bulk-invite]]</button>
14
- </div>
15
-
16
- <div style="max-height: 500px; overflow: auto;">
17
- <div component="groups/invited/alert" class="alert alert-info {{{ if group.invited.length }}}hidden{{{ end }}}">[[groups:invited.none]]</div>
18
- <table component="groups/invited" class="table table-hover">
19
- <tbody>
20
- {{{ each group.invited }}}
21
- <tr data-uid="{group.invited.uid}" class="align-middle">
22
- <td class="member-name p-2 d-flex align-items-center justify-content-between">
23
- <div class="d-flex align-items-center gap-2">
24
- <a class="text-decoration-none" href="{config.relative_path}/user/{group.invited.userslug}">{{buildAvatar(group.invited, "24px", true)}}</a>
25
- <a href="{config.relative_path}/user/{group.invited.userslug}">{group.invited.username}</a>
26
- </div>
27
- <button class="btn btn-outline-secondary btn-sm text-nowrap" data-action="rescindInvite">[[groups:invited.uninvite]]</button>
28
- </td>
29
- </tr>
30
- {{{ end }}}
31
- </tbody>
32
- </table>
33
- </div>
@@ -1,21 +0,0 @@
1
- {{{each groups}}}
2
- <div class="col-lg-4 col-md-6 col-sm-12 mb-3" component="groups/summary" data-slug="{groups.slug}">
3
- <div class="card h-100">
4
- <a href="{config.relative_path}/groups/{groups.slug}" class="card-header list-cover" style="{{{ if groups.cover:thumb:url }}}background-image: url({./cover:thumb:url});background-size: cover; min-height: 125px; background-position: {./cover:position}{{{ end }}}">
5
- <h5 class="card-title d-inline-block mw-100 px-2 py-1 text-truncate text-capitalize fw-bold rounded-1" style="color: white;background-color: rgba(0,0,0,0.5);">{generateGroupDisplayName(@value)} <small>{formattedNumber(groups.memberCount)}</small></h5>
6
- </a>
7
- <div class="card-body">
8
- <p class="text-muted">
9
- {./description}
10
- </p>
11
- <ul class="members list-unstyled d-flex align-items-center gap-2 flex-wrap">
12
- {{{each groups.members}}}
13
- <li>
14
- <a href="{config.relative_path}/user/{groups.members.userslug}">{{buildAvatar(groups.members, "24px", true)}}</a>
15
- </li>
16
- {{{end}}}
17
- </ul>
18
- </div>
19
- </div>
20
- </div>
21
- {{{end}}}