first commit

This commit is contained in:
Noor E Ilahi
2026-01-09 12:54:53 +05:30
commit 7ccf44f7da
1070 changed files with 113036 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
import StoreService from './store.service';
import axios from 'axios';
export default class ApiService extends StoreService {
storeNs = 'user';
constructor(context) {
super(context);
}
/**
* @param params
* @returns {Promise<AxiosResponse<T>>}
*/
async checkConnectionDatabase(params) {
return await axios.post('setup/database', params);
}
async finishSetup(params) {
return await axios.put('setup/save', params);
}
token() {
return this.context.getters['token'];
}
checkApiAuth() {
return axios
.get('/auth/me', { ignoreCancel: true })
.then(({ data }) => {
this.context.dispatch('setLoggedInStatus', true);
this.context.dispatch('setUser', data.data);
return Promise.resolve();
})
.catch(() => {
localStorage.removeItem('access_token');
this.context.dispatch('forceUserExit');
return Promise.reject();
});
}
setUserData(user) {
this.context.dispatch('setUser', user);
}
setUserToken(token) {
if (token) {
localStorage.setItem('access_token', token);
} else {
localStorage.removeItem('access_token');
}
this.context.dispatch('setToken', token);
}
setLoggedInStatus(status = true) {
this.context.dispatch('setLoggedInStatus', status);
}
isLoggedIn() {
return this.context.getters.loggedIn;
}
attemptLogin(credentials) {
return axios
.post('/auth/login', credentials, { ignoreCancel: true })
.then(({ data }) => {
this.setUserToken(data.data.access_token);
this.setUserData(data.data.user);
this.setLoggedInStatus();
return Promise.resolve(data);
})
.catch(response => {
return Promise.reject(response);
});
}
attemptDesktopLogin(token) {
const instance = axios.create();
instance.defaults.headers.common['Authorization'] = `desktop ${token}`;
return instance
.put('/auth/desktop-key', {}, { ignoreCancel: true })
.then(({ data }) => {
this.setUserToken(data.access_token);
this.setUserData(data.user);
this.setLoggedInStatus();
return Promise.resolve(data);
})
.catch(response => {
return Promise.reject(response);
});
}
logout() {
return axios.post('/auth/logout').then(() => {
this.context.dispatch('forceUserExit');
});
}
async getCompanyData() {
const { data } = await axios.get('/company-settings', { ignoreCancel: true });
this.context.dispatch('setCompanyData', data.data);
return data.data;
}
async status() {
try {
const { data } = await axios.get('/status', { ignoreCancel: true });
return data.data;
} catch (e) {
return { cattr: false };
}
}
serverUrl = axios.defaults.baseURL;
}

View File

@@ -0,0 +1,15 @@
import axios from 'axios';
export default class AuthService {
resetPasswordRequest(data) {
return axios.post('auth/password/reset/request', data);
}
resetPasswordValidateToken(data) {
return axios.post('auth/password/reset/validate', data);
}
resetPasswordProcess(data) {
return axios.post('auth/password/reset/process', data);
}
}

View File

@@ -0,0 +1,14 @@
import StoreService from './store.service';
export default class MessageService extends StoreService {
updateMessage(message, type = 'info') {
this.context.dispatch('setMessage', { message, type });
}
getMessage() {
return {
data: this.context.getters.message,
type: this.context.getters.type,
};
}
}

View File

