mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-12 13:28:36 +03:00
Validate uniqueness of tags and ignore global tag duplicates
This commit is contained in:
@@ -31,12 +31,12 @@ export default class Notification extends React.Component{
|
||||
if (this.props.isNotification) {
|
||||
return (
|
||||
<div className={`notification-wrapper`}>
|
||||
{this.props.notifications.map(not => (
|
||||
{this.props.notifications.map(notification => (
|
||||
<div className='notification' onClick={() => this.toggleDetails() }>
|
||||
<button onClick={() => this.props.toggle()} className="side-menu-burg over-white is-active"><span /></button>
|
||||
<div className={`message ${not.type}`}>{`${not.message}`}</div>
|
||||
<div className={`message ${notification.type}`}>{`${notification.message}`}</div>
|
||||
<div className={`details ${this.state.isExtended}`}>
|
||||
{(not.items !== null) ? this.renderItems(not.items) : ''}
|
||||
{(notification.items !== null) ? this.renderItems(notification.items) : ''}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
@@ -18,6 +18,34 @@ function makeError(type, id, message) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const isLeaf = node => (Object.keys(node.children).length === 0);
|
||||
const isDuplicate = (node, set) => { return (set.has(node.key)); };
|
||||
|
||||
|
||||
/*
|
||||
* Traverse a tag tree and check its duplicates
|
||||
*/
|
||||
function traverseNodeAndCheckIt(node, parent, set, duplicates) {
|
||||
// If it's a leaf, check that it's not duplicate
|
||||
if (isLeaf(node)) {
|
||||
if (isDuplicate(node, set)) {
|
||||
duplicates.push({
|
||||
id: node.key,
|
||||
error: makeError('Tags', node.key, 'tag was found more than once in hierarchy. Ignoring duplicate.')
|
||||
});
|
||||
delete parent.children[node.key];
|
||||
} else {
|
||||
set.add(node.key);
|
||||
}
|
||||
} else {
|
||||
// If it's not a leaf, simply keep going
|
||||
Object.values(node.children).forEach((childNode) => {
|
||||
traverseNodeAndCheckIt(childNode, node, set, duplicates);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate domain schema
|
||||
*/
|
||||
@@ -27,7 +55,7 @@ export function validate(domain) {
|
||||
categories: [],
|
||||
sites: [],
|
||||
notifications: domain.notifications,
|
||||
tags: domain.tags
|
||||
tags: {}
|
||||
}
|
||||
|
||||
const discardedDomain = {
|
||||
@@ -59,7 +87,7 @@ export function validate(domain) {
|
||||
validateItem(site, 'sites', siteSchema);
|
||||
});
|
||||
|
||||
// Message the number of failed items
|
||||
// Message the number of failed items in domain
|
||||
Object.keys(discardedDomain).forEach(disc => {
|
||||
const len = discardedDomain[disc].length;
|
||||
if (len) {
|
||||
@@ -69,7 +97,22 @@ export function validate(domain) {
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
// Validate uniqueness of tags
|
||||
const tagSet = new Set([]);
|
||||
const duplicateTags = [];
|
||||
traverseNodeAndCheckIt(domain.tags, {}, tagSet, duplicateTags);
|
||||
|
||||
// Duplicated tags
|
||||
if (duplicateTags.length > 0) {
|
||||
sanitizedDomain.notifications.push({
|
||||
message: `Tags are required to be unique. Ignoring duplicates for now.`,
|
||||
items: duplicateTags,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
sanitizedDomain.tags = domain.tags;
|
||||
|
||||
return sanitizedDomain;
|
||||
}
|
||||
|
||||
@@ -57,15 +57,23 @@
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-radius: 3px;
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
background: $darkgrey;
|
||||
color: $offwhite;
|
||||
font-family: monospace;
|
||||
|
||||
&.true {
|
||||
height: auto;
|
||||
transition: height 0.4s;
|
||||
transition: height 0.4s, margin 0.4s;
|
||||
}
|
||||
|
||||
&.false {
|
||||
height: 0;
|
||||
transition: height 0.4s;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
transition: height 0.4s, margin 0.4s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user