Projects Dropdown App Service
This commit is contained in:
parent
0bf40fd449
commit
43a27f845a
1 changed files with 132 additions and 0 deletions
|
@ -0,0 +1,132 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
import VueResource from 'vue-resource';
|
||||||
|
|
||||||
|
import bp from '../../breakpoints';
|
||||||
|
import Api from '../../api';
|
||||||
|
import AccessorUtilities from '../../lib/utils/accessor';
|
||||||
|
|
||||||
|
import { FREQUENT_PROJECTS, HOUR_IN_MS, STORAGE_KEY } from '../constants';
|
||||||
|
|
||||||
|
Vue.use(VueResource);
|
||||||
|
|
||||||
|
export default class ProjectsService {
|
||||||
|
constructor(currentUserName) {
|
||||||
|
this.isLocalStorageAvailable = AccessorUtilities.isLocalStorageAccessSafe();
|
||||||
|
this.currentUserName = currentUserName;
|
||||||
|
this.storageKey = `${this.currentUserName}/${STORAGE_KEY}`;
|
||||||
|
this.projectsPath = Vue.resource(Api.buildUrl(Api.projectsPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
getSearchedProjects(searchQuery) {
|
||||||
|
return this.projectsPath.get({
|
||||||
|
simple: false,
|
||||||
|
per_page: 20,
|
||||||
|
membership: !!gon.current_user_id,
|
||||||
|
order_by: 'last_activity_at',
|
||||||
|
search: searchQuery,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getFrequentProjects() {
|
||||||
|
if (this.isLocalStorageAvailable) {
|
||||||
|
return this.getTopFrequentProjects();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
logProjectAccess(project) {
|
||||||
|
let matchFound = false;
|
||||||
|
let storedFrequentProjects;
|
||||||
|
|
||||||
|
if (this.isLocalStorageAvailable) {
|
||||||
|
const storedRawProjects = localStorage.getItem(this.storageKey);
|
||||||
|
|
||||||
|
// Check if there's any frequent projects list set
|
||||||
|
if (!storedRawProjects) {
|
||||||
|
// No frequent projects list set, set one up.
|
||||||
|
storedFrequentProjects = [];
|
||||||
|
storedFrequentProjects.push({ ...project, frequency: 1 });
|
||||||
|
} else {
|
||||||
|
// Check if project is already present in frequents list
|
||||||
|
// When found, update metadata of it.
|
||||||
|
storedFrequentProjects = JSON.parse(storedRawProjects).map((projectItem) => {
|
||||||
|
if (projectItem.id === project.id) {
|
||||||
|
matchFound = true;
|
||||||
|
const diff = Math.abs(project.lastAccessedOn - projectItem.lastAccessedOn) / HOUR_IN_MS;
|
||||||
|
const updatedProject = {
|
||||||
|
...project,
|
||||||
|
frequency: projectItem.frequency,
|
||||||
|
lastAccessedOn: projectItem.lastAccessedOn,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if duration since last access of this project
|
||||||
|
// is over an hour
|
||||||
|
if (diff > 1) {
|
||||||
|
return {
|
||||||
|
...updatedProject,
|
||||||
|
frequency: updatedProject.frequency + 1,
|
||||||
|
lastAccessedOn: Date.now(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...updatedProject,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return projectItem;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check whether currently logged project is present in frequents list
|
||||||
|
if (!matchFound) {
|
||||||
|
// We always keep size of frequents collection to 20 projects
|
||||||
|
// out of which only 5 projects with
|
||||||
|
// highest value of `frequency` and most recent `lastAccessedOn`
|
||||||
|
// are shown in projects dropdown
|
||||||
|
if (storedFrequentProjects.length === FREQUENT_PROJECTS.MAX_COUNT) {
|
||||||
|
storedFrequentProjects.shift(); // Remove an item from head of array
|
||||||
|
}
|
||||||
|
|
||||||
|
storedFrequentProjects.push({ ...project, frequency: 1 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem(this.storageKey, JSON.stringify(storedFrequentProjects));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getTopFrequentProjects() {
|
||||||
|
const storedFrequentProjects = JSON.parse(localStorage.getItem(this.storageKey));
|
||||||
|
let frequentProjectsCount = FREQUENT_PROJECTS.LIST_COUNT_DESKTOP;
|
||||||
|
|
||||||
|
if (!storedFrequentProjects) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bp.getBreakpointSize() === 'sm' ||
|
||||||
|
bp.getBreakpointSize() === 'xs') {
|
||||||
|
frequentProjectsCount = FREQUENT_PROJECTS.LIST_COUNT_MOBILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const frequentProjects = storedFrequentProjects
|
||||||
|
.filter(project => project.frequency >= FREQUENT_PROJECTS.ELIGIBLE_FREQUENCY);
|
||||||
|
|
||||||
|
// Sort all frequent projects in decending order of frequency
|
||||||
|
// and then by lastAccessedOn with recent most first
|
||||||
|
frequentProjects.sort((projectA, projectB) => {
|
||||||
|
if (projectA.frequency < projectB.frequency) {
|
||||||
|
return 1;
|
||||||
|
} else if (projectA.frequency > projectB.frequency) {
|
||||||
|
return -1;
|
||||||
|
} else if (projectA.lastAccessedOn < projectB.lastAccessedOn) {
|
||||||
|
return 1;
|
||||||
|
} else if (projectA.lastAccessedOn > projectB.lastAccessedOn) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
return _.first(frequentProjects, frequentProjectsCount);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue