Skip to content
This repository has been archived by the owner on Apr 14, 2021. It is now read-only.

Keith: Hook up settings for group labels to new API endpoints #487

Merged
merged 2 commits into from Dec 13, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
96 changes: 96 additions & 0 deletions esper.com/ts/manage.js/Actions.BatchGroupLabels.ts
@@ -0,0 +1,96 @@
/*
Manage batch label changes
*/

module Esper.Actions.BatchGroupLabels {

// Simple store for sole purpose of tracking status updates
var Store = new Model2.Store<string, {}>({ cap: 100 });

// Queue a batch label change
export function rename(groupId: string, oldLabel: string, newLabel: string) {
Analytics.track(Analytics.Trackable.RenameGroupLabel, {
_id: groupId,
oldLabel: oldLabel,
newLabel: newLabel
});

return queueBatchLabelUpdate(groupId, oldLabel, {
addLabels: [newLabel.trim()],
removeLabels: [oldLabel]
});
}

export function remove(groupId: string, label: string) {
Analytics.track(Analytics.Trackable.DeleteTimeStatsLabel, {
_id: groupId,
label: label
});
return queueBatchLabelUpdate(groupId, label, {
removeLabels: [label]
});
}

export function getStatus(groupId: string) {
return Store.get(groupId)
.mapOr(Model2.DataStatus.READY, (m) => m.dataStatus);
}

function queueBatchLabelUpdate(groupId: string, label: string, opt: {
addLabels?: string[], removeLabels?: string[]
}) {
var req: ApiT.LabelChangeRequest = { selection: ["Label", label] };
if (opt.removeLabels) {
req.remove_labels = opt.removeLabels;
}
if (opt.addLabels) {
req.add_labels = opt.addLabels;
}

var p = BatchQueue.enqueue(groupId, {
groupId: groupId,
request: req
});
Store.push(groupId, p, Option.none<{}>());
}

interface QueueRequest {
groupId: string;
request: ApiT.LabelChangeRequest;
};

var BatchQueue = new Queue2.Processor(
// Processor
function(r: QueueRequest) {
return Api.changeGroupEventLabels(r.groupId, r.request);
},

// Pre-processor
function(requests: QueueRequest[]) {
var next = requests.shift();

// Filter out redundant requests, while adding them to the combined
// request
requests = _.filter(requests, (r) => {
if (r.groupId === next.groupId &&
_.isEqual(r.request.selection, next.request.selection))
{
next.request.add_labels = _(next.request.add_labels)
.difference(r.request.remove_labels)
.union(r.request.add_labels)
.value();

next.request.remove_labels = _(next.request.remove_labels)
.difference(r.request.add_labels)
.union(r.request.remove_labels)
.value();

return false;
}
return true;
});

requests.unshift(next);
return requests;
});
}
20 changes: 10 additions & 10 deletions esper.com/ts/manage.js/Views.GroupLabelSettings.tsx
Expand Up @@ -30,7 +30,7 @@ module Esper.Views {

setLabelColor(group: ApiT.Group) {
return function(oldInfo: ApiT.LabelInfo, newColor: string) {
// TODO: Add in functionality to change group label colors
return Actions.Groups.setLabelColor(group.groupid, oldInfo, newColor);
};
}

Expand All @@ -56,22 +56,22 @@ module Esper.Views {
var archive = this.archive(group);
return function(label: Types.LabelBase) {
archive(label);
// FIXME: Disable batch labelling until we properly figure this out
// Actions.BatchLabels.remove(this.props.group.groupid, label);
Actions.BatchGroupLabels.remove(
group.groupid,
label.displayAs
);
};
}

renameLabel(group: ApiT.Group) {
return function(orig: Types.LabelBase, val: Types.LabelBase) {
Actions.Groups.renameLabel(group.groupid, orig, val);
// FIXME: Disable batch labelling until we properly figure this out
// Actions.BatchLabels.rename(this.props.group.groupid, orig, val);
Actions.BatchGroupLabels.rename(
group.groupid,
orig.displayAs,
val.displayAs
);
};
}
}
}





