petra-tool / frontend / store / site.js
site.js
Raw
import Vue from 'vue';

export default {
  namespaced: true,

  state() {
    return {
      // Main
      team: {},
      board: {},
      matrix: null,
      phases: null,
      deliverables: [],
      methods: [],
      navigationDrawer: false,
      rightDrawer: false,

      // Filters
      labelFilter: {name: ''}, // empty label with name property
      cycleFilter: null,

      // Dialogs
      expiredCycleDialog: null,
    };
  },

  mutations: {
    setTeam: (state, team) => (state.team = team),

    addCycle: (state, cycle) => (state.team.cycles.push(cycle)),
    deleteCycle: (state, id) => (state.team.cycles = state.team.cycles.filter(cycle => cycle.id !== id)),
    // finishCycle: (state, finishedCycle) => (state.team.cycles.find(cycle => cycle.id === finishedCycle.id).finished = finishedCycle.finished),
    setSettings: (state, settings) => state.team.settings = settings,

    setBoard: (state, board) => (state.board = board),
    destroyBoard: (state) => state.board = null,
    addLabel: (state, label) => {
      // Check for duplicates
      if (state.board.labels.filter(m => m.id === label.id).length === 0) {
        state.board.labels.push(label)
      }
    },
    deleteLabel: (state, label) => (state.board.labels = state.board.labels.filter(m => m.id !== label.id)),
    addTask: (state, task) => (state.board.tasks.push(task)),
    removeTask: (state, task) => {
      state.board.tasks = state.board.tasks.filter(t => t.id !== task.id)
    },

    setMatrix: (state, matrix) => state.matrix = matrix,
    setPhases: (state, phases) => state.phases = phases,

    setDeliverables: (state, deliverables) => state.deliverables = deliverables,
    setMethods: (state, methods) => state.methods = methods,

    toggleNavigationDrawer: (state, value) => state.navigationDrawer = value,
    toggleRightDrawer: (state, value) => state.rightDrawer = value,

    setFilter: (state, label) => (state.labelFilter = label),
    setCycleFilter: (state, filter) => (state.cycleFilter = filter),
    removeFilter: (state) => state.labelFilter = {name: ''},
    removeCycleFilter: (state) => state.cycleFilter = null,

    setExpiredCycleDialog: (state, dialog) => state.expiredCycleDialog = dialog,
  },

  getters: {
    getTeam: (state) => state.team || [],
    getMembers: (state) => state.team.members || [],
    getCycles: (state) => state.team.cycles || [],
    getSettings: (state) => state.team.settings || [],

    getBoard: (state) => state.board,
    getTasks: (state) => state.board.tasks || [],
    getLabelFilter: (state) => state.labelFilter,
    getFilteredTasks: (state) => {
      if (state.labelFilter.name) {
        return state.board.tasks.filter(task => task.label.name === state.labelFilter.name)
      } else {
        return state.board.tasks
      }
    },

    getMatrix: (state) => state.matrix,
    getPhases: (state) => state.phases,

    getDeliverables: (state) => state.deliverables || [],
    getMethods: (state) => state.methods || [],

    getNavigationDrawer: (state) => state.navigationDrawer,
    getRightDrawer: (state) => state.rightDrawer,

    getCycleFinished: (state) => {
      return state.team.cycles.filter(cycle => cycle.status === 'Done' || cycle.status === 'Reflect')
    },
    getCycleTodo: (state) => {
      return state.team.cycles.filter(cycle => cycle.status === 'Ongoing')
    },

    getCycleFilter: (state) => state.cycleFilter,
    getFilteredCycles: (state) => {
      if (state.cycleFilter === 'complete')
        return state.team.cycles.filter(cycle => cycle.status === 'Done')
      else if (state.cycleFilter === 'todo')
        return state.team.cycles.filter(cycle => cycle.status === 'Ongoing')
      else if (state.cycleFilter === 'reflect')
        return state.team.cycles.filter(cycle => cycle.status === 'Reflect')
      else
        return state.team.cycles
    },

    getExpiredCycleDialog: (state) => state.expiredCycleDialog,
  },

  actions: {
    setTeam: ({commit}, newTeam) => commit('setTeam', newTeam),

    addCycle: ({commit}, newCycle) => (commit('addCycle', newCycle)),
    deleteCycle: ({commit}, id) => (commit('deleteCycle', id)),
    // finishCycle: ({commit}, finishedCycle) => (commit('finishCycle', finishedCycle)),
    updateCycle({commit}, updatedCycle) {
      commit('deleteCycle', updatedCycle.id)
      commit('addCycle', updatedCycle)
    },
    setSettings: ({commit}, settings) => commit('setSettings', settings),

    setBoard: ({commit}, response) => (commit('setBoard', response)),
    destroyBoard: ({commit}) => commit('destroyBoard'),
    updateLabel: ({commit}, label) => {
      commit('deleteLabel', label);
      commit('addLabel', label);
    },
    addLabel: ({commit, state}, newLabel) => {
      commit('addLabel', newLabel)
      var intersection = state.board.tasks.filter(e => !newLabel.tasks.some(e2 => e.id !== e2.id))
      if (intersection.length === 0)
        // sometimes tasks are already present in the kanban
        // thus, add tasks only if task.id is not present in the board-tasklist
        newLabel.tasks.forEach(task => commit('addTask', task))
    },
    deleteLabel: ({commit}, label) => (commit('deleteLabel', label)),
    addTask: ({commit}, newTask) => (commit('addTask', newTask)),
    // updateTask: ({commit}, updatedTask) => (commit('updateTask', updatedTask)),
    updateTask: ({commit}, updatedTask) => {
      commit('removeTask', updatedTask)
      commit('addTask', updatedTask)
    },
    removeTask: ({commit}, task) => (commit('removeTask', task)),

    fetchMatrix({commit}) {
      return Vue.$http.get('/matrix').then(res => {
        const matrix = {
          counts: res.data.counts,
          counts_normalized: res.data.counts_normalized,
          fidelity: res.data.fidelity
        }
        commit('setMatrix', matrix)
      })
    },

    fetchProgress({commit}) {
      return Vue.$http.get('/progress').then(res => {
        commit('setPhases', res.data.phases)
      })
    },

    fetchPrototyping({commit, state}) {
      const bdPresent = state.team.members.some(member => member.role === 'BD' & member.available)

      return Vue.$http.get(`/prototyping?bd-present=${ bdPresent }`).then(res => {
        commit('setDeliverables', res.data.deliverables)
        commit('setMethods', res.data.methods)
      })
    },

    logout: ({commit}) => {
      commit('setTeam', {})
      commit('setBoard', {})
      commit('setMatrix', null)
      commit('toggleNavigationDrawer', false)
      commit('toggleRightDrawer', false)
      commit('removeCycleFilter')
      commit('removeFilter')
      commit('setDeliverables', [])
      commit('setMethods', [])
    },

    toggleNavigationDrawer: ({commit}, value) => commit('toggleNavigationDrawer', value),
    toggleRightDrawer: ({commit}, value) => commit('toggleRightDrawer', value),

    // For filters see https://stackoverflow.com/a/42662812
    // and http://www.ritzcovan.com/index.php/2018/10/01/filtering-data-in-vuex/
    // labelFilter has to be a label with property name
    filterBoardByLabel: ({commit}, label) => (commit('setFilter', label)),
    filterCyclesByStatus: ({commit}, filter) => commit('setCycleFilter', filter),
    removeFilter: ({commit}) => commit('removeFilter'),
    removeCycleFilter: ({commit}) => commit('removeCycleFilter'),

    setExpiredCycleDialog: ({commit}, value) => commit('setExpiredCycleDialog', value),
  }
}