New Directory Setup (#2065)

* chore: moved app & space from apps to root

* chore: modified workspace configuration

* chore: modified dockerfiles for space and web

* chore: modified icons for space

* feat: updated files for new svg icons supported by next-images

* chore: added /spaces base path for next

* chore: added compose config for space

* chore: updated husky configuration

* chore: updated workflows for new configuration

* chore: changed app name to web

* fix: resolved build errors with web

* chore: reset file tracing root for both projects

* chore: added nginx config for deploy

* fix: eslint and tsconfig settings for space app

* husky setup fixes based on new dir

* eslint fixes

* prettier formatting

---------

Co-authored-by: Henit Chobisa <chobisa.henit@gmail.com>
This commit is contained in:
sriram veeraghanta 2023-09-03 18:50:30 +05:30 committed by GitHub
parent 20e36194b4
commit 1e152c666c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
1022 changed files with 1475 additions and 1240 deletions

View file

@ -1,103 +0,0 @@
import { observable, action, computed, makeObservable, runInAction, reaction } from "mobx";
// services
import IssueService from "services/issue.service";
// store
import { RootStore } from "./root";
// types
// import { IssueDetailType, TIssueBoardKeys } from "types/issue";
import { IIssue, IIssueState, IIssueLabel } from "types/issue";
export interface IIssueStore {
loader: boolean;
error: any;
// issue options
issues: IIssue[] | null;
states: IIssueState[] | null;
labels: IIssueLabel[] | null;
// filtering
filteredStates: string[];
filteredLabels: string[];
filteredPriorities: string[];
// service
issueService: any;
// actions
fetchPublicIssues: (workspace_slug: string, project_slug: string, params: any) => void;
getCountOfIssuesByState: (state: string) => number;
getFilteredIssuesByState: (state: string) => IIssue[];
}
class IssueStore implements IIssueStore {
loader: boolean = false;
error: any | null = null;
states: IIssueState[] | null = [];
labels: IIssueLabel[] | null = [];
filteredStates: string[] = [];
filteredLabels: string[] = [];
filteredPriorities: string[] = [];
issues: IIssue[] | null = [];
issue_detail: any = {};
rootStore: RootStore;
issueService: any;
constructor(_rootStore: any) {
makeObservable(this, {
// observable
loader: observable,
error: observable,
// issue options
states: observable.ref,
labels: observable.ref,
// filtering
filteredStates: observable.ref,
filteredLabels: observable.ref,
filteredPriorities: observable.ref,
// issues
issues: observable.ref,
issue_detail: observable.ref,
// actions
fetchPublicIssues: action,
getFilteredIssuesByState: action,
});
this.rootStore = _rootStore;
this.issueService = new IssueService();
}
fetchPublicIssues = async (workspaceSlug: string, projectId: string, params: any) => {
try {
this.loader = true;
this.error = null;
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];
runInAction(() => {
this.states = _states;
this.labels = _labels;
this.issues = _issues;
this.loader = false;
});
}
} catch (error) {
this.loader = false;
this.error = error;
}
};
// computed
getCountOfIssuesByState(state_id: string): number {
return this.issues?.filter((issue) => issue.state == state_id).length || 0;
}
getFilteredIssuesByState = (state_id: string): IIssue[] | [] =>
this.issues?.filter((issue) => issue.state == state_id) || [];
}
export default IssueStore;

View file

