* use common getIssues from issue service instead of multiple different services for modules and cycles * Use SQLite to store issues locally and load issues from it. * Fix incorrect total count and filtering on assignees. * enable parallel API calls * use common getIssues from issue service instead of multiple different services for modules and cycles * Use SQLite to store issues locally and load issues from it. * Fix incorrect total count and filtering on assignees. * enable parallel API calls * chore: deleted issue list * - Handle local mutations - Implement getting the updates - Use SWR to update/sync data * Wait for sync to complete in get issues * Fix build errors * Fix build issue * - Sync updates to local-db - Fallback to server when the local data is loading - Wait when the updates are being fetched * Add issues in batches * Disable skeleton loaders for first 10 issues * Load issues in bulk * working version of sql lite with grouped issues * Use window queries for group by * - Fix sort by date fields - Fix the total count * - Fix grouping by created by - Fix order by and limit * fix pagination * Fix sorting on issue priority * - Add secondary sort order - Fix group by priority * chore: added timestamp filter for deleted issues * - Extract local DB into its own class - Implement sorting by label names * Implement subgroup by * sub group by changes * Refactor query constructor * Insert or update issues instead of directly adding them. * Segregated queries. Not working though!! * - Get filtered issues and then group them. - Cleanup code. - Implement order by labels. * Fix build issues * Remove debuggers * remove loaders while changing sorting or applying filters * fix loader while clearing all filters * Fix issue with project being synced twice * Improve project sync * Optimize the queries * Make create dummy data more realistic * dev: added total pages in the global paginator * chore: updated total_paged count * chore: added state_group in the issues pagination * chore: removed deleted_at from the issue pagination payload * chore: replaced state_group with state__group * Integrate new getIssues API, and fix sync issues bug. * Fix issue with SWR running twice in workspace wrapper * Fix DB initialization called when opening project for the first time. * Add all the tables required for sorting * Exclude description from getIssues * Add getIssue function. * Add only selected fields to get query. * Fix the count query * Minor query optimization when no joins are required. * fetch issue description from local db * clear local db on signout * Correct dummy data creation * Fix sort by assignee * sync to local changes * chore: added archived issues in the deleted endpoint * Sync deletes to local db. * - Add missing indexes for tables used in sorting in spreadsheet layout. - Add options table * Make fallback optional in getOption * Kanban column virtualization * persist project sync readiness to sqlite and use that as the source of truth for the project issues to be ready * fix build errors * Fix calendar view * fetch slimed down version of modules in project wrapper * fetch toned down modules and then fetch complete modules * Fix multi value order by in spread sheet layout * Fix sort by * Fix the query when ordering by multi field names * Remove unused import * Fix sort by multi value fields * Format queries and fix order by * fix order by for multi issue * fix loaders for spreadsheet * Fallback to manual order whn moving away from spreadsheet layout * fix minor bug * Move fix for order_by when switching from spreadsheet layout to translateQueryParams * fix default rendering of kanban groups * Fix none priority being saved as null * Remove debugger statement * Fix issue load * chore: updated isue paginated query from to * Fix sub issues and start and target date filters * Fix active and backlog filter * Add default order by * Update the Query param to match with backend. * local sqlite db versioning * When window is hidden, do not perform any db versioning * fix error handling and fall back to server when database errors out * Add ability to disable local db cache * remove db version check from getIssues function * change db version to number and remove workspaceInitPromise in storage.sqlite * - Sync the entire workspace in the background - Add get sub issue method with distribution * Make changes to get issues for sync to match backend. * chore: handled workspace and project in v2 paginted issues * disable issue description and title until fetched from server * sync issues post bulk operations * fix server error * fix front end build * Remove full workspace sync * - Remove the toast message on sync. - Update the disable local message. * Add Hardcoded constant to disable the local db caching * fix lint errors * Fix order by in grouping * update yarn lock * fix build * fix plane-web imports * address review comments --------- Co-authored-by: rahulramesha <rahulramesham@gmail.com> Co-authored-by: NarayanBavisetti <narayan3119@gmail.com> Co-authored-by: gurusainath <gurusainath007@gmail.com>
118 lines
3.5 KiB
TypeScript
118 lines
3.5 KiB
TypeScript
import { TIssue } from "@plane/types";
|
|
import { rootStore } from "@/lib/store-context";
|
|
import { IssueService } from "@/services/issue";
|
|
import { persistence } from "../storage.sqlite";
|
|
import { ARRAY_FIELDS, PRIORITY_MAP } from "./constants";
|
|
import { issueSchema } from "./schemas";
|
|
|
|
export const PROJECT_OFFLINE_STATUS: Record<string, boolean> = {};
|
|
|
|
export const addIssue = async (issue: any) => {
|
|
if (document.hidden || !rootStore.user.localDBEnabled) return;
|
|
|
|
persistence.db.exec("BEGIN TRANSACTION;");
|
|
stageIssueInserts(issue);
|
|
persistence.db.exec("COMMIT;");
|
|
};
|
|
|
|
export const addIssuesBulk = async (issues: any, batchSize = 100) => {
|
|
if (!rootStore.user.localDBEnabled) return;
|
|
|
|
for (let i = 0; i < issues.length; i += batchSize) {
|
|
const batch = issues.slice(i, i + batchSize);
|
|
|
|
persistence.db.exec("BEGIN TRANSACTION;");
|
|
batch.forEach((issue: any) => {
|
|
if (!issue.type_id) {
|
|
issue.type_id = "";
|
|
}
|
|
stageIssueInserts(issue);
|
|
});
|
|
await persistence.db.exec("COMMIT;");
|
|
}
|
|
};
|
|
export const deleteIssueFromLocal = async (issue_id: any) => {
|
|
if (!rootStore.user.localDBEnabled) return;
|
|
|
|
const deleteQuery = `delete from issues where id='${issue_id}'`;
|
|
const deleteMetaQuery = `delete from issue_meta where issue_id='${issue_id}'`;
|
|
|
|
persistence.db.exec("BEGIN TRANSACTION;");
|
|
persistence.db.exec(deleteQuery);
|
|
persistence.db.exec(deleteMetaQuery);
|
|
persistence.db.exec("COMMIT;");
|
|
};
|
|
|
|
export const updateIssue = async (issue: TIssue) => {
|
|
if (document.hidden || !rootStore.user.localDBEnabled) return;
|
|
|
|
const issue_id = issue.id;
|
|
// delete the issue and its meta data
|
|
await deleteIssueFromLocal(issue_id);
|
|
addIssue(issue);
|
|
};
|
|
|
|
export const syncDeletesToLocal = async (workspaceId: string, projectId: string, queries: any) => {
|
|
if (!rootStore.user.localDBEnabled) return;
|
|
|
|
const issueService = new IssueService();
|
|
const response = await issueService.getDeletedIssues(workspaceId, projectId, queries);
|
|
if (Array.isArray(response)) {
|
|
response.map(async (issue) => deleteIssueFromLocal(issue));
|
|
}
|
|
};
|
|
|
|
const stageIssueInserts = (issue: any) => {
|
|
const issue_id = issue.id;
|
|
issue.priority_proxy = PRIORITY_MAP[issue.priority as keyof typeof PRIORITY_MAP];
|
|
|
|
const keys = Object.keys(issueSchema);
|
|
const sanitizedIssue = keys.reduce((acc: any, key) => {
|
|
if (issue[key] || issue[key] === 0) {
|
|
acc[key] = issue[key];
|
|
}
|
|
return acc;
|
|
}, {});
|
|
|
|
const columns = "'" + Object.keys(sanitizedIssue).join("','") + "'";
|
|
|
|
const values = Object.values(sanitizedIssue)
|
|
.map((value) => {
|
|
if (value === null) {
|
|
return "";
|
|
}
|
|
if (typeof value === "object") {
|
|
return `'${JSON.stringify(value)}'`;
|
|
}
|
|
if (typeof value === "string") {
|
|
return `'${value}'`;
|
|
}
|
|
return value;
|
|
})
|
|
.join(", ");
|
|
|
|
const query = `INSERT OR REPLACE INTO issues (${columns}) VALUES (${values});`;
|
|
persistence.db.exec(query);
|
|
|
|
persistence.db.exec({
|
|
sql: `DELETE from issue_meta where issue_id='${issue_id}'`,
|
|
});
|
|
|
|
ARRAY_FIELDS.forEach((field) => {
|
|
const values = issue[field];
|
|
if (values && values.length) {
|
|
values.forEach((val: any) => {
|
|
persistence.db.exec({
|
|
sql: `INSERT OR REPLACE into issue_meta(issue_id,key,value) values (?,?,?) `,
|
|
bind: [issue_id, field, val],
|
|
});
|
|
});
|
|
} else {
|
|
// Added for empty fields?
|
|
persistence.db.exec({
|
|
sql: `INSERT OR REPLACE into issue_meta(issue_id,key,value) values (?,?,?) `,
|
|
bind: [issue_id, field, ""],
|
|
});
|
|
}
|
|
});
|
|
};
|