MortarStone Tags Redesign

Redesigning MortarStone Tags


The problem

MortarStone is a donation management platform for nonprofit organizations and churches.  Part of MortarStone's mission is to make it easy for our users to quickly hone in on the right donors based on their behavior so they can respond to them as soon as possible, ensure that their retention is down and growth is promoted. In an attempt to accomplish that, MortarStone created a feature called Triggers. The idea was that users would be able to set up certain behavioral conditions and MortarStone would alert users when donors fit those conditions. Although the functionality technically achieved that, many users complained that the UI was too confusing and we found that an even greater number of users were simply ignoring this part of the app.

The old triggers UI

The tags concept

I started by talking to some of the users that were using Triggers to get a better idea of what they would like to do with this feature and how to make something easy to use yet powerful. I iterated over a few different prototypes using MarvelApp based on wireframes and went over our solution with our users. You can view the entire prototype of the MortarStone redesign here.


The feedback

After talking to some of our users, we discovered that what they wanted were two types of tags: Static and Smart. Static tags are used to tag donors manually by attributes that cannot be measured within MortarStone. For instance, users may want to tag some of their donors as "Dog Owners" so they can filter by them or put them in an email list. Smart tags would allow users to automatically apply and unapply tags to their whole donor base by setting up conditions.

The result

Creating a smart tag

Filtering by tags

Once a user creates a smart tag, it automatically shows up as a filter options in different views so that users can hone in on donors that fit the smart tag condition.

Extra credit: Making filters stateful

The response upon releasing Smart Tags was overwhelmingly positive. Our users picked up on the functionality easily and a majority of them started using them extensively right away. But something unexpected happened–as our users were using our tag filters, we started getting the same complaint: "I love the new tags, but if I'm filtering my list down based on tags, access a single record and then come back to the main list, the filters I had selected are checked off!"

I figured that since users just wanted the state of their filters to be maintained during an active session, there was no need to store this data in our database; a simply stateful service would suffice.

'use strict';

var app = angular.module('frontendCompanyApp');
app.factory('msFilterState', function () {
  var service = {};
  var state = null;
  service.getState = function () {
    return state;
  service.updateState = function (filterItems) {
    state = filterItems;
  return service;

This service takes the state from any controller in the application, stores the list of checked items in an object, and provides that object back to controllers when they need it. Since AngularJS services do not get reset when the user moves from one view to another (unlike controllers), services are a great solution to store state information in a way that can easily be shared across different controllers without a need to rely on the server side.

The final result

Now our users can set up smart tag conditions in a way that is intuitive to them, use those tags to filter their donor lists and maintain their selected filters throughout their session.