@ -1,320 +0,0 @@
import { makeObservable, observable, action, runInAction } from "mobx";
import { v4 as uuidv4 } from "uuid";
// store
import { RootStore } from "./root";
// services
import IssueService from "services/issue.service";
import { IIssue, IVote } from "types/issue";
export type IPeekMode = "side" | "modal" | "full";
export interface IIssueDetailStore {
loader: boolean;
error: any;
// peek info
peekId: string | null;
peekMode: IPeekMode;
details: {
[key: string]: IIssue;
};
// peek actions
setPeekId: (issueId: string | null) => void;
setPeekMode: (mode: IPeekMode) => void;
// issue details
fetchIssueDetails: (workspaceId: string, projectId: string, issueId: string) => void;
// issue comments
addIssueComment: (workspaceId: string, projectId: string, issueId: string, data: any) => Promise<void>;
updateIssueComment: (
workspaceId: string,
projectId: string,
issueId: string,
comment_id: string,
data: any
) => Promise<any>;
deleteIssueComment: (workspaceId: string, projectId: string, issueId: string, comment_id: string) => void;
// issue reactions
addIssueReaction: (workspaceId: string, projectId: string, issueId: string, reactionHex: string) => void;
removeIssueReaction: (workspaceId: string, projectId: string, issueId: string, reactionHex: string) => void;
// issue votes
addIssueVote: (workspaceId: string, projectId: string, issueId: string, data: { vote: 1 | -1 }) => Promise<void>;
removeIssueVote: (workspaceId: string, projectId: string, issueId: string) => Promise<void>;
}
class IssueDetailStore implements IssueDetailStore {
loader: boolean = false;
error: any = null;
peekId: string | null = null;
peekMode: IPeekMode = "side";
details: {
[key: string]: IIssue;
} = {};
issueService;
rootStore: RootStore;
constructor(_rootStore: RootStore) {
makeObservable(this, {
loader: observable.ref,
error: observable.ref,
// peek
peekId: observable.ref,
peekMode: observable.ref,
details: observable.ref,
// actions
setPeekId: action,
fetchIssueDetails: action,
setPeekMode: action,
});
this.issueService = new IssueService();
this.rootStore = _rootStore;
}
setPeekId = (issueId: string | null) => {
this.peekId = issueId;
};
setPeekMode = (mode: IPeekMode) => {
this.peekMode = mode;
};
fetchIssueDetails = async (workspaceSlug: string, projectId: string, issueId: string) => {
try {
this.loader = true;
this.error = null;
const issueDetails = this.rootStore.issue.issues?.find((i) => i.id === issueId);
const commentsResponse = await this.issueService.getIssueComments(workspaceSlug, projectId, issueId);
if (issueDetails) {
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...(this.details[issueId] ?? issueDetails),
comments: commentsResponse,
},
};
});
}
} catch (error) {
this.loader = false;
this.error = error;
}
};
addIssueComment = async (workspaceSlug: string, projectId: string, issueId: string, data: any) => {
try {
const issueDetails = this.rootStore.issue.issues?.find((i) => i.id === issueId);
const issueCommentResponse = await this.issueService.createIssueComment(workspaceSlug, projectId, issueId, data);
if (issueDetails) {
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...issueDetails,
comments: [...this.details[issueId].comments, issueCommentResponse],
},
};
});
}
return issueCommentResponse;
} catch (error) {
console.log("Failed to add issue comment");
throw error;
}
};
updateIssueComment = async (
workspaceSlug: string,
projectId: string,
issueId: string,
commentId: string,
data: any
) => {
try {
const issueCommentUpdateResponse = await this.issueService.updateIssueComment(
workspaceSlug,
projectId,
issueId,
commentId,
data
);
if (issueCommentUpdateResponse) {
const remainingComments = this.details[issueId].comments.filter((com) => com.id != commentId);
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...this.details[issueId],
comments: [...remainingComments, issueCommentUpdateResponse],
},
};
});
}
return issueCommentUpdateResponse;
} catch (error) {
console.log("Failed to add issue comment");
}
};
deleteIssueComment = async (workspaceSlug: string, projectId: string, issueId: string, comment_id: string) => {
try {
await this.issueService.deleteIssueComment(workspaceSlug, projectId, issueId, comment_id);
const remainingComments = this.details[issueId].comments.filter((c) => c.id != comment_id);
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...this.details[issueId],
comments: remainingComments,
},
};
});
} catch (error) {
console.log("Failed to add issue vote");
}
};
addIssueReaction = async (workspaceSlug: string, projectId: string, issueId: string, reactionHex: string) => {
try {
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...this.details[issueId],
reactions: [
...this.details[issueId].reactions,
{
id: uuidv4(),
issue: issueId,
reaction: reactionHex,
actor_detail: this.rootStore.user.currentActor,
},
],
},
};
});
await this.issueService.createIssueReaction(workspaceSlug, projectId, issueId, {
reaction: reactionHex,
});
} catch (error) {
console.log("Failed to add issue vote");
const issueReactions = await this.issueService.getIssueReactions(workspaceSlug, projectId, issueId);
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...this.details[issueId],
reactions: issueReactions,
},
};
});
}
};
removeIssueReaction = async (workspaceSlug: string, projectId: string, issueId: string, reactionHex: string) => {
try {
const newReactions = this.details[issueId].reactions.filter(
(_r) => !(_r.reaction === reactionHex && _r.actor_detail.id === this.rootStore.user.currentUser?.id)
);
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...this.details[issueId],
reactions: newReactions,
},
};
});
await this.issueService.deleteIssueReaction(workspaceSlug, projectId, issueId, reactionHex);
} catch (error) {
console.log("Failed to remove issue reaction");
const reactions = await this.issueService.getIssueReactions(workspaceSlug, projectId, issueId);
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...this.details[issueId],
reactions: reactions,
},
};
});
}
};
addIssueVote = async (workspaceSlug: string, projectId: string, issueId: string, data: { vote: 1 | -1 }) => {
const newVote: IVote = {
actor: this.rootStore.user.currentUser?.id ?? "",
actor_detail: this.rootStore.user.currentActor,
issue: issueId,
project: projectId,
workspace: workspaceSlug,
vote: data.vote,
};
const filteredVotes = this.details[issueId].votes.filter((v) => v.actor !== this.rootStore.user.currentUser?.id);
try {
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...this.details[issueId],
votes: [...filteredVotes, newVote],
},
};
});
await this.issueService.createIssueVote(workspaceSlug, projectId, issueId, data);
} catch (error) {
console.log("Failed to add issue vote");
const issueVotes = await this.issueService.getIssueVotes(workspaceSlug, projectId, issueId);
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...this.details[issueId],
votes: issueVotes,
},
};
});
}
};
removeIssueVote = async (workspaceSlug: string, projectId: string, issueId: string) => {
const newVotes = this.details[issueId].votes.filter((v) => v.actor !== this.rootStore.user.currentUser?.id);
try {
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...this.details[issueId],
votes: newVotes,
},
};
});
await this.issueService.deleteIssueVote(workspaceSlug, projectId, issueId);
} catch (error) {
console.log("Failed to remove issue vote");
const issueVotes = await this.issueService.getIssueVotes(workspaceSlug, projectId, issueId);
runInAction(() => {
this.details = {
...this.details,
[issueId]: {
...this.details[issueId],
votes: issueVotes,
},
};
});
}
};
}
export default IssueDetailStore;

