Utopian contribution: "Article module: add tags"

Task: @gregory.latinier/utopian-v2-task-article-module-add-a-tag
PR: https://github.com/utopian-io/v2.utopian.io/pull/224

This is my second Utopian contribution, and, as you can see in the task description, it is very similar to the first one. The main difference is that a regex had to be checked because the user can only add lowercase alphanumeric characters, '-', '+', '.', and '#' for the article's tags.
Utopian.io - adding tags special chars.gif

While doing this task I realized that there were some improvements that could have been made, and so I added to this task, and also to the first task on a different PR

The Autocomplete Component works the same way as before:

q-field(orientation="vertical", :label="$t('articles.createEdit.tags.label')", :count="5")
  q-chips-input(
    v-model="article.tags"
    @duplicate="duplicatedTags"
    @input="chipsInputChange"
    :placeholder="article.tags.length === 0 ? $t('articles.createEdit.tags.placeholder') : ''"
    :error="$v.article.tags.$error"
  )
    q-autocomplete(@search="tagsAutocomplete", :min-characters="2", :max-results="10")

Utopian.io - adding tags.gif

The frontend validation is checked inside an if statement every time a new value is added to the field and it's automatically deleted if an error is found. Also, a message is displayed to the user.

chipsInputChange (newTags) {
  const regex = /^[a-z0-9-+.#]*$/
  const newTag = newTags[newTags.length - 1] 
  if (!newTag.match(regex)) {
    this.article.tags.pop()
    this.setAppError('articles.createEdit.tags.errors.invalidCharacters')
  }
  if (newTags.length > 5) {
    this.article.tags.pop()
    this.setAppError('articles.createEdit.tags.errors.maxItems')
  }
}

Of course, a backend validation was also done.

Utopian.io - addind not supported chars.gif

The UML for this task is articles.tags[], so the Mongo query works the same way as the first task.

const tags = await Article.aggregate([
  { '$unwind': '$tags' },
  { '$match': { tags: { '$regex': `^${req.payload.partial}`, '$options': 'i', '$nin': req.payload.tags } } },
  { '$group': { _id: '$tags', occurrences: { '$sum': 1 } } },
  { '$limit': 10 },
  { '$addFields': { name: '$_id' } },
  { '$sort': { 'occurrences': -1, 'name': 1 } }
])

API TESTS

  • Article creation: the tag object was added to all existent tests.
  • Search tag endpoint: After ['post-test', 'post-update', 'c++', 'c#', '.net'] was added as tags to an article, this test checks if ['post-update'] is returned as a autocomplete option when a user has already typed 'post-test' as an article tag.

This was also a great task for me because I realized a few things that I could have done better in the first one. When you develop a similar task, naturally, you have a more severe criticism of your own work and, consequently, you find ways to improve it.

Thanks again for @utopian-io!

H2
H3
H4
Upload from PC
Video gallery
3 columns
2 columns
1 column
10 Comments