allowing updating of flag data

v1.18.x
Julian Lam 9 years ago
parent 7d53b778de
commit 8dc57cba58

@ -4,8 +4,9 @@
define('admin/manage/flags', [
'forum/infinitescroll',
'autocomplete',
'Chart'
], function(infinitescroll, autocomplete, Chart) {
'Chart',
'components'
], function(infinitescroll, autocomplete, Chart, components) {
var Flags = {};
@ -21,6 +22,7 @@ define('admin/manage/flags', [
handleDelete();
handleInfiniteScroll();
handleGraphs();
handleFormActions();
};
function handleDismiss() {
@ -150,5 +152,19 @@ define('admin/manage/flags', [
});
}
function handleFormActions() {
components.get('posts/flag').find('[component="posts/flag/update"]').on('click', function() {
var pid = $(this).parents('[component="posts/flag"]').attr('data-pid');
var formData = $($(this).parents('form').get(0)).serializeArray();
socket.emit('posts.updateFlag', {
pid: pid,
data: formData
}, function(err) {
console.log(arguments);
});
});
}
return Flags;
});

@ -2,6 +2,7 @@
var async = require('async');
var posts = require('../../posts');
var user = require('../../user');
var analytics = require('../../analytics');
var flagsController = {};
@ -25,15 +26,32 @@ flagsController.get = function(req, res, next) {
},
analytics: function(next) {
analytics.getDailyStatsForSet('analytics:flags', Date.now(), 30, next);
}
},
assignees: async.apply(user.getAdminsandGlobalMods)
}, next);
}
], function (err, results) {
if (err) {
return next(err);
}
// Minimise data set for assignees so tjs does less work
results.assignees = results.assignees.map(function(userObj) {
var keep = ['uid', 'username'];
for(var prop in userObj) {
if (userObj.hasOwnProperty(prop)) {
if (keep.indexOf(prop) === -1) {
delete userObj[prop];
}
}
}
return userObj;
});
var data = {
posts: results.posts,
assignees: results.assignees,
analytics: results.analytics,
next: stop + 1,
byUsername: byUsername,

@ -226,4 +226,38 @@ module.exports = function(Posts) {
}
], callback);
};
Posts.updateFlagData = function(pid, flagObj, callback) {
// Retrieve existing flag data to compare for history-saving purposes
var changes = [];
var changeset = {};
var prop;
Posts.getPostData(pid, function(err, postData) {
// Track new additions
for(prop in flagObj) {
if (flagObj.hasOwnProperty(prop) && !postData.hasOwnProperty('flag:' + prop)) {
changes.push(prop);
}
// Generate changeset for object modification
if (flagObj.hasOwnProperty(prop)) {
changeset['flag:' + prop] = flagObj[prop];
}
}
// Track changed items
for(prop in postData) {
if (
postData.hasOwnProperty(prop) && prop.startsWith('flag:') &&
flagObj.hasOwnProperty(prop.slice(5)) &&
postData[prop] !== flagObj[prop.slice(5)]
) {
changes.push(prop.slice(5));
}
}
// Save flag data into post hash
Posts.setPostFields(pid, changeset, callback);
});
};
};

@ -163,7 +163,35 @@ module.exports = function(SocketPosts) {
},
function (posts, next) {
next(null, {posts: posts, next: stop + 1});
},
}
], callback);
};
SocketPosts.updateFlag = function(socket, data, callback) {
if (!data || !(data.pid && data.data)) {
return callback('[[error:invalid-data]]');
}
var payload = {};
async.waterfall([
function (next) {
user.isAdminOrGlobalMod(socket.uid, next);
},
function (isAdminOrGlobalModerator, next) {
if (!isAdminOrGlobalModerator) {
return next(new Error('[[no-privileges]]'));
}
// Translate form data into object
payload = data.data.reduce(function(memo, cur) {
memo[cur.name] = cur.value;
return memo;
}, payload);
next(null, data.pid, payload);
},
async.apply(posts.updateFlagData)
], callback);
}
};

@ -2,6 +2,7 @@
var async = require('async');
var groups = require('./groups');
var plugins = require('./plugins');
var db = require('./database');
var topics = require('./topics');
@ -260,6 +261,19 @@ var utils = require('../public/src/utils');
});
};
User.getAdminsandGlobalMods = function(callback) {
async.parallel({
admins: async.apply(groups.getMembers, 'administrators', 0, -1),
mods: async.apply(groups.getMembers, 'Global Moderators', 0, -1)
}, function(err, results) {
if (err) {
return callback(err);
}
User.getUsersData(results.admins.concat(results.mods), callback);
});
};
User.addInterstitials = function(callback) {
plugins.registerHook('core', {
hook: 'filter:register.interstitial',

@ -44,7 +44,7 @@
<div data-next="{next}">
<div class="panel-group post-container" id="accordion" role="tablist" aria-multiselectable="true" data-next="{next}">
<div component="posts/flags" class="panel-group post-container" id="accordion" role="tablist" aria-multiselectable="true" data-next="{next}">
<!-- IF !posts.length -->
<div class="alert alert-success">
No flagged posts!
@ -52,7 +52,7 @@
<!-- ENDIF !posts.length -->
<!-- BEGIN posts -->
<div class="panel panel-default">
<div class="panel panel-default" component="posts/flag" data-pid="{../pid}">
<div class="panel-heading" role="tab">
<h4 class="panel-title">
<a role="button" data-toggle="collapse" data-parent="#accordion" href="#flag-pid-{posts.pid}" aria-expanded="true" aria-controls="flag-pid-{posts.pid}">
@ -118,14 +118,17 @@
<div class="col-sm-6">
<form role="form">
<div class="form-group">
<label for="{../pid}-assignee">[[topic:flag_manage_assignee]]</label>
<select class="form-control" id="{../pid}-assignee" name="assignee">
<option value="2">julian</option>
<label for="{posts.pid}-assignee">[[topic:flag_manage_assignee]]</label>
<select class="form-control" id="{posts.pid}-assignee" name="assignee">
<option value="">No Assignee</option>
<!-- BEGIN assignees -->
<option value="{../uid}">{../username}</option>
<!-- END assignees -->
</select>
</div>
<div class="form-group">
<label for="{../pid}-state">[[topic:flag_manage_state]]</label>
<select class="form-control" id="{../pid}-state" name="state">
<label for="{posts.pid}-state">[[topic:flag_manage_state]]</label>
<select class="form-control" id="{posts.pid}-state" name="state">
<option value="open">[[topic:flag_manage_state_open]]</option>
<option value="wip">[[topic:flag_manage_state_wip]]</option>
<option value="resolved">[[topic:flag_manage_state_resolved]]</option>
@ -133,10 +136,10 @@
</select>
</div>
<div class="form-group">
<label for="{../pid}-notes">[[topic:flag_manage_notes]]</label>
<textarea class="form-control" id="{../pid}-notes" name="notes"></textarea>
<label for="{posts.pid}-notes">[[topic:flag_manage_notes]]</label>
<textarea class="form-control" id="{posts.pid}-notes" name="notes"></textarea>
</div>
<button class="btn btn-sm btn-primary btn-block">[[topic:flag_manage_update]]</button>
<button type="button" component="posts/flag/update" class="btn btn-sm btn-primary btn-block">[[topic:flag_manage_update]]</button>
</form>
</div>
<div class="col-sm-6">

Loading…
Cancel
Save