mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
refactor: move flags into core
This commit is contained in:
179
src/views/flags/detail.tpl
Normal file
179
src/views/flags/detail.tpl
Normal file
@@ -0,0 +1,179 @@
|
||||
<!-- IMPORT partials/breadcrumbs.tpl -->
|
||||
|
||||
<div class="d-flex flex-column flex-md-row">
|
||||
<div class="flex-shrink-0 d-flex flex-column gap-3 border-end-md text-sm mb-3 pe-4" style="flex-basis: 240px !important;">
|
||||
<div class="d-grid gap-1">
|
||||
<a class="btn btn-ghost btn-sm ff-secondary border d-flex gap-2 align-items-center" href="{config.relative_path}/{type_path}/{targetId}">
|
||||
<i class="fa fa-fw fa-external-link text-primary"></i>
|
||||
[[flags:go-to-target]]
|
||||
</a>
|
||||
|
||||
{{{ if target.uid }}}
|
||||
<div class="btn-group dropend" data-uid="{target.uid}">
|
||||
<button type="button" class="btn btn-ghost btn-sm ff-secondary border d-flex gap-2 align-items-center dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<i class="fa fa-fw fa-street-view text-primary"></i>
|
||||
[[flags:flagged-user]]
|
||||
<i class="fa fa-chevron-right ms-auto text-secondary"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu p-1 text-sm" role="menu">
|
||||
<li><a class="dropdown-item rounded-1" href="{config.relative_path}/uid/{target.uid}" role="menuitem">[[flags:view-profile]]</a></li>
|
||||
{{{ if !config.disableChat }}}
|
||||
<li><a class="dropdown-item rounded-1" href="#" data-action="chat" role="menuitem">[[flags:start-new-chat]]</a></li>
|
||||
{{{ end }}}
|
||||
<li class="dropdown-divider"></li>
|
||||
{{{ if privileges.ban }}}
|
||||
<li class="{{{ if target.user.banned }}}hidden{{{ end }}}"><a class="dropdown-item rounded-1" href="#" data-action="ban" role="menuitem">[[user:ban-account]]</a></li>
|
||||
<li class="{{{ if !target.user.banned }}}hidden{{{ end }}}"><a class="dropdown-item rounded-1" href="#" data-action="unban" role="menuitem">[[user:unban-account]]</a></li>
|
||||
{{{ end }}}
|
||||
{{{ if privileges.mute}}}
|
||||
<li class="{{{ if target.user.muted }}}hidden{{{ end }}}"><a class="dropdown-item rounded-1" href="#" data-action="mute" role="menuitem">[[user:mute-account]]</a></li>
|
||||
<li class="{{{ if !target.user.muted }}}hidden{{{ end }}}"><a class="dropdown-item rounded-1" href="#" data-action="unmute" role="menuitem">[[user:unmute-account]]</a></li>
|
||||
{{{ end }}}
|
||||
{{{ if privileges.admin:users }}}
|
||||
<li><a class="dropdown-item rounded-1" href="#" data-action="delete-account" role="menuitem">[[user:delete-account-as-admin]]</a></li>
|
||||
<li><a class="dropdown-item rounded-1" href="#" data-action="delete-content" role="menuitem">[[user:delete-content]]</a></li>
|
||||
<li><a class="dropdown-item rounded-1" href="#" data-action="delete-all" role="menuitem">[[user:delete-all]]</a></li>
|
||||
{{{ end }}}
|
||||
</ul>
|
||||
</div>
|
||||
{{{ end }}}
|
||||
|
||||
<a class="btn btn-ghost btn-sm ff-secondary border d-flex gap-2 align-items-center" href="#" data-action="assign">
|
||||
<i class="fa fa-fw fa-id-card-o text-primary"></i>
|
||||
[[flags:assign-to-me]]
|
||||
</a>
|
||||
|
||||
{{{ if type_bool.post }}}
|
||||
{{{ if !target.deleted}}}
|
||||
<a class="d-flex gap-2 align-items-center btn btn-sm btn-outline-danger border border-secondary-subtle text-start" href="#" data-action="delete-post"><i class="fa fa-fw fa-trash"></i> [[flags:delete-post]]</a>
|
||||
{{{ else }}}
|
||||
<a class="d-flex gap-2 align-items-center btn btn-sm btn-danger border border-secondary-subtle text-start" href="#" data-action="purge-post"><i class="fa fa-fw fa-trash"></i> [[flags:purge-post]]</a>
|
||||
<a class="d-flex gap-2 align-items-center btn btn-sm btn-outline-success border border-secondary-subtle text-start" href="#" data-action="restore-post"><i class="fa fa-fw fa-reply"></i><i class="fa fa-trash"></i> [[flags:restore-post]]</a>
|
||||
{{{ end }}}
|
||||
{{{ end }}}
|
||||
</div>
|
||||
|
||||
<form class="d-flex flex-column gap-3" id="attributes">
|
||||
<div>
|
||||
<label class="text-muted fw-semibold" for="state">[[flags:state]]</label>
|
||||
<select class="form-select form-select-sm" id="state" name="state" disabled>
|
||||
<option value="open">[[flags:state-open]]</option>
|
||||
<option value="wip">[[flags:state-wip]]</option>
|
||||
<option value="resolved">[[flags:state-resolved]]</option>
|
||||
<option value="rejected">[[flags:state-rejected]]</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-muted fw-semibold" for="assignee">[[flags:assignee]]</label>
|
||||
<select class="form-control form-control-sm" id="assignee" name="assignee" disabled>
|
||||
<option value="">[[flags:no-assignee]]</option>
|
||||
{{{each assignees}}}
|
||||
<option value="{../uid}">{../username}</option>
|
||||
{{{end}}}
|
||||
</select>
|
||||
</div>
|
||||
<div class="d-grid">
|
||||
<button type="button" class="btn btn-primary" data-action="update">[[flags:update]]</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="overflow-auto" component="flag/history" style="max-height: 30rem;">
|
||||
<h2 class="h6 fw-bold">[[flags:history]]</h2>
|
||||
{{{ if !history.length }}}
|
||||
<div class="alert alert-success text-center">[[flags:no-history]]</div>
|
||||
{{{ end }}}
|
||||
{{{ each history }}}
|
||||
<div class="d-flex flex-column gap-1">
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<a class="d-flex text-decoration-none" href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "16px", true)}</a>
|
||||
<a href="{config.relative_path}/user/{./user.userslug}">{./user.username}</a>
|
||||
<span class="timeago text-muted text-nowrap" title="{./datetimeISO}"></span>
|
||||
</div>
|
||||
<div>
|
||||
<ul class="list-unstyled">
|
||||
{{{ each ./fields }}}
|
||||
<li>
|
||||
[[flags:{@key}]]{{{ if @value }}} → <span class="fw-semibold">{@value}</span>{{{ end }}}
|
||||
</li>
|
||||
{{{ end }}}
|
||||
{{{ each ./meta }}}
|
||||
<li>
|
||||
{{./key}}{{{ if ./value }}} → <span class="fw-semibold">{./value}</span>{{{ end }}}
|
||||
</li>
|
||||
{{{ end }}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1 ps-md-2 ps-lg-5" style="min-width:0;">
|
||||
<div class="d-flex flex-column gap-4">
|
||||
<h2 class="h6 fw-bold">
|
||||
{target_readable}
|
||||
</h2>
|
||||
<div component="flag/content" class="d-flex flex-column gap-1 pb-3 border-bottom">
|
||||
{{{ if type_bool.post }}}
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<a class="d-flex text-decoration-none" href="{config.relative_path}/user/{target.user.userslug}">{buildAvatar(target.user, "16px", true)}</a>
|
||||
<a href="{config.relative_path}/user/{target.user.userslug}">{target.user.username}</a>
|
||||
<span class="timeago text-muted" title="{target.timestampISO}"></span>
|
||||
</div>
|
||||
<blockquote>{target.content}</blockquote>
|
||||
{{{ end }}}
|
||||
|
||||
{{{ if type_bool.user }}}
|
||||
<div class="d-flex gap-2">
|
||||
<a href="{config.relative_path}/user/{./target.userslug}">{buildAvatar(target, "16px", true)}</a>
|
||||
<a href="{config.relative_path}/user/{./target.userslug}">{target.username}</a>
|
||||
</div>
|
||||
<blockquote>{{{ if target.aboutme }}}{target.aboutme}{{{ else }}}<em>[[flags:target-aboutme-empty]]</em>{{{ end }}}</blockquote>
|
||||
{{{ end }}}
|
||||
|
||||
{{{ if type_bool.empty }}}
|
||||
<div class="alert alert-warning" role="alert">[[flags:target-purged]]</div>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
<div class="flag/reports" class="pb-4 border-bottom">
|
||||
<h2 class="h6 fw-bold">[[flags:reports]]</h2>
|
||||
<ul class="list-unstyled mt-4">
|
||||
{{{ each reports }}}
|
||||
<li class="d-flex flex-column gap-1" component="flag/report" data-timestamp="{./timestamp}">
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<a class="d-flex text-decoration-none" href="{config.relative_path}/user/{./reporter.userslug}">{buildAvatar(./reporter, "16px", true)}</a>
|
||||
<a href="{config.relative_path}/user/{./reporter.userslug}">{./reporter.username}</a>
|
||||
<span class="timeago text-muted" title="{./timestampISO}"></span>
|
||||
</div>
|
||||
<p>{./value}</p>
|
||||
</li>
|
||||
{{{ end }}}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pb-4 border-bottom">
|
||||
<div class="d-flex align-items-center">
|
||||
<h2 class="h6 fw-bold me-auto mb-0">[[flags:notes]]</h2>
|
||||
<button class="btn btn-ghost ff-secondary border" data-action="addEditNote">[[flags:add-note]]</button>
|
||||
</div>
|
||||
<ul component="flag/notes" class="list-unstyled mt-4">
|
||||
{{{ if !notes.length }}}
|
||||
<em>[[flags:no-notes]]</em>
|
||||
{{{ end }}}
|
||||
{{{ each notes }}}
|
||||
<li class="d-flex flex-column gap-1" component="flag/note" data-datetime="{./datetime}" data-index="{@index}">
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<a href="{config.relative_path}/user/{./user.userslug}">{buildAvatar(./user, "16px", true)}</a>
|
||||
<a href="{config.relative_path}/user/{./user.userslug}">{./user.username}</a>
|
||||
<span class="timeago text-muted" title="{./datetimeISO}"></span>
|
||||
<div class=" ms-auto flex-shrink-0">
|
||||
<a href="#" class="btn btn-sm btn-link" data-action="addEditNote"><i class="fa fa-pencil"></i></a>
|
||||
<a href="#" class="btn btn-sm btn-link" data-action="delete-note"><i class="fa fa-trash text-danger"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<p>{./content}</p>
|
||||
</li>
|
||||
{{{ end }}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
6
src/views/flags/list.tpl
Normal file
6
src/views/flags/list.tpl
Normal file
@@ -0,0 +1,6 @@
|
||||
<!-- IMPORT partials/breadcrumbs.tpl -->
|
||||
|
||||
<div class="d-flex flex-column gap-3">
|
||||
<!-- IMPORT partials/flags/filters.tpl -->
|
||||
<!-- IMPORT partials/flags/results.tpl -->
|
||||
</div>
|
||||
9
src/views/partials/flags/bulk-actions.tpl
Normal file
9
src/views/partials/flags/bulk-actions.tpl
Normal file
@@ -0,0 +1,9 @@
|
||||
<div class="dropdown" component="flags/bulk-actions">
|
||||
<button class="filter-btn btn btn-light btn-sm border" data-bs-toggle="dropdown" autocomplete="off" aria-haspopup="true" aria-expanded="false" disabled="disabled">
|
||||
<span class="filter-label">[[flags:bulk-actions]]</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu dropdown-menu-end p-1 text-sm" role="menu">
|
||||
<li><a href="#" class="dropdown-item rounded-1" data-action="bulk-assign" role="menuitem">[[flags:assign-to-me]]</a></li>
|
||||
<li><a href="#" class="dropdown-item rounded-1" data-action="bulk-mark-resolved" role="menuitem">[[flags:bulk-resolve]]</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
188
src/views/partials/flags/filters.tpl
Normal file
188
src/views/partials/flags/filters.tpl
Normal file
@@ -0,0 +1,188 @@
|
||||
<div component="flags/filters" class="d-flex flex-wrap gap-2 pb-3 border-bottom">
|
||||
<div class="btn-group bottom-sheet">
|
||||
<a class="filter-btn btn btn-light btn-sm border {{{ if filters.quick }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="filter-label">{{{ if filters.quick }}}[[flags:filter-quick-{./filters.quick}]]{{{ else }}}[[flags:quick-filters]]{{{ end }}}</span>
|
||||
<span class="caret text-primary opacity-75"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu p-1 text-sm" role="menu">
|
||||
<li>
|
||||
<a class="dropdown-item rounded-1" href="{config.relative_path}/flags?quick=mine" role="menuitem">[[flags:filter-quick-mine]]</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div component="category/dropdown" class="btn-group category-dropdown-container bottom-sheet">
|
||||
<button type="button" class="filter-btn btn btn-light btn-sm border dropdown-toggle {{{ if filters.cid }}}active-filter{{{ end }}}" data-bs-toggle="dropdown">
|
||||
{{{ if selectedCategory }}}
|
||||
<span class="category-item d-inline-flex align-items-center gap-1">
|
||||
{buildCategoryIcon(selectedCategory, "18px", "rounded-circle")}
|
||||
<span class="visible-md-inline visible-lg-inline">{selectedCategory.name}</span>
|
||||
</span>
|
||||
{{{ else }}}
|
||||
<span class="visible-md-inline visible-lg-inline">[[unread:all-categories]]</span>
|
||||
{{{ end }}}
|
||||
<span class="caret text-primary opacity-75"></span>
|
||||
</button>
|
||||
<div component="category-selector-search" class="hidden position-absolute">
|
||||
<input type="text" class="form-control form-control-sm" placeholder="[[search:type-to-search]]" autocomplete="off">
|
||||
</div>
|
||||
|
||||
<div class="dropdown-menu p-1">
|
||||
<ul component="category/list" class="list-unstyled mb-0 text-sm category-dropdown-menu ghost-scrollbar" role="menu">
|
||||
{{{each categoryItems}}}
|
||||
<li role="presentation" class="category {{{ if ../disabledClass }}}disabled{{{ end }}}" data-cid="{../cid}" data-parent-cid="{../parentCid}" data-name="{../name}">
|
||||
<a class="dropdown-item rounded-1 d-flex align-items-center gap-2" role="menuitem" href="#">
|
||||
{../level}
|
||||
<span component="category-markup" class="flex-grow-1" style="{{{ if ../match }}}font-weight: bold;{{{end}}}">
|
||||
<div class="category-item d-inline-flex align-items-center gap-1">
|
||||
{{{ if ./icon }}}
|
||||
{buildCategoryIcon(@value, "24px", "rounded-circle")}
|
||||
{{{ end }}}
|
||||
{./name}
|
||||
</div>
|
||||
</span>
|
||||
<i component="category/select/icon" class="flex-shrink-0 fa fa-fw fa-check {{{ if !../selected }}}invisible{{{ end }}}"></i>
|
||||
</a>
|
||||
</li>
|
||||
{{{end}}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group bottom-sheet">
|
||||
<a class="filter-btn btn btn-light btn-sm border {{{ if (sort != "newest") }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="filter-label">{{{ if (sort != "newest") }}}[[flags:sort-{./sort}]]{{{ else }}}[[flags:sort]]{{{ end }}}</span>
|
||||
<span class="caret text-primary opacity-75"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu p-1 text-sm" role="menu">
|
||||
<li><h6 class="dropdown-header">[[flags:sort-all]]</h6></li>
|
||||
<li class="dropdown-item rounded-1" data-name="sort" data-value="newest" role="menuitem">[[flags:sort-newest]]</li>
|
||||
<li class="dropdown-item rounded-1" data-name="sort" data-value="oldest" role="menuitem">[[flags:sort-oldest]]</li>
|
||||
<li class="dropdown-item rounded-1" data-name="sort" data-value="reports" role="menuitem">[[flags:sort-reports]]</li>
|
||||
<li><h6 class="dropdown-header">[[flags:sort-posts-only]]</h6></li>
|
||||
<li class="dropdown-item rounded-1" data-name="sort" data-value="downvotes" role="menuitem">[[flags:sort-downvotes]]</li>
|
||||
<li class="dropdown-item rounded-1" data-name="sort" data-value="upvotes" role="menuitem">[[flags:sort-upvotes]]</li>
|
||||
<li class="dropdown-item rounded-1" data-name="sort" data-value="replies" role="menuitem">[[flags:sort-replies]]</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="btn-group bottom-sheet">
|
||||
<a class="filter-btn btn btn-light btn-sm border {{{ if filters.state }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="filter-label">{{{ if filters.state }}}[[flags:state-{./filters.state}]]{{{ else }}}[[flags:filter-state]]{{{ end }}}</span>
|
||||
<span class="caret text-primary opacity-75"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu p-1 text-sm" role="menu">
|
||||
<li class="dropdown-item rounded-1" data-name="state" data-value="open" role="menuitem">[[flags:state-open]]</li>
|
||||
<li class="dropdown-item rounded-1" data-name="state" data-value="wip" role="menuitem">[[flags:state-wip]]</li>
|
||||
<li class="dropdown-item rounded-1" data-name="state" data-value="resolved" role="menuitem">[[flags:state-resolved]]</li>
|
||||
<li class="dropdown-item rounded-1" data-name="state" data-value="rejected" role="menuitem">[[flags:state-rejected]]</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="btn-group bottom-sheet">
|
||||
<a class="filter-btn btn btn-light btn-sm border {{{ if filters.type }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="filter-label">{{{ if filters.type }}}[[flags:filter-type-{./filters.type}]]{{{ else }}}[[flags:filter-type]]{{{ end }}}</span>
|
||||
<span class="caret text-primary opacity-75"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu p-1 text-sm" role="menu">
|
||||
<li class="dropdown-item rounded-1" data-name="type" data-value="all" role="menuitem">[[flags:filter-type-all]]</li>
|
||||
<li class="dropdown-item rounded-1" data-name="type" data-value="post" role="menuitem">[[flags:filter-type-post]]</li>
|
||||
<li class="dropdown-item rounded-1" data-name="type" data-value="user" role="menuitem">[[flags:filter-type-user]]</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div component="flags/filter/assignee" class="dropdown bottom-sheet" data-filter-name="assignee">
|
||||
<a component="user/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.assignee }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="filter-label">[[flags:filter-assignee]]</span>
|
||||
<span class="caret text-primary opacity-75"></span>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu p-1 text-sm" style="min-width: 350px;" role="menu">
|
||||
<li class="px-3 py-1 d-flex flex-column gap-2">
|
||||
<input type="text" class="form-control" component="user/filter/search" placeholder="[[search:type-a-username]]">
|
||||
<div component="user/filter/selected" class="d-flex flex-wrap gap-2">
|
||||
{{{ each selected.assignee }}}
|
||||
<div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
|
||||
{buildAvatar(@value, "16px", true)} {./username}
|
||||
<button component="user/filter/delete" data-uid="{./uid}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
|
||||
</div>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
<hr/>
|
||||
<div component="user/filter/results" class="d-flex flex-wrap gap-2">
|
||||
{{{ each userFilterResults }}}
|
||||
<button class="btn btn-light btn-sm border" data-uid="{./uid}" data-username="{./username}">{buildAvatar(@value, "16px", true)} {./username}</button>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div component="flags/filter/reporterId" class="dropdown bottom-sheet" data-filter-name="reporterId">
|
||||
<a component="user/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.reporterId }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="filter-label">[[flags:filter-reporterId]]</span>
|
||||
<span class="caret text-primary opacity-75"></span>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu p-1 text-sm" style="min-width: 350px;" role="menu">
|
||||
<li class="px-3 py-1 d-flex flex-column gap-2">
|
||||
<input type="text" class="form-control" component="user/filter/search" placeholder="[[search:type-a-username]]">
|
||||
<div component="user/filter/selected" class="d-flex flex-wrap gap-2">
|
||||
{{{ each selected.reporterId }}}
|
||||
<div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
|
||||
{buildAvatar(@value, "16px", true)} {./username}
|
||||
<button component="user/filter/delete" data-uid="{./uid}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
|
||||
</div>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
<hr/>
|
||||
<div component="user/filter/results" class="d-flex flex-wrap gap-2">
|
||||
{{{ each userFilterResults }}}
|
||||
<button class="btn btn-light btn-sm border" data-uid="{./uid}" data-username="{./username}">{buildAvatar(@value, "16px", true)} {./username}</button>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div component="flags/filter/targetUid" class="dropdown bottom-sheet" data-filter-name="targetUid">
|
||||
<a component="user/filter/button" class="filter-btn btn btn-light btn-sm border {{{ if filters.targetUid }}}active-filter{{{ end }}} dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="filter-label">[[flags:filter-targetUid]]</span>
|
||||
<span class="caret text-primary opacity-75"></span>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu p-1 text-sm" style="min-width: 350px;" role="menu">
|
||||
<li class="px-3 py-1 d-flex flex-column">
|
||||
<input type="text" class="form-control" component="user/filter/search" placeholder="[[search:type-a-username]]">
|
||||
<div component="user/filter/selected" class="d-flex flex-wrap gap-2">
|
||||
{{{ each selected.targetUid }}}
|
||||
<div class="d-flex px-2 py-1 rounded-1 text-bg-primary gap-2 align-items-center text-sm">
|
||||
{buildAvatar(@value, "16px", true)} {./username}
|
||||
<button component="user/filter/delete" data-uid="{./uid}" class="btn btn-primary btn-sm py-0"><i class="fa fa-times fa-xs"></i></button>
|
||||
</div>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
<hr/>
|
||||
<div component="user/filter/results" class="d-flex flex-wrap gap-2">
|
||||
{{{ each userFilterResults }}}
|
||||
<button class="btn btn-light btn-sm border" data-uid="{./uid}" data-username="{./username}">{buildAvatar(@value, "16px", true)} {./username}</button>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div component="flags/filters/reset" class="ms-auto">
|
||||
<a class="filter-btn btn btn-warning btn-sm border {{{ if !hasFilter }}}btn-light disabled{{{ end }}}" href="{config.relative_path}/flags" role="button">
|
||||
<span class="filter-label">[[flags:filter-reset]]</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- IMPORT partials/flags/bulk-actions.tpl -->
|
||||
|
||||
<form role="form">
|
||||
<input type="hidden" name="sort" value="{./sort}" />
|
||||
<input type="hidden" name="state" value="{./filters.state}" />
|
||||
<input type="hidden" name="type" value="{./filters.type}" />
|
||||
</form>
|
||||
</div>
|
||||
38
src/views/partials/flags/results.tpl
Normal file
38
src/views/partials/flags/results.tpl
Normal file
@@ -0,0 +1,38 @@
|
||||
<div class="card card-header text-xs px-2 py-1 fw-semibold border-0 align-self-start">
|
||||
[[flags:x-flags-found, {count}]]
|
||||
</div>
|
||||
|
||||
<table class="table table-striped table-hover" component="flags/list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="text-xs text-muted">[[flags:reports]]</th>
|
||||
<th class="text-xs text-muted">[[flags:first-reported]]</th>
|
||||
<th class="text-xs text-muted">[[flags:state]]</th>
|
||||
<th>
|
||||
<input type="checkbox" data-action="toggle-all" autocomplete="off" />
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{{ each flags }}}
|
||||
<tr data-flag-id="{./flagId}">
|
||||
<td>
|
||||
<a class="text-reset text-decoration-underline" href="{config.relative_path}/flags/{./flagId}">
|
||||
{./target_readable}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{./heat}
|
||||
</td>
|
||||
<td><span class="timeago" title="{./datetimeISO}"></span></td>
|
||||
<td><span class="badge bg-{./labelClass}">[[flags:state-{./state}]]</span></td>
|
||||
<td>
|
||||
<input type="checkbox" autocomplete="off" />
|
||||
</td>
|
||||
</tr>
|
||||
{{{end}}}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- IMPORT partials/paginator.tpl -->
|
||||
Reference in New Issue
Block a user