import { jugglService } from "@/services/juggl.service.js"; export const juggl = { state: { apiUrl: "https://juggl.giller.dev/api", projects: [], records: [], tags: [], statistics: [], user: undefined, auth: undefined, recordsLimit: 0 }, mutations: { setProjects(state, projects) { state.projects = projects; }, setRecords(state, records) { state.records = records; }, setTags(state, tags) { state.tags = tags; }, setStatistics(state, statistics) { state.statistics = statistics; }, setRecordsLimit(state, limit) { state.recordsLimit = limit; }, setUser(state, user) { state.user = user; }, logout(state) { state.auth = undefined; localStorage.removeItem("apiKey"); localStorage.removeItem("userId"); }, login(state, { apiKey, userId }) { state.auth = { apiKey: apiKey, userId: userId }; localStorage.setItem("apiKey", apiKey); localStorage.setItem("userId", userId); } }, getters: { runningRecords: state => { return Object.values(state.records).filter(record => record.running); }, finishedRecords: state => { return Object.values(state.records).filter(record => !record.running); }, getFilteredRecords: (state, getters) => ({ running = undefined, projectVisible = undefined, records = undefined }) => { if (records == undefined) { records = getters.records; } var visibleProjects = getters.visibleProjects; var visibleIds = []; Object.values(visibleProjects) .filter(p => p.visible) .forEach(p => { visibleIds.push(p.project_id); }); return Object.values(records).filter(rec => { if (running !== undefined && running !== rec.running) { return false; } var recProjectVisible = visibleIds.includes(rec.project_id); if ( projectVisible !== undefined && projectVisible !== recProjectVisible ) { return false; } return true; }); }, getFilteredStatistics: (state, getters) => ({ projectVisible = undefined }) => { return Object.values(getters.statistics).filter(statistic => { if ( projectVisible !== undefined && statistic.visible !== projectVisible ) { return false; } return true; }); }, auth: state => state.auth, apiUrl: state => state.apiUrl, user: state => state.user, isLoggedIn: state => !!state.auth, statistics: state => state.statistics, records: state => state.records, projects: state => state.projects, tags: state => state.tags, projectIds: state => { var projectIds = []; Object.values(state.projects).forEach(project => { projectIds.push(project.project_id); }); return projectIds; }, runningProjectIds: (state, getters) => { var runningProjectIds = []; Object.values(getters.runningRecords).forEach(record => { var projectId = record.project_id; if (runningProjectIds.includes(runningProjectIds) === false) { runningProjectIds.push(projectId); } }); return runningProjectIds; }, finishedProjectIds: (state, getters) => { var runningProjectIds = getters.runningProjectIds; return getters.projectIds.filter(id => !runningProjectIds.includes(id)); }, finishedProjects: (state, getters) => { return getters.getFilteredProjects({ finished: true }); }, visibleProjects: (state, getters) => { return getters.getFilteredProjects({ visible: true }); }, runningProjects: (state, getters) => { var ids = getters.runningProjectIds; return Object.values(state.projects).filter(project => ids.includes(project.project_id) ); }, getProjectById: (state, getters) => id => { return Object.values(getters.projects).find( project => project.project_id === id ); }, getFilteredProjects: (state, getters) => ({ finished = undefined, visible = undefined, projects = undefined }) => { if (projects == undefined) { projects = getters.projects; } var runningIds = getters.runningProjectIds; return Object.values(projects).filter(project => { var projectFinished = !runningIds.includes(project.project_id); if (finished !== undefined && finished !== projectFinished) { return false; } if (visible !== undefined && visible !== project.visible) { return false; } return true; }); }, getFilteredTags: (state, getters) => ({ visible = undefined, tags = undefined }) => { if (tags == undefined) { tags = getters.tags; } return Object.values(tags).filter(tag => { if (visible != undefined && visible !== tag.visible) { return false; } return true; }); }, getTagById: (state, getters) => id => { return Object.values(getters.tags).find(tag => tag.record_tag_id === id); }, getRecordById: (state, getters) => id => { return Object.values(getters.records).find( record => record.record_id === id ); }, getRecordsExceptId: (state, getters) => id => { return Object.values(getters.records).filter( record => record.record_id !== id ); }, getProjectsExceptId: (state, getters) => id => { return Object.values(getters.projects).filter( project => project.project_id !== id ); }, getTagsExceptId: (state, getters) => id => { return Object.values(getters.tags).filter( tag => tag.record_tag_id !== id ); } }, actions: { loadProjects({ commit }) { return jugglService.getProjects().then(r => { commit("setProjects", r.data.projects); }); }, loadTags({ commit }) { return jugglService.getTags().then(r => { commit("setTags", r.data.record_tags); }); }, loadUser({ commit }) { return jugglService .getUser() .catch(() => { return false; }) .then(r => { commit("setUser", r.data.users[0]); return true; }); }, loadRecords({ commit, state, getters }, { limit, finished, visible }) { if (limit !== undefined) { commit("setRecordsLimit", limit); } var payload = { limit: state.recordsLimit, finished: finished, visible: visible }; return jugglService.getRecords(payload).then(r => { var allRecords = Object.values(r.data.records); if (finished === true) { allRecords = [...allRecords, ...getters.runningRecords]; } else if (finished === false) { allRecords = [...allRecords, ...getters.finishedRecords]; } commit("setRecords", allRecords); }); }, loadDailyStatistics({ dispatch }, { date }) { dispatch("loadStatistics", { from: date, until: date }); }, loadMonthlyStatistics( { dispatch }, { startYear, startMonth, endYear, endMonth } ) { // Month in date object goes from 0 - 11 var options = { from: new Date(startYear, startMonth - 1, 2), until: new Date(endYear, endMonth, 0) // 0 leads to the last day of the previous month }; dispatch("loadStatistics", options); }, async loadStatistics({ commit }, options) { var results = Object.values( (await jugglService.getStatistics(options)).data.statistics ); commit("setStatistics", results); }, loadRunningRecords({ commit, getters }) { return jugglService.getRunningRecords().then(r => { var allRecords = { ...getters.finishedRecords, ...r.data.records }; commit("setRecords", allRecords); }); }, login({ commit, getters }, { userId, apiKey }) { // Is already logged in? if (getters.isLoggedIn) { this.dispatch("logout"); } commit("login", { apiKey: apiKey, userId: userId }); return this.dispatch("loadUser") .catch(() => { this.dispatch("logout"); return false; }) .then(r => { if (r === false) { this.dispatch("logout"); return false; } else { return true; } }); }, logout({ commit }) { commit("setUser", undefined); commit("setProjects", []); commit("setRecords", []); commit("logout"); }, endRecord({ getters }, recordId) { if (recordId === undefined) { return false; } return jugglService .endRecord(recordId) .catch(() => { return false; }) .then(() => { // TODO: Return ended record from API var record = getters.getRecordById(recordId); record.running = false; return true; }); }, addProject(context, { name }) { return jugglService .addProject(name) .catch(() => { return false; }) .then(() => { this.dispatch("loadProjects"); return true; }); }, addTag(context, { name }) { return jugglService .addTag(name) .catch(() => { return false; }) .then(() => { this.dispatch("loadTags"); return true; }); }, addTagToRecord(context, { tagId, recordId }) { return jugglService .addTagToRecord(tagId, recordId) .catch(() => { return false; }) .then(() => { // TODO: Manualy add tag return true; }); }, removeTagFromRecord(context, { tagId, recordId }) { return jugglService .removeTagFromRecord(tagId, recordId) .catch(() => { return false; }) .then(() => { // TODO: Manualy remove tag return true; }); }, startRecord(context, projectId) { if (projectId === undefined) { return false; } return jugglService .startRecord(projectId) .catch(() => { return false; }) .then(() => { this.dispatch("loadRunningRecords"); return true; }); }, removeRecord({ commit, getters }, recordId) { if (recordId === undefined) { return false; } return jugglService .removeRecord(recordId) .catch(() => { return false; }) .then(() => { commit("setRecords", getters.getRecordsExceptId(recordId)); return true; }); }, removeProject({ commit, getters }, projectId) { if (projectId === undefined) { return false; } return jugglService .removeProject(projectId) .catch(() => { return false; }) .then(() => { commit("setProjects", getters.getProjectsExceptId(projectId)); return true; }); }, removeTag({ commit, getters }, tagId) { if (tagId === undefined) { return false; } return jugglService .removeRecordTag(tagId) .catch(() => { return false; }) .then(() => { commit("setTags", getters.getTagsExceptId(tagId)); return true; }); }, loadSavedLogin() { var userId = localStorage.getItem("userId"); var apiKey = localStorage.getItem("apiKey"); if (userId == undefined || apiKey == undefined) { return; } this.dispatch("login", { apiKey: apiKey, userId: userId }); }, removeLocalRecords({ commit }) { commit("setRecords", []); }, updateRecord({ commit, getters }, record) { if (record.record_id === undefined) { return; } return jugglService .updateRecord(record) .catch(() => { return false; }) .then(() => { // TODO: Return updated record from API var records = getters.getRecordsExceptId(record.record_id); records.push(record); commit("setRecords", records); return true; }); }, updateTag({ commit, getters }, tag) { if (tag.record_tag_id === undefined) { return; } return jugglService .updateRecordTag(tag) .catch(() => { return false; }) .then(() => { // TODO: Return updated tag from API var tags = getters.getTagsExceptId(tag.record_tag_id); tags.push(tag); commit("setTags", tags); return true; }); }, updateProject({ commit, getters }, project) { if (project.project_id === undefined) { return; } return jugglService .updateProject(project) .catch(() => { return false; }) .then(() => { // TODO: Return updated project from API var projects = getters.getProjectsExceptId(project.project_id); projects.push(project); commit("setProjects", projects); return true; }); } } };