2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2025-09-06 10:50:21 +08:00

Convert flags admin to flexbox

This commit is contained in:
Robin Ward 2017-09-11 14:01:59 -04:00
parent 1af4acbb3d
commit cc1a461254
10 changed files with 358 additions and 285 deletions

View file

@ -0,0 +1,3 @@
export default Ember.Component.extend({
classNames: ['flagged-post-response']
});

View file

@ -1,7 +1,12 @@
import showModal from 'discourse/lib/show-modal';
export default Ember.Component.extend({
tagName: '',
tagName: 'div',
classNameBindings: [
':flagged-post',
'flaggedPost.hidden:hidden-post',
'flaggedPost.deleted'
],
removeAfter(promise) {
return promise.then(() => {

View file

@ -134,15 +134,7 @@ const FlaggedPost = Post.extend({
postHidden: Ember.computed.alias('hidden'),
@computed
extraClasses() {
let classes = [];
if (this.get('hidden')) { classes.push('hidden-post'); }
if (this.get('deleted')) { classes.push('deleted'); }
return classes.join(' ');
},
deleted: Ember.computed.or('deleted_at', 'topic_deleted_at')
deleted: Ember.computed.or('deleted_at', 'topic_deleted_at'),
});
FlaggedPost.reopenClass({

View file

@ -0,0 +1,7 @@
{{#link-to 'adminUser' response.user class="response-avatar"}}
{{avatar response.user imageSize="medium"}}
{{/link-to}}
<div class='excerpt'>{{{response.excerpt}}}</div>
{{#if hasMore}}
<a href={{permalink}} class="has-more">{{i18n 'admin.flags.more'}}</a>
{{/if}}

View file

@ -1,175 +1,144 @@
<tr class="flagged-post {{flaggedPost.extraClasses}}">
<td class='excerpt'>
<div class="flex-center-align">
<div class="flagged-post-avatar">
{{#if flaggedPost.postAuthorFlagged}}
{{#if flaggedPost.user}}
{{#link-to 'adminUser' flaggedPost.user}}{{avatar flaggedPost.user imageSize="large"}}{{/link-to}}
{{#if flaggedPost.wasEdited}}
{{d-icon "pencil" title="admin.flags.was_edited"}}
{{/if}}
{{/if}}
<div class='flagged-post-details'>
<div class="flagged-post-avatar">
{{#if flaggedPost.postAuthorFlagged}}
{{#if flaggedPost.user}}
{{#link-to 'adminUser' flaggedPost.user}}{{avatar flaggedPost.user imageSize="large"}}{{/link-to}}
{{#if flaggedPost.wasEdited}}
{{d-icon "pencil" title="admin.flags.was_edited"}}
{{/if}}
{{#if canAct}}
{{#if flaggedPost.previous_flags_count}}
<span title="{{i18n 'admin.flags.previous_flags_count' count=flaggedPost.previous_flags_count}}" class="badge-notification flagged-posts">{{flaggedPost.previous_flags_count}}</span>
{{/if}}
{{/if}}
</div>
<div class="topic-excerpt">
{{#unless hideTitle}}
<h3>
{{#if flaggedPost.topic.isPrivateMessage}}
<span class="private-message-glyph">{{d-icon "envelope"}}</span>
{{/if}}
{{topic-status topic=flaggedPost.topic}}
<a href='{{unbound flaggedPost.url}}'>{{{unbound flaggedPost.topic.fancyTitle}}}</a>
</h3>
{{/unless}}
{{#unless site.mobileView}}
{{#if flaggedPost.postAuthorFlagged}}
<p>{{{flaggedPost.excerpt}}}</p>
{{/if}}
{{/unless}}
</div>
</div>
{{#if site.mobileView}}
{{#if flaggedPost.postAuthorFlagged}}
<p>{{{flaggedPost.excerpt}}}</p>
{{/if}}
{{/if}}
</td>
<td class='flaggers'>
<table>
<tbody>
{{#each flaggedPost.flaggers as |flagger|}}
<tr>
<td class='avatar'>
{{#link-to 'adminUser' flagger.user class='flagger'}}
{{avatar flagger.user imageSize="medium"}}
{{/link-to}}
</td>
<td>
{{#link-to 'adminUser' flagger.user}}
{{flagger.user.username}}
{{/link-to}}
{{format-age flagger.flaggedAt}}
<br>
{{flagger.flagType}}
</td>
</tr>
{{/each}}
</tbody>
</table>
</td>
<td class='flaggers result'>
{{#if showResolvedBy}}
<table>
<tbody>
{{#each flaggedPost.flaggers as |flagger|}}
<tr>
<td class='avatar'>
{{#link-to 'adminUser' flagger.disposedBy}}
{{avatar flagger.disposedBy imageSize="medium"}}
{{/link-to}}
</td>
<td>
{{format-age flagger.disposedAt}}
{{{flagger.dispositionIcon}}}
{{#if flagger.tookAction}}
{{d-icon "gavel" title="admin.flags.took_action"}}
{{/if}}
</td>
</tr>
{{/each}}
</tbody>
</table>
{{#if canAct}}
{{#if flaggedPost.previous_flags_count}}
<span title="{{i18n 'admin.flags.previous_flags_count' count=flaggedPost.previous_flags_count}}" class="badge-notification previous-flagged-posts">{{flaggedPost.previous_flags_count}}</span>
{{/if}}
{{/if}}
</td>
</div>
</tr>
<div class="flagged-post-excerpt">
{{#unless hideTitle}}
<h3>
{{#if flaggedPost.topic.isPrivateMessage}}
<span class="private-message-glyph">{{d-icon "envelope"}}</span>
{{/if}}
{{topic-status topic=flaggedPost.topic}}
<a href='{{unbound flaggedPost.url}}'>{{{unbound flaggedPost.topic.fancyTitle}}}</a>
</h3>
{{/unless}}
{{#if flaggedPost.postAuthorFlagged}}
<p>{{{flaggedPost.excerpt}}}</p>
{{/if}}
</div>
<div class='flaggers'>
{{#if site.mobileView}}
<div class='flaggers-title'>
{{i18n 'admin.flags.flagged_by'}}
</div>
{{/if}}
{{#each flaggedPost.flaggers as |flagger|}}
<div class='flagger'>
{{#link-to 'adminUser' flagger.user class='flagger-avatar'}}
{{avatar flagger.user imageSize="medium"}}
{{/link-to}}
<div class='flagger-details'>
<div class='flagger-username'>
{{#link-to 'adminUser' flagger.user}}
{{flagger.user.username}}
{{/link-to}}
</div>
<div class='flagger-flagged-at'>
{{format-age flagger.flaggedAt}}
</div>
<div class='flagger-flag-type'>
{{flagger.flagType}}
</div>
</div>
</div>
{{/each}}
</div>
{{#if showResolvedBy}}
<div class='flagged-post-resolved-by'>
{{#each flaggedPost.flaggers as |flagger|}}
<div class='disposer'>
{{#link-to 'adminUser' flagger.disposedBy class="disposer-avatar"}}
{{avatar flagger.disposedBy imageSize="medium"}}
{{/link-to}}
<div class='disposer-details'>
{{format-age flagger.disposedAt}}
{{{flagger.dispositionIcon}}}
{{#if flagger.tookAction}}
{{d-icon "gavel" title="admin.flags.took_action"}}
{{/if}}
</div>
</div>
{{/each}}
</div>
{{/if}}
</div>
{{#if flaggedPost.topicFlagged}}
<tr class='message'>
<td colspan="3">
<div>
{{{i18n 'admin.flags.topic_flagged'}}}&nbsp;<a href='{{unbound flaggedPost.url}}' class="btn">{{i18n 'admin.flags.visit_topic'}}</a>
</div>
</td>
</tr>
<div class='flagged-post-message'>
<span class='text'>{{{i18n 'admin.flags.topic_flagged'}}}</span>
<a href={{flaggedPost.url}} class="btn">{{i18n 'admin.flags.visit_topic'}}</a>
</div>
{{/if}}
{{#each flaggedPost.conversations as |c|}}
<tr class='message'>
<td colspan="3">
<div>
{{#if c.response}}
<p>
{{#link-to 'adminUser' c.response.user}}{{avatar c.response.user imageSize="medium"}}{{/link-to}}&nbsp;{{{c.response.excerpt}}}
</p>
{{#if c.reply}}
<p>
{{#link-to 'adminUser' c.reply.user}}{{avatar c.reply.user imageSize="medium"}}{{/link-to}}&nbsp;{{{c.reply.excerpt}}}
{{#if c.hasMore}}
<a href="{{unbound c.permalink}}">{{i18n 'admin.flags.more'}}</a>
{{/if}}
</p>
{{/if}}
<a href="{{unbound c.permalink}}">
{{d-button
class="btn-reply"
icon="reply"
label="admin.flags.reply_message"}}
</a>
{{/if}}
</div>
</td>
</tr>
<div class='flagged-post-message'>
{{#if c.response}}
{{flagged-post-response response=c.response}}
{{#if c.reply}}
{{flagged-post-response response=c.reply hasMore=c.hasMore permalink=c.permalink}}
{{/if}}
<a href={{c.permalink}} class="btn btn-reply">
{{d-icon "reply"}}
{{i18n "admin.flags.reply_message"}}
</a>
{{/if}}
</div>
{{/each}}
{{#if canAct}}
<tr>
<td colspan="3" class="action">
{{d-button
title="admin.flags.agree_title"
class="agree-flag"
label="admin.flags.agree"
icon="thumbs-o-up"
action="showAgreeFlagModal"
ellipsis=true}}
{{#if flaggedPost.postHidden}}
{{d-button
title="admin.flags.disagree_flag_unhide_post_title"
class="disagree-flag"
action="disagree"
icon="thumbs-o-down"
label="admin.flags.disagree_flag_unhide_post"}}
{{else}}
{{d-button
title="admin.flags.disagree_flag_title"
class="disagree-flag"
action="disagree"
icon="thumbs-o-down"
label="admin.flags.disagree_flag"}}
{{/if}}
<div class='flagged-post-controls'>
{{d-button
title="admin.flags.agree_title"
class="agree-flag"
label="admin.flags.agree"
icon="thumbs-o-up"
action="showAgreeFlagModal"
ellipsis=true}}
{{#if flaggedPost.postHidden}}
{{d-button
class="defer-flag"
title="admin.flags.defer_flag_title"
action="defer"
icon="external-link"
label="admin.flags.defer_flag"}}
title="admin.flags.disagree_flag_unhide_post_title"
class="disagree-flag"
action="disagree"
icon="thumbs-o-down"
label="admin.flags.disagree_flag_unhide_post"}}
{{else}}
{{d-button
class="btn-danger delete-flag"
title="admin.flags.delete_title"
action="showDeleteFlagModal"
icon="trash-o"
label="admin.flags.delete"}}
</td>
</tr>
title="admin.flags.disagree_flag_title"
class="disagree-flag"
action="disagree"
icon="thumbs-o-down"
label="admin.flags.disagree_flag"}}
{{/if}}
{{d-button
class="defer-flag"
title="admin.flags.defer_flag_title"
action="defer"
icon="external-link"
label="admin.flags.defer_flag"}}
{{d-button
class="btn-danger delete-flag"
title="admin.flags.delete_title"
action="showDeleteFlagModal"
icon="trash-o"
label="admin.flags.delete"}}
</div>
{{/if}}

View file

@ -1,24 +1,24 @@
{{#if flaggedPosts}}
{{#load-more selector=".flagged-post" action=(action "loadMore")}}
<table class="admin-flags">
<thead>
<tr>
<th class='excerpt'></th>
<th class='flaggers'>{{i18n 'admin.flags.flagged_by'}}</th>
<th class='flaggers'>{{#if showResolvedBy}}{{i18n 'admin.flags.resolved_by'}}{{/if}}</th>
</tr>
</thead>
<tbody>
{{#each flaggedPosts as |flaggedPost|}}
{{flagged-post
flaggedPost=flaggedPost
canAct=canAct
showResolvedBy=showResolvedBy
removePost=(action "removePost" flaggedPost)
hideTitle=topic}}
{{/each}}
</tbody>
</table>
<div class='flagged-posts-header'>
<div class='flagged-by-header'>
{{i18n 'admin.flags.flagged_by'}}
</div>
{{#if showResolvedBy}}
{{i18n 'admin.flags.resolved_by'}}
{{/if}}
</div>
<div class='flagged-posts'>
{{#each flaggedPosts as |flaggedPost|}}
{{flagged-post
flaggedPost=flaggedPost
canAct=canAct
showResolvedBy=showResolvedBy
removePost=(action "removePost" flaggedPost)
hideTitle=topic}}
{{/each}}
</div>
{{/load-more}}
{{else}}
<p>{{i18n 'admin.flags.no_results'}}</p>

View file

@ -4,7 +4,7 @@
@import "common/foundation/helpers";
@import "common/admin/customize";
@import "common/admin/flagged_topics";
@import "common/admin/flagging";
$mobile-breakpoint: 700px;
@ -63,11 +63,6 @@ $mobile-breakpoint: 700px;
.filters input { margin-bottom: 0; }
}
td.flaggers td {
border-bottom: none;
border-top: none;
}
.site-texts {
.search-area {
margin-bottom: 2em;
@ -766,49 +761,6 @@ section.details {
}
}
.admin-flags {
.hidden-post td.excerpt,
.hidden-post td.user {
opacity: 0.5;
}
.deleted td.excerpt,
.deleted td.user {
background-color: scale-color($danger, $lightness: 70%);
}
.message { background-color: $highlight-medium; }
.message:hover { background-color: $highlight-low; }
.flagged-post-avatar {
margin-right: 10px;
}
.excerpt {
padding: 8px;
word-wrap: break-word;
.fa { display: inline-block; }
h3 {
margin-top: 0;
margin-bottom: 5px;
}
p:last-child {
margin-bottom: 0;
}
}
tr.message td {
padding-left: 60px;
}
.flagged-posts { background: $danger; }
.action {
button { margin: 4px; }
text-align: right;
}
}
/* Dashboard */
.dashboard-left {
@ -1421,14 +1373,6 @@ button.ru {
visibility: hidden;
}
.delete-flag-modal, .agree-flag-modal {
button {
display: block;
margin: 10px 0 10px 10px;
padding: 10px 15px;
}
}
.start-backup-modal {
.btn {
margin: 10px 0 10px 5px;
@ -1904,18 +1848,6 @@ table#user-badges {
left: -100%;
}
.mobile-view .admin-flags {
.flaggers {
padding: 2px;
.avatar {
padding: 0;
}
}
tr.message td {
padding-left: 8px;
}
}
.cboxcontainer {

View file

@ -1,28 +0,0 @@
.flag-counts {
display: inline-block;
margin-right: 0.5em;
.type-count {
color: $primary-medium;
font-size: 0.9em;
}
}
.flagged-topic {
td.topic-title {
width: 400px;
a {
width: 400px;
display: inline-block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}
.flagged-topic-details {
display: flex;
justify-content: space-between;
}

View file

@ -0,0 +1,193 @@
.flagged-posts-header {
display: flex;
justify-content: flex-end;
font-weight: bold;
.flagged-by-header {
width: 12em;
}
padding-bottom: 0.5em;
border-bottom: 1px solid $primary-low;
}
.flagged-post.hidden-post {
.flagged-post-excerpt, .flagged-post-avatar {
opacity: 0.5;
}
}
.flagged-post.deleted {
.flagged-post-excerpt, .flagged-post-avatar {
background-color: scale-color($danger, $lightness: 70%);
}
}
.flagged-post {
padding: 1em 0 0 0;
border-bottom: 1px solid $primary-low;
.flagged-post-details {
display: flex;
justify-content: space-between;
.flagged-post-avatar {
margin-right: 1em;
position: relative;
img.avatar {
min-width: 45px;
}
.previous-flagged-posts {
position: absolute;
right: -5px;
top: -5px;
background-color: $danger;
}
}
.flagged-post-excerpt {
min-width: 70%;
width: 80%;
word-wrap: break-word;
.d-icon {
display: inline-block;
}
h3 {
margin-top: 0;
margin-bottom: 0.5em;
}
p:last-child {
margin-bottom: 0;
}
margin-right: 1em;
}
}
.flagger {
width: 12em;
display: flex;
margin-bottom: 1em;
}
.flagger-avatar, .disposer-avatar {
margin-right: 1em;
min-width: 32px;
}
.disposer {
width: 7em;
justify-content: flex-end;
display: flex;
margin-bottom: 1em;
}
.flagged-post-resolved-by {
width: 12em;
}
.flagged-post-message {
padding: 0.5em 0 0.5em 4em;
margin-bottom: 0.5em;
background-color: $highlight-medium;
.text {
margin-right: 1em;
}
&:hover {
background-color: $highlight-low;
}
}
.flagged-post-response {
display: flex;
align-items: center;
margin-bottom: 0.5em;
.response-avatar {
margin-right: 0.5em;
}
.has-more {
margin-left: 1em;
}
}
.flagged-post-controls {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
button {
margin-right: 0.5em;
margin-bottom: 0.5em;
}
}
}
.flag-counts {
display: inline-block;
margin-right: 0.5em;
.type-count {
color: $primary-medium;
font-size: 0.9em;
}
}
.flagged-topic {
td.topic-title {
width: 400px;
a {
width: 400px;
display: inline-block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}
.flagged-topic-details {
display: flex;
justify-content: space-between;
}
.delete-flag-modal, .agree-flag-modal {
button {
display: block;
margin: 10px 0 10px 10px;
padding: 10px 15px;
}
}
.mobile-view {
.flagged-posts-header {
display: none;
}
.flagged-posts {
.flagged-post-details {
flex-wrap: wrap;
justify-content: flex-start;
.flagged-post-avatar {
margin-right: 10px;
}
.flagged-post-excerpt {
width: 70%;
}
.flaggers-title {
font-weight: bold;
margin: 0.5em 0;
}
.flaggers {
margin-left: 4em;
margin-bottom: 1em;
}
}
}
}

View file

@ -4,7 +4,7 @@ acceptance("Admin - Flagging", { loggedIn: true });
QUnit.test("flagged posts", assert => {
visit("/admin/flags/active");
andThen(() => {
assert.equal(find('.admin-flags .flagged-post').length, 1);
assert.equal(find('.flagged-posts .flagged-post').length, 1);
assert.equal(find('.flagged-post .flaggers .flagger').length, 1, 'shows who flagged it');
});
});