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', [ define('admin/manage/flags', [
'forum/infinitescroll', 'forum/infinitescroll',
'autocomplete', 'autocomplete',
'Chart' 'Chart',
], function(infinitescroll, autocomplete, Chart) { 'components'
], function(infinitescroll, autocomplete, Chart, components) {
var Flags = {}; var Flags = {};
@ -21,6 +22,7 @@ define('admin/manage/flags', [
handleDelete(); handleDelete();
handleInfiniteScroll(); handleInfiniteScroll();
handleGraphs(); handleGraphs();
handleFormActions();
}; };
function handleDismiss() { 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; return Flags;
}); });

@ -2,6 +2,7 @@
var async = require('async'); var async = require('async');
var posts = require('../../posts'); var posts = require('../../posts');
var user = require('../../user');
var analytics = require('../../analytics'); var analytics = require('../../analytics');
var flagsController = {}; var flagsController = {};
@ -25,15 +26,32 @@ flagsController.get = function(req, res, next) {
}, },
analytics: function(next) { analytics: function(next) {
analytics.getDailyStatsForSet('analytics:flags', Date.now(), 30, next); analytics.getDailyStatsForSet('analytics:flags', Date.now(), 30, next);
} },
assignees: async.apply(user.getAdminsandGlobalMods)
}, next); }, next);
} }
], function (err, results) { ], function (err, results) {
if (err) { if (err) {
return next(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 = { var data = {
posts: results.posts, posts: results.posts,
assignees: results.assignees,
analytics: results.analytics, analytics: results.analytics,
next: stop + 1, next: stop + 1,
byUsername: byUsername, byUsername: byUsername,

@ -226,4 +226,38 @@ module.exports = function(Posts) {
} }
], callback); ], 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) { function (posts, next) {
next(null, {posts: posts, next: stop + 1}); next(null, {posts: posts, next: stop + 1});
}, }
], callback); ], 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 async = require('async');
var groups = require('./groups');
var plugins = require('./plugins'); var plugins = require('./plugins');
var db = require('./database'); var db = require('./database');
var topics = require('./topics'); 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) { User.addInterstitials = function(callback) {
plugins.registerHook('core', { plugins.registerHook('core', {
hook: 'filter:register.interstitial', hook: 'filter:register.interstitial',

@ -44,7 +44,7 @@
<div data-next="{next}"> <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 --> <!-- IF !posts.length -->
<div class="alert alert-success"> <div class="alert alert-success">
No flagged posts! No flagged posts!
@ -52,7 +52,7 @@
<!-- ENDIF !posts.length --> <!-- ENDIF !posts.length -->
<!-- BEGIN posts --> <!-- BEGIN posts -->
<div class="panel panel-default"> <div class="panel panel-default" component="posts/flag" data-pid="{../pid}">
<div class="panel-heading" role="tab"> <div class="panel-heading" role="tab">
<h4 class="panel-title"> <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}"> <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"> <div class="col-sm-6">
<form role="form"> <form role="form">
<div class="form-group"> <div class="form-group">
<label for="{../pid}-assignee">[[topic:flag_manage_assignee]]</label> <label for="{posts.pid}-assignee">[[topic:flag_manage_assignee]]</label>
<select class="form-control" id="{../pid}-assignee" name="assignee"> <select class="form-control" id="{posts.pid}-assignee" name="assignee">
<option value="2">julian</option> <option value="">No Assignee</option>
<!-- BEGIN assignees -->
<option value="{../uid}">{../username}</option>
<!-- END assignees -->
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="{../pid}-state">[[topic:flag_manage_state]]</label> <label for="{posts.pid}-state">[[topic:flag_manage_state]]</label>
<select class="form-control" id="{../pid}-state" name="state"> <select class="form-control" id="{posts.pid}-state" name="state">
<option value="open">[[topic:flag_manage_state_open]]</option> <option value="open">[[topic:flag_manage_state_open]]</option>
<option value="wip">[[topic:flag_manage_state_wip]]</option> <option value="wip">[[topic:flag_manage_state_wip]]</option>
<option value="resolved">[[topic:flag_manage_state_resolved]]</option> <option value="resolved">[[topic:flag_manage_state_resolved]]</option>
@ -133,10 +136,10 @@
</select> </select>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="{../pid}-notes">[[topic:flag_manage_notes]]</label> <label for="{posts.pid}-notes">[[topic:flag_manage_notes]]</label>
<textarea class="form-control" id="{../pid}-notes" name="notes"></textarea> <textarea class="form-control" id="{posts.pid}-notes" name="notes"></textarea>
</div> </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> </form>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-6">

Loading…
Cancel
Save