@@ -0,0 +1,24 @@
export default class ReportService {
/**
* @returns {Promise<AxiosResponse<T>>}
* @param startAt
* @param endAt
* @param users
* @param projects
*/
getReport(startAt, endAt, users, projects) {
throw new Error('getReport must be implemented in ReportService class');
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param startAt
* @param endAt
* @param users
* @param projects
* @param format
*/
downloadReport(startAt, endAt, users, projects, format) {
throw new Error('downloadReport must be implemented in ReportService class');
}
}

View File

@@ -0,0 +1,46 @@
export default class ResourceService {
constructor(idParam = 'id') {
this.idParam = idParam;
}
getItemRequestUri(id) {
throw new Error('getItemRequestUri must be implemented in Resource class');
}
getIdParam() {
return this.idParam;
}
getAll() {
throw new Error('getAll must be implemented in Resource class');
}
getItem(id) {
throw new Error('getItem must be implemented in Resource class');
}
deleteItem(id) {
return undefined;
}
save(data, isNew = false) {
return undefined;
}
create(data) {
return undefined;
}
getOptionLabelKey() {
return undefined;
}
getOptionList() {
return this.getAll({ headers: { 'X-Paginate': 'false' } }).then(({ data }) =>
data.data.map(option => ({
value: option.id,
label: option[this.getOptionLabelKey()],
})),
);
}
}

View File

@@ -0,0 +1,25 @@
import axios from 'axios';
export default class AboutService {
async getGeneralInfo() {
const result = await axios.get('about');
return result.data;
}
async getStorageInfo() {
const result = await axios.get('about/storage');
return result.data.data;
}
startCleanup() {
return axios.post('about/storage');
}
async getReportTypes() {
const result = await axios.get('about/reports');
return result.data.data.types;
}
}

View File

@@ -0,0 +1,24 @@
import axios from 'axios';
import ResourceService from '@/services/resource.service';
export default class GanttService extends ResourceService {
getGanttData(projectId) {
return axios.get(`projects/gantt-data?id=${projectId}`);
}
getPhases(projectId) {
return axios.get(`projects/phases?id=${projectId}`);
}
createRelation(taskId, relation) {
return axios.post(`tasks/create-relation`, {
task_id: taskId,
related_task_id: relation.taskId,
relation_type: relation.type,
});
}
removeRelation({ parent_id, child_id }) {
return axios.post(`tasks/remove-relation`, {
parent_id,
child_id,
});
}
}

View File

@@ -0,0 +1,63 @@
import ResourceService from '@/services/resource.service';
import axios from 'axios';
import { serialize } from '@/utils/url';
export default class PriorityService extends ResourceService {
/**
* @param config
* @returns {Promise<AxiosResponse<T>>}
*/
async getAll(config = {}) {
return (await axios.get('priorities/list', config)).data.data;
}
/**
* @param id
* @returns string
*/
getItemRequestUri(id) {
return `priorities/show?${serialize({ id })}`;
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
getItem(id) {
return axios.get(this.getItemRequestUri(id));
}
/**
* @param data
* @param isNew
* @returns {Promise<AxiosResponse<T>>}
*/
save(data, isNew = false) {
return axios.post(`priorities/${isNew ? 'create' : 'edit'}`, data);
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
deleteItem(id) {
return axios.post('priorities/remove', { id });
}
/**
* @returns string
*/
getOptionLabelKey() {
return 'name';
}
/**
*
* @param filters
* @param config
* @returns {Promise<AxiosResponse<T>>}
*/
async getWithFilters(filters, config = {}) {
return (await axios.post('priorities/list', filters, config)).data;
}
}

View File

@@ -0,0 +1,63 @@
import ResourceService from '@/services/resource.service';
import axios from 'axios';
import { serialize } from '@/utils/url';
export default class ProjectGroupsService extends ResourceService {
/**
* @param config
* @returns {Promise<AxiosResponse<T>>}
*/
async getAll(config = {}) {
return (await axios.get('project-groups/list', config)).data.data;
}
/**
* @param id
* @returns string
*/
getItemRequestUri(id) {
return `project-groups/show?${serialize({ id })}`;
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
getItem(id) {
return axios.get(this.getItemRequestUri(id) + '&' + serialize({ with: ['groupParent'] }));
}
/**
* @param data
* @param isNew
* @returns {Promise<AxiosResponse<T>>}
*/
save(data, isNew = false) {
return axios.post(`project-groups/${isNew ? 'create' : 'edit'}`, data);
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
deleteItem(id) {
return axios.post('project-groups/remove', { id });
}
/**
* @returns string
*/
getOptionLabelKey() {
return 'name';
}
/**
*
* @param filters
* @param config
* @returns {Promise<AxiosResponse<T>>}
*/
async getWithFilters(filters, config = {}) {
return (await axios.post('project-groups/list', filters, config)).data;
}
}

View File

@@ -0,0 +1,82 @@
import ResourceService from '@/services/resource.service';
import axios from 'axios';
import { serialize } from '@/utils/url';
export default class ProjectService extends ResourceService {
constructor(params = {}) {
super();
this.params = params;
}
/**
* @param id
* @returns {string}
*/
getItemRequestUri(id) {
return `projects/show?id=${id}`;
}
/**
* @param id
* @param filters
* @returns {Promise<AxiosResponse<T>>}
*/
getItem(id, filters = {}) {
return axios.get(this.getItemRequestUri(id) + '&' + serialize(filters));
}
/**
* @returns {Promise<AxiosResponse<T>>}
*/
async getAll(config = {}) {
return (
await axios.get('projects/list', {
...config,
params: this.params,
})
).data.data;
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
deleteItem(id) {
return axios.post('projects/remove', { id });
}
/**
*
* @param filters
* @param config
* @returns {Promise<AxiosResponse<T>>}
*/
getWithFilters(filters, config = {}) {
return axios.post('projects/list', filters, config);
}
/**
* @param data
* @param isNew
* @returns {Promise<AxiosResponse<T>>}
*/
save(data, isNew = false) {
return axios.post(`projects/${isNew ? 'create' : 'edit'}`, data);
}
getMembers(id) {
return axios.post('project-members/list', { project_id: id });
}
bulkEditMembers(data) {
return axios.post('project-members/bulk-edit', data);
}
/**
*
* @returns {string}
*/
getOptionLabelKey() {
return 'name';
}
}

View File

@@ -0,0 +1,11 @@
import ResourceService from '@/services/resource.service';
import axios from 'axios';
export default class RoleService extends ResourceService {
/**
* @returns {Promise<AxiosResponse<T>>}
*/
getAll() {
return axios.get('roles/list');
}
}

View File

@@ -0,0 +1,44 @@
import ResourceService from '@/services/resource.service';
import axios from 'axios';
export default class ScreenshotService extends ResourceService {
/**
* @param id
* @returns string
*/
getItemRequestUri(id) {
return `screenshots/show?id=${id}`;
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
getItem(id) {
return axios.get(this.getItemRequestUri(id));
}
/**
* @returns {Promise<AxiosResponse<T>>}
*/
getAll() {
return axios.get('screenshots/list');
}
/**
* @param filters
* @param config
* @returns {Promise<AxiosResponse<T>>}
*/
getWithFilters(filters, config = {}) {
return axios.post('screenshots/list', filters, config);
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
deleteItem(id) {
return axios.post('screenshots/remove', { id });
}
}

View File

@@ -0,0 +1,74 @@
import ResourceService from '@/services/resource.service';
import axios from 'axios';
import { serialize } from '@/utils/url';
export default class StatusService extends ResourceService {
/**
* @param config
* @returns {Promise<AxiosResponse<T>>}
*/
async getAll(config = {}) {
return (await axios.get('statuses/list', config)).data.data;
}
/**
* @param id
* @returns string
*/
getItemRequestUri(id) {
return `statuses/show?${serialize({ id })}`;
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
getItem(id) {
return axios.get(this.getItemRequestUri(id));
}
/**
* @param data
* @param isNew
* @returns {Promise<AxiosResponse<T>>}
*/
save(data, isNew = false) {
return axios.post(`statuses/${isNew ? 'create' : 'edit'}`, data);
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
deleteItem(id) {
return axios.post('statuses/remove', { id });
}
/**
* @returns string
*/
getOptionLabelKey() {
return 'name';
}
getOptionList() {
// TODO: this probably will throw :(
return this.getAll().then(({ data }) =>
data.data.map(option => ({
value: option.id,
label: option[this.getOptionLabelKey()],
active: option.active,
})),
);
}
/**
*
* @param filters
* @param config
* @returns {Promise<AxiosResponse<T>>}
*/
getWithFilters(filters, config = {}) {
return axios.post('statuses/list', filters, config);
}
}

View File

@@ -0,0 +1,36 @@
import ResourceService from '@/services/resource.service';
import axios from 'axios';
export default class TaskActivityService extends ResourceService {
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
deleteComment(id) {
return axios.post('task-comment/remove', { id });
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param data
*/
saveComment(data) {
return axios.post('task-comment/create', data);
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param data
*/
editComment(data) {
return axios.post('task-comment/edit', data);
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param data
*/
getActivity(data) {
return axios.post('tasks/activity', data);
}
}

View File

@@ -0,0 +1,96 @@
import ResourceService from '@/services/resource.service';
import axios from 'axios';
import { serialize } from '@/utils/url';
export default class TasksService extends ResourceService {
/**
* @returns {Promise<AxiosResponse<T>>}
*/
getAll() {
return axios.get('tasks/list');
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param id
* @param filters
*/
getItem(id, filters = {}) {
return axios.get(this.getItemRequestUri(id) + '&' + serialize(filters));
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param id
*/
getItemRequestUri(id) {
return `tasks/show?${serialize({ id })}`;
}
/**
* @param userID
* @returns {Promise<AxiosResponse<T>>}
*/
getDashboardTasks(userID) {
return axios.get(`tasks/dashboard?${serialize({ user_id: userID, with: ['project'] })}`);
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param filters
* @param config
*/
getWithFilters(filters, config = {}) {
return axios.post('tasks/list', filters, config);
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param id
*/
deleteItem(id) {
return axios.post('tasks/remove', { id });
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param data
* @param isNew
*/
save(data, isNew = false) {
return axios.post(`tasks/${isNew ? 'create' : 'edit'}`, data);
}
getOptionLabelKey() {
return 'task_name';
}
/**
* Upload attachment
* @returns {Promise<void>}
* @param payload
* @param progressCallback
*/
async uploadAttachment(payload, progressCallback) {
const formData = new FormData();
formData.append('attachment', payload);
const { data } = await axios.post('/attachment', formData, {
onUploadProgress: progressCallback,
});
return data;
}
/**
* Generate tmp url for attachment
* @returns {Promise<void>}
* @param uuid
* @param seconds
*/
async generateAttachmentTmpUrl(uuid, seconds = null) {
const { data } = await axios.get(
`/attachment/${uuid}/temporary-url?${typeof seconds === 'number' ? serialize({ seconds }) : ''}`,
);
return data;
}
}

View File

@@ -0,0 +1,60 @@
import ResourceService from '@/services/resource.service';
import axios from 'axios';
export default class TimeIntervalService extends ResourceService {
/**
* @returns {string}
* @param id
*/
getItemRequestUri(id) {
return `time-intervals/show?id=${id}`;
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param id
*/
getItem(id) {
return axios.get(this.getItemRequestUri(id));
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param filters
*/
getAll(filters = {}) {
return axios.post('time-intervals/list', filters);
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param data
*/
save(data) {
return axios.post('time-intervals/create', data);
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param data
*/
bulkEdit(data) {
return axios.post('time-intervals/bulk-edit', data);
}
/**
* @returns {Promise<AxiosResponse<T>>}
* @param data
*/
bulkDelete(data) {
return axios.post('time-intervals/bulk-remove', data);
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
deleteItem(id) {
return axios.post('time-intervals/remove', { id });
}
}

View File

@@ -0,0 +1,63 @@
import ResourceService from '@/services/resource.service';
import axios from 'axios';
import { serialize } from '@/utils/url';
export default class UsersService extends ResourceService {
/**
* @param config
* @returns {Promise<AxiosResponse<T>>}
*/
async getAll(config = {}) {
return (await axios.get('users/list', config)).data.data;
}
/**
* @param id
* @returns string
*/
getItemRequestUri(id) {
return `users/show?${serialize({ id, with: ['role', 'projectsRelation.role'] })}`;
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
getItem(id) {
return axios.get(this.getItemRequestUri(id));
}
/**
* @param data
* @param isNew
* @returns {Promise<AxiosResponse<T>>}
*/
save(data, isNew = false) {
return axios.post(`users/${isNew ? 'create' : 'edit'}`, data);
}
/**
* @param id
* @returns {Promise<AxiosResponse<T>>}
*/
deleteItem(id) {
return axios.post('users/remove', { id });
}
/**
* @returns string
*/
getOptionLabelKey() {
return 'full_name';
}
/**
*
* @param filters
* @param config
* @returns {Promise<AxiosResponse<T>>}
*/
getWithFilters(filters, config = {}) {
return axios.post('users/list', filters, config);
}
}

View File

@@ -0,0 +1,31 @@
/**
* Section service <abstract> class.
* Used to fetch data from api for inside DynamicSettings.vue
* Data is stored inside store -> settings -> sections -> data
*/
export default class SettingsService {
/**
* API endpoint URL
* @returns string
*/
getItemRequestUri() {
throw new Error('getItemRequestUri must be implemented in SettingsService class');
}
/**
* Fetch item data from api endpoint
* @returns {data}
*/
getAll() {
throw new Error('getAll must be implemented in SettingsService class');
}
/**
* Save item data
* @param data
* @returns {Promise<void>}
*/
save(data) {
throw new Error('save must be implemented in SettingsService class');
}
}

View File

@@ -0,0 +1,11 @@
export default class StoreService {
storeNs = undefined;
constructor(context) {
this.context = context;
}
getStoreName(caller) {
return `${this.storeNs}/${caller}`;
}
}