View file

@ -1,88 +0,0 @@
// mobx
import { observable, action, makeObservable, runInAction } from "mobx";
// service
import ProjectService from "services/project.service";
// types
import { IWorkspace, IProject, IProjectSettings } from "types/project";
export interface IProjectStore {
loader: boolean;
error: any | null;
workspace: IWorkspace | null;
project: IProject | null;
deploySettings: IProjectSettings | null;
viewOptions: any;
activeBoard: string | null;
fetchProjectSettings: (workspace_slug: string, project_slug: string) => Promise<void>;
setActiveBoard: (value: string) => void;
}
class ProjectStore implements IProjectStore {
loader: boolean = false;
error: any | null = null;
// data
workspace: IWorkspace | null = null;
project: IProject | null = null;
deploySettings: IProjectSettings | null = null;
viewOptions: any = null;
activeBoard: string | null = null;
// root store
rootStore;
// service
projectService;
constructor(_rootStore: any | null = null) {
makeObservable(this, {
// loaders and error observables
loader: observable,
error: observable.ref,
// observable
workspace: observable.ref,
project: observable.ref,
deploySettings: observable.ref,
viewOptions: observable.ref,
activeBoard: observable.ref,
// actions
fetchProjectSettings: action,
setActiveBoard: action,
// computed
});
this.rootStore = _rootStore;
this.projectService = new ProjectService();
}
fetchProjectSettings = async (workspace_slug: string, project_slug: string) => {
try {
this.loader = true;
this.error = null;
const response = await this.projectService.getProjectSettings(workspace_slug, project_slug);
if (response) {
const _project: IProject = { ...response?.project_details };
const _workspace: IWorkspace = { ...response?.workspace_detail };
const _viewOptions = { ...response?.views };
const _deploySettings = { ...response };
runInAction(() => {
this.project = _project;
this.workspace = _workspace;
this.viewOptions = _viewOptions;
this.deploySettings = _deploySettings;
this.loader = false;
});
}
return response;
} catch (error) {
this.loader = false;
this.error = error;
return error;
}
};
setActiveBoard = (boardValue: string) => {
this.activeBoard = boardValue;
};
}
export default ProjectStore;

