fix: updated store and types in packages

This commit is contained in:
gurusainath 2024-01-31 11:37:02 +05:30
parent 088cc8c659
commit dfb6b2b247
8 changed files with 335 additions and 130 deletions

View File

@ -27,7 +27,7 @@ export * from "./auth";
export * from "./api_token";
export * from "./instance";
export * from "./app";
export * from "./view";
export * from "./view/root";
export type NestedKeyOf<ObjectType extends object> = {
[Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends object

View File

@ -1,88 +0,0 @@
declare enum EGlobalViewAccess {
"public" = 0,
"private" = 1,
"shared" = 2,
}
export type TViewAccess =
| EGlobalViewAccess.public
| EGlobalViewAccess.private
| EGlobalViewAccess.shared;
export type TViewLayouts =
| "list"
| "kanban"
| "calendar"
| "spreadsheet"
| "gantt";
export type TViewFilters = {
project: string[];
priority: string[];
state: string[];
state_group: string[];
assignees: string[];
mentions: string[];
created_by: string[];
label: string[];
start_date: string[];
target_date: string[];
};
export type TViewDisplayFilters = {
group_by: string;
sub_group_by: string;
order_by: string;
issue_type: string;
layout: TViewLayouts;
};
export type TViewDisplayProperties = {
assignee: boolean;
start_date: boolean;
due_date: boolean;
labels: boolean;
key: boolean;
priority: boolean;
state: boolean;
sub_issue_count: boolean;
link: boolean;
attachment_count: boolean;
estimate: boolean;
created_on: boolean;
updated_on: boolean;
};
export type TViewFilterProps = {
filters: TViewFilters;
display_filters: TViewDisplayFilters;
display_properties: TViewDisplayProperties;
};
export type TViewFilterPartialProps = {
filters: Partial<TViewFilters>;
display_filters: Partial<TViewDisplayFilters>;
display_properties: Partial<TViewDisplayProperties>;
};
export type TView = {
readonly id: string;
readonly workspace: string;
readonly project: string | undefined;
name: string;
description: string;
readonly query: string;
filters: TViewFilters;
display_filters: TViewDisplayFilters;
display_properties: TViewDisplayProperties;
readonly access: TViewAccess;
readonly owned_by: string;
readonly sort_order: number;
readonly is_locked: boolean;
readonly is_pinned: boolean;
readonly is_favorite: boolean;
readonly created_by: string;
readonly updated_by: string;
readonly created_at: Date;
readonly updated_at: Date;
};

34
packages/types/src/view/base.d.ts vendored Normal file
View File

@ -0,0 +1,34 @@
import { TFilters, TDisplayFilters, TDisplayProperties } from "./filter";
declare enum EGlobalViewAccess {
"public" = 0,
"private" = 1,
"shared" = 2,
}
export type TViewAccess =
| EGlobalViewAccess.public
| EGlobalViewAccess.private
| EGlobalViewAccess.shared;
export type TView = {
readonly id: string;
readonly workspace: string;
readonly project: string | undefined;
name: string;
description: string;
readonly query: string;
filters: TFilters;
display_filters: TDisplayFilters;
display_properties: TDisplayProperties;
readonly access: TViewAccess;
readonly owned_by: string;
readonly sort_order: number;
readonly is_locked: boolean;
readonly is_pinned: boolean;
readonly is_favorite: boolean;
readonly created_by: string;
readonly updated_by: string;
readonly created_at: Date;
readonly updated_at: Date;
};

74
packages/types/src/view/filter.d.ts vendored Normal file
View File

@ -0,0 +1,74 @@
export type TLayouts = "list" | "kanban" | "calendar" | "spreadsheet" | "gantt";
export type TCalendarLayouts = "month" | "week";
export type TFilters = {
project: string[];
priority: string[];
state: string[];
state_group: string[];
assignees: string[];
mentions: string[];
subscriber: string[];
created_by: string[];
labels: string[];
start_date: string[];
target_date: string[];
};
export type TDisplayFilters = {
layout: TLayouts;
group_by: string | undefined;
sub_group_by: string | undefined;
order_by: string;
type: string | undefined;
sub_issue: boolean;
show_empty_groups: boolean;
calendar: {
show_weekends: boolean;
layout: TCalendarLayouts;
};
};
export type TDisplayProperties = {
assignee: boolean;
start_date: boolean;
due_date: boolean;
labels: boolean;
key: boolean;
priority: boolean;
state: boolean;
sub_issue_count: boolean;
link: boolean;
attachment_count: boolean;
estimate: boolean;
created_on: boolean;
updated_on: boolean;
};
export type TFilterProps = {
filters: TFilters;
display_filters: TDisplayFilters;
display_properties: TDisplayProperties;
};
export type TFilterPartialProps = {
filters: Partial<TFilters>;
display_filters: Partial<TDisplayFilters>;
display_properties: Partial<TDisplayProperties>;
};
export type TFilterQueryParams =
| "project"
| "priority"
| "state"
| "state_group"
| "assignees"
| "mentions"
| "subscriber"
| "created_by"
| "labels"
| "start_date"
| "target_date"
| "type"
| "sub_issue";

2
packages/types/src/view/root.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
export * from "./filter";
export * from "./base";

View File

@ -1 +1,104 @@
export class ViewFilterHelpers {}
import isEmpty from "lodash/isEmpty";
// types
import { TFilters, TDisplayFilters, TDisplayProperties, TFilterProps, TFilterQueryParams } from "@plane/types";
export class FiltersHelper {
// computed filters
computedFilters = (filters: TFilters, defaultValues?: Partial<TFilters>): TFilters => ({
project: filters?.project || defaultValues?.project || [],
priority: filters?.priority || defaultValues?.priority || [],
state: filters?.state || defaultValues?.state || [],
state_group: filters?.state_group || defaultValues?.state_group || [],
assignees: filters?.assignees || defaultValues?.assignees || [],
mentions: filters?.mentions || defaultValues?.mentions || [],
subscriber: filters?.subscriber || defaultValues?.subscriber || [],
created_by: filters?.created_by || defaultValues?.created_by || [],
labels: filters?.labels || defaultValues?.labels || [],
start_date: filters?.start_date || defaultValues?.start_date || [],
target_date: filters?.target_date || defaultValues?.target_date || [],
});
// computed display filters
computedDisplayFilters = (
displayFilters: TDisplayFilters,
defaultValues?: Partial<TDisplayFilters>
): TDisplayFilters => ({
layout: displayFilters?.layout || defaultValues?.layout || "list",
group_by: displayFilters?.group_by || defaultValues?.group_by || "none",
sub_group_by: displayFilters?.sub_group_by || defaultValues?.sub_group_by || undefined,
order_by: displayFilters?.order_by || defaultValues?.order_by || "sort_order",
type: displayFilters?.type || defaultValues?.type || undefined,
sub_issue: displayFilters?.sub_issue || defaultValues?.sub_issue || false,
show_empty_groups: displayFilters?.show_empty_groups || defaultValues?.show_empty_groups || false,
calendar: {
show_weekends: displayFilters?.calendar?.show_weekends || defaultValues?.calendar?.show_weekends || false,
layout: displayFilters?.calendar?.layout || defaultValues?.calendar?.layout || "month",
},
});
// computed display properties
computedDisplayProperties = (
displayProperties: TDisplayProperties,
defaultValues?: Partial<TDisplayProperties>
): TDisplayProperties => ({
assignee: displayProperties?.assignee || defaultValues?.assignee || true,
start_date: displayProperties?.start_date || defaultValues?.start_date || true,
due_date: displayProperties?.due_date || defaultValues?.due_date || true,
labels: displayProperties?.labels || defaultValues?.labels || true,
priority: displayProperties?.priority || defaultValues?.priority || true,
state: displayProperties?.state || defaultValues?.state || true,
sub_issue_count: displayProperties?.sub_issue_count || defaultValues?.sub_issue_count || true,
attachment_count: displayProperties?.attachment_count || defaultValues?.attachment_count || true,
link: displayProperties?.link || defaultValues?.link || true,
estimate: displayProperties?.estimate || defaultValues?.estimate || true,
key: displayProperties?.key || defaultValues?.key || true,
created_on: displayProperties?.created_on || defaultValues?.created_on || true,
updated_on: displayProperties?.updated_on || defaultValues?.updated_on || true,
});
// compute filters and display_filters issue query parameters
computeAppliedFiltersQueryParameters = (
filters: TFilterProps,
acceptableParamsByLayout: string[]
): { params: any; query: string } => {
const paramsObject: Partial<Record<TFilterQueryParams, string | boolean>> = {};
let paramsString = "";
const filteredParams: Partial<Record<TFilterQueryParams, undefined | string[] | boolean | string>> = {
// issue filters
priority: filters.filters?.priority || undefined,
state_group: filters.filters?.state_group || undefined,
state: filters.filters?.state || undefined,
assignees: filters.filters?.assignees || undefined,
mentions: filters.filters?.mentions || undefined,
created_by: filters.filters?.created_by || undefined,
labels: filters.filters?.labels || undefined,
start_date: filters.filters?.start_date || undefined,
target_date: filters.filters?.target_date || undefined,
project: filters.filters?.project || undefined,
subscriber: filters.filters?.subscriber || undefined,
// display filters
type: filters?.display_filters?.type || undefined,
sub_issue: filters?.display_filters?.sub_issue || true,
};
Object.keys(filteredParams).forEach((key) => {
const _key = key as TFilterQueryParams;
const _value: string | boolean | string[] | undefined = filteredParams[_key];
if (_value != undefined && acceptableParamsByLayout.includes(_key))
paramsObject[_key] = Array.isArray(_value) ? _value.join(",") : _value;
});
if (paramsObject && !isEmpty(paramsObject)) {
paramsString = Object.keys(paramsObject)
.map((key) => {
const _key = key as TFilterQueryParams;
const _value: string | boolean | undefined = paramsObject[_key];
if (!undefined) return `${_key}=${_value}`;
})
.join("&");
}
return { params: paramsObject, query: paramsString };
};
}

View File

@ -18,7 +18,7 @@ type TViewRoot = {
// actions
fetch: () => Promise<void>;
create: (view: Partial<TView>) => Promise<void>;
delete: (viewId: string) => Promise<void>;
remove: (viewId: string) => Promise<void>;
duplicate: (viewId: string) => Promise<void>;
};
@ -34,7 +34,7 @@ export class ViewRoot implements TViewRoot {
// actions
fetch: action,
create: action,
delete: action,
remove: action,
duplicate: action,
});
}
@ -49,6 +49,10 @@ export class ViewRoot implements TViewRoot {
}
// actions
/**
* @description This method is used to fetch all the views
* @returns
*/
fetch = async () => {
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return;
@ -63,6 +67,11 @@ export class ViewRoot implements TViewRoot {
});
};
/**
* @description This method is used to create a view
* @param data: Partial<TView>
* @returns
*/
create = async (data: Partial<TView>) => {
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return;
@ -75,7 +84,12 @@ export class ViewRoot implements TViewRoot {
});
};
delete = async (viewId: string) => {
/**
* @description This method is used to remove a view
* @param viewId: string
* @returns
*/
remove = async (viewId: string) => {
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return;
@ -86,6 +100,11 @@ export class ViewRoot implements TViewRoot {
});
};
/**
* @description This method is used to duplicate a view
* @param viewId: string
* @returns
*/
duplicate = async (viewId: string) => {
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return;

View File

@ -6,27 +6,29 @@ import { RootStore } from "store/root.store";
import { TViewService } from "services/view/types";
import {
TView,
TViewFilters,
TViewDisplayFilters,
TViewDisplayProperties,
TViewFilterProps,
TViewFilterPartialProps,
TFilters,
TDisplayFilters,
TDisplayProperties,
TFilterProps,
TFilterPartialProps,
TViewAccess,
} from "@plane/types";
// helpers
import { FiltersHelper } from "./filters_helpers";
type TLoader = "submitting" | "submit" | undefined;
export type TViewsStore = TView & {
// observables
loader: TLoader;
filtersToUpdate: TViewFilterPartialProps;
filtersToUpdate: TFilterPartialProps;
// computed
appliedFilters: TViewFilterProps | undefined;
appliedFiltersQueryParams: undefined;
appliedFilters: TFilterProps | undefined;
appliedFiltersQueryParams: string | undefined;
// helper actions
updateFilters: (filters: Partial<TViewFilters>) => void;
updateDisplayFilters: (display_filters: Partial<TViewDisplayFilters>) => void;
updateDisplayProperties: (display_properties: Partial<TViewDisplayProperties>) => void;
updateFilters: (filters: Partial<TFilters>) => void;
updateDisplayFilters: (display_filters: Partial<TDisplayFilters>) => void;
updateDisplayProperties: (display_properties: Partial<TDisplayProperties>) => void;
resetFilterChanges: () => void;
saveFilterChanges: () => void;
// actions
@ -37,16 +39,16 @@ export type TViewsStore = TView & {
update: (viewData: Partial<TView>) => Promise<void>;
};
export class ViewsStore implements TViewsStore {
export class ViewsStore extends FiltersHelper implements TViewsStore {
id: string;
workspace: string;
project: string | undefined;
name: string;
description: string;
query: string;
filters: TViewFilters;
display_filters: TViewDisplayFilters;
display_properties: TViewDisplayProperties;
filters: TFilters;
display_filters: TDisplayFilters;
display_properties: TDisplayProperties;
access: TViewAccess;
owned_by: string;
sort_order: number;
@ -59,22 +61,23 @@ export class ViewsStore implements TViewsStore {
updated_at: Date;
loader: TLoader = undefined;
filtersToUpdate: TViewFilterPartialProps = {
filtersToUpdate: TFilterPartialProps = {
filters: {},
display_filters: {},
display_properties: {},
};
constructor(private store: RootStore, _view: TView, private service: TViewService) {
super();
this.id = _view.id;
this.workspace = _view.workspace;
this.project = _view.project;
this.name = _view.name;
this.description = _view.description;
this.query = _view.query;
this.filters = _view.filters;
this.display_filters = _view.display_filters;
this.display_properties = _view.display_properties;
this.filters = this.computedFilters(_view.filters);
this.display_filters = this.computedDisplayFilters(_view.display_filters);
this.display_properties = this.computedDisplayProperties(_view.display_properties);
this.access = _view.access;
this.owned_by = _view.owned_by;
this.sort_order = _view.sort_order;
@ -108,35 +111,74 @@ export class ViewsStore implements TViewsStore {
// computed
get appliedFilters() {
return undefined;
return {
filters: this.computedFilters(this.filters, this.filtersToUpdate.filters),
display_filters: this.computedDisplayFilters(this.display_filters, this.filtersToUpdate.display_filters),
display_properties: this.computedDisplayProperties(
this.display_properties,
this.filtersToUpdate.display_properties
),
};
}
get appliedFiltersQueryParams() {
return undefined;
const filters = this.appliedFilters;
return this.computeAppliedFiltersQueryParameters(filters, [])?.query || undefined;
}
// helper actions
updateFilters = (filters: Partial<TViewFilters>) => {
/**
* @description This method is used to update the filters of the view
* @param filters: Partial<TFilters>
*/
updateFilters = (filters: Partial<TFilters>) => {
runInAction(() => {
this.loader = "submit";
this.filtersToUpdate.filters = filters;
});
};
updateDisplayFilters = async (display_filters: Partial<TViewDisplayFilters>) => {
/**
* @description This method is used to update the display filters of the view
* @param display_filters: Partial<TDisplayFilters>
*/
updateDisplayFilters = async (display_filters: Partial<TDisplayFilters>) => {
const appliedFilters = this.appliedFilters;
const layout = appliedFilters.display_filters.layout;
const sub_group_by = appliedFilters.display_filters.sub_group_by;
const group_by = appliedFilters.display_filters.group_by;
const sub_issue = appliedFilters.display_filters.sub_issue;
if (group_by === undefined) display_filters.sub_group_by = undefined;
if (layout === "kanban") {
if (sub_group_by === group_by) display_filters.group_by = undefined;
if (group_by === null) display_filters.group_by = "state";
}
if (layout === "spreadsheet" && sub_issue === true) display_filters.sub_issue = false;
runInAction(() => {
this.loader = "submit";
this.filtersToUpdate.display_filters = display_filters;
});
};
updateDisplayProperties = async (display_properties: Partial<TViewDisplayProperties>) => {
/**
* @description This method is used to update the display properties of the view
* @param display_properties: Partial<TDisplayProperties>
*/
updateDisplayProperties = async (display_properties: Partial<TDisplayProperties>) => {
runInAction(() => {
this.loader = "submit";
this.filtersToUpdate.display_properties = display_properties;
});
};
/**
* @description This method is used to reset the changes made to the filters
*/
resetFilterChanges = () => {
runInAction(() => {
this.loader = undefined;
@ -148,6 +190,9 @@ export class ViewsStore implements TViewsStore {
});
};
/**
* @description This method is used to save the changes made to the filters
*/
saveFilterChanges = async () => {
this.loader = "submitting";
if (this.appliedFilters) await this.update(this.appliedFilters);
@ -155,6 +200,10 @@ export class ViewsStore implements TViewsStore {
};
// actions
/**
* @description This method is used to update the view lock
* @returns
*/
lockView = async () => {
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return;
@ -167,6 +216,10 @@ export class ViewsStore implements TViewsStore {
});
};
/**
* @description This method is used to remove the view lock
* @returns
*/
unlockView = async () => {
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return;
@ -179,6 +232,10 @@ export class ViewsStore implements TViewsStore {
});
};
/**
* @description This method is used to update the view favorite
* @returns
*/
makeFavorite = async () => {
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return;
@ -191,6 +248,10 @@ export class ViewsStore implements TViewsStore {
});
};
/**
* @description This method is used to remove the view favorite
* @returns
*/
removeFavorite = async () => {
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return;
@ -203,22 +264,22 @@ export class ViewsStore implements TViewsStore {
});
};
/**
* @description This method is used to update the view
* @param viewData
*/
update = async (viewData: Partial<TView>) => {
try {
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return;
const { workspaceSlug, projectId } = this.store.app.router;
if (!workspaceSlug) return;
const view = await this.service.update(workspaceSlug, this.id, viewData, projectId);
if (!view) return;
const view = await this.service.update(workspaceSlug, this.id, viewData, projectId);
if (!view) return;
runInAction(() => {
Object.keys(viewData).forEach((key) => {
const _key = key as keyof TView;
set(this, _key, viewData[_key]);
});
runInAction(() => {
Object.keys(viewData).forEach((key) => {
const _key = key as keyof TView;
set(this, _key, viewData[_key]);
});
} catch (error) {
console.log(error);
}
});
};
}