value objects

Como criar status para as tarefas utilizando value objects – ToDo List 4

Introdução

Neste artigo vou mostrar como criar status para as tarefas utilizando value objects no projeto ToDo List.

Em um sistema de lista de tarefas, é comum as tarefas terem status por exemplo de “em aberto”, “concluído”, “arquivado” e entre outros.

Isso possibilita que o usuário faça o gerenciamento dos status de suas tarefas, e consiga ver quais tarefas ainda estão pendentes.

Para isso vou fazer a implementação dos status para cada tarefa.

Caso você não tenha visto os outros artigos desse projeto ToDo List, veja aqui.

Enum / value objects

Para a implementação dos status da tarefa, vou utilizar uma técnica que é chamado de ENUM, porém eu conheço como value objects.

Basicamente, essa técnica da a possibilidade de criar um conjunto de valores fixos para serem utilizados, com isso vai ficar mais fácil para ler um código.

Na prática, vou criar um arquivo para colocar as constantes que vão representar os status, onde Open = 1, Finished = 2 e Arquived = 3.

Adaptar formulário

A primeira etapa da implementação, é adaptar o formulário para ter um campo novo, que será o de status.

Para isso vou utilizar o campo select do BootstrapVue. Nele vou colocar a lista de opções que será a lista dos status.

Caso você não tenha o código fonte do projeto, pegue aqui.

No arquivo Form.vue, vou adicionar abaixo do campo de descrição, o campo com o select.

<b-form-group
    label="Descrição"
    label-for="description"
  >
    <b-form-select v-model="form.status" :options="optionsStatus"></b-form-select>
</b-form-group>

Agora, para as alterações na parte do script, vou precisar criar um novo campo dentro da chave form, e também a chave de opções no data.

form: {
    subject: "",
    description: "",
    status: 1
  },
  methodSave: "new",
  optionsStatus: [
    { value: 1, text: "Aberto" },
    { value: 2, text: "Finalizado" },
    { value: 3, text: "Arquivado" },
]

Isso já vai fazer o select funcionar, porém, os valores do status estão fixos no código, e é nesse momento que vou utilizar o value objects.

Utilizando o Enum

Dentro do diretório src, vou criar um novo chamado valueObjects, e dentro dele um arquivo chamado status.js.

// -> src/valueObjects/status.js
export default {
    OPEN: 1,
    FINISHED: 2,
    ARCHIVED: 3
}

Certo, agora dentro dele tenho as três constantes de status da tarefa.

Agora vou importar este arquivo para o Form.vue e vou utilizar este value objects para atribuir o valor.

//importação do objeto de valor
import Status from "@/valueObjects/status";

Substitua o código dentro do return do data, para este:

form: {
    subject: "",
    description: "",
    status: Status.OPEN
  },
  methodSave: "new",
  optionsStatus: [
    { value: Status.OPEN, text: "Aberto" },
    { value: Status.FINISHED, text: "Finalizado" },
    { value: Status.ARCHIVED, text: "Arquivado" },
]

Dessa forma fica mais fácil de ler e entender que o status padrão é o aberto, e também que há os três status, não preciso lembrar qual o código de cada um, posso utilizar somente as constantes do objeto de valor sem me preocupar.

Se outro desenvolvedor olhar este código, talvez ele não saiba qual o código de status de cada um, mas vai entender isso.

Caso tenha novos status na aplicação, só adicionar um valor no value objects.

Com isso, agora o formulário vai ter esse campo:

value objects preview

E as novas tarefas que forem salvas, já terão o status, seja na criação ou edição.

Outra alteração que fiz no Form.vue, é no botão de salvar e no método que salva as tarefas.

No botão, retirei o :disabled e na função fiz a validação dos dados antes de salvar efetivamente.

O botão ficou assim:

<b-button 
    type="submit" 
    variant="outline-primary" 
    @click="saveTask"
> Salvar </b-button>

E o método de salvar:

