Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/ui/src/popovers/popover-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const PopoverMenu = <T,>(props: TPopoverMenu<T>) => {
popoverClassName = "",
keyExtractor,
render,
popoverButtonRef,
} = props;

return (
Expand All @@ -32,6 +33,7 @@ export const PopoverMenu = <T,>(props: TPopoverMenu<T>) => {
panelClassName
)}
popoverClassName={popoverClassName}
popoverButtonRef={popoverButtonRef}
>
<Fragment>
{data.map((item, index) => (
Expand Down
33 changes: 18 additions & 15 deletions packages/ui/src/popovers/popover.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Fragment, useState } from "react";
import React, { Fragment, Ref, useState } from "react";
import { usePopper } from "react-popper";
import { Popover as HeadlessReactPopover, Transition } from "@headlessui/react";
// helpers
Expand All @@ -17,9 +17,10 @@ export const Popover = (props: TPopover) => {
disabled = false,
panelClassName = "",
children,
popoverButtonRef,
} = props;
// states
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
const [referenceElement, setReferenceElement] = useState<HTMLDivElement | null>(null);
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(null);

// react-popper derived values
Expand All @@ -37,19 +38,21 @@ export const Popover = (props: TPopover) => {

return (
<HeadlessReactPopover className={cn("relative flex h-full w-full items-center justify-center", popoverClassName)}>
<HeadlessReactPopover.Button
ref={setReferenceElement}
className={cn(
{
"flex justify-center items-center text-base h-6 w-6 rounded transition-all bg-custom-background-90 hover:bg-custom-background-80":
!button,
},
buttonClassName
)}
disabled={disabled}
>
{button ? button : <EllipsisVertical className="h-3 w-3" />}
</HeadlessReactPopover.Button>
<div ref={setReferenceElement} className="w-full">
<HeadlessReactPopover.Button
ref={popoverButtonRef as Ref<HTMLButtonElement>}
className={cn(
{
"flex justify-center items-center text-base h-6 w-6 rounded transition-all bg-custom-background-90 hover:bg-custom-background-80":
!button,
},
buttonClassName
)}
disabled={disabled}
>
{button ? button : <EllipsisVertical className="h-3 w-3" />}
</HeadlessReactPopover.Button>
</div>

<Transition
as={Fragment}
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/popovers/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from "react";
import { MutableRefObject, ReactNode } from "react";
import { Placement } from "@popperjs/core";

export type TPopoverButtonDefaultOptions = {
Expand All @@ -15,6 +15,7 @@ export type TPopoverDefaultOptions = TPopoverButtonDefaultOptions & {
// panel styling
panelClassName?: string;
popoverClassName?: string;
popoverButtonRef?: MutableRefObject<HTMLButtonElement | null>;
};

export type TPopover = TPopoverDefaultOptions & {
Expand Down
1 change: 1 addition & 0 deletions web/ce/components/issues/worklog/activity/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ type TIssueActivityWorklog = {
projectId: string;
issueId: string;
activityComment: TIssueActivityComment;
ends?: "top" | "bottom";
};

export const IssueActivityWorklog: FC<TIssueActivityWorklog> = () => <></>;
37 changes: 23 additions & 14 deletions web/ce/constants/workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,69 @@ import { Props } from "@/components/icons/types";
// constants
import { EUserWorkspaceRoles } from "@/constants/workspace";

export const WORKSPACE_SETTINGS_LINKS: {
key: string;
label: string;
href: string;
access: EUserWorkspaceRoles;
highlight: (pathname: string, baseUrl: string) => boolean;
Icon: React.FC<Props>;
}[] = [
{
export const WORKSPACE_SETTINGS = {
general: {
key: "general",
label: "General",
href: `/settings`,
access: EUserWorkspaceRoles.GUEST,
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/`,
Icon: SettingIcon,
},
{
members: {
key: "members",
label: "Members",
href: `/settings/members`,
access: EUserWorkspaceRoles.GUEST,
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/members/`,
Icon: SettingIcon,
},
{
"billing-and-plans": {
key: "billing-and-plans",
label: "Billing and plans",
href: `/settings/billing`,
access: EUserWorkspaceRoles.ADMIN,
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/billing/`,
Icon: SettingIcon,
},
{
export: {
key: "export",
label: "Exports",
href: `/settings/exports`,
access: EUserWorkspaceRoles.MEMBER,
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/exports/`,
Icon: SettingIcon,
},
{
webhooks: {
key: "webhooks",
label: "Webhooks",
href: `/settings/webhooks`,
access: EUserWorkspaceRoles.ADMIN,
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/webhooks/`,
Icon: SettingIcon,
},
{
"api-tokens": {
key: "api-tokens",
label: "API tokens",
href: `/settings/api-tokens`,
access: EUserWorkspaceRoles.ADMIN,
highlight: (pathname: string, baseUrl: string) => pathname === `${baseUrl}/settings/api-tokens/`,
Icon: SettingIcon,
},
};

export const WORKSPACE_SETTINGS_LINKS: {
key: string;
label: string;
href: string;
access: EUserWorkspaceRoles;
highlight: (pathname: string, baseUrl: string) => boolean;
Icon: React.FC<Props>;
}[] = [
WORKSPACE_SETTINGS["general"],
WORKSPACE_SETTINGS["members"],
WORKSPACE_SETTINGS["billing-and-plans"],
WORKSPACE_SETTINGS["export"],
WORKSPACE_SETTINGS["webhooks"],
WORKSPACE_SETTINGS["api-tokens"],
];
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
/* eslint-disable no-useless-catch */

import concat from "lodash/concat";
import set from "lodash/set";
import sortBy from "lodash/sortBy";
import uniq from "lodash/uniq";
import update from "lodash/update";
import { action, makeObservable, observable, runInAction } from "mobx";
import { TIssueActivityComment, TIssueActivity, TIssueActivityMap, TIssueActivityIdMap } from "@plane/types";
// plane web constants
import { EActivityFilterType } from "@/plane-web/constants/issues";
// plane web store types
import { RootStore } from "@/plane-web/store/root.store";
// services
import { IssueActivityService } from "@/services/issue";
// types
import { IIssueDetail } from "./root.store";

export type TActivityLoader = "fetch" | "mutate" | undefined;

Expand Down Expand Up @@ -38,12 +42,11 @@ export class IssueActivityStore implements IIssueActivityStore {
loader: TActivityLoader = "fetch";
activities: TIssueActivityIdMap = {};
activityMap: TIssueActivityMap = {};
// root store
rootIssueDetailStore: IIssueDetail;

// services
issueActivityService;

constructor(rootStore: IIssueDetail) {
constructor(protected store: RootStore) {
makeObservable(this, {
// observables
loader: observable.ref,
Expand All @@ -52,8 +55,6 @@ export class IssueActivityStore implements IIssueActivityStore {
// actions
fetchActivities: action,
});
// root store
this.rootIssueDetailStore = rootStore;
// services
this.issueActivityService = new IssueActivityService();
}
Expand All @@ -69,50 +70,46 @@ export class IssueActivityStore implements IIssueActivityStore {
return this.activityMap[activityId] ?? undefined;
};

getActivityCommentByIssueId = (issueId: string) => {
public getActivityCommentByIssueId(issueId: string) {
if (!issueId) return undefined;

let activityComments: TIssueActivityComment[] = [];

const activities = this.getActivitiesByIssueId(issueId) || [];
const comments = this.rootIssueDetailStore.comment.getCommentsByIssueId(issueId) || [];
const comments = this.store.issue.issueDetail.comment.getCommentsByIssueId(issueId) || [];

activities.forEach((activityId) => {
const activity = this.getActivityById(activityId);
if (!activity) return;
activityComments.push({
id: activity.id,
activity_type: "ACTIVITY",
activity_type: EActivityFilterType.ACTIVITY,
created_at: activity.created_at,
});
});

comments.forEach((commentId) => {
const comment = this.rootIssueDetailStore.comment.getCommentById(commentId);
const comment = this.store.issue.issueDetail.comment.getCommentById(commentId);
if (!comment) return;
activityComments.push({
id: comment.id,
activity_type: "COMMENT",
activity_type: EActivityFilterType.COMMENT,
created_at: comment.created_at,
});
});

activityComments = sortBy(activityComments, "created_at");
activityComments = activityComments.map((activityComment) => ({
id: activityComment.id,
activity_type: activityComment.activity_type,
}));

return activityComments;
};
}

// actions
fetchActivities = async (
public async fetchActivities(
workspaceSlug: string,
projectId: string,
issueId: string,
loaderType: TActivityLoader = "fetch"
) => {
) {
try {
this.loader = loaderType;

Expand Down Expand Up @@ -140,7 +137,8 @@ export class IssueActivityStore implements IIssueActivityStore {

return activities;
} catch (error) {
this.loader = undefined;
throw error;
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const IssueActivityCommentRoot: FC<TIssueActivityCommentRoot> = observer(
projectId={projectId}
issueId={issueId}
activityComment={activityComment}
ends={index === 0 ? "top" : index === filteredActivityComments.length - 1 ? "bottom" : undefined}
/>
) : (
<></>
Expand Down
10 changes: 8 additions & 2 deletions web/core/store/issue/issue-details/root.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ import {
TIssueRelationTypes,
TIssueDetailWidget,
} from "@plane/types";
// plane web store
import {
IIssueActivityStore,
IssueActivityStore,
IIssueActivityStoreActions,
TActivityLoader,
} from "@/plane-web/store/issue/issue-details/activity.store";
import { IIssueRootStore } from "../root.store";
import { IIssueActivityStore, IssueActivityStore, IIssueActivityStoreActions, TActivityLoader } from "./activity.store";
import { IIssueAttachmentStore, IssueAttachmentStore, IIssueAttachmentStoreActions } from "./attachment.store";
import { IIssueCommentStore, IssueCommentStore, IIssueCommentStoreActions, TCommentLoader } from "./comment.store";
import {
Expand Down Expand Up @@ -187,7 +193,7 @@ export class IssueDetail implements IIssueDetail {
this.issue = new IssueStore(this);
this.reaction = new IssueReactionStore(this);
this.attachment = new IssueAttachmentStore(rootStore);
this.activity = new IssueActivityStore(this);
this.activity = new IssueActivityStore(rootStore.rootStore);
this.comment = new IssueCommentStore(this);
this.commentReaction = new IssueCommentReactionStore(this);
this.subIssues = new IssueSubIssuesStore(this);
Expand Down
9 changes: 5 additions & 4 deletions web/core/store/issue/root.store.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import isEmpty from "lodash/isEmpty";
import { autorun, makeObservable, observable } from "mobx";
import { ICycle, IIssueLabel, IModule, IProject, IState, IUserLite } from "@plane/types";
// plane web root store
import { RootStore } from "@/plane-web/store/root.store";
// root store
import { IWorkspaceMembership } from "@/store/member/workspace-member.store";
import { CoreRootStore } from "../root.store";
import { IStateStore, StateStore } from "../state.store";
// issues data store
import { IArchivedIssuesFilter, ArchivedIssuesFilter, IArchivedIssues, ArchivedIssues } from "./archived";
Expand Down Expand Up @@ -43,7 +44,7 @@ export interface IIssueRootStore {
moduleMap: Record<string, IModule> | undefined;
cycleMap: Record<string, ICycle> | undefined;

rootStore: CoreRootStore;
rootStore: RootStore;

issues: IIssueStore;

Expand Down Expand Up @@ -98,7 +99,7 @@ export class IssueRootStore implements IIssueRootStore {
moduleMap: Record<string, IModule> | undefined = undefined;
cycleMap: Record<string, ICycle> | undefined = undefined;

rootStore: CoreRootStore;
rootStore: RootStore;

issues: IIssueStore;

Expand Down Expand Up @@ -133,7 +134,7 @@ export class IssueRootStore implements IIssueRootStore {
issueKanBanView: IIssueKanBanViewStore;
issueCalendarView: ICalendarStore;

constructor(rootStore: CoreRootStore) {
constructor(rootStore: RootStore) {
makeObservable(this, {
workspaceSlug: observable.ref,
projectId: observable.ref,
Expand Down
1 change: 1 addition & 0 deletions web/ee/store/issue/issue-details/activity.store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "ce/store/issue/issue-details/activity.store";