diff --git a/r2/r2/controllers/api.py b/r2/r2/controllers/api.py
index 63f02cba0..b4055bb36 100644
--- a/r2/r2/controllers/api.py
+++ b/r2/r2/controllers/api.py
@@ -2085,6 +2085,14 @@ class ApiController(RedditController):
jquery('input[name="text"]').data('saved', text)
jquery('input[name="css_class"]').data('saved', css_class)
+ @validatedForm(VFlairManager(),
+ VModhash(),
+ flair_template_id = nop("flair_template_id"))
+ def POST_deleteflairtemplate(self, form, jquery, flair_template_id):
+ idx = FlairTemplateBySubredditIndex.by_sr(c.site._id)
+ if idx.delete_by_id(flair_template_id):
+ jquery('#%s' % flair_template_id).parent().remove()
+
@validatedForm(VFlairManager(), VModhash())
def POST_clearflairtemplates(self, form, jquery):
FlairTemplateBySubredditIndex.clear(c.site._id)
diff --git a/r2/r2/models/flair.py b/r2/r2/models/flair.py
index 512984217..19c9514b6 100644
--- a/r2/r2/models/flair.py
+++ b/r2/r2/models/flair.py
@@ -191,7 +191,7 @@ class FlairTemplateBySubredditIndex(tdb_cassandra.Thing):
for k in idx._index_keys():
del idx[k]
- # TODO: delete the dangling reference this leaves behind
+ # TODO: delete the orphaned FlairTemplate row
idx._commit()
@@ -226,3 +226,15 @@ class FlairTemplateBySubredditIndex(tdb_cassandra.Thing):
# Assign to position and commit.
setattr(self, self._make_index_key(position), ft_id)
self._commit()
+
+ def delete_by_id(self, ft_id):
+ for key in self._index_keys():
+ ft = getattr(self, key)
+ if ft == ft_id:
+ # TODO: delete the orphaned FlairTemplate row
+ g.log.debug('deleting ft %s (%s)', ft, key)
+ del self[key]
+ self._commit()
+ return True
+ g.log.debug("couldn't find %s to delete", ft_id)
+ return False
diff --git a/r2/r2/public/static/css/reddit.css b/r2/r2/public/static/css/reddit.css
index 38e862fd6..c0f760307 100644
--- a/r2/r2/public/static/css/reddit.css
+++ b/r2/r2/public/static/css/reddit.css
@@ -686,6 +686,15 @@ a.author { margin-right: 0.5em; }
.flairrow button { display: none; }
.flairrow .edited button { display: inline-block; }
+.flairdeletebtn {
+ color: black;
+ font-weight: bold;
+ opacity: 0.2;
+ text-decoration: none;
+}
+
+.flairrow:hover .flairdeletebtn { opacity: 1.0; }
+
.flairselector { font-size: x-small; position: absolute; width: 400px; }
.flairselector h2 {
diff --git a/r2/r2/public/static/js/flair.js b/r2/r2/public/static/js/flair.js
index 4bc173696..d71caf2fb 100644
--- a/r2/r2/public/static/js/flair.js
+++ b/r2/r2/public/static/js/flair.js
@@ -10,6 +10,14 @@ $(function() {
}
}
+ function onDelete(action) {
+ return post_form(this.parentNode, action);
+ }
+
+ function makeOnDelete(action) {
+ return function() { return onDelete.call(this, action); };
+ }
+
function onFocus() {
showSaveButton(this);
}
@@ -129,6 +137,10 @@ $(function() {
$(".flairlist").delegate(".flaircell input", "focus", onFocus);
$(".flairlist").delegate(".flaircell input", "keyup", onEdit);
$(".flairlist").delegate(".flaircell input", "change", onEdit);
+ $(".flairlist").delegate(".flairtemplate .flairdeletebtn", "click",
+ makeOnDelete("deleteflairtemplate"));
+ $(".flairlist").delegate(".flairgrant .flairdeletebtn", "click",
+ makeOnDelete("deleteflair"));
// Event handlers for sidebar flair prefs.
$(".flairtoggle").submit(function() {
diff --git a/r2/r2/templates/flairtemplateeditor.html b/r2/r2/templates/flairtemplateeditor.html
index d3e6c082e..95956da69 100644
--- a/r2/r2/templates/flairtemplateeditor.html
+++ b/r2/r2/templates/flairtemplateeditor.html
@@ -50,5 +50,8 @@
${utils.error_field('BAD_CSS_NAME', 'css_class')}
${utils.error_field('TOO_MUCH_FLAIR_CSS', 'css_class')}
+ %if thing.id:
+ X
+ %endif