saveTask() {
  this.$v.$touch(); //nova validação do formulário
  if (this.$v.$error) return; //se não for válido não deixa salvar

  if(this.methodSave === "update"){
    this.form.save();
    this.showToast("success", "Sucesso!", "Tarefa atualizada com ouceso");
    this.$router.push({ name: "list" });
    return;
  }

  const task = new TasksModel(this.form);
  task.save();

  this.showToast("success", "Sucesso!", "Tarefa criada com suceso");
  this.$router.push({ name: "list" });
}

Função para atualizar o status

Com o funcionamento do formulário pronto, a próxima etapa é criar as funções para atualizar para concluído e arquivado.

A lógica para as duas funções é a mesma, ambas vão trocar para um status, mostrar um alerta e refazer a busca das tarefas.

Como regra de negócio, defini que uma tarefa arquivada, não vai aparecer na lista, somente as abertas e as concluídas.

As tarefas concluídas irão ficar com o texto riscado.

No componente List.vue, vou criar dois novos botões, o “concluir” e o “arquivar”:

<b-button
  variant="outline-secondary"
  class="mr-2"
  @click="updateStatus(task.id, status.FINISHED)"
>
  Concluir
</b-button>

<b-button
   variant="outline-secondary"
   class="mr-2"
   @click="updateStatus(task.id, status.ARCHIVED)"
>
   Arquivar
</b-button>

Agora, vou fazer novamente a importação do value objects de status:

import Status from "@/valueObjects/status";

E agora vou declarar a função para trocar o status:

async updateStatus(taskId, status) {
  let task = await TasksModel.find(taskId);
  task.status = status;
  await task.save();

  this.showToast("success", "Sucesso!", "Status da tarefa atualizado com sucesso");
  this.tasks = await TasksModel.params({ status: this.statusList }).get();
},

Nesse método, para refazer a busca das tarefas, e não buscar as tarefas arquivadas, usei a variável this.statusList, que contém um array com os dois status que irão aparecer na tela, vou colocar essa variável dentro do data:

Preciso também declarar uma variável status, para usar o value objects no template.

data() {
    return {
      tasks: [],
      taskSelected: [],
      statusList: [Status.OPEN, Status.FINISHED],
      status: Status
    };
  },

Além dessa nova função de atualizar o status, precisa trocar essa busca no created e no confirmRemove, para todos os métodos fazerem a mesma busca.

async created() {
    this.tasks = await TasksModel.params({ status: this.statusList }).get();
  },
async confirmRemoveTask() {
      this.taskSelected.delete();
      this.tasks = await TasksModel.params({ status: this.statusList }).get();
      this.hideModal();
    },

A última parte é fazer a tarefa concluída ficar riscada.

Para isso, vou adicionar uma classe dinamicamente no card, e quando a tarefa for finalizada, aplica essa classe:

<b-card :title="task.subject" class="mb-2" :class="{ 'finished-task': isFinished(task) }">

O isFinished é um método que retornará true ou false, de acordo com o status da tarefa, e para a comparação também vou utilizar o value objects.

Dessa forma também fica mais fácil entender o que está na comparação:

isFinished(task) {
  return task.status === Status.FINISHED;
}

E agora vou criar o estilo da classe:

/* Colocar essa parte na tag style do componente */
.finished-task {
  opacity: 0.7
}
.finished-task > .card-body > h4, .finished-task > .card-body > p {
  text-decoration: line-through;
}

Com isso o resultado é esse:

Vídeo

Código fonte

O código fonte está no meu CodeSandbox, neste link.

Para ver outros canais onde o posto conteúdo sobre VueJS, veja os Links do Programando Soluções.

Conclusão

Com isso, foi possível ver como utilizar value objects para criar constantes e utilizar posteriormente, deixa o código mais legível.

Com o value objects o código também fica mais extensível, se quiser criar mais status pode adicionar no arquivo e utilizar no resto do código.

Referências

https://pt.stackoverflow.com/questions/7360/por-que-e-quando-usar-enum-em-java

Este conteúdo te ajudou de alguma forma?

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Usamos cookies para lhe proporcionar a melhor experiência possível no nosso site. Ao continuar a usar este site, você concorda com o uso de cookies.
Ok
Privacy Policy