Skip to content

Commit f44db89

Browse files
[WEB-2628] fix: Sorting by estimates (#5988)
* fix estimates sorting in Front end side * change estimate sorting keys * - Fix estimate sorting when local db is enabled - Fix a bug with with sorting on special fields on spreadsheet layout - Cleanup logging * Add logic for order by based on layout for special cases of no load --------- Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
1 parent 8c3189e commit f44db89

File tree

7 files changed

+96
-35
lines changed

7 files changed

+96
-35
lines changed

packages/types/src/view-props.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ export type TIssueOrderByOptions =
4040
| "-issue_cycle__cycle__name"
4141
| "target_date"
4242
| "-target_date"
43-
| "estimate_point"
44-
| "-estimate_point"
43+
| "estimate_point__key"
44+
| "-estimate_point__key"
4545
| "start_date"
4646
| "-start_date"
4747
| "link_count"

web/core/constants/spreadsheet.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ export const SPREADSHEET_PROPERTY_DETAILS: {
7979
},
8080
estimate: {
8181
title: "Estimate",
82-
ascendingOrderKey: "estimate_point",
82+
ascendingOrderKey: "estimate_point__key",
8383
ascendingOrderTitle: "Low",
84-
descendingOrderKey: "-estimate_point",
84+
descendingOrderKey: "-estimate_point__key",
8585
descendingOrderTitle: "High",
8686
icon: Triangle,
8787
Column: SpreadsheetEstimateColumn,

web/core/local-db/storage.sqlite.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ export class Storage {
300300
const { cursor, group_by, sub_group_by } = queries;
301301

302302
const query = issueFilterQueryConstructor(this.workspaceSlug, projectId, queries);
303+
log("#### Query", query);
303304
const countQuery = issueFilterCountQueryConstructor(this.workspaceSlug, projectId, queries);
304305
const start = performance.now();
305306
let issuesRaw: any[] = [];

web/core/local-db/utils/load-workspace.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@ export const getStates = async (workspaceSlug: string) => {
8787
export const getEstimatePoints = async (workspaceSlug: string) => {
8888
const estimateService = new EstimateService();
8989
const estimates = await estimateService.fetchWorkspaceEstimates(workspaceSlug);
90-
const objects: IEstimatePoint[] = [];
90+
let objects: IEstimatePoint[] = [];
9191
(estimates || []).forEach((estimate: IEstimate) => {
9292
if (estimate?.points) {
93-
objects.concat(estimate.points);
93+
objects = objects.concat(estimate.points);
9494
}
9595
});
9696
return objects;
@@ -104,6 +104,9 @@ export const getMembers = async (workspaceSlug: string) => {
104104
};
105105

106106
export const loadWorkSpaceData = async (workspaceSlug: string) => {
107+
if (!persistence.db || !persistence.db.exec) {
108+
return;
109+
}
107110
log("Loading workspace data");
108111
const promises = [];
109112
promises.push(getLabels(workspaceSlug));
@@ -112,7 +115,7 @@ export const loadWorkSpaceData = async (workspaceSlug: string) => {
112115
promises.push(getStates(workspaceSlug));
113116
promises.push(getEstimatePoints(workspaceSlug));
114117
promises.push(getMembers(workspaceSlug));
115-
const [labels, modules, cycles, states, estimates, memebers] = await Promise.all(promises);
118+
const [labels, modules, cycles, states, estimates, members] = await Promise.all(promises);
116119

117120
const start = performance.now();
118121
await persistence.db.exec("BEGIN;");
@@ -121,7 +124,7 @@ export const loadWorkSpaceData = async (workspaceSlug: string) => {
121124
await batchInserts(cycles, "cycles", cycleSchema);
122125
await batchInserts(states, "states", stateSchema);
123126
await batchInserts(estimates, "estimate_points", estimatePointSchema);
124-
await batchInserts(memebers, "members", memberSchema);
127+
await batchInserts(members, "members", memberSchema);
125128
await persistence.db.exec("COMMIT;");
126129
const end = performance.now();
127130
log("Time taken to load workspace data", end - start);

web/core/local-db/utils/query-constructor.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export const SPECIAL_ORDER_BY = {
1818
"-issue_cycle__cycle__name": "cycles",
1919
state__name: "states",
2020
"-state__name": "states",
21+
estimate_point__key: "estimate_point",
22+
"-estimate_point__key": "estimate_point",
2123
};
2224
export const issueFilterQueryConstructor = (workspaceSlug: string, projectId: string, queries: any) => {
2325
const {
@@ -48,8 +50,6 @@ export const issueFilterQueryConstructor = (workspaceSlug: string, projectId: st
4850
4951
`;
5052

51-
log("###", sql);
52-
5353
return sql;
5454
}
5555
if (group_by) {
@@ -64,8 +64,6 @@ export const issueFilterQueryConstructor = (workspaceSlug: string, projectId: st
6464
WHERE rank <= ${per_page}
6565
`;
6666

67-
log("###", sql);
68-
6967
return sql;
7068
}
7169

@@ -78,16 +76,18 @@ export const issueFilterQueryConstructor = (workspaceSlug: string, projectId: st
7876
sql += `SELECT fi.* , `;
7977
if (order_by.includes("assignee")) {
8078
sql += ` s.first_name as ${name} `;
79+
} else if (order_by.includes("estimate")) {
80+
sql += ` s.key as ${name} `;
8181
} else {
82-
sql += ` s.name as ${name} `;
82+
sql += ` s.name as ${name} `;
8383
}
8484
sql += `FROM fi `;
8585
if (order_by && Object.keys(SPECIAL_ORDER_BY).includes(order_by)) {
8686
if (order_by.includes("cycle")) {
8787
sql += `
8888
LEFT JOIN cycles s on fi.cycle_id = s.id`;
8989
}
90-
if (order_by.includes("estimate_point")) {
90+
if (order_by.includes("estimate_point__key")) {
9191
sql += `
9292
LEFT JOIN estimate_points s on fi.estimate_point = s.id`;
9393
}
@@ -120,7 +120,6 @@ export const issueFilterQueryConstructor = (workspaceSlug: string, projectId: st
120120
`;
121121
sql += ` group by i.id ${orderByString} LIMIT ${pageSize} OFFSET ${offset * 1 + page * pageSize};`;
122122

123-
log("######$$$", sql);
124123
return sql;
125124
}
126125

@@ -149,7 +148,6 @@ export const issueFilterQueryConstructor = (workspaceSlug: string, projectId: st
149148
// Add offset and paging to query
150149
sql += ` LIMIT ${pageSize} OFFSET ${offset * 1 + page * pageSize};`;
151150

152-
log("$$$", sql);
153151
return sql;
154152
};
155153

web/core/local-db/utils/query.utils.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export const translateQueryParams = (queries: any) => {
4545
}
4646

4747
// Fix invalid orderby when switching from spreadsheet layout
48-
if (layout === "spreadsheet" && Object.keys(SPECIAL_ORDER_BY).includes(order_by)) {
48+
if (layout !== "spreadsheet" && Object.keys(SPECIAL_ORDER_BY).includes(order_by)) {
4949
otherProps.order_by = "sort_order";
5050
}
5151
// For each property value, replace None with empty string
@@ -336,6 +336,9 @@ const getSingleFilterFields = (queries: any) => {
336336
if (state_group) {
337337
fields.add("states.'group' as state_group");
338338
}
339+
if (order_by?.includes("estimate_point__key")) {
340+
fields.add("estimate_point");
341+
}
339342
return Array.from(fields);
340343
};
341344

web/core/store/issue/helpers/base-issues.store.ts

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import { EIssueLayoutTypes, ISSUE_PRIORITIES } from "@/constants/issue";
3636
// helpers
3737
import { convertToISODateString } from "@/helpers/date-time.helper";
3838
// local-db
39+
import { SPECIAL_ORDER_BY } from "@/local-db/utils/query-constructor";
3940
import { updatePersistentLayer } from "@/local-db/utils/utils";
4041
// services
4142
import { CycleService } from "@/services/cycle.service";
@@ -164,8 +165,8 @@ const ISSUE_ORDERBY_KEY: Record<TIssueOrderByOptions, keyof TIssue> = {
164165
"-issue_cycle__cycle__name": "cycle_id",
165166
target_date: "target_date",
166167
"-target_date": "target_date",
167-
estimate_point: "estimate_point",
168-
"-estimate_point": "estimate_point",
168+
estimate_point__key: "estimate_point",
169+
"-estimate_point__key": "estimate_point",
169170
start_date: "start_date",
170171
"-start_date": "start_date",
171172
link_count: "link_count",
@@ -282,6 +283,19 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
282283
const displayFilters = this.issueFilterStore?.issueFilters?.displayFilters;
283284
if (!displayFilters) return;
284285

286+
const layout = displayFilters.layout;
287+
const orderBy = displayFilters.order_by;
288+
289+
// Temporary code to fix no load order by
290+
if (
291+
this.rootIssueStore.rootStore.user.localDBEnabled &&
292+
layout !== EIssueLayoutTypes.SPREADSHEET &&
293+
orderBy &&
294+
Object.keys(SPECIAL_ORDER_BY).includes(orderBy)
295+
) {
296+
return "sort_order";
297+
}
298+
285299
return displayFilters?.order_by;
286300
}
287301

@@ -1701,13 +1715,14 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
17011715
* @returns string | string[] of sortable fields to be used for sorting
17021716
*/
17031717
populateIssueDataForSorting(
1704-
dataType: "state_id" | "label_ids" | "assignee_ids" | "module_ids" | "cycle_id",
1718+
dataType: "state_id" | "label_ids" | "assignee_ids" | "module_ids" | "cycle_id" | "estimate_point",
17051719
dataIds: string | string[] | null | undefined,
1720+
projectId: string | undefined | null,
17061721
order?: "asc" | "desc"
17071722
) {
17081723
if (!dataIds) return;
17091724

1710-
const dataValues: string[] = [];
1725+
const dataValues: (string | number)[] = [];
17111726
const isDataIdsArray = Array.isArray(dataIds);
17121727
const dataIdsArray = isDataIdsArray ? dataIds : [dataIds];
17131728

@@ -1757,6 +1772,26 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
17571772
}
17581773
break;
17591774
}
1775+
case "estimate_point": {
1776+
// return if project Id does not exist
1777+
if (!projectId) break;
1778+
// get the estimate ID for the current Project
1779+
const currentProjectEstimateId =
1780+
this.rootIssueStore.rootStore.projectEstimate.currentActiveEstimateIdByProjectId(projectId);
1781+
// return if current Estimate Id for the project is not available
1782+
if (!currentProjectEstimateId) break;
1783+
// get Estimate based on Id
1784+
const estimate = this.rootIssueStore.rootStore.projectEstimate.estimateById(currentProjectEstimateId);
1785+
// If Estimate is not available, then return
1786+
if (!estimate) break;
1787+
// Get Estimate Value
1788+
const estimateKey = estimate?.estimatePointById(dataIds as string)?.key;
1789+
1790+
// If Value string i not available or empty then return
1791+
if (estimateKey === undefined) break;
1792+
1793+
dataValues.push(estimateKey);
1794+
}
17601795
}
17611796

17621797
return isDataIdsArray ? (order ? orderBy(dataValues, undefined, [order]) : dataValues) : dataValues;
@@ -1771,11 +1806,17 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
17711806
return getIssueIds(orderBy(array, "sort_order"));
17721807
case "state__name":
17731808
return getIssueIds(
1774-
orderBy(array, (issue) => this.populateIssueDataForSorting("state_id", issue?.["state_id"]))
1809+
orderBy(array, (issue) =>
1810+
this.populateIssueDataForSorting("state_id", issue?.["state_id"], issue?.["project_id"])
1811+
)
17751812
);
17761813
case "-state__name":
17771814
return getIssueIds(
1778-
orderBy(array, (issue) => this.populateIssueDataForSorting("state_id", issue?.["state_id"]), ["desc"])
1815+
orderBy(
1816+
array,
1817+
(issue) => this.populateIssueDataForSorting("state_id", issue?.["state_id"], issue?.["project_id"]),
1818+
["desc"]
1819+
)
17791820
);
17801821
// dates
17811822
case "created_at":
@@ -1826,15 +1867,23 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
18261867
case "-attachment_count":
18271868
return getIssueIds(orderBy(array, "attachment_count", ["desc"]));
18281869

1829-
case "estimate_point":
1870+
case "estimate_point__key":
18301871
return getIssueIds(
1831-
orderBy(array, [getSortOrderToFilterEmptyValues.bind(null, "estimate_point"), "estimate_point"])
1872+
orderBy(array, [
1873+
getSortOrderToFilterEmptyValues.bind(null, "estimate_point"),
1874+
(issue) =>
1875+
this.populateIssueDataForSorting("estimate_point", issue?.["estimate_point"], issue?.["project_id"]),
1876+
])
18321877
); //preferring sorting based on empty values to always keep the empty values below
1833-
case "-estimate_point":
1878+
case "-estimate_point__key":
18341879
return getIssueIds(
18351880
orderBy(
18361881
array,
1837-
[getSortOrderToFilterEmptyValues.bind(null, "estimate_point"), "estimate_point"], //preferring sorting based on empty values to always keep the empty values below
1882+
[
1883+
getSortOrderToFilterEmptyValues.bind(null, "estimate_point"),
1884+
(issue) =>
1885+
this.populateIssueDataForSorting("estimate_point", issue?.["estimate_point"], issue?.["project_id"]),
1886+
], //preferring sorting based on empty values to always keep the empty values below
18381887
["asc", "desc"]
18391888
)
18401889
);
@@ -1854,7 +1903,8 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
18541903
return getIssueIds(
18551904
orderBy(array, [
18561905
getSortOrderToFilterEmptyValues.bind(null, "label_ids"), //preferring sorting based on empty values to always keep the empty values below
1857-
(issue) => this.populateIssueDataForSorting("label_ids", issue?.["label_ids"], "asc"),
1906+
(issue) =>
1907+
this.populateIssueDataForSorting("label_ids", issue?.["label_ids"], issue?.["project_id"], "asc"),
18581908
])
18591909
);
18601910
case "-labels__name":
@@ -1863,7 +1913,8 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
18631913
array,
18641914
[
18651915
getSortOrderToFilterEmptyValues.bind(null, "label_ids"), //preferring sorting based on empty values to always keep the empty values below
1866-
(issue) => this.populateIssueDataForSorting("label_ids", issue?.["label_ids"], "asc"),
1916+
(issue) =>
1917+
this.populateIssueDataForSorting("label_ids", issue?.["label_ids"], issue?.["project_id"], "asc"),
18671918
],
18681919
["asc", "desc"]
18691920
)
@@ -1873,7 +1924,8 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
18731924
return getIssueIds(
18741925
orderBy(array, [
18751926
getSortOrderToFilterEmptyValues.bind(null, "module_ids"), //preferring sorting based on empty values to always keep the empty values below
1876-
(issue) => this.populateIssueDataForSorting("module_ids", issue?.["module_ids"], "asc"),
1927+
(issue) =>
1928+
this.populateIssueDataForSorting("module_ids", issue?.["module_ids"], issue?.["project_id"], "asc"),
18771929
])
18781930
);
18791931
case "-issue_module__module__name":
@@ -1882,7 +1934,8 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
18821934
array,
18831935
[
18841936
getSortOrderToFilterEmptyValues.bind(null, "module_ids"), //preferring sorting based on empty values to always keep the empty values below
1885-
(issue) => this.populateIssueDataForSorting("module_ids", issue?.["module_ids"], "asc"),
1937+
(issue) =>
1938+
this.populateIssueDataForSorting("module_ids", issue?.["module_ids"], issue?.["project_id"], "asc"),
18861939
],
18871940
["asc", "desc"]
18881941
)
@@ -1892,7 +1945,7 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
18921945
return getIssueIds(
18931946
orderBy(array, [
18941947
getSortOrderToFilterEmptyValues.bind(null, "cycle_id"), //preferring sorting based on empty values to always keep the empty values below
1895-
(issue) => this.populateIssueDataForSorting("cycle_id", issue?.["cycle_id"], "asc"),
1948+
(issue) => this.populateIssueDataForSorting("cycle_id", issue?.["cycle_id"], issue?.["project_id"], "asc"),
18961949
])
18971950
);
18981951
case "-issue_cycle__cycle__name":
@@ -1901,7 +1954,8 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
19011954
array,
19021955
[
19031956
getSortOrderToFilterEmptyValues.bind(null, "cycle_id"), //preferring sorting based on empty values to always keep the empty values below
1904-
(issue) => this.populateIssueDataForSorting("cycle_id", issue?.["cycle_id"], "asc"),
1957+
(issue) =>
1958+
this.populateIssueDataForSorting("cycle_id", issue?.["cycle_id"], issue?.["project_id"], "asc"),
19051959
],
19061960
["asc", "desc"]
19071961
)
@@ -1911,7 +1965,8 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
19111965
return getIssueIds(
19121966
orderBy(array, [
19131967
getSortOrderToFilterEmptyValues.bind(null, "assignee_ids"), //preferring sorting based on empty values to always keep the empty values below
1914-
(issue) => this.populateIssueDataForSorting("assignee_ids", issue?.["assignee_ids"], "asc"),
1968+
(issue) =>
1969+
this.populateIssueDataForSorting("assignee_ids", issue?.["assignee_ids"], issue?.["project_id"], "asc"),
19151970
])
19161971
);
19171972
case "-assignees__first_name":
@@ -1920,7 +1975,8 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
19201975
array,
19211976
[
19221977
getSortOrderToFilterEmptyValues.bind(null, "assignee_ids"), //preferring sorting based on empty values to always keep the empty values below
1923-
(issue) => this.populateIssueDataForSorting("assignee_ids", issue?.["assignee_ids"], "asc"),
1978+
(issue) =>
1979+
this.populateIssueDataForSorting("assignee_ids", issue?.["assignee_ids"], issue?.["project_id"], "asc"),
19241980
],
19251981
["asc", "desc"]
19261982
)

0 commit comments

Comments
 (0)