Skip to content

Commit

Permalink
Merge remote-tracking branch 'wfp/suppress-tags' into stage-main-10-1c
Browse files Browse the repository at this point in the history
  • Loading branch information
schuyler1d committed Mar 30, 2021
2 parents 5e1ed02 + 92184a5 commit 1505fc8
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/api/campaign-contact.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const schema = `
validTimezone: Boolean
includePastDue: Boolean
tags: [String]
suppressedTags: [String]
contactId: String
errorCode: [Int]
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/IncomingMessageFilter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ class IncomingMessageFilter extends Component {
return left.text.localeCompare(right.text, "en", { sensitivity: "base" });
});

//this.state.texterSearchText = this.props.texterSearchText;
// this.state.texterSearchText = this.props.texterSearchText;

return (
<Card>
Expand Down
64 changes: 56 additions & 8 deletions src/components/TagsSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ import MenuItem from "material-ui/MenuItem";
import Divider from "material-ui/Divider";
import Humps from "humps";

const inlineStyles = {
sectionLabel: {
margin: "5px 0 0 20px",
fontWeight: "bold",
fontSize: 16
}
};

const NO_TAG = { id: -1, name: "NO TAG" };
const ANY_TAG = { id: -2, name: "ANY TAG" };
const IGNORE_TAGS = { id: -3, name: "IGNORE TAGS" };
Expand All @@ -19,7 +27,8 @@ const makeTagMetafilter = (ignoreTags, anyTag, noTag, tagItem) => {
ignoreTags,
anyTag,
noTag,
selectedTags: {}
selectedTags: {},
suppressedTags: {}
};

if (tagItem) {
Expand Down Expand Up @@ -54,6 +63,7 @@ export class TagsSelector extends React.Component {

cloneTagFilter = () => {
const selectedTags = {};

if (Object.keys(this.props.tagsFilter.selectedTags || {}).length > 0) {
Object.keys(this.props.tagsFilter.selectedTags).forEach(key => {
if (key > 0) {
Expand All @@ -62,11 +72,22 @@ export class TagsSelector extends React.Component {
});
}

const suppressedTags = {};

if (Object.keys(this.props.tagsFilter.suppressedTags || {}).length > 0) {
Object.keys(this.props.tagsFilter.suppressedTags).forEach(key => {
if (key > 0) {
suppressedTags[key] = this.state.tags[key] || TAG_META_FILTERS[key];
}
});
}

return {
ignoreTags: this.props.tagsFilter.ignoreTags,
anyTag: this.props.tagsFilter.anyTag,
noTag: this.props.tagsFilter.noTag,
selectedTags
selectedTags,
suppressedTags
};
};

Expand All @@ -89,8 +110,14 @@ export class TagsSelector extends React.Component {

if (itemClicked.id in tagFilter.selectedTags) {
delete tagFilter.selectedTags[itemClicked.id];
} else if (itemClicked.id in tagFilter.suppressedTags) {
delete tagFilter.suppressedTags[itemClicked.id];
} else if (String(itemClicked.id).startsWith("s_")) {
tagFilter.suppressedTags[itemClicked.id] = itemClicked;
delete tagFilter.selectedTags[itemClicked.id.replace("s_", "")];
} else {
tagFilter.selectedTags[itemClicked.id] = itemClicked;
delete tagFilter.suppressedTags[`s_${itemClicked.id}`];
}
}

Expand Down Expand Up @@ -118,10 +145,10 @@ export class TagsSelector extends React.Component {
];
return this.createMenuItem(tagFilter, isChecked);
});
return [...menuItems, <Divider key={-9999} inset />];
return menuItems;
};

createMenuItems = tagFilters => {
createTagMenuItems = tagFilters => {
return tagFilters
.sort((left, right) => {
if (left.name === right.name) {
Expand All @@ -131,8 +158,11 @@ export class TagsSelector extends React.Component {
return left.name < right.name ? 0 : 1;
})
.map(tagFilter => {
const isChecked =
tagFilter.id in (this.state.tagFilter.selectedTags || []);
const isChecked = [
...Object.keys(this.state.tagFilter.selectedTags || {}),
...Object.keys(this.state.tagFilter.suppressedTags || {})
].includes(tagFilter.id);

return this.createMenuItem(tagFilter, isChecked);
});
};
Expand All @@ -151,7 +181,10 @@ export class TagsSelector extends React.Component {
return [IGNORE_TAGS];
}

return Object.values(tagFilter.selectedTags);
return [
...Object.values(tagFilter.selectedTags),
...Object.values(tagFilter.suppressedTags)
];
};

render = () => (
Expand All @@ -161,9 +194,24 @@ export class TagsSelector extends React.Component {
hintText={this.props.hintText}
floatingLabelText={"Tags"}
floatingLabelFixed
maxHeight={600}
>
{this.createMetaFilterMenuItems(Object.values(TAG_META_FILTERS))}
{this.createMenuItems(Object.values(this.state.tags))}

<Divider inset />
<div style={inlineStyles.sectionLabel}>FILTER BY TAGS</div>

{this.createTagMenuItems(Object.values(this.state.tags))}

<Divider inset />
<div style={inlineStyles.sectionLabel}>SUPPRESS TAGS</div>

{this.createTagMenuItems(
Object.values(this.state.tags).map(tag => ({
...tag,
id: `s_${tag.id}`
}))
)}
</SelectField>
);
}
Expand Down
8 changes: 6 additions & 2 deletions src/containers/AdminIncomingMessageList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ export class AdminIncomingMessageList extends Component {
const selectedTags = Object.keys(
nextState.tagsFilter.selectedTags || {}
).filter(t => t);
query.tags = selectedTags.join(",");
const suppressedTags = Object.keys(
nextState.tagsFilter.suppressedTags || {}
).filter(t => t);
query.tags = [...selectedTags, ...suppressedTags].join(",");
}
}
// default false
Expand Down Expand Up @@ -367,7 +370,8 @@ export class AdminIncomingMessageList extends Component {

const contactsFilter = {
...this.state.contactsFilter,
tags: newTagsFilter || undefined
tags: (newTagsFilter || {}).include || undefined,
suppressedTags: (newTagsFilter || {}).suppress || undefined
};

this.setState({
Expand Down
16 changes: 10 additions & 6 deletions src/lib/conversations.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
export const tagsFilterStateFromTagsFilter = tagsFilter => {
let newTagsFilter = null;
const newTagsFilter = {};
if (tagsFilter.anyTag) {
newTagsFilter = ["*"];
newTagsFilter.include = ["*"];
} else if (tagsFilter.noTag) {
newTagsFilter = [];
newTagsFilter.include = [];
} else if (!tagsFilter.ignoreTags) {
newTagsFilter = Object.values(tagsFilter.selectedTags).map(
tagFilter => tagFilter.id
newTagsFilter.include = Object.values(tagsFilter.selectedTags || {}).map(
tagFilter => (tagFilter || {}).id
);
newTagsFilter.suppress = Object.values(tagsFilter.suppressedTags || {}).map(
tagFilter => (tagFilter || {}).id
);
}
return newTagsFilter;
Expand Down Expand Up @@ -108,6 +111,7 @@ export const getConversationFiltersFromQuery = (query, organizationTags) => {
}
}
const newTagsFilter = tagsFilterStateFromTagsFilter(filters.tagsFilter);
filters.contactsFilter.tags = newTagsFilter;
filters.contactsFilter.tags = newTagsFilter.include;
filters.contactsFilter.suppressedTags = newTagsFilter.suppress;
return filters;
};
18 changes: 18 additions & 0 deletions src/server/api/conversations.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,24 @@ function getConversationsJoinsAndWhereClause(
query = query.whereExists(tagsSubquery);
}
}

if (contactsFilter.suppressedTags) {
const tags = contactsFilter.suppressedTags.map(id =>
id.replace("s_", "")
);

if (tags.length >= 1) {
query = query.whereNotExists(
r.knexReadOnly
.select(1)
.from("tag_campaign_contact")
.whereRaw(
"campaign_contact.id = tag_campaign_contact.campaign_contact_id"
)
.whereIn("tag_id", tags)
);
}
}
}

return query;
Expand Down

0 comments on commit 1505fc8

Please sign in to comment.