View file

@ -1,23 +0,0 @@
// mobx lite
import { enableStaticRendering } from "mobx-react-lite";
// store imports
import UserStore from "./user";
import IssueStore, { IIssueStore } from "./issue";
import ProjectStore, { IProjectStore } from "./project";
import IssueDetailStore, { IIssueDetailStore } from "./issue_details";
enableStaticRendering(typeof window === "undefined");
export class RootStore {
user: UserStore;
issue: IIssueStore;
issueDetails: IIssueDetailStore;
project: IProjectStore;
constructor() {
this.user = new UserStore(this);
this.issue = new IssueStore(this);
this.project = new ProjectStore(this);
this.issueDetails = new IssueDetailStore(this);
}
}

View file

@ -1,92 +0,0 @@
// mobx
import { observable, action, computed, makeObservable, runInAction } from "mobx";
// service
import UserService from "services/user.service";
import { ActorDetail } from "types/issue";
// types
import { IUser } from "types/user";
export interface IUserStore {
currentUser: any | null;
fetchCurrentUser: () => void;
currentActor: () => any;
}
class UserStore implements IUserStore {
currentUser: IUser | null = null;
// root store
rootStore;
// service
userService;
constructor(_rootStore: any) {
makeObservable(this, {
// observable
currentUser: observable.ref,
// actions
setCurrentUser: action,
// computed
currentActor: computed,
});
this.rootStore = _rootStore;
this.userService = new UserService();
}
setCurrentUser = (user: any) => {
runInAction(() => {
this.currentUser = { ...user };
});
};
get currentActor(): any {
return {
avatar: this.currentUser?.avatar,
display_name: this.currentUser?.display_name,
first_name: this.currentUser?.first_name,
id: this.currentUser?.id,
is_bot: false,
last_name: this.currentUser?.last_name,
};
}
/**
*
* @param callback
* @description A wrapper function to check user authentication; it redirects to the login page if not authenticated, otherwise, it executes a callback.
* @example this.requiredLogin(() => { // do something });
*/
requiredLogin = (callback: () => void) => {
if (this.currentUser) {
callback();
return;
}
this.fetchCurrentUser()
.then(() => {
if (!this.currentUser) {
const currentPath = window.location.pathname;
window.location.href = `/?next_path=${currentPath}`;
} else callback();
})
.catch(() => {
const currentPath = window.location.pathname;
window.location.href = `/?next_path=${currentPath}`;
});
};
fetchCurrentUser = async () => {
try {
const response = await this.userService.currentUser();
if (response) {
runInAction(() => {
this.currentUser = response;
});
}
} catch (error) {
console.error("Failed to fetch current user", error);
}
};
}
export default UserStore;