34 changes: 32 additions & 2 deletions lib-ts/Actions.Groups.ts
Expand Up @@ -310,15 +310,24 @@ module Esper.Actions.Groups {

export var LabelUpdateQueue = new Queue2.Processor(
function(update: LabelUpdate) {
Analytics.track(Analytics.Trackable.SetTimeStatsLabels, {
Analytics.track(Analytics.Trackable.SetGroupLabels, {
numLabels: update.labels.length,
_id: update.groupId,
labels: _.map(update.labels, (l) => l.original)
});

return Api.putGroupLabels(update.groupId, {
let p = Api.putGroupLabels(update.groupId, {
labels: _.map(update.labels, (l) => l.original)
});

return p.then(() => Api.batch(() => {
var promises = _.map(update.labels, (l) =>
Api.setGroupLabelColor(update.groupId, {
label: l.original,
color: l.color || Colors.getNewColorForLabel()
}));
return Util.when(promises);
})).then(() => null);
},

// Always use last update (put operation)
Expand Down Expand Up @@ -361,6 +370,27 @@ module Esper.Actions.Groups {
return setGroupLabels(_id, group, labelInfos);
}

export function setLabelColor(_id: string,
labelInfo: ApiT.LabelInfo,
newColor: string) {
var group = Stores.Groups.require(_id);
if (! group) return;

var oldLabelInfo = _.find(group.group_labels, labelInfo);
if (!oldLabelInfo || oldLabelInfo.color == newColor) return;

var groupCopy = _.cloneDeep(group);
_.find(groupCopy.group_labels, labelInfo).color = newColor;

var request = {
label: labelInfo.original,
color: newColor
};

var p = Api.setGroupLabelColor(group.groupid, request);
Stores.Groups.GroupStore.push(_id, p, Option.some(groupCopy));
}

function setGroupLabels(_id: string, group: ApiT.Group, labels: ApiT.LabelInfo[]) {
// Store values immutable so clone
var groupCopy = _.cloneDeep(group);
Expand Down
18 changes: 8 additions & 10 deletions lib-ts/Actions.Teams.ts
Expand Up @@ -153,20 +153,18 @@ module Esper.Actions.Teams {
labels: _.map(update.labels, (l) => l.original)
});

// FIXME: Batching does not seem to work
// return Api.batch(function() {
var p = Api.putSyncedLabels(update.teamId, {
labels: _.map(update.labels, (l) => l.original)
});

var promises = _.map(update.labels, (l) =>
Api.setLabelColor(update.teamId, {
label: l.original,
color: l.color || Colors.getNewColorForLabel()
}));

return p.then(() => Util.when(promises));
// });
return p.then(() => Api.batch(() => {
var promises = _.map(update.labels, (l) =>
Api.setLabelColor(update.teamId, {
label: l.original,
color: l.color || Colors.getNewColorForLabel()
}));
return Util.when(promises);
})).then(() => null);
},

// Always use last update (put operation)
Expand Down
4 changes: 4 additions & 0 deletions lib-ts/Analytics.ts
Expand Up @@ -32,11 +32,15 @@ module Esper.Analytics {

SetTimeStatsLabels, // Set labels for a team
SetTimeStatsCalendars, // Set calendars for a team
SetGroupLabels, // Set labels for a group

// Batch Label Changes
RenameTimeStatsLabel, // Rename label on team (and on all events)
DeleteTimeStatsLabel, // Delete label from team (and remove from
// all events)
RenameGroupLabel, // Rename label on group (and on all events)
DeleteGroupLabel, // Delete label from group (and remove from
// all events)

// Preferences changes
UpdateGeneralPrefs, // Changes one of the general preferences
Expand Down
17 changes: 17 additions & 0 deletions lib-ts/Api.ts
Expand Up @@ -478,6 +478,15 @@ module Esper.Api {
return JsonHttp.post(url, req);
}

export function setGroupLabelColor(
groupid: string, req: ApiT.SetLabelColorRequest
): JsonPromise<ApiT.LabelInfo> {
var url = `${prefix}/api/group-label/set-color/${string(Login.me())}`
+ `/${string(groupid)}`;
return JsonHttp.post(url, req);
}


/***** Google profile information *****/

export function getGoogleEmail(myUID: string, theirUID: string,
Expand Down Expand Up @@ -699,6 +708,14 @@ module Esper.Api {
return JsonHttp.post(url, req);
}

export function changeGroupEventLabels(groupId: string,
req: ApiT.LabelChangeRequest): JsonPromise<void>
{
var url = prefix + "/api/group/event/label-change/" + string(Login.myUid())
+ "/" + string(groupId);
return JsonHttp.post(url, req);
}

export function setPredictLabels(teamId: string,
req: ApiT.LabelsSetPredictRequest)
: JsonPromise<ApiT.GenericCalendarEvents>
Expand Down