New support: add tags to tickets

This commit is contained in:
yflory 2024-03-04 13:48:56 +01:00
parent c10176585a
commit ec5bfc236f
4 changed files with 97 additions and 9 deletions

View File

@ -5,10 +5,12 @@
*/
@import (reference) "./colortheme-all.less";
@import (reference) './tokenfield.less';
.support_main () {
@ticket-bg: @cp_support-bg;
@msg-bg: @cp_support-msg-bg;
@fromme-bg: @cp_support-header-bg;
.tokenfield_main();
.cp-support-form-container {
div {
margin-bottom: 10px;

View File

@ -398,6 +398,7 @@ define([
editKeyStr: seed
}
});
console.error(hash);
loadAdminDoc(ctx, hash, waitFor());
}).nThen(() => {
console.log('Support admin loaded');
@ -646,6 +647,23 @@ define([
});
};
var setTagsAdmin = (ctx, data, cId, cb) => {
if (!ctx.adminRdyEvt) { return void cb({ error: 'EFORBIDDEN' }); }
let id = data.id;
ctx.adminRdyEvt.reg(() => {
let doc = ctx.adminDoc.proxy;
let t = doc.tickets;
let chan = data.channel;
let ticket = t.active[chan] || t.pending[chan] || t.closed[chan];
ticket.tags = data.tags || [];
Realtime.whenRealtimeSyncs(ctx.adminDoc.realtime, function () {
cb({done:true});
});
});
};
var clearLegacy = function (ctx, data, cId, cb) {
let proxy = ctx.store.proxy;
ctx.store.mailbox.close('supportadmin', function () {
@ -1245,6 +1263,9 @@ define([
if (cmd === 'USE_RECORDED') {
return void useRecorded(ctx, data, clientId, cb);
}
if (cmd === 'SET_TAGS_ADMIN') {
return void setTagsAdmin(ctx, data, clientId, cb);
}
if (cmd === 'GET_LEGACY') {
return void getLegacy(ctx, data, clientId, cb);
}

View File

@ -83,6 +83,7 @@ define([
// Support panel functions
let open = [];
let refreshAll = function () {};
let allTags = [];
let refresh = ($container, type, _cb) => {
let cb = Util.mkAsync(_cb || function () {});
APP.module.execCommand('LIST_TICKETS_ADMIN', {
@ -228,21 +229,44 @@ define([
}
refreshAll();
});
};
onMove.isTicketActive = type === 'active';
const onTag = (channel, tags) => {
APP.module.execCommand('SET_TAGS_ADMIN', {
channel, tags
}, function (obj) {
if (obj && obj.error) {
console.error(obj && obj.error);
return void UI.warn(Messages.error);
}
(tags || []).forEach(tag => {
if (!allTags.includes(tag)) { allTags.push(tag); }
});
//UI.log(Messags.saved);
//refreshAll();
});
};
onTag.getAllTags = () => {
return allTags || [];
};
// Show tickets, reload the previously open ones and cal back
// once everything is loaded
let n = nThen;
Object.keys(tickets).sort(sortTicket).forEach(function (channel) {
// Update allTags
var d = tickets[channel];
(d.tags || []).forEach(tag => {
if (!allTags.includes(tag)) { allTags.push(tag); }
});
// Make ticket
var ticket = APP.support.makeTicket({
id: channel,
content: d,
form: activeForms[channel],
recorded: APP.recorded,
onShow, onHide, onClose, onReply, onMove
onShow, onHide, onClose, onReply, onMove, onTag
});
var container;
@ -283,6 +307,7 @@ define([
};
}));
}).nThen(waitFor => {
allTags = [];
refresh($(activeContainer), 'active', waitFor());
refresh($(pendingContainer), 'pending', waitFor());
refresh($(closedContainer), 'closed', waitFor());

View File

@ -385,7 +385,7 @@ define([
var makeTicket = function (ctx, opts) {
let { id, content, form, recorded,
onShow, onHide, onClose, onReply, onMove, onDelete } = opts;
onShow, onHide, onClose, onReply, onMove, onDelete, onTag } = opts;
var common = ctx.common;
var metadataMgr = common.getMetadataMgr();
var privateData = metadataMgr.getPrivateData();
@ -406,12 +406,13 @@ define([
var adminClasses = '';
var adminOpen;
var ticket;
let tagsContainer;
if (ctx.isAdmin) {
// Admin custom style
adminClasses = `.cp-not-loaded`;
// Admin actions
let show = h('button.btn.btn-primary.cp-support-expand', Messages.admin_support_open);
let $show = $(show);
// Copy URL
let url = h('button.btn.fa.fa-link', { title: Messages.share_linkCopy, });
$(url).click(function (e) {
e.stopPropagation();
@ -422,6 +423,9 @@ define([
});
// Load & open ticket
let show = h('button.btn.btn-primary.cp-support-expand', Messages.admin_support_open);
let $show = $(show);
let visible = false;
adminOpen = function (force, cb) {
var $ticket = $(ticket);
@ -445,17 +449,52 @@ define([
};
Util.onClickEnter($show, adminOpen);
let settings;
// Move active/pending
let move;
if (onMove) {
let text = onMove.isTicketActive ? Messages.support_movePending
: Messages.support_moveActive;
settings = h('button.btn.btn-secondary.fa.fa-archive', { title: text });
Util.onClickEnter($(settings), function () {
move = h('button.btn.btn-secondary.fa.fa-archive', { title: text });
Util.onClickEnter($(move), function () {
onMove(ticket, id, content);
});
}
adminActions = h('span.cp-support-title-buttons', [ url, settings, show ]);
let tag;
if (onTag && onTag.getAllTags) {
tag = h('button.btn.btn-secondary.fa.fa-tags', {
title: Messages.fm_tagsName
});
tagsContainer = h('div');
let $tags = $(tagsContainer).hide();
let input = UI.dialog.textInput({id: `cp-${Util.uid()}`});
$tags.append(input);
let existing = onTag.getAllTags();
let _field = UI.tokenField(input, existing).preventDuplicates(function (val) {
UI.warn(Messages._getKey('tags_duplicate', [val]));
});
_field.setTokens(content.tags || []);
$tags.find('.token').off('click');
let commitTags = function () {
setTimeout(() => {
let newTags = Util.deduplicateString(_field.getTokens().map(function (t) {
return t.toLowerCase();
}));
$tags.find('.token').off('click');
onTag(id, newTags);
});
};
_field.tokenfield.on('tokenfield:createdtoken', commitTags);
_field.tokenfield.on('tokenfield:editedoken', commitTags);
_field.tokenfield.on('tokenfield:removedtoken', commitTags);
Util.onClickEnter($(tag), () => {
$tags.toggle();
});
}
adminActions = h('span.cp-support-title-buttons', [ url, move, tag, show ]);
}
let isPremium = content.premium ? '.cp-support-ispremium' : '';
@ -471,6 +510,7 @@ define([
h('span', new Date(content.time).toLocaleString()),
adminActions,
]),
tagsContainer,
actions
]);
ticket.open = adminOpen;