feat: converting space app to use nextjs app dir (#4451)

* feat: changemod space

* fix: space app dir fixes

* fix: build errors
This commit is contained in:
sriram veeraghanta 2024-05-14 14:26:54 +05:30 committed by GitHub
parent 087d54a261
commit febf19ccc0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
98 changed files with 1038 additions and 1551 deletions

View file

@ -18,15 +18,18 @@ type TError = {
export interface IInstanceStore {
// issues
isLoading: boolean;
instance: IInstance | undefined;
data: IInstance | NonNullable<unknown>;
config: Record<string, any>;
error: TError | undefined;
// action
fetchInstanceInfo: () => Promise<void>;
hydrate: (data: Record<string, unknown>, config: Record<string, unknown>) => void;
}
export class InstanceStore implements IInstanceStore {
isLoading: boolean = true;
instance: IInstance | undefined = undefined;
data: IInstance | Record<string, any> = {};
config: Record<string, unknown> = {};
error: TError | undefined = undefined;
// services
instanceService;
@ -35,15 +38,22 @@ export class InstanceStore implements IInstanceStore {
makeObservable(this, {
// observable
isLoading: observable.ref,
instance: observable,
data: observable,
config: observable,
error: observable,
// actions
fetchInstanceInfo: action,
hydrate: action,
});
// services
this.instanceService = new InstanceService();
}
hydrate = (data: Record<string, unknown>, config: Record<string, unknown>) => {
this.data = { ...this.data, ...data };
this.config = { ...this.config, ...config };
};
/**
* @description fetching instance information
*/
@ -51,10 +61,11 @@ export class InstanceStore implements IInstanceStore {
try {
this.isLoading = true;
this.error = undefined;
const instance = await this.instanceService.getInstanceInfo();
const instanceDetails = await this.instanceService.getInstanceInfo();
runInAction(() => {
this.isLoading = false;
this.instance = instance;
this.data = instanceDetails.instance;
this.config = instanceDetails.config;
});
} catch (error) {
runInAction(() => {

View file

@ -55,7 +55,7 @@ export interface IIssueDetailStore {
removeIssueVote: (workspaceId: string, projectId: string, issueId: string) => Promise<void>;
}
class IssueDetailStore implements IIssueDetailStore {
export class IssueDetailStore implements IIssueDetailStore {
loader: boolean = false;
error: any = null;
peekId: string | null = null;
@ -431,5 +431,3 @@ class IssueDetailStore implements IIssueDetailStore {
}
};
}
export default IssueDetailStore;

View file

@ -1,15 +1,16 @@
import { action, makeObservable, observable, runInAction, computed } from "mobx";
// types
// constants
import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue";
// store
import { RootStore } from "@/store/root.store";
import { IIssueFilterOptions, TIssueParams } from "./types";
import { handleIssueQueryParamsByLayout } from "./helpers";
import { IssueFilterBaseStore } from "./base-issue-filter.store";
// types
import { TIssueBoardKeys, IIssueFilterOptions, TIssueParams } from "@/types/issue";
interface IFiltersOptions {
filters: IIssueFilterOptions;
}
export interface IIssuesFilterStore {
export interface IIssueFilterStore {
// observables
projectIssueFilters: { [projectId: string]: IFiltersOptions } | undefined;
// computed
@ -21,15 +22,13 @@ export interface IIssuesFilterStore {
updateFilters: (projectId: string, filters: IIssueFilterOptions) => Promise<IFiltersOptions>;
}
export class IssuesFilterStore extends IssueFilterBaseStore implements IIssuesFilterStore {
export class IssueFilterStore implements IIssueFilterStore {
// observables
projectIssueFilters: { [projectId: string]: IFiltersOptions } | undefined = undefined;
// root store
rootStore;
constructor(_rootStore: RootStore) {
super(_rootStore);
makeObservable(this, {
// observables
projectIssueFilters: observable.ref,
@ -43,35 +42,61 @@ export class IssuesFilterStore extends IssueFilterBaseStore implements IIssuesFi
this.rootStore = _rootStore;
}
// helper methods
computedFilter = (filters: any, filteredParams: any) => {
const computedFilters: any = {};
Object.keys(filters).map((key) => {
if (filters[key] != undefined && filteredParams.includes(key))
computedFilters[key] =
typeof filters[key] === "string" || typeof filters[key] === "boolean" ? filters[key] : filters[key].join(",");
});
return computedFilters;
};
// helpers
issueDisplayFilters = (projectId: string) => {
if (!projectId) return undefined;
return this.projectIssueFilters?.[projectId] || undefined;
};
// actions
handleIssueQueryParamsByLayout = (layout: TIssueBoardKeys | undefined, viewType: "issues"): TIssueParams[] | null => {
const queryParams: TIssueParams[] = [];
if (!layout) return null;
const layoutOptions = ISSUE_DISPLAY_FILTERS_BY_LAYOUT[viewType][layout];
// add filters query params
layoutOptions.filters.forEach((option: any) => {
queryParams.push(option);
});
return queryParams;
};
// actions
updateFilters = async (projectId: string, filters: IIssueFilterOptions) => {
try {
let _projectIssueFilters = { ...this.projectIssueFilters };
if (!_projectIssueFilters) _projectIssueFilters = {};
if (!_projectIssueFilters[projectId]) _projectIssueFilters[projectId] = { filters: {} };
let issueFilters = { ...this.projectIssueFilters };
if (!issueFilters) issueFilters = {};
if (!issueFilters[projectId]) issueFilters[projectId] = { filters: {} };
const _filters = {
filters: { ..._projectIssueFilters[projectId].filters },
const newFilters = {
filters: { ...issueFilters[projectId].filters },
};
_filters.filters = { ..._filters.filters, ...filters };
newFilters.filters = { ...newFilters.filters, ...filters };
_projectIssueFilters[projectId] = {
filters: _filters.filters,
issueFilters[projectId] = {
filters: newFilters.filters,
};
runInAction(() => {
this.projectIssueFilters = _projectIssueFilters;
this.projectIssueFilters = issueFilters;
});
return _filters;
return newFilters;
} catch (error) {
throw error;
}
@ -89,7 +114,7 @@ export class IssuesFilterStore extends IssueFilterBaseStore implements IIssuesFi
get appliedFilters() {
const userFilters = this.issueFilters;
const layout = this.rootStore.project?.activeBoard;
const layout = this.rootStore.project?.activeLayout;
if (!userFilters || !layout) return undefined;
let filteredRouteParams: any = {
@ -98,7 +123,7 @@ export class IssuesFilterStore extends IssueFilterBaseStore implements IIssuesFi
labels: userFilters?.filters?.labels || undefined,
};
const filteredParams = handleIssueQueryParamsByLayout(layout, "issues");
const filteredParams = this.handleIssueQueryParamsByLayout(layout, "issues");
if (filteredParams) filteredRouteParams = this.computedFilter(filteredRouteParams, filteredParams);
return filteredRouteParams;

View file

@ -1,11 +1,11 @@
import { observable, action, computed, makeObservable, runInAction } from "mobx";
import { observable, action, makeObservable, runInAction } from "mobx";
// services
import IssueService from "@/services/issue.service";
// types
import { IIssue, IIssueState, IIssueLabel } from "@/types/issue";
// store
import { RootStore } from "./root.store";
// types
// import { IssueDetailType, TIssueBoardKeys } from "types/issue";
import { IIssue, IIssueState, IIssueLabel } from "types/issue";
export interface IIssueStore {
loader: boolean;
@ -26,7 +26,7 @@ export interface IIssueStore {
getFilteredIssuesByState: (state: string) => IIssue[];
}
class IssueStore implements IIssueStore {
export class IssueStore implements IIssueStore {
loader: boolean = false;
error: any | null = null;
@ -75,13 +75,13 @@ class IssueStore implements IIssueStore {
const response = await this.issueService.getPublicIssues(workspaceSlug, projectId, params);
if (response) {
const _states: IIssueState[] = [...response?.states];
const _labels: IIssueLabel[] = [...response?.labels];
const _issues: IIssue[] = [...response?.issues];
const states: IIssueState[] = [...response?.states];
const labels: IIssueLabel[] = [...response?.labels];
const issues: IIssue[] = [...response?.issues];
runInAction(() => {
this.states = _states;
this.labels = _labels;
this.issues = _issues;
this.states = states;
this.labels = labels;
this.issues = issues;
this.loader = false;
});
}
@ -99,5 +99,3 @@ class IssueStore implements IIssueStore {
getFilteredIssuesByState = (state_id: string): IIssue[] | [] =>
this.issues?.filter((issue) => issue.state == state_id) || [];
}
export default IssueStore;

View file

@ -1,29 +0,0 @@
// types
import { RootStore } from "@/store/root.store";
export interface IIssueFilterBaseStore {
// helper methods
computedFilter(filters: any, filteredParams: any): any;
}
export class IssueFilterBaseStore implements IIssueFilterBaseStore {
// root store
rootStore;
constructor(_rootStore: RootStore) {
// root store
this.rootStore = _rootStore;
}
// helper methods
computedFilter = (filters: any, filteredParams: any) => {
const computedFilters: any = {};
Object.keys(filters).map((key) => {
if (filters[key] != undefined && filteredParams.includes(key))
computedFilters[key] =
typeof filters[key] === "string" || typeof filters[key] === "boolean" ? filters[key] : filters[key].join(",");
});
return computedFilters;
};
}

View file

@ -1,52 +0,0 @@
import { TIssueBoardKeys } from "types/issue";
import { IIssueFilterOptions, TIssueParams } from "./types";
export const isNil = (value: any) => {
if (value === undefined || value === null) return true;
return false;
};
export interface ILayoutDisplayFiltersOptions {
filters: (keyof IIssueFilterOptions)[];
display_properties: boolean | null;
display_filters: null;
extra_options: null;
}
export const ISSUE_DISPLAY_FILTERS_BY_LAYOUT: {
[pageType: string]: { [layoutType: string]: ILayoutDisplayFiltersOptions };
} = {
issues: {
list: {
filters: ["priority", "state", "labels"],
display_properties: null,
display_filters: null,
extra_options: null,
},
kanban: {
filters: ["priority", "state", "labels"],
display_properties: null,
display_filters: null,
extra_options: null,
},
},
};
export const handleIssueQueryParamsByLayout = (
layout: TIssueBoardKeys | undefined,
viewType: "issues"
): TIssueParams[] | null => {
const queryParams: TIssueParams[] = [];
if (!layout) return null;
const layoutOptions = ISSUE_DISPLAY_FILTERS_BY_LAYOUT[viewType][layout];
// add filters query params
layoutOptions.filters.forEach((option) => {
queryParams.push(option);
});
return queryParams;
};

View file

@ -1,36 +0,0 @@
import { IIssue } from "types/issue";
export type TIssueGroupByOptions = "state" | "priority" | "labels" | null;
export type TIssueParams = "priority" | "state" | "labels";
export interface IIssueFilterOptions {
state?: string[] | null;
labels?: string[] | null;
priority?: string[] | null;
}
// issues
export interface IGroupedIssues {
[group_id: string]: string[];
}
export interface ISubGroupedIssues {
[sub_grouped_id: string]: {
[group_id: string]: string[];
};
}
export type TUnGroupedIssues = string[];
export interface IIssueResponse {
[issue_id: string]: IIssue;
}
export type TLoader = "init-loader" | "mutation" | undefined;
export interface ViewFlags {
enableQuickAdd: boolean;
enableIssueCreation: boolean;
enableInlineEditing: boolean;
}

View file

@ -11,11 +11,15 @@ export interface IProjectStore {
error: any | null;
workspace: IWorkspace | null;
project: IProject | null;
deploySettings: IProjectSettings | null;
viewOptions: any;
activeBoard: TIssueBoardKeys | null;
settings: IProjectSettings | null;
activeLayout: TIssueBoardKeys;
layoutOptions: Record<TIssueBoardKeys, boolean>;
canReact: boolean;
canComment: boolean;
canVote: boolean;
fetchProjectSettings: (workspace_slug: string, project_slug: string) => Promise<void>;
setActiveBoard: (value: TIssueBoardKeys) => void;
setActiveLayout: (value: TIssueBoardKeys) => void;
hydrate: (projectSettings: any) => void;
}
export class ProjectStore implements IProjectStore {
@ -24,9 +28,18 @@ export class ProjectStore implements IProjectStore {
// data
workspace: IWorkspace | null = null;
project: IProject | null = null;
deploySettings: IProjectSettings | null = null;
viewOptions: any = null;
activeBoard: TIssueBoardKeys | null = null;
settings: IProjectSettings | null = null;
activeLayout: TIssueBoardKeys = "list";
layoutOptions: Record<TIssueBoardKeys, boolean> = {
list: true,
kanban: true,
calendar: false,
gantt: false,
spreadsheet: false,
};
canReact: boolean = false;
canComment: boolean = false;
canVote: boolean = false;
// root store
rootStore;
// service
@ -38,14 +51,18 @@ export class ProjectStore implements IProjectStore {
loader: observable,
error: observable.ref,
// observable
workspace: observable.ref,
project: observable.ref,
deploySettings: observable.ref,
viewOptions: observable.ref,
activeBoard: observable.ref,
workspace: observable,
project: observable,
settings: observable,
layoutOptions: observable,
activeLayout: observable.ref,
canReact: observable.ref,
canComment: observable.ref,
canVote: observable.ref,
// actions
fetchProjectSettings: action,
setActiveBoard: action,
setActiveLayout: action,
hydrate: action,
// computed
});
@ -53,6 +70,20 @@ export class ProjectStore implements IProjectStore {
this.projectService = new ProjectService();
}
hydrate = (projectSettings: any) => {
const { workspace_detail, project_details, views, votes, comments, reactions } = projectSettings;
this.workspace = workspace_detail;
this.project = project_details;
this.layoutOptions = views;
this.canComment = comments;
this.canVote = votes;
this.canReact = reactions;
};
setActiveLayout = (boardValue: TIssueBoardKeys) => {
this.activeLayout = boardValue;
};
fetchProjectSettings = async (workspace_slug: string, project_slug: string) => {
try {
this.loader = true;
@ -68,8 +99,8 @@ export class ProjectStore implements IProjectStore {
runInAction(() => {
this.project = currentProject;
this.workspace = currentWorkspace;
this.viewOptions = currentViewOptions;
this.deploySettings = currentDeploySettings;
this.layoutOptions = currentViewOptions;
this.settings = currentDeploySettings;
this.loader = false;
});
}
@ -80,8 +111,4 @@ export class ProjectStore implements IProjectStore {
return error;
}
};
setActiveBoard = (boardValue: TIssueBoardKeys) => {
this.activeBoard = boardValue;
};
}

View file

@ -1,13 +1,11 @@
// mobx lite
import { enableStaticRendering } from "mobx-react-lite";
// store imports
import { IInstanceStore, InstanceStore } from "@/store/instance.store";
import { IProjectStore, ProjectStore } from "@/store/project";
import { IUserStore, UserStore } from "@/store/user";
import IssueStore, { IIssueStore } from "./issue";
import IssueDetailStore, { IIssueDetailStore } from "./issue_details";
import { IIssuesFilterStore, IssuesFilterStore } from "./issues/issue-filters.store";
import { IssueDetailStore, IIssueDetailStore } from "@/store/issue-detail.store";
import { IssueStore, IIssueStore } from "@/store/issue.store";
import { IProjectStore, ProjectStore } from "@/store/project.store";
import { IUserStore, UserStore } from "@/store/user.store";
import { IssueFilterStore, IIssueFilterStore } from "./issue-filters.store";
import { IMentionsStore, MentionsStore } from "./mentions.store";
enableStaticRendering(typeof window === "undefined");
@ -16,33 +14,36 @@ export class RootStore {
instance: IInstanceStore;
user: IUserStore;
project: IProjectStore;
issue: IIssueStore;
issueDetails: IIssueDetailStore;
mentionsStore: IMentionsStore;
issuesFilter: IIssuesFilterStore;
issueDetail: IIssueDetailStore;
mentionStore: IMentionsStore;
issueFilter: IIssueFilterStore;
constructor() {
this.instance = new InstanceStore(this);
this.user = new UserStore(this);
this.project = new ProjectStore(this);
this.issue = new IssueStore(this);
this.issueDetails = new IssueDetailStore(this);
this.mentionsStore = new MentionsStore(this);
this.issuesFilter = new IssuesFilterStore(this);
this.issueDetail = new IssueDetailStore(this);
this.mentionStore = new MentionsStore(this);
this.issueFilter = new IssueFilterStore(this);
}
resetOnSignOut = () => {
localStorage.setItem("theme", "system");
// eslint-disable-next-line @typescript-eslint/no-explicit-any
hydrate = (data: any) => {
if (!data) return;
this.instance.hydrate(data?.instance || {}, data?.config || {});
this.user.hydrate(data?.user || {});
};
reset = () => {
localStorage.setItem("theme", "system");
this.instance = new InstanceStore(this);
this.user = new UserStore(this);
this.project = new ProjectStore(this);
this.issue = new IssueStore(this);
this.issueDetails = new IssueDetailStore(this);
this.mentionsStore = new MentionsStore(this);
this.issuesFilter = new IssuesFilterStore(this);
this.issueDetail = new IssueDetailStore(this);
this.mentionStore = new MentionsStore(this);
this.issueFilter = new IssueFilterStore(this);
};
}

View file

@ -3,11 +3,11 @@ import { action, computed, makeObservable, observable, runInAction } from "mobx"
// types
import { IUser } from "@plane/types";
// services
import { AuthService } from "@/services/authentication.service";
import { AuthService } from "@/services/auth.service";
import { UserService } from "@/services/user.service";
// stores
import { RootStore } from "@/store/root.store";
import { ProfileStore, IProfileStore } from "@/store/user/profile.store";
import { ProfileStore, IProfileStore } from "@/store/profile.store";
import { ActorDetail } from "@/types/issue";
type TUserErrorStatus = {
@ -22,12 +22,13 @@ export interface IUserStore {
error: TUserErrorStatus | undefined;
data: IUser | undefined;
// store observables
userProfile: IProfileStore;
profile: IProfileStore;
// computed
currentActor: ActorDetail;
// actions
fetchCurrentUser: () => Promise<IUser | undefined>;
updateCurrentUser: (data: Partial<IUser>) => Promise<IUser | undefined>;
hydrate: (data: IUser) => void;
reset: () => void;
signOut: () => Promise<void>;
}
@ -39,14 +40,14 @@ export class UserStore implements IUserStore {
error: TUserErrorStatus | undefined = undefined;
data: IUser | undefined = undefined;
// store observables
userProfile: IProfileStore;
profile: IProfileStore;
// service
userService: UserService;
authService: AuthService;
constructor(private store: RootStore) {
// stores
this.userProfile = new ProfileStore(store);
this.profile = new ProfileStore(store);
// service
this.userService = new UserService();
this.authService = new AuthService();
@ -58,7 +59,7 @@ export class UserStore implements IUserStore {
error: observable,
// model observables
data: observable,
userProfile: observable,
profile: observable,
// computed
currentActor: computed,
// actions
@ -94,7 +95,7 @@ export class UserStore implements IUserStore {
});
const user = await this.userService.currentUser();
if (user && user?.id) {
await this.userProfile.fetchUserProfile();
await this.profile.fetchUserProfile();
runInAction(() => {
this.data = user;
this.isLoading = false;
@ -153,6 +154,10 @@ export class UserStore implements IUserStore {
}
};
hydrate = (data: IUser): void => {
this.data = { ...this.data, ...data };
};
/**
* @description resets the user store
* @returns {void}
@ -163,7 +168,7 @@ export class UserStore implements IUserStore {
this.isLoading = false;
this.error = undefined;
this.data = undefined;
this.userProfile = new ProfileStore(this.store);
this.profile = new ProfileStore(this.store);
});
};