mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
fix: bug and auth fixes (#1224)
* fix: sign in and invitation page fixes * fix: project and workspace services track event fix * fix: user onboarding complete track event fix * fix: issue track event fix * fix: partial property , issue comment and mark as done issue track event fix * fix: bulk delete , move to cycle or module and issue label track event fix * fix: state , cycle and module track event fix * fix: pages and block track event fix * fix: integration , estimate , importer , analytics and gpt track event fix * fix: view track event fix * fix: build fix * fix: build fix
This commit is contained in:
parent
c127353281
commit
6f2a38ad66
@ -18,7 +18,7 @@ import { Loader, PrimaryButton } from "components/ui";
|
|||||||
// helpers
|
// helpers
|
||||||
import { convertResponseToBarGraphData } from "helpers/analytics.helper";
|
import { convertResponseToBarGraphData } from "helpers/analytics.helper";
|
||||||
// types
|
// types
|
||||||
import { IAnalyticsParams, IAnalyticsResponse } from "types";
|
import { IAnalyticsParams, IAnalyticsResponse, ICurrentUserResponse } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { ANALYTICS } from "constants/fetch-keys";
|
import { ANALYTICS } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -29,6 +29,7 @@ type Props = {
|
|||||||
control: Control<IAnalyticsParams, any>;
|
control: Control<IAnalyticsParams, any>;
|
||||||
setValue: UseFormSetValue<IAnalyticsParams>;
|
setValue: UseFormSetValue<IAnalyticsParams>;
|
||||||
fullScreen: boolean;
|
fullScreen: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CustomAnalytics: React.FC<Props> = ({
|
export const CustomAnalytics: React.FC<Props> = ({
|
||||||
@ -38,6 +39,7 @@ export const CustomAnalytics: React.FC<Props> = ({
|
|||||||
control,
|
control,
|
||||||
setValue,
|
setValue,
|
||||||
fullScreen,
|
fullScreen,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
@ -124,6 +126,7 @@ export const CustomAnalytics: React.FC<Props> = ({
|
|||||||
params={params}
|
params={params}
|
||||||
fullScreen={fullScreen}
|
fullScreen={fullScreen}
|
||||||
isProjectLevel={isProjectLevel}
|
isProjectLevel={isProjectLevel}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -27,6 +27,7 @@ import { renderShortDate } from "helpers/date-time.helper";
|
|||||||
import {
|
import {
|
||||||
IAnalyticsParams,
|
IAnalyticsParams,
|
||||||
IAnalyticsResponse,
|
IAnalyticsResponse,
|
||||||
|
ICurrentUserResponse,
|
||||||
IExportAnalyticsFormData,
|
IExportAnalyticsFormData,
|
||||||
IProject,
|
IProject,
|
||||||
IWorkspace,
|
IWorkspace,
|
||||||
@ -41,6 +42,7 @@ type Props = {
|
|||||||
params: IAnalyticsParams;
|
params: IAnalyticsParams;
|
||||||
fullScreen: boolean;
|
fullScreen: boolean;
|
||||||
isProjectLevel: boolean;
|
isProjectLevel: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AnalyticsSidebar: React.FC<Props> = ({
|
export const AnalyticsSidebar: React.FC<Props> = ({
|
||||||
@ -48,6 +50,7 @@ export const AnalyticsSidebar: React.FC<Props> = ({
|
|||||||
params,
|
params,
|
||||||
fullScreen,
|
fullScreen,
|
||||||
isProjectLevel = false,
|
isProjectLevel = false,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, cycleId, moduleId } = router.query;
|
const { workspaceSlug, projectId, cycleId, moduleId } = router.query;
|
||||||
@ -138,7 +141,8 @@ export const AnalyticsSidebar: React.FC<Props> = ({
|
|||||||
? "MODULE_ANALYTICS_EXPORT"
|
? "MODULE_ANALYTICS_EXPORT"
|
||||||
: projectId
|
: projectId
|
||||||
? "PROJECT_ANALYTICS_EXPORT"
|
? "PROJECT_ANALYTICS_EXPORT"
|
||||||
: "WORKSPACE_ANALYTICS_EXPORT"
|
: "WORKSPACE_ANALYTICS_EXPORT",
|
||||||
|
user
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
import { IAnalyticsParams, IWorkspace } from "types";
|
import { IAnalyticsParams, IWorkspace } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { ANALYTICS, CYCLE_DETAILS, MODULE_DETAILS, PROJECT_DETAILS } from "constants/fetch-keys";
|
import { ANALYTICS, CYCLE_DETAILS, MODULE_DETAILS, PROJECT_DETAILS } from "constants/fetch-keys";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
@ -47,6 +48,8 @@ export const AnalyticsProjectModal: React.FC<Props> = ({ isOpen, onClose }) => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, cycleId, moduleId } = router.query;
|
const { workspaceSlug, projectId, cycleId, moduleId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { control, watch, setValue } = useForm<IAnalyticsParams>({ defaultValues });
|
const { control, watch, setValue } = useForm<IAnalyticsParams>({ defaultValues });
|
||||||
|
|
||||||
const params: IAnalyticsParams = {
|
const params: IAnalyticsParams = {
|
||||||
@ -136,7 +139,8 @@ export const AnalyticsProjectModal: React.FC<Props> = ({ isOpen, onClose }) => {
|
|||||||
|
|
||||||
trackEventServices.trackAnalyticsEvent(
|
trackEventServices.trackAnalyticsEvent(
|
||||||
eventPayload,
|
eventPayload,
|
||||||
cycleId ? `CYCLE_${eventType}` : moduleId ? `MODULE_${eventType}` : `PROJECT_${eventType}`
|
cycleId ? `CYCLE_${eventType}` : moduleId ? `MODULE_${eventType}` : `PROJECT_${eventType}`,
|
||||||
|
user
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -210,6 +214,7 @@ export const AnalyticsProjectModal: React.FC<Props> = ({ isOpen, onClose }) => {
|
|||||||
control={control}
|
control={control}
|
||||||
setValue={setValue}
|
setValue={setValue}
|
||||||
fullScreen={fullScreen}
|
fullScreen={fullScreen}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</Tab.Panel>
|
</Tab.Panel>
|
||||||
</Tab.Panels>
|
</Tab.Panels>
|
||||||
|
@ -7,7 +7,7 @@ import { Command } from "cmdk";
|
|||||||
// services
|
// services
|
||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
// constants
|
// constants
|
||||||
import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY, PROJECT_MEMBERS } from "constants/fetch-keys";
|
import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY, PROJECT_MEMBERS } from "constants/fetch-keys";
|
||||||
// icons
|
// icons
|
||||||
@ -18,9 +18,10 @@ import { Avatar } from "components/ui";
|
|||||||
type Props = {
|
type Props = {
|
||||||
setIsPaletteOpen: Dispatch<SetStateAction<boolean>>;
|
setIsPaletteOpen: Dispatch<SetStateAction<boolean>>;
|
||||||
issue: IIssue;
|
issue: IIssue;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ChangeIssueAssignee: React.FC<Props> = ({ setIsPaletteOpen, issue }) => {
|
export const ChangeIssueAssignee: React.FC<Props> = ({ setIsPaletteOpen, issue, user }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, issueId } = router.query;
|
const { workspaceSlug, projectId, issueId } = router.query;
|
||||||
|
|
||||||
@ -71,7 +72,7 @@ export const ChangeIssueAssignee: React.FC<Props> = ({ setIsPaletteOpen, issue }
|
|||||||
|
|
||||||
const payload = { ...formData };
|
const payload = { ...formData };
|
||||||
await issuesService
|
await issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload)
|
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
||||||
})
|
})
|
||||||
|
@ -7,7 +7,7 @@ import { Command } from "cmdk";
|
|||||||
// services
|
// services
|
||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
// constants
|
// constants
|
||||||
import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys";
|
import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys";
|
||||||
import { PRIORITIES } from "constants/project";
|
import { PRIORITIES } from "constants/project";
|
||||||
@ -17,9 +17,10 @@ import { CheckIcon, getPriorityIcon } from "components/icons";
|
|||||||
type Props = {
|
type Props = {
|
||||||
setIsPaletteOpen: Dispatch<SetStateAction<boolean>>;
|
setIsPaletteOpen: Dispatch<SetStateAction<boolean>>;
|
||||||
issue: IIssue;
|
issue: IIssue;
|
||||||
|
user: ICurrentUserResponse;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ChangeIssuePriority: React.FC<Props> = ({ setIsPaletteOpen, issue }) => {
|
export const ChangeIssuePriority: React.FC<Props> = ({ setIsPaletteOpen, issue, user }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, issueId } = router.query;
|
const { workspaceSlug, projectId, issueId } = router.query;
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ export const ChangeIssuePriority: React.FC<Props> = ({ setIsPaletteOpen, issue }
|
|||||||
|
|
||||||
const payload = { ...formData };
|
const payload = { ...formData };
|
||||||
await issuesService
|
await issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload)
|
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
||||||
})
|
})
|
||||||
|
@ -12,7 +12,7 @@ import { getStatesList } from "helpers/state.helper";
|
|||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
import stateService from "services/state.service";
|
import stateService from "services/state.service";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
// fetch keys
|
// fetch keys
|
||||||
import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY, STATES_LIST } from "constants/fetch-keys";
|
import { ISSUE_DETAILS, PROJECT_ISSUES_ACTIVITY, STATES_LIST } from "constants/fetch-keys";
|
||||||
// icons
|
// icons
|
||||||
@ -21,9 +21,10 @@ import { CheckIcon, getStateGroupIcon } from "components/icons";
|
|||||||
type Props = {
|
type Props = {
|
||||||
setIsPaletteOpen: Dispatch<SetStateAction<boolean>>;
|
setIsPaletteOpen: Dispatch<SetStateAction<boolean>>;
|
||||||
issue: IIssue;
|
issue: IIssue;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ChangeIssueState: React.FC<Props> = ({ setIsPaletteOpen, issue }) => {
|
export const ChangeIssueState: React.FC<Props> = ({ setIsPaletteOpen, issue, user }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, issueId } = router.query;
|
const { workspaceSlug, projectId, issueId } = router.query;
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ export const ChangeIssueState: React.FC<Props> = ({ setIsPaletteOpen, issue }) =
|
|||||||
|
|
||||||
const payload = { ...formData };
|
const payload = { ...formData };
|
||||||
await issuesService
|
await issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload)
|
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutateIssueDetails();
|
mutateIssueDetails();
|
||||||
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
||||||
|
@ -136,7 +136,7 @@ export const CommandPalette: React.FC = () => {
|
|||||||
|
|
||||||
const payload = { ...formData };
|
const payload = { ...formData };
|
||||||
await issuesService
|
await issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload)
|
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
||||||
mutate(ISSUE_DETAILS(issueId as string));
|
mutate(ISSUE_DETAILS(issueId as string));
|
||||||
@ -330,25 +330,33 @@ export const CommandPalette: React.FC = () => {
|
|||||||
<>
|
<>
|
||||||
<ShortcutsModal isOpen={isShortcutsModalOpen} setIsOpen={setIsShortcutsModalOpen} />
|
<ShortcutsModal isOpen={isShortcutsModalOpen} setIsOpen={setIsShortcutsModalOpen} />
|
||||||
{workspaceSlug && (
|
{workspaceSlug && (
|
||||||
<CreateProjectModal isOpen={isProjectModalOpen} setIsOpen={setIsProjectModalOpen} />
|
<CreateProjectModal
|
||||||
|
isOpen={isProjectModalOpen}
|
||||||
|
setIsOpen={setIsProjectModalOpen}
|
||||||
|
user={user}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{projectId && (
|
{projectId && (
|
||||||
<>
|
<>
|
||||||
<CreateUpdateCycleModal
|
<CreateUpdateCycleModal
|
||||||
isOpen={isCreateCycleModalOpen}
|
isOpen={isCreateCycleModalOpen}
|
||||||
handleClose={() => setIsCreateCycleModalOpen(false)}
|
handleClose={() => setIsCreateCycleModalOpen(false)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<CreateUpdateModuleModal
|
<CreateUpdateModuleModal
|
||||||
isOpen={isCreateModuleModalOpen}
|
isOpen={isCreateModuleModalOpen}
|
||||||
setIsOpen={setIsCreateModuleModalOpen}
|
setIsOpen={setIsCreateModuleModalOpen}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<CreateUpdateViewModal
|
<CreateUpdateViewModal
|
||||||
handleClose={() => setIsCreateViewModalOpen(false)}
|
handleClose={() => setIsCreateViewModalOpen(false)}
|
||||||
isOpen={isCreateViewModalOpen}
|
isOpen={isCreateViewModalOpen}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<CreateUpdatePageModal
|
<CreateUpdatePageModal
|
||||||
isOpen={isCreateUpdatePageModalOpen}
|
isOpen={isCreateUpdatePageModalOpen}
|
||||||
handleClose={() => setIsCreateUpdatePageModalOpen(false)}
|
handleClose={() => setIsCreateUpdatePageModalOpen(false)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -357,6 +365,7 @@ export const CommandPalette: React.FC = () => {
|
|||||||
handleClose={() => setDeleteIssueModal(false)}
|
handleClose={() => setDeleteIssueModal(false)}
|
||||||
isOpen={deleteIssueModal}
|
isOpen={deleteIssueModal}
|
||||||
data={issueDetails}
|
data={issueDetails}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -367,6 +376,7 @@ export const CommandPalette: React.FC = () => {
|
|||||||
<BulkDeleteIssuesModal
|
<BulkDeleteIssuesModal
|
||||||
isOpen={isBulkDeleteIssuesModalOpen}
|
isOpen={isBulkDeleteIssuesModalOpen}
|
||||||
setIsOpen={setIsBulkDeleteIssuesModalOpen}
|
setIsOpen={setIsBulkDeleteIssuesModalOpen}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<Transition.Root
|
<Transition.Root
|
||||||
show={isPaletteOpen}
|
show={isPaletteOpen}
|
||||||
@ -854,6 +864,7 @@ export const CommandPalette: React.FC = () => {
|
|||||||
<ChangeIssueState
|
<ChangeIssueState
|
||||||
issue={issueDetails}
|
issue={issueDetails}
|
||||||
setIsPaletteOpen={setIsPaletteOpen}
|
setIsPaletteOpen={setIsPaletteOpen}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -861,12 +872,14 @@ export const CommandPalette: React.FC = () => {
|
|||||||
<ChangeIssuePriority
|
<ChangeIssuePriority
|
||||||
issue={issueDetails}
|
issue={issueDetails}
|
||||||
setIsPaletteOpen={setIsPaletteOpen}
|
setIsPaletteOpen={setIsPaletteOpen}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{page === "change-issue-assignee" && issueDetails && (
|
{page === "change-issue-assignee" && issueDetails && (
|
||||||
<ChangeIssueAssignee
|
<ChangeIssueAssignee
|
||||||
issue={issueDetails}
|
issue={issueDetails}
|
||||||
setIsPaletteOpen={setIsPaletteOpen}
|
setIsPaletteOpen={setIsPaletteOpen}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{page === "change-interface-theme" && (
|
{page === "change-interface-theme" && (
|
||||||
|
@ -5,7 +5,7 @@ import { SingleBoard } from "components/core/board-view/single-board";
|
|||||||
// helpers
|
// helpers
|
||||||
import { addSpaceIfCamelCase } from "helpers/string.helper";
|
import { addSpaceIfCamelCase } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssue, IState, UserAuth } from "types";
|
import { ICurrentUserResponse, IIssue, IState, UserAuth } from "types";
|
||||||
import { getStateGroupIcon } from "components/icons";
|
import { getStateGroupIcon } from "components/icons";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -19,6 +19,7 @@ type Props = {
|
|||||||
handleTrashBox: (isDragging: boolean) => void;
|
handleTrashBox: (isDragging: boolean) => void;
|
||||||
removeIssue: ((bridgeId: string, issueId: string) => void) | null;
|
removeIssue: ((bridgeId: string, issueId: string) => void) | null;
|
||||||
isCompleted?: boolean;
|
isCompleted?: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ export const AllBoards: React.FC<Props> = ({
|
|||||||
handleTrashBox,
|
handleTrashBox,
|
||||||
removeIssue,
|
removeIssue,
|
||||||
isCompleted = false,
|
isCompleted = false,
|
||||||
|
user,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
@ -65,6 +67,7 @@ export const AllBoards: React.FC<Props> = ({
|
|||||||
handleTrashBox={handleTrashBox}
|
handleTrashBox={handleTrashBox}
|
||||||
removeIssue={removeIssue}
|
removeIssue={removeIssue}
|
||||||
isCompleted={isCompleted}
|
isCompleted={isCompleted}
|
||||||
|
user={user}
|
||||||
userAuth={userAuth}
|
userAuth={userAuth}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -17,7 +17,7 @@ import { PlusIcon } from "@heroicons/react/24/outline";
|
|||||||
// helpers
|
// helpers
|
||||||
import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
|
import { replaceUnderscoreIfSnakeCase } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssue, IState, UserAuth } from "types";
|
import { ICurrentUserResponse, IIssue, IState, UserAuth } from "types";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
type?: "issue" | "cycle" | "module";
|
type?: "issue" | "cycle" | "module";
|
||||||
@ -31,6 +31,7 @@ type Props = {
|
|||||||
handleTrashBox: (isDragging: boolean) => void;
|
handleTrashBox: (isDragging: boolean) => void;
|
||||||
removeIssue: ((bridgeId: string, issueId: string) => void) | null;
|
removeIssue: ((bridgeId: string, issueId: string) => void) | null;
|
||||||
isCompleted?: boolean;
|
isCompleted?: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ export const SingleBoard: React.FC<Props> = ({
|
|||||||
handleTrashBox,
|
handleTrashBox,
|
||||||
removeIssue,
|
removeIssue,
|
||||||
isCompleted = false,
|
isCompleted = false,
|
||||||
|
user,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
// collapse/expand
|
// collapse/expand
|
||||||
@ -129,6 +131,7 @@ export const SingleBoard: React.FC<Props> = ({
|
|||||||
removeIssue(issue.bridge_id, issue.id);
|
removeIssue(issue.bridge_id, issue.id);
|
||||||
}}
|
}}
|
||||||
isCompleted={isCompleted}
|
isCompleted={isCompleted}
|
||||||
|
user={user}
|
||||||
userAuth={userAuth}
|
userAuth={userAuth}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -44,7 +44,7 @@ import { LayerDiagonalIcon } from "components/icons";
|
|||||||
import { handleIssuesMutation } from "constants/issue";
|
import { handleIssuesMutation } from "constants/issue";
|
||||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssue, Properties, TIssueGroupByOptions, UserAuth } from "types";
|
import { ICurrentUserResponse, IIssue, Properties, TIssueGroupByOptions, UserAuth } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import {
|
||||||
CYCLE_DETAILS,
|
CYCLE_DETAILS,
|
||||||
@ -69,6 +69,7 @@ type Props = {
|
|||||||
handleDeleteIssue: (issue: IIssue) => void;
|
handleDeleteIssue: (issue: IIssue) => void;
|
||||||
handleTrashBox: (isDragging: boolean) => void;
|
handleTrashBox: (isDragging: boolean) => void;
|
||||||
isCompleted?: boolean;
|
isCompleted?: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -87,6 +88,7 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
handleDeleteIssue,
|
handleDeleteIssue,
|
||||||
handleTrashBox,
|
handleTrashBox,
|
||||||
isCompleted = false,
|
isCompleted = false,
|
||||||
|
user,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
// context menu
|
// context menu
|
||||||
@ -170,7 +172,7 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
issuesService
|
issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, issueId, formData)
|
.patchIssue(workspaceSlug as string, projectId as string, issueId, formData, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (cycleId) {
|
if (cycleId) {
|
||||||
mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params));
|
mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params));
|
||||||
@ -342,6 +344,7 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
|
user={user}
|
||||||
selfPositioned
|
selfPositioned
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -350,6 +353,7 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
|
user={user}
|
||||||
selfPositioned
|
selfPositioned
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -357,6 +361,7 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
<ViewDueDateSelect
|
<ViewDueDateSelect
|
||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -384,6 +389,7 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
tooltipPosition="left"
|
tooltipPosition="left"
|
||||||
|
user={user}
|
||||||
selfPositioned
|
selfPositioned
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -392,6 +398,7 @@ export const SingleBoardIssue: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
|
user={user}
|
||||||
selfPositioned
|
selfPositioned
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -18,7 +18,7 @@ import { DangerButton, SecondaryButton } from "components/ui";
|
|||||||
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline";
|
||||||
import { LayerDiagonalIcon } from "components/icons";
|
import { LayerDiagonalIcon } from "components/icons";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
// fetch keys
|
// fetch keys
|
||||||
import { PROJECT_ISSUES_LIST } from "constants/fetch-keys";
|
import { PROJECT_ISSUES_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -29,9 +29,10 @@ type FormInput = {
|
|||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BulkDeleteIssuesModal: React.FC<Props> = ({ isOpen, setIsOpen }) => {
|
export const BulkDeleteIssuesModal: React.FC<Props> = ({ isOpen, setIsOpen, user }) => {
|
||||||
const [query, setQuery] = useState("");
|
const [query, setQuery] = useState("");
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -91,9 +92,14 @@ export const BulkDeleteIssuesModal: React.FC<Props> = ({ isOpen, setIsOpen }) =>
|
|||||||
|
|
||||||
if (workspaceSlug && projectId) {
|
if (workspaceSlug && projectId) {
|
||||||
await issuesServices
|
await issuesServices
|
||||||
.bulkDeleteIssues(workspaceSlug as string, projectId as string, {
|
.bulkDeleteIssues(
|
||||||
issue_ids: data.delete_issue_ids,
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
{
|
||||||
|
issue_ids: data.delete_issue_ids,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
title: "Success",
|
title: "Success",
|
||||||
|
@ -24,7 +24,7 @@ import {
|
|||||||
formatDate,
|
formatDate,
|
||||||
} from "helpers/calendar.helper";
|
} from "helpers/calendar.helper";
|
||||||
// types
|
// types
|
||||||
import { ICalendarRange, IIssue, UserAuth } from "types";
|
import { ICalendarRange, ICurrentUserResponse, IIssue, UserAuth } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import {
|
||||||
CYCLE_ISSUES_WITH_PARAMS,
|
CYCLE_ISSUES_WITH_PARAMS,
|
||||||
@ -38,6 +38,7 @@ type Props = {
|
|||||||
handleDeleteIssue: (issue: IIssue) => void;
|
handleDeleteIssue: (issue: IIssue) => void;
|
||||||
addIssueToDate: (date: string) => void;
|
addIssueToDate: (date: string) => void;
|
||||||
isCompleted: boolean;
|
isCompleted: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ export const CalendarView: React.FC<Props> = ({
|
|||||||
handleDeleteIssue,
|
handleDeleteIssue,
|
||||||
addIssueToDate,
|
addIssueToDate,
|
||||||
isCompleted = false,
|
isCompleted = false,
|
||||||
|
user,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
const [showWeekEnds, setShowWeekEnds] = useState(false);
|
const [showWeekEnds, setShowWeekEnds] = useState(false);
|
||||||
@ -134,9 +136,15 @@ export const CalendarView: React.FC<Props> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
issuesService
|
issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, draggableId, {
|
.patchIssue(
|
||||||
target_date: destination?.droppableId,
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
draggableId,
|
||||||
|
{
|
||||||
|
target_date: destination?.droppableId,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => mutate(fetchKey));
|
.then(() => mutate(fetchKey));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -219,6 +227,7 @@ export const CalendarView: React.FC<Props> = ({
|
|||||||
addIssueToDate={addIssueToDate}
|
addIssueToDate={addIssueToDate}
|
||||||
isMonthlyView={isMonthlyView}
|
isMonthlyView={isMonthlyView}
|
||||||
showWeekEnds={showWeekEnds}
|
showWeekEnds={showWeekEnds}
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
@ -10,7 +10,7 @@ import { PlusSmallIcon } from "@heroicons/react/24/outline";
|
|||||||
// helper
|
// helper
|
||||||
import { formatDate } from "helpers/calendar.helper";
|
import { formatDate } from "helpers/calendar.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
handleEditIssue: (issue: IIssue) => void;
|
handleEditIssue: (issue: IIssue) => void;
|
||||||
@ -23,6 +23,7 @@ type Props = {
|
|||||||
addIssueToDate: (date: string) => void;
|
addIssueToDate: (date: string) => void;
|
||||||
isMonthlyView: boolean;
|
isMonthlyView: boolean;
|
||||||
showWeekEnds: boolean;
|
showWeekEnds: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
isNotAllowed: boolean;
|
isNotAllowed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -34,6 +35,7 @@ export const SingleCalendarDate: React.FC<Props> = ({
|
|||||||
addIssueToDate,
|
addIssueToDate,
|
||||||
isMonthlyView,
|
isMonthlyView,
|
||||||
showWeekEnds,
|
showWeekEnds,
|
||||||
|
user,
|
||||||
isNotAllowed,
|
isNotAllowed,
|
||||||
}) => {
|
}) => {
|
||||||
const [showAllIssues, setShowAllIssues] = useState(false);
|
const [showAllIssues, setShowAllIssues] = useState(false);
|
||||||
@ -72,6 +74,7 @@ export const SingleCalendarDate: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
handleEditIssue={handleEditIssue}
|
handleEditIssue={handleEditIssue}
|
||||||
handleDeleteIssue={handleDeleteIssue}
|
handleDeleteIssue={handleDeleteIssue}
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -28,7 +28,7 @@ import { LayerDiagonalIcon } from "components/icons";
|
|||||||
// helper
|
// helper
|
||||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||||
// type
|
// type
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import {
|
||||||
CYCLE_ISSUES_WITH_PARAMS,
|
CYCLE_ISSUES_WITH_PARAMS,
|
||||||
@ -44,6 +44,7 @@ type Props = {
|
|||||||
provided: DraggableProvided;
|
provided: DraggableProvided;
|
||||||
snapshot: DraggableStateSnapshot;
|
snapshot: DraggableStateSnapshot;
|
||||||
issue: IIssue;
|
issue: IIssue;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
isNotAllowed: boolean;
|
isNotAllowed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,6 +55,7 @@ export const SingleCalendarIssue: React.FC<Props> = ({
|
|||||||
provided,
|
provided,
|
||||||
snapshot,
|
snapshot,
|
||||||
issue,
|
issue,
|
||||||
|
user,
|
||||||
isNotAllowed,
|
isNotAllowed,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -95,7 +97,7 @@ export const SingleCalendarIssue: React.FC<Props> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
issuesService
|
issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, formData)
|
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, formData, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(fetchKey);
|
mutate(fetchKey);
|
||||||
})
|
})
|
||||||
@ -183,6 +185,7 @@ export const SingleCalendarIssue: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
position="left"
|
position="left"
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -192,6 +195,7 @@ export const SingleCalendarIssue: React.FC<Props> = ({
|
|||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
position="left"
|
position="left"
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -199,6 +203,7 @@ export const SingleCalendarIssue: React.FC<Props> = ({
|
|||||||
<ViewDueDateSelect
|
<ViewDueDateSelect
|
||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -227,6 +232,7 @@ export const SingleCalendarIssue: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
position="left"
|
position="left"
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -235,6 +241,7 @@ export const SingleCalendarIssue: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
position="left"
|
position="left"
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -10,6 +10,7 @@ import aiService from "services/ai.service";
|
|||||||
import trackEventServices from "services/track-event.service";
|
import trackEventServices from "services/track-event.service";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// ui
|
// ui
|
||||||
import { Input, PrimaryButton, SecondaryButton } from "components/ui";
|
import { Input, PrimaryButton, SecondaryButton } from "components/ui";
|
||||||
|
|
||||||
@ -60,6 +61,8 @@ export const GptAssistantModal: React.FC<Props> = ({
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const editorRef = useRef<any>(null);
|
const editorRef = useRef<any>(null);
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
@ -97,10 +100,15 @@ export const GptAssistantModal: React.FC<Props> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
await aiService
|
await aiService
|
||||||
.createGptTask(workspaceSlug as string, projectId as string, {
|
.createGptTask(
|
||||||
prompt: content && content !== "" ? content : htmlContent ?? "",
|
workspaceSlug as string,
|
||||||
task: formData.task,
|
projectId as string,
|
||||||
})
|
{
|
||||||
|
prompt: content && content !== "" ? content : htmlContent ?? "",
|
||||||
|
task: formData.task,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setResponse(res.response_html);
|
setResponse(res.response_html);
|
||||||
setFocus("task");
|
setFocus("task");
|
||||||
@ -190,10 +198,15 @@ export const GptAssistantModal: React.FC<Props> = ({
|
|||||||
if (block)
|
if (block)
|
||||||
trackEventServices.trackUseGPTResponseEvent(
|
trackEventServices.trackUseGPTResponseEvent(
|
||||||
block,
|
block,
|
||||||
"USE_GPT_RESPONSE_IN_PAGE_BLOCK"
|
"USE_GPT_RESPONSE_IN_PAGE_BLOCK",
|
||||||
|
user
|
||||||
);
|
);
|
||||||
else if (issue)
|
else if (issue)
|
||||||
trackEventServices.trackUseGPTResponseEvent(issue, "USE_GPT_RESPONSE_IN_ISSUE");
|
trackEventServices.trackUseGPTResponseEvent(
|
||||||
|
issue,
|
||||||
|
"USE_GPT_RESPONSE_IN_ISSUE",
|
||||||
|
user
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Use this response
|
Use this response
|
||||||
|
@ -17,6 +17,7 @@ import { useProjectMyMembership } from "contexts/project-member.context";
|
|||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
import useIssuesView from "hooks/use-issues-view";
|
import useIssuesView from "hooks/use-issues-view";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// components
|
// components
|
||||||
import { AllLists, AllBoards, FilterList, CalendarView, GanttChartView } from "components/core";
|
import { AllLists, AllBoards, FilterList, CalendarView, GanttChartView } from "components/core";
|
||||||
import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues";
|
import { CreateUpdateIssueModal, DeleteIssueModal } from "components/issues";
|
||||||
@ -89,6 +90,8 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
|
|
||||||
const { memberRole } = useProjectMyMembership();
|
const { memberRole } = useProjectMyMembership();
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -220,11 +223,17 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
|
|
||||||
// patch request
|
// patch request
|
||||||
issuesService
|
issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, draggedItem.id, {
|
.patchIssue(
|
||||||
priority: draggedItem.priority,
|
workspaceSlug as string,
|
||||||
state: draggedItem.state,
|
projectId as string,
|
||||||
sort_order: draggedItem.sort_order,
|
draggedItem.id,
|
||||||
})
|
{
|
||||||
|
priority: draggedItem.priority,
|
||||||
|
state: draggedItem.state,
|
||||||
|
sort_order: draggedItem.sort_order,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
const sourceStateBeforeDrag = states.find((state) => state.name === source.droppableId);
|
const sourceStateBeforeDrag = states.find((state) => state.name === source.droppableId);
|
||||||
|
|
||||||
@ -232,14 +241,17 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
sourceStateBeforeDrag?.group !== "completed" &&
|
sourceStateBeforeDrag?.group !== "completed" &&
|
||||||
response?.state_detail?.group === "completed"
|
response?.state_detail?.group === "completed"
|
||||||
)
|
)
|
||||||
trackEventServices.trackIssueMarkedAsDoneEvent({
|
trackEventServices.trackIssueMarkedAsDoneEvent(
|
||||||
workspaceSlug,
|
{
|
||||||
workspaceId: draggedItem.workspace,
|
workspaceSlug,
|
||||||
projectName: draggedItem.project_detail.name,
|
workspaceId: draggedItem.workspace,
|
||||||
projectIdentifier: draggedItem.project_detail.identifier,
|
projectName: draggedItem.project_detail.name,
|
||||||
projectId,
|
projectIdentifier: draggedItem.project_detail.identifier,
|
||||||
issueId: draggedItem.id,
|
projectId,
|
||||||
});
|
issueId: draggedItem.id,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
);
|
||||||
|
|
||||||
if (cycleId) {
|
if (cycleId) {
|
||||||
mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params));
|
mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params));
|
||||||
@ -419,6 +431,7 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
isOpen={createViewModal !== null}
|
isOpen={createViewModal !== null}
|
||||||
handleClose={() => setCreateViewModal(null)}
|
handleClose={() => setCreateViewModal(null)}
|
||||||
preLoadedData={createViewModal}
|
preLoadedData={createViewModal}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<CreateUpdateIssueModal
|
<CreateUpdateIssueModal
|
||||||
isOpen={createIssueModal && preloadedData?.actionType === "createIssue"}
|
isOpen={createIssueModal && preloadedData?.actionType === "createIssue"}
|
||||||
@ -437,6 +450,7 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
handleClose={() => setDeleteIssueModal(false)}
|
handleClose={() => setDeleteIssueModal(false)}
|
||||||
isOpen={deleteIssueModal}
|
isOpen={deleteIssueModal}
|
||||||
data={issueToDelete}
|
data={issueToDelete}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<TransferIssuesModal
|
<TransferIssuesModal
|
||||||
handleClose={() => setTransferIssuesModal(false)}
|
handleClose={() => setTransferIssuesModal(false)}
|
||||||
@ -508,6 +522,7 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
isCompleted={isCompleted}
|
isCompleted={isCompleted}
|
||||||
|
user={user}
|
||||||
userAuth={memberRole}
|
userAuth={memberRole}
|
||||||
/>
|
/>
|
||||||
) : issueView === "kanban" ? (
|
) : issueView === "kanban" ? (
|
||||||
@ -528,6 +543,7 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
isCompleted={isCompleted}
|
isCompleted={isCompleted}
|
||||||
|
user={user}
|
||||||
userAuth={memberRole}
|
userAuth={memberRole}
|
||||||
/>
|
/>
|
||||||
) : issueView === "calendar" ? (
|
) : issueView === "calendar" ? (
|
||||||
@ -536,6 +552,7 @@ export const IssuesView: React.FC<Props> = ({
|
|||||||
handleDeleteIssue={handleDeleteIssue}
|
handleDeleteIssue={handleDeleteIssue}
|
||||||
addIssueToDate={addIssueToDate}
|
addIssueToDate={addIssueToDate}
|
||||||
isCompleted={isCompleted}
|
isCompleted={isCompleted}
|
||||||
|
user={user}
|
||||||
userAuth={memberRole}
|
userAuth={memberRole}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
@ -3,7 +3,7 @@ import useIssuesView from "hooks/use-issues-view";
|
|||||||
// components
|
// components
|
||||||
import { SingleList } from "components/core/list-view/single-list";
|
import { SingleList } from "components/core/list-view/single-list";
|
||||||
// types
|
// types
|
||||||
import { IIssue, IState, UserAuth } from "types";
|
import { ICurrentUserResponse, IIssue, IState, UserAuth } from "types";
|
||||||
|
|
||||||
// types
|
// types
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -16,6 +16,7 @@ type Props = {
|
|||||||
openIssuesListModal?: (() => void) | null;
|
openIssuesListModal?: (() => void) | null;
|
||||||
removeIssue: ((bridgeId: string, issueId: string) => void) | null;
|
removeIssue: ((bridgeId: string, issueId: string) => void) | null;
|
||||||
isCompleted?: boolean;
|
isCompleted?: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ export const AllLists: React.FC<Props> = ({
|
|||||||
handleDeleteIssue,
|
handleDeleteIssue,
|
||||||
removeIssue,
|
removeIssue,
|
||||||
isCompleted = false,
|
isCompleted = false,
|
||||||
|
user,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
const { groupedByIssues, groupByProperty: selectedGroup, showEmptyGroups } = useIssuesView();
|
const { groupedByIssues, groupByProperty: selectedGroup, showEmptyGroups } = useIssuesView();
|
||||||
@ -58,6 +60,7 @@ export const AllLists: React.FC<Props> = ({
|
|||||||
openIssuesListModal={type !== "issue" ? openIssuesListModal : null}
|
openIssuesListModal={type !== "issue" ? openIssuesListModal : null}
|
||||||
removeIssue={removeIssue}
|
removeIssue={removeIssue}
|
||||||
isCompleted={isCompleted}
|
isCompleted={isCompleted}
|
||||||
|
user={user}
|
||||||
userAuth={userAuth}
|
userAuth={userAuth}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -36,7 +36,7 @@ import { LayerDiagonalIcon } from "components/icons";
|
|||||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||||
import { handleIssuesMutation } from "constants/issue";
|
import { handleIssuesMutation } from "constants/issue";
|
||||||
// types
|
// types
|
||||||
import { IIssue, Properties, UserAuth } from "types";
|
import { ICurrentUserResponse, IIssue, Properties, UserAuth } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import {
|
||||||
CYCLE_DETAILS,
|
CYCLE_DETAILS,
|
||||||
@ -57,6 +57,7 @@ type Props = {
|
|||||||
removeIssue?: (() => void) | null;
|
removeIssue?: (() => void) | null;
|
||||||
handleDeleteIssue: (issue: IIssue) => void;
|
handleDeleteIssue: (issue: IIssue) => void;
|
||||||
isCompleted?: boolean;
|
isCompleted?: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,6 +72,7 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
groupTitle,
|
groupTitle,
|
||||||
handleDeleteIssue,
|
handleDeleteIssue,
|
||||||
isCompleted = false,
|
isCompleted = false,
|
||||||
|
user,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
// context menu
|
// context menu
|
||||||
@ -141,7 +143,7 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
issuesService
|
issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, issueId, formData)
|
.patchIssue(workspaceSlug as string, projectId as string, issueId, formData, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (cycleId) {
|
if (cycleId) {
|
||||||
mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params));
|
mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId as string, params));
|
||||||
@ -241,6 +243,7 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
position="right"
|
position="right"
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -249,6 +252,7 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
position="right"
|
position="right"
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -256,6 +260,7 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
<ViewDueDateSelect
|
<ViewDueDateSelect
|
||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -284,6 +289,7 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
position="right"
|
position="right"
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -292,6 +298,7 @@ export const SingleListIssue: React.FC<Props> = ({
|
|||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
position="right"
|
position="right"
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -19,7 +19,14 @@ import { getPriorityIcon, getStateGroupIcon } from "components/icons";
|
|||||||
// helpers
|
// helpers
|
||||||
import { addSpaceIfCamelCase } from "helpers/string.helper";
|
import { addSpaceIfCamelCase } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssue, IIssueLabels, IState, TIssueGroupByOptions, UserAuth } from "types";
|
import {
|
||||||
|
ICurrentUserResponse,
|
||||||
|
IIssue,
|
||||||
|
IIssueLabels,
|
||||||
|
IState,
|
||||||
|
TIssueGroupByOptions,
|
||||||
|
UserAuth,
|
||||||
|
} from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS } from "constants/fetch-keys";
|
import { PROJECT_ISSUE_LABELS, PROJECT_MEMBERS } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -39,6 +46,7 @@ type Props = {
|
|||||||
openIssuesListModal?: (() => void) | null;
|
openIssuesListModal?: (() => void) | null;
|
||||||
removeIssue: ((bridgeId: string, issueId: string) => void) | null;
|
removeIssue: ((bridgeId: string, issueId: string) => void) | null;
|
||||||
isCompleted?: boolean;
|
isCompleted?: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
userAuth: UserAuth;
|
userAuth: UserAuth;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -56,6 +64,7 @@ export const SingleList: React.FC<Props> = ({
|
|||||||
openIssuesListModal,
|
openIssuesListModal,
|
||||||
removeIssue,
|
removeIssue,
|
||||||
isCompleted = false,
|
isCompleted = false,
|
||||||
|
user,
|
||||||
userAuth,
|
userAuth,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -208,6 +217,7 @@ export const SingleList: React.FC<Props> = ({
|
|||||||
removeIssue(issue.bridge_id, issue.id);
|
removeIssue(issue.bridge_id, issue.id);
|
||||||
}}
|
}}
|
||||||
isCompleted={isCompleted}
|
isCompleted={isCompleted}
|
||||||
|
user={user}
|
||||||
userAuth={userAuth}
|
userAuth={userAuth}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
@ -8,6 +8,7 @@ import { mutate } from "swr";
|
|||||||
import cyclesService from "services/cycles.service";
|
import cyclesService from "services/cycles.service";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// components
|
// components
|
||||||
import {
|
import {
|
||||||
CreateUpdateCycleModal,
|
CreateUpdateCycleModal,
|
||||||
@ -48,6 +49,7 @@ export const CyclesView: React.FC<Props> = ({ cycles, viewType }) => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const handleEditCycle = (cycle: ICycle) => {
|
const handleEditCycle = (cycle: ICycle) => {
|
||||||
@ -158,11 +160,13 @@ export const CyclesView: React.FC<Props> = ({ cycles, viewType }) => {
|
|||||||
isOpen={createUpdateCycleModal}
|
isOpen={createUpdateCycleModal}
|
||||||
handleClose={() => setCreateUpdateCycleModal(false)}
|
handleClose={() => setCreateUpdateCycleModal(false)}
|
||||||
data={selectedCycleToUpdate}
|
data={selectedCycleToUpdate}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<DeleteCycleModal
|
<DeleteCycleModal
|
||||||
isOpen={deleteCycleModal}
|
isOpen={deleteCycleModal}
|
||||||
setIsOpen={setDeleteCycleModal}
|
setIsOpen={setDeleteCycleModal}
|
||||||
data={selectedCycleToDelete}
|
data={selectedCycleToDelete}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
{cycles ? (
|
{cycles ? (
|
||||||
cycles.length > 0 ? (
|
cycles.length > 0 ? (
|
||||||
|
@ -14,11 +14,12 @@ import { DangerButton, SecondaryButton } from "components/ui";
|
|||||||
// icons
|
// icons
|
||||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import type { ICycle } from "types";
|
import type { ICurrentUserResponse, ICycle } from "types";
|
||||||
type TConfirmCycleDeletionProps = {
|
type TConfirmCycleDeletionProps = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
data?: ICycle | null;
|
data?: ICycle | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import {
|
||||||
@ -34,6 +35,7 @@ export const DeleteCycleModal: React.FC<TConfirmCycleDeletionProps> = ({
|
|||||||
isOpen,
|
isOpen,
|
||||||
setIsOpen,
|
setIsOpen,
|
||||||
data,
|
data,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
|
||||||
@ -53,7 +55,7 @@ export const DeleteCycleModal: React.FC<TConfirmCycleDeletionProps> = ({
|
|||||||
setIsDeleteLoading(true);
|
setIsDeleteLoading(true);
|
||||||
|
|
||||||
await cycleService
|
await cycleService
|
||||||
.deleteCycle(workspaceSlug as string, data.project, data.id)
|
.deleteCycle(workspaceSlug as string, data.project, data.id, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const cycleType = getDateRangeStatus(data.start_date, data.end_date);
|
const cycleType = getDateRangeStatus(data.start_date, data.end_date);
|
||||||
const fetchKey =
|
const fetchKey =
|
||||||
|
@ -15,7 +15,7 @@ import { CycleForm } from "components/cycles";
|
|||||||
// helper
|
// helper
|
||||||
import { getDateRangeStatus, isDateGreaterThanToday } from "helpers/date-time.helper";
|
import { getDateRangeStatus, isDateGreaterThanToday } from "helpers/date-time.helper";
|
||||||
// types
|
// types
|
||||||
import type { ICycle } from "types";
|
import type { ICurrentUserResponse, ICycle } from "types";
|
||||||
// fetch keys
|
// fetch keys
|
||||||
import {
|
import {
|
||||||
COMPLETED_CYCLES_LIST,
|
COMPLETED_CYCLES_LIST,
|
||||||
@ -30,12 +30,14 @@ type CycleModalProps = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
data?: ICycle | null;
|
data?: ICycle | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CreateUpdateCycleModal: React.FC<CycleModalProps> = ({
|
export const CreateUpdateCycleModal: React.FC<CycleModalProps> = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
handleClose,
|
handleClose,
|
||||||
data,
|
data,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
@ -46,7 +48,7 @@ export const CreateUpdateCycleModal: React.FC<CycleModalProps> = ({
|
|||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
await cycleService
|
await cycleService
|
||||||
.createCycle(workspaceSlug.toString(), projectId.toString(), payload)
|
.createCycle(workspaceSlug.toString(), projectId.toString(), payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
switch (getDateRangeStatus(res.start_date, res.end_date)) {
|
switch (getDateRangeStatus(res.start_date, res.end_date)) {
|
||||||
case "completed":
|
case "completed":
|
||||||
@ -84,7 +86,7 @@ export const CreateUpdateCycleModal: React.FC<CycleModalProps> = ({
|
|||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
await cycleService
|
await cycleService
|
||||||
.updateCycle(workspaceSlug.toString(), projectId.toString(), cycleId, payload)
|
.updateCycle(workspaceSlug.toString(), projectId.toString(), cycleId, payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
switch (getDateRangeStatus(data?.start_date, data?.end_date)) {
|
switch (getDateRangeStatus(data?.start_date, data?.end_date)) {
|
||||||
case "completed":
|
case "completed":
|
||||||
|
@ -4,6 +4,7 @@ import { useRouter } from "next/router";
|
|||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// headless ui
|
// headless ui
|
||||||
import { Listbox, Transition } from "@headlessui/react";
|
import { Listbox, Transition } from "@headlessui/react";
|
||||||
// icons
|
// icons
|
||||||
@ -35,6 +36,8 @@ export const CycleSelect: React.FC<IssueCycleSelectProps> = ({
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { data: cycles } = useSWR(
|
const { data: cycles } = useSWR(
|
||||||
workspaceSlug && projectId ? CYCLES_LIST(projectId) : null,
|
workspaceSlug && projectId ? CYCLES_LIST(projectId) : null,
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
@ -54,7 +57,11 @@ export const CycleSelect: React.FC<IssueCycleSelectProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CreateUpdateCycleModal isOpen={isCycleModalActive} handleClose={closeCycleModal} />
|
<CreateUpdateCycleModal
|
||||||
|
isOpen={isCycleModalActive}
|
||||||
|
handleClose={closeCycleModal}
|
||||||
|
user={user}
|
||||||
|
/>
|
||||||
<Listbox as="div" className="relative" value={value} onChange={onChange} multiple={multiple}>
|
<Listbox as="div" className="relative" value={value} onChange={onChange} multiple={multiple}>
|
||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<>
|
<>
|
||||||
|
@ -39,7 +39,7 @@ import {
|
|||||||
renderShortDate,
|
renderShortDate,
|
||||||
} from "helpers/date-time.helper";
|
} from "helpers/date-time.helper";
|
||||||
// types
|
// types
|
||||||
import { ICycle, IIssue } from "types";
|
import { ICurrentUserResponse, ICycle, IIssue } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { CYCLE_DETAILS, CYCLE_ISSUES } from "constants/fetch-keys";
|
import { CYCLE_DETAILS, CYCLE_ISSUES } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -48,6 +48,7 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
cycleStatus: string;
|
cycleStatus: string;
|
||||||
isCompleted: boolean;
|
isCompleted: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CycleDetailsSidebar: React.FC<Props> = ({
|
export const CycleDetailsSidebar: React.FC<Props> = ({
|
||||||
@ -55,6 +56,7 @@ export const CycleDetailsSidebar: React.FC<Props> = ({
|
|||||||
isOpen,
|
isOpen,
|
||||||
cycleStatus,
|
cycleStatus,
|
||||||
isCompleted,
|
isCompleted,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const [cycleDeleteModal, setCycleDeleteModal] = useState(false);
|
const [cycleDeleteModal, setCycleDeleteModal] = useState(false);
|
||||||
|
|
||||||
@ -94,7 +96,7 @@ export const CycleDetailsSidebar: React.FC<Props> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
cyclesService
|
cyclesService
|
||||||
.patchCycle(workspaceSlug as string, projectId as string, cycleId as string, data)
|
.patchCycle(workspaceSlug as string, projectId as string, cycleId as string, data, user)
|
||||||
.then(() => mutate(CYCLE_DETAILS(cycleId as string)))
|
.then(() => mutate(CYCLE_DETAILS(cycleId as string)))
|
||||||
.catch((e) => console.log(e));
|
.catch((e) => console.log(e));
|
||||||
};
|
};
|
||||||
@ -294,7 +296,12 @@ export const CycleDetailsSidebar: React.FC<Props> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DeleteCycleModal isOpen={cycleDeleteModal} setIsOpen={setCycleDeleteModal} data={cycle} />
|
<DeleteCycleModal
|
||||||
|
isOpen={cycleDeleteModal}
|
||||||
|
setIsOpen={setCycleDeleteModal}
|
||||||
|
data={cycle}
|
||||||
|
user={user}
|
||||||
|
/>
|
||||||
<div
|
<div
|
||||||
className={`fixed top-[66px] ${
|
className={`fixed top-[66px] ${
|
||||||
isOpen ? "right-0" : "-right-[24rem]"
|
isOpen ? "right-0" : "-right-[24rem]"
|
||||||
|
@ -17,7 +17,7 @@ import { Input, PrimaryButton, SecondaryButton, TextArea } from "components/ui";
|
|||||||
// helpers
|
// helpers
|
||||||
import { checkDuplicates } from "helpers/array.helper";
|
import { checkDuplicates } from "helpers/array.helper";
|
||||||
// types
|
// types
|
||||||
import { IEstimate, IEstimateFormData } from "types";
|
import { ICurrentUserResponse, IEstimate, IEstimateFormData } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { ESTIMATES_LIST, ESTIMATE_DETAILS } from "constants/fetch-keys";
|
import { ESTIMATES_LIST, ESTIMATE_DETAILS } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -25,6 +25,7 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
data?: IEstimate;
|
data?: IEstimate;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FormValues = {
|
type FormValues = {
|
||||||
@ -49,7 +50,7 @@ const defaultValues: Partial<FormValues> = {
|
|||||||
value6: "",
|
value6: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CreateUpdateEstimateModal: React.FC<Props> = ({ handleClose, data, isOpen }) => {
|
export const CreateUpdateEstimateModal: React.FC<Props> = ({ handleClose, data, isOpen, user }) => {
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
formState: { isSubmitting },
|
formState: { isSubmitting },
|
||||||
@ -73,7 +74,7 @@ export const CreateUpdateEstimateModal: React.FC<Props> = ({ handleClose, data,
|
|||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
await estimatesService
|
await estimatesService
|
||||||
.createEstimate(workspaceSlug as string, projectId as string, payload)
|
.createEstimate(workspaceSlug as string, projectId as string, payload, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(ESTIMATES_LIST(projectId as string));
|
mutate(ESTIMATES_LIST(projectId as string));
|
||||||
onClose();
|
onClose();
|
||||||
@ -118,7 +119,13 @@ export const CreateUpdateEstimateModal: React.FC<Props> = ({ handleClose, data,
|
|||||||
);
|
);
|
||||||
|
|
||||||
await estimatesService
|
await estimatesService
|
||||||
.patchEstimate(workspaceSlug as string, projectId as string, data?.id as string, payload)
|
.patchEstimate(
|
||||||
|
workspaceSlug as string,
|
||||||
|
projectId as string,
|
||||||
|
data?.id as string,
|
||||||
|
payload,
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(ESTIMATES_LIST(projectId.toString()));
|
mutate(ESTIMATES_LIST(projectId.toString()));
|
||||||
mutate(ESTIMATE_DETAILS(data.id));
|
mutate(ESTIMATE_DETAILS(data.id));
|
||||||
|
@ -16,15 +16,17 @@ import { PencilIcon, TrashIcon } from "@heroicons/react/24/outline";
|
|||||||
// helpers
|
// helpers
|
||||||
import { orderArrayBy } from "helpers/array.helper";
|
import { orderArrayBy } from "helpers/array.helper";
|
||||||
// types
|
// types
|
||||||
import { IEstimate } from "types";
|
import { ICurrentUserResponse, IEstimate } from "types";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
estimate: IEstimate;
|
estimate: IEstimate;
|
||||||
editEstimate: (estimate: IEstimate) => void;
|
editEstimate: (estimate: IEstimate) => void;
|
||||||
handleEstimateDelete: (estimateId: string) => void;
|
handleEstimateDelete: (estimateId: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SingleEstimate: React.FC<Props> = ({
|
export const SingleEstimate: React.FC<Props> = ({
|
||||||
|
user,
|
||||||
estimate,
|
estimate,
|
||||||
editEstimate,
|
editEstimate,
|
||||||
handleEstimateDelete,
|
handleEstimateDelete,
|
||||||
@ -52,7 +54,7 @@ export const SingleEstimate: React.FC<Props> = ({
|
|||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
await projectService
|
await projectService
|
||||||
.updateProject(workspaceSlug as string, projectId as string, payload)
|
.updateProject(workspaceSlug as string, projectId as string, payload, user)
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "error",
|
type: "error",
|
||||||
|
@ -15,7 +15,7 @@ import { DangerButton, Input, SecondaryButton } from "components/ui";
|
|||||||
// icons
|
// icons
|
||||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import { IImporterService } from "types";
|
import { ICurrentUserResponse, IImporterService } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { IMPORTER_SERVICES_LIST } from "constants/fetch-keys";
|
import { IMPORTER_SERVICES_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -23,9 +23,10 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
data: IImporterService | null;
|
data: IImporterService | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeleteImportModal: React.FC<Props> = ({ isOpen, handleClose, data }) => {
|
export const DeleteImportModal: React.FC<Props> = ({ isOpen, handleClose, data, user }) => {
|
||||||
const [deleteLoading, setDeleteLoading] = useState(false);
|
const [deleteLoading, setDeleteLoading] = useState(false);
|
||||||
const [confirmDeleteImport, setConfirmDeleteImport] = useState(false);
|
const [confirmDeleteImport, setConfirmDeleteImport] = useState(false);
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ export const DeleteImportModal: React.FC<Props> = ({ isOpen, handleClose, data }
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
IntegrationService.deleteImporterService(workspaceSlug as string, data.service, data.id)
|
IntegrationService.deleteImporterService(workspaceSlug as string, data.service, data.id, user)
|
||||||
.catch(() =>
|
.catch(() =>
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "error",
|
type: "error",
|
||||||
|
@ -27,7 +27,7 @@ import { ArrowLeftIcon, ListBulletIcon } from "@heroicons/react/24/outline";
|
|||||||
// images
|
// images
|
||||||
import GithubLogo from "public/services/github.png";
|
import GithubLogo from "public/services/github.png";
|
||||||
// types
|
// types
|
||||||
import { IGithubRepoCollaborator, IGithubServiceImportFormData } from "types";
|
import { ICurrentUserResponse, IGithubRepoCollaborator, IGithubServiceImportFormData } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import {
|
||||||
APP_INTEGRATIONS,
|
APP_INTEGRATIONS,
|
||||||
@ -89,7 +89,11 @@ const integrationWorkflowData = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const GithubImporterRoot = () => {
|
type Props = {
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const GithubImporterRoot: React.FC<Props> = ({ user }) => {
|
||||||
const [currentStep, setCurrentStep] = useState<IIntegrationData>({
|
const [currentStep, setCurrentStep] = useState<IIntegrationData>({
|
||||||
state: "import-configure",
|
state: "import-configure",
|
||||||
});
|
});
|
||||||
@ -157,7 +161,7 @@ export const GithubImporterRoot = () => {
|
|||||||
project_id: formData.project,
|
project_id: formData.project,
|
||||||
};
|
};
|
||||||
|
|
||||||
await GithubIntegrationService.createGithubServiceImport(workspaceSlug as string, payload)
|
await GithubIntegrationService.createGithubServiceImport(workspaceSlug as string, payload, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
router.push(`/${workspaceSlug}/settings/import-export`);
|
router.push(`/${workspaceSlug}/settings/import-export`);
|
||||||
mutate(IMPORTER_SERVICES_LIST(workspaceSlug as string));
|
mutate(IMPORTER_SERVICES_LIST(workspaceSlug as string));
|
||||||
|
@ -6,6 +6,8 @@ import { useRouter } from "next/router";
|
|||||||
|
|
||||||
import useSWR, { mutate } from "swr";
|
import useSWR, { mutate } from "swr";
|
||||||
|
|
||||||
|
// hooks
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// services
|
// services
|
||||||
import IntegrationService from "services/integration";
|
import IntegrationService from "services/integration";
|
||||||
// components
|
// components
|
||||||
@ -35,6 +37,8 @@ const IntegrationGuide = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, provider } = router.query;
|
const { workspaceSlug, provider } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { data: importerServices } = useSWR(
|
const { data: importerServices } = useSWR(
|
||||||
workspaceSlug ? IMPORTER_SERVICES_LIST(workspaceSlug as string) : null,
|
workspaceSlug ? IMPORTER_SERVICES_LIST(workspaceSlug as string) : null,
|
||||||
workspaceSlug ? () => IntegrationService.getImporterServicesList(workspaceSlug as string) : null
|
workspaceSlug ? () => IntegrationService.getImporterServicesList(workspaceSlug as string) : null
|
||||||
@ -51,6 +55,7 @@ const IntegrationGuide = () => {
|
|||||||
isOpen={deleteImportModal}
|
isOpen={deleteImportModal}
|
||||||
handleClose={() => setDeleteImportModal(false)}
|
handleClose={() => setDeleteImportModal(false)}
|
||||||
data={importToDelete}
|
data={importToDelete}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<div className="h-full space-y-2">
|
<div className="h-full space-y-2">
|
||||||
{!provider && (
|
{!provider && (
|
||||||
@ -156,8 +161,8 @@ const IntegrationGuide = () => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{provider && provider === "github" && <GithubImporterRoot />}
|
{provider && provider === "github" && <GithubImporterRoot user={user} />}
|
||||||
{provider && provider === "jira" && <JiraImporterRoot />}
|
{provider && provider === "jira" && <JiraImporterRoot user={user} />}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -35,7 +35,7 @@ import {
|
|||||||
|
|
||||||
import JiraLogo from "public/services/jira.png";
|
import JiraLogo from "public/services/jira.png";
|
||||||
|
|
||||||
import { IJiraImporterForm } from "types";
|
import { ICurrentUserResponse, IJiraImporterForm } from "types";
|
||||||
|
|
||||||
const integrationWorkflowData: Array<{
|
const integrationWorkflowData: Array<{
|
||||||
title: string;
|
title: string;
|
||||||
@ -64,7 +64,11 @@ const integrationWorkflowData: Array<{
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const JiraImporterRoot = () => {
|
type Props = {
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const JiraImporterRoot: React.FC<Props> = ({ user }) => {
|
||||||
const [currentStep, setCurrentStep] = useState<IJiraIntegrationData>({
|
const [currentStep, setCurrentStep] = useState<IJiraIntegrationData>({
|
||||||
state: "import-configure",
|
state: "import-configure",
|
||||||
});
|
});
|
||||||
@ -85,7 +89,7 @@ export const JiraImporterRoot = () => {
|
|||||||
if (!workspaceSlug) return;
|
if (!workspaceSlug) return;
|
||||||
|
|
||||||
await jiraImporterService
|
await jiraImporterService
|
||||||
.createJiraImporter(workspaceSlug.toString(), data)
|
.createJiraImporter(workspaceSlug.toString(), data, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(IMPORTER_SERVICES_LIST(workspaceSlug.toString()));
|
mutate(IMPORTER_SERVICES_LIST(workspaceSlug.toString()));
|
||||||
router.push(`/${workspaceSlug}/settings/import-export`);
|
router.push(`/${workspaceSlug}/settings/import-export`);
|
||||||
|
@ -27,7 +27,7 @@ import { Loader } from "components/ui";
|
|||||||
import { renderShortNumericDateFormat, timeAgo } from "helpers/date-time.helper";
|
import { renderShortNumericDateFormat, timeAgo } from "helpers/date-time.helper";
|
||||||
import { addSpaceIfCamelCase } from "helpers/string.helper";
|
import { addSpaceIfCamelCase } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssueComment, IIssueLabels } from "types";
|
import { ICurrentUserResponse, IIssueComment, IIssueLabels } from "types";
|
||||||
import { PROJECT_ISSUES_ACTIVITY, PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
import { PROJECT_ISSUES_ACTIVITY, PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
||||||
import useEstimateOption from "hooks/use-estimate-option";
|
import useEstimateOption from "hooks/use-estimate-option";
|
||||||
|
|
||||||
@ -110,7 +110,11 @@ const activityDetails: {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const IssueActivitySection: React.FC = () => {
|
type Props = {
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const IssueActivitySection: React.FC<Props> = ({ user }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, issueId } = router.query;
|
const { workspaceSlug, projectId, issueId } = router.query;
|
||||||
|
|
||||||
@ -143,7 +147,8 @@ export const IssueActivitySection: React.FC = () => {
|
|||||||
projectId as string,
|
projectId as string,
|
||||||
issueId as string,
|
issueId as string,
|
||||||
comment.id,
|
comment.id,
|
||||||
comment
|
comment,
|
||||||
|
user
|
||||||
)
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutateIssueActivities();
|
mutateIssueActivities();
|
||||||
@ -160,7 +165,8 @@ export const IssueActivitySection: React.FC = () => {
|
|||||||
workspaceSlug as string,
|
workspaceSlug as string,
|
||||||
projectId as string,
|
projectId as string,
|
||||||
issueId as string,
|
issueId as string,
|
||||||
commentId
|
commentId,
|
||||||
|
user
|
||||||
)
|
)
|
||||||
.then(() => mutateIssueActivities());
|
.then(() => mutateIssueActivities());
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,7 @@ import useToast from "hooks/use-toast";
|
|||||||
// ui
|
// ui
|
||||||
import { Loader, SecondaryButton } from "components/ui";
|
import { Loader, SecondaryButton } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import type { IIssueComment } from "types";
|
import type { ICurrentUserResponse, IIssueComment } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys";
|
import { PROJECT_ISSUES_ACTIVITY } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -40,7 +40,11 @@ const defaultValues: Partial<IIssueComment> = {
|
|||||||
comment_html: "",
|
comment_html: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AddComment: React.FC = () => {
|
type Props = {
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const AddComment: React.FC<Props> = ({ user }) => {
|
||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
control,
|
control,
|
||||||
@ -67,7 +71,13 @@ export const AddComment: React.FC = () => {
|
|||||||
)
|
)
|
||||||
return;
|
return;
|
||||||
await issuesServices
|
await issuesServices
|
||||||
.createIssueComment(workspaceSlug as string, projectId as string, issueId as string, formData)
|
.createIssueComment(
|
||||||
|
workspaceSlug as string,
|
||||||
|
projectId as string,
|
||||||
|
issueId as string,
|
||||||
|
formData,
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
|
@ -17,7 +17,7 @@ import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
|||||||
// ui
|
// ui
|
||||||
import { SecondaryButton, DangerButton } from "components/ui";
|
import { SecondaryButton, DangerButton } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import type { IIssue } from "types";
|
import type { ICurrentUserResponse, IIssue } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import {
|
||||||
CYCLE_ISSUES_WITH_PARAMS,
|
CYCLE_ISSUES_WITH_PARAMS,
|
||||||
@ -30,9 +30,10 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
data: IIssue | null;
|
data: IIssue | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeleteIssueModal: React.FC<Props> = ({ isOpen, handleClose, data }) => {
|
export const DeleteIssueModal: React.FC<Props> = ({ isOpen, handleClose, data, user }) => {
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -57,7 +58,7 @@ export const DeleteIssueModal: React.FC<Props> = ({ isOpen, handleClose, data })
|
|||||||
if (!workspaceSlug || !projectId || !data) return;
|
if (!workspaceSlug || !projectId || !data) return;
|
||||||
|
|
||||||
await issueServices
|
await issueServices
|
||||||
.deleteIssue(workspaceSlug as string, projectId as string, data.id)
|
.deleteIssue(workspaceSlug as string, projectId as string, data.id, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (issueView === "calendar") {
|
if (issueView === "calendar") {
|
||||||
const calendarFetchKey = cycleId
|
const calendarFetchKey = cycleId
|
||||||
|
@ -39,7 +39,7 @@ import { SparklesIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
|||||||
// helpers
|
// helpers
|
||||||
import { cosineSimilarity } from "helpers/string.helper";
|
import { cosineSimilarity } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import type { IIssue } from "types";
|
import type { ICurrentUserResponse, IIssue } from "types";
|
||||||
// rich-text-editor
|
// rich-text-editor
|
||||||
const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), {
|
const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), {
|
||||||
ssr: false,
|
ssr: false,
|
||||||
@ -91,6 +91,7 @@ export interface IssueFormProps {
|
|||||||
setCreateMore: React.Dispatch<React.SetStateAction<boolean>>;
|
setCreateMore: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
status: boolean;
|
status: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const IssueForm: FC<IssueFormProps> = ({
|
export const IssueForm: FC<IssueFormProps> = ({
|
||||||
@ -103,6 +104,7 @@ export const IssueForm: FC<IssueFormProps> = ({
|
|||||||
setCreateMore,
|
setCreateMore,
|
||||||
handleClose,
|
handleClose,
|
||||||
status,
|
status,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
// states
|
// states
|
||||||
const [mostSimilarIssue, setMostSimilarIssue] = useState<IIssue | undefined>();
|
const [mostSimilarIssue, setMostSimilarIssue] = useState<IIssue | undefined>();
|
||||||
@ -177,10 +179,15 @@ export const IssueForm: FC<IssueFormProps> = ({
|
|||||||
setIAmFeelingLucky(true);
|
setIAmFeelingLucky(true);
|
||||||
|
|
||||||
aiService
|
aiService
|
||||||
.createGptTask(workspaceSlug as string, projectId as string, {
|
.createGptTask(
|
||||||
prompt: issueName,
|
workspaceSlug as string,
|
||||||
task: "Generate a proper description for this issue in context of a project management software.",
|
projectId as string,
|
||||||
})
|
{
|
||||||
|
prompt: issueName,
|
||||||
|
task: "Generate a proper description for this issue in context of a project management software.",
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.response === "")
|
if (res.response === "")
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
@ -227,12 +234,18 @@ export const IssueForm: FC<IssueFormProps> = ({
|
|||||||
isOpen={stateModal}
|
isOpen={stateModal}
|
||||||
handleClose={() => setStateModal(false)}
|
handleClose={() => setStateModal(false)}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
|
user={user}
|
||||||
|
/>
|
||||||
|
<CreateUpdateCycleModal
|
||||||
|
isOpen={cycleModal}
|
||||||
|
handleClose={() => setCycleModal(false)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<CreateUpdateCycleModal isOpen={cycleModal} handleClose={() => setCycleModal(false)} />
|
|
||||||
<CreateLabelModal
|
<CreateLabelModal
|
||||||
isOpen={labelModal}
|
isOpen={labelModal}
|
||||||
handleClose={() => setLabelModal(false)}
|
handleClose={() => setLabelModal(false)}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -102,9 +102,15 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = ({
|
|||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
await issuesService
|
await issuesService
|
||||||
.addIssueToCycle(workspaceSlug as string, activeProject ?? "", cycleId, {
|
.addIssueToCycle(
|
||||||
issues: [issueId],
|
workspaceSlug as string,
|
||||||
})
|
activeProject ?? "",
|
||||||
|
cycleId,
|
||||||
|
{
|
||||||
|
issues: [issueId],
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (cycleId) {
|
if (cycleId) {
|
||||||
mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId, params));
|
mutate(CYCLE_ISSUES_WITH_PARAMS(cycleId, params));
|
||||||
@ -117,9 +123,15 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = ({
|
|||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
await modulesService
|
await modulesService
|
||||||
.addIssuesToModule(workspaceSlug as string, activeProject ?? "", moduleId as string, {
|
.addIssuesToModule(
|
||||||
issues: [issueId],
|
workspaceSlug as string,
|
||||||
})
|
activeProject ?? "",
|
||||||
|
moduleId as string,
|
||||||
|
{
|
||||||
|
issues: [issueId],
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (moduleId) {
|
if (moduleId) {
|
||||||
mutate(MODULE_ISSUES_WITH_PARAMS(moduleId as string, params));
|
mutate(MODULE_ISSUES_WITH_PARAMS(moduleId as string, params));
|
||||||
@ -148,7 +160,7 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = ({
|
|||||||
if (!workspaceSlug) return;
|
if (!workspaceSlug) return;
|
||||||
|
|
||||||
await issuesService
|
await issuesService
|
||||||
.createIssues(workspaceSlug as string, activeProject ?? "", payload)
|
.createIssues(workspaceSlug as string, activeProject ?? "", payload, user)
|
||||||
.then(async (res) => {
|
.then(async (res) => {
|
||||||
mutate(PROJECT_ISSUES_LIST_WITH_PARAMS(activeProject ?? "", params));
|
mutate(PROJECT_ISSUES_LIST_WITH_PARAMS(activeProject ?? "", params));
|
||||||
if (payload.cycle && payload.cycle !== "") await addIssueToCycle(res.id, payload.cycle);
|
if (payload.cycle && payload.cycle !== "") await addIssueToCycle(res.id, payload.cycle);
|
||||||
@ -180,7 +192,7 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = ({
|
|||||||
|
|
||||||
const updateIssue = async (payload: Partial<IIssue>) => {
|
const updateIssue = async (payload: Partial<IIssue>) => {
|
||||||
await issuesService
|
await issuesService
|
||||||
.updateIssue(workspaceSlug as string, activeProject ?? "", data?.id ?? "", payload)
|
.updateIssue(workspaceSlug as string, activeProject ?? "", data?.id ?? "", payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (isUpdatingSingleIssue) {
|
if (isUpdatingSingleIssue) {
|
||||||
mutate<IIssue>(PROJECT_ISSUES_DETAILS, (prevData) => ({ ...prevData, ...res }), false);
|
mutate<IIssue>(PROJECT_ISSUES_DETAILS, (prevData) => ({ ...prevData, ...res }), false);
|
||||||
@ -261,6 +273,7 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = ({
|
|||||||
projectId={activeProject ?? ""}
|
projectId={activeProject ?? ""}
|
||||||
setActiveProject={setActiveProject}
|
setActiveProject={setActiveProject}
|
||||||
status={data ? true : false}
|
status={data ? true : false}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</Dialog.Panel>
|
</Dialog.Panel>
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
|
@ -7,6 +7,7 @@ import { mutate } from "swr";
|
|||||||
|
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// services
|
// services
|
||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
// components
|
// components
|
||||||
@ -37,6 +38,9 @@ type Props = {
|
|||||||
export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId }) => {
|
export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const partialUpdateIssue = useCallback(
|
const partialUpdateIssue = useCallback(
|
||||||
@ -55,7 +59,7 @@ export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId
|
|||||||
);
|
);
|
||||||
|
|
||||||
issuesService
|
issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, issueId, formData)
|
.patchIssue(workspaceSlug as string, projectId as string, issueId, formData, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate(USER_ISSUE(workspaceSlug as string));
|
mutate(USER_ISSUE(workspaceSlug as string));
|
||||||
})
|
})
|
||||||
@ -110,6 +114,7 @@ export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId
|
|||||||
<ViewPrioritySelect
|
<ViewPrioritySelect
|
||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -117,6 +122,7 @@ export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId
|
|||||||
<ViewStateSelect
|
<ViewStateSelect
|
||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -124,6 +130,7 @@ export const MyIssuesListItem: React.FC<Props> = ({ issue, properties, projectId
|
|||||||
<ViewDueDateSelect
|
<ViewDueDateSelect
|
||||||
issue={issue}
|
issue={issue}
|
||||||
partialUpdateIssue={partialUpdateIssue}
|
partialUpdateIssue={partialUpdateIssue}
|
||||||
|
user={user}
|
||||||
isNotAllowed={isNotAllowed}
|
isNotAllowed={isNotAllowed}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -12,6 +12,7 @@ import { TwitterPicker } from "react-color";
|
|||||||
import { Popover, Listbox, Transition } from "@headlessui/react";
|
import { Popover, Listbox, Transition } from "@headlessui/react";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// services
|
// services
|
||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
import modulesService from "services/modules.service";
|
import modulesService from "services/modules.service";
|
||||||
@ -76,6 +77,8 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, issueId } = router.query;
|
const { workspaceSlug, projectId, issueId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { memberRole } = useProjectMyMembership();
|
const { memberRole } = useProjectMyMembership();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
@ -110,7 +113,7 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
|
|||||||
const handleNewLabel = (formData: any) => {
|
const handleNewLabel = (formData: any) => {
|
||||||
if (!workspaceSlug || !projectId || isSubmitting) return;
|
if (!workspaceSlug || !projectId || isSubmitting) return;
|
||||||
issuesService
|
issuesService
|
||||||
.createIssueLabel(workspaceSlug as string, projectId as string, formData)
|
.createIssueLabel(workspaceSlug as string, projectId as string, formData, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
issueLabelMutate((prevData) => [...(prevData ?? []), res], false);
|
issueLabelMutate((prevData) => [...(prevData ?? []), res], false);
|
||||||
@ -124,9 +127,15 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
|
|||||||
if (!workspaceSlug || !projectId || !issueDetail) return;
|
if (!workspaceSlug || !projectId || !issueDetail) return;
|
||||||
|
|
||||||
issuesService
|
issuesService
|
||||||
.addIssueToCycle(workspaceSlug as string, projectId as string, cycleDetails.id, {
|
.addIssueToCycle(
|
||||||
issues: [issueDetail.id],
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
cycleDetails.id,
|
||||||
|
{
|
||||||
|
issues: [issueDetail.id],
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate(ISSUE_DETAILS(issueId as string));
|
mutate(ISSUE_DETAILS(issueId as string));
|
||||||
});
|
});
|
||||||
@ -139,9 +148,15 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
|
|||||||
if (!workspaceSlug || !projectId || !issueDetail) return;
|
if (!workspaceSlug || !projectId || !issueDetail) return;
|
||||||
|
|
||||||
modulesService
|
modulesService
|
||||||
.addIssuesToModule(workspaceSlug as string, projectId as string, moduleDetail.id, {
|
.addIssuesToModule(
|
||||||
issues: [issueDetail.id],
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
moduleDetail.id,
|
||||||
|
{
|
||||||
|
issues: [issueDetail.id],
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate(ISSUE_DETAILS(issueId as string));
|
mutate(ISSUE_DETAILS(issueId as string));
|
||||||
});
|
});
|
||||||
@ -228,6 +243,7 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
|
|||||||
handleClose={() => setDeleteIssueModal(false)}
|
handleClose={() => setDeleteIssueModal(false)}
|
||||||
isOpen={deleteIssueModal}
|
isOpen={deleteIssueModal}
|
||||||
data={issueDetail ?? null}
|
data={issueDetail ?? null}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<div className="sticky top-5 w-full divide-y-2 divide-brand-base">
|
<div className="sticky top-5 w-full divide-y-2 divide-brand-base">
|
||||||
<div className="flex items-center justify-between pb-3">
|
<div className="flex items-center justify-between pb-3">
|
||||||
|
@ -21,15 +21,16 @@ import { ChevronRightIcon, PlusIcon, XMarkIcon } from "@heroicons/react/24/outli
|
|||||||
// helpers
|
// helpers
|
||||||
import { orderArrayBy } from "helpers/array.helper";
|
import { orderArrayBy } from "helpers/array.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssue, ISubIssueResponse } from "types";
|
import { ICurrentUserResponse, IIssue, ISubIssueResponse } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_ISSUES_LIST, SUB_ISSUES } from "constants/fetch-keys";
|
import { PROJECT_ISSUES_LIST, SUB_ISSUES } from "constants/fetch-keys";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
parentIssue: IIssue;
|
parentIssue: IIssue;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SubIssuesList: FC<Props> = ({ parentIssue }) => {
|
export const SubIssuesList: FC<Props> = ({ parentIssue, user }) => {
|
||||||
// states
|
// states
|
||||||
const [createIssueModal, setCreateIssueModal] = useState(false);
|
const [createIssueModal, setCreateIssueModal] = useState(false);
|
||||||
const [subIssuesListModal, setSubIssuesListModal] = useState(false);
|
const [subIssuesListModal, setSubIssuesListModal] = useState(false);
|
||||||
@ -134,7 +135,7 @@ export const SubIssuesList: FC<Props> = ({ parentIssue }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
issuesService
|
issuesService
|
||||||
.patchIssue(workspaceSlug.toString(), projectId.toString(), issueId, { parent: null })
|
.patchIssue(workspaceSlug.toString(), projectId.toString(), issueId, { parent: null }, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate(SUB_ISSUES(parentIssue.id ?? ""));
|
mutate(SUB_ISSUES(parentIssue.id ?? ""));
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ import { AssigneesList, Avatar, CustomSearchSelect, Tooltip } from "components/u
|
|||||||
// icons
|
// icons
|
||||||
import { UserGroupIcon } from "@heroicons/react/24/outline";
|
import { UserGroupIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_MEMBERS } from "constants/fetch-keys";
|
import { PROJECT_MEMBERS } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ type Props = {
|
|||||||
position?: "left" | "right";
|
position?: "left" | "right";
|
||||||
selfPositioned?: boolean;
|
selfPositioned?: boolean;
|
||||||
tooltipPosition?: "left" | "right";
|
tooltipPosition?: "left" | "right";
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
isNotAllowed: boolean;
|
isNotAllowed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -31,6 +32,7 @@ export const ViewAssigneeSelect: React.FC<Props> = ({
|
|||||||
position = "left",
|
position = "left",
|
||||||
selfPositioned = false,
|
selfPositioned = false,
|
||||||
tooltipPosition = "right",
|
tooltipPosition = "right",
|
||||||
|
user,
|
||||||
isNotAllowed,
|
isNotAllowed,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -83,7 +85,8 @@ export const ViewAssigneeSelect: React.FC<Props> = ({
|
|||||||
projectName: issue.project_detail.name,
|
projectName: issue.project_detail.name,
|
||||||
issueId: issue.id,
|
issueId: issue.id,
|
||||||
},
|
},
|
||||||
"ISSUE_PROPERTY_UPDATE_ASSIGNEE"
|
"ISSUE_PROPERTY_UPDATE_ASSIGNEE",
|
||||||
|
user
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
options={options}
|
options={options}
|
||||||
|
@ -7,15 +7,21 @@ import { findHowManyDaysLeft } from "helpers/date-time.helper";
|
|||||||
// services
|
// services
|
||||||
import trackEventServices from "services/track-event.service";
|
import trackEventServices from "services/track-event.service";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
issue: IIssue;
|
issue: IIssue;
|
||||||
partialUpdateIssue: (formData: Partial<IIssue>, issueId: string) => void;
|
partialUpdateIssue: (formData: Partial<IIssue>, issueId: string) => void;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
isNotAllowed: boolean;
|
isNotAllowed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ViewDueDateSelect: React.FC<Props> = ({ issue, partialUpdateIssue, isNotAllowed }) => {
|
export const ViewDueDateSelect: React.FC<Props> = ({
|
||||||
|
issue,
|
||||||
|
partialUpdateIssue,
|
||||||
|
user,
|
||||||
|
isNotAllowed,
|
||||||
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
@ -51,7 +57,8 @@ export const ViewDueDateSelect: React.FC<Props> = ({ issue, partialUpdateIssue,
|
|||||||
projectName: issue.project_detail.name,
|
projectName: issue.project_detail.name,
|
||||||
issueId: issue.id,
|
issueId: issue.id,
|
||||||
},
|
},
|
||||||
"ISSUE_PROPERTY_UPDATE_DUE_DATE"
|
"ISSUE_PROPERTY_UPDATE_DUE_DATE",
|
||||||
|
user
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
className={issue?.target_date ? "w-[6.5rem]" : "w-[5rem] text-center"}
|
className={issue?.target_date ? "w-[6.5rem]" : "w-[5rem] text-center"}
|
||||||
|
@ -11,13 +11,14 @@ import { CustomSelect, Tooltip } from "components/ui";
|
|||||||
// icons
|
// icons
|
||||||
import { PlayIcon } from "@heroicons/react/24/outline";
|
import { PlayIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
issue: IIssue;
|
issue: IIssue;
|
||||||
partialUpdateIssue: (formData: Partial<IIssue>, issueId: string) => void;
|
partialUpdateIssue: (formData: Partial<IIssue>, issueId: string) => void;
|
||||||
position?: "left" | "right";
|
position?: "left" | "right";
|
||||||
selfPositioned?: boolean;
|
selfPositioned?: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
isNotAllowed: boolean;
|
isNotAllowed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ export const ViewEstimateSelect: React.FC<Props> = ({
|
|||||||
partialUpdateIssue,
|
partialUpdateIssue,
|
||||||
position = "left",
|
position = "left",
|
||||||
selfPositioned = false,
|
selfPositioned = false,
|
||||||
|
user,
|
||||||
isNotAllowed,
|
isNotAllowed,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -51,7 +53,8 @@ export const ViewEstimateSelect: React.FC<Props> = ({
|
|||||||
projectName: issue.project_detail.name,
|
projectName: issue.project_detail.name,
|
||||||
issueId: issue.id,
|
issueId: issue.id,
|
||||||
},
|
},
|
||||||
"ISSUE_PROPERTY_UPDATE_ESTIMATE"
|
"ISSUE_PROPERTY_UPDATE_ESTIMATE",
|
||||||
|
user
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
label={
|
label={
|
||||||
|
@ -7,7 +7,7 @@ import { CustomSelect, Tooltip } from "components/ui";
|
|||||||
// icons
|
// icons
|
||||||
import { getPriorityIcon } from "components/icons/priority-icon";
|
import { getPriorityIcon } from "components/icons/priority-icon";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
// constants
|
// constants
|
||||||
import { PRIORITIES } from "constants/project";
|
import { PRIORITIES } from "constants/project";
|
||||||
// services
|
// services
|
||||||
@ -18,6 +18,7 @@ type Props = {
|
|||||||
partialUpdateIssue: (formData: Partial<IIssue>, issueId: string) => void;
|
partialUpdateIssue: (formData: Partial<IIssue>, issueId: string) => void;
|
||||||
position?: "left" | "right";
|
position?: "left" | "right";
|
||||||
selfPositioned?: boolean;
|
selfPositioned?: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
isNotAllowed: boolean;
|
isNotAllowed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ export const ViewPrioritySelect: React.FC<Props> = ({
|
|||||||
partialUpdateIssue,
|
partialUpdateIssue,
|
||||||
position = "left",
|
position = "left",
|
||||||
selfPositioned = false,
|
selfPositioned = false,
|
||||||
|
user,
|
||||||
isNotAllowed,
|
isNotAllowed,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -45,7 +47,8 @@ export const ViewPrioritySelect: React.FC<Props> = ({
|
|||||||
projectName: issue.project_detail.name,
|
projectName: issue.project_detail.name,
|
||||||
issueId: issue.id,
|
issueId: issue.id,
|
||||||
},
|
},
|
||||||
"ISSUE_PROPERTY_UPDATE_PRIORITY"
|
"ISSUE_PROPERTY_UPDATE_PRIORITY",
|
||||||
|
user
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
maxHeight="md"
|
maxHeight="md"
|
||||||
|
@ -13,7 +13,7 @@ import { getStateGroupIcon } from "components/icons";
|
|||||||
import { addSpaceIfCamelCase } from "helpers/string.helper";
|
import { addSpaceIfCamelCase } from "helpers/string.helper";
|
||||||
import { getStatesList } from "helpers/state.helper";
|
import { getStatesList } from "helpers/state.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssue } from "types";
|
import { ICurrentUserResponse, IIssue } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { STATES_LIST } from "constants/fetch-keys";
|
import { STATES_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ type Props = {
|
|||||||
partialUpdateIssue: (formData: Partial<IIssue>, issueId: string) => void;
|
partialUpdateIssue: (formData: Partial<IIssue>, issueId: string) => void;
|
||||||
position?: "left" | "right";
|
position?: "left" | "right";
|
||||||
selfPositioned?: boolean;
|
selfPositioned?: boolean;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
isNotAllowed: boolean;
|
isNotAllowed: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ export const ViewStateSelect: React.FC<Props> = ({
|
|||||||
partialUpdateIssue,
|
partialUpdateIssue,
|
||||||
position = "left",
|
position = "left",
|
||||||
selfPositioned = false,
|
selfPositioned = false,
|
||||||
|
user,
|
||||||
isNotAllowed,
|
isNotAllowed,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -77,21 +79,25 @@ export const ViewStateSelect: React.FC<Props> = ({
|
|||||||
projectName: issue.project_detail.name,
|
projectName: issue.project_detail.name,
|
||||||
issueId: issue.id,
|
issueId: issue.id,
|
||||||
},
|
},
|
||||||
"ISSUE_PROPERTY_UPDATE_STATE"
|
"ISSUE_PROPERTY_UPDATE_STATE",
|
||||||
|
user
|
||||||
);
|
);
|
||||||
|
|
||||||
const oldState = states.find((s) => s.id === issue.state);
|
const oldState = states.find((s) => s.id === issue.state);
|
||||||
const newState = states.find((s) => s.id === data);
|
const newState = states.find((s) => s.id === data);
|
||||||
|
|
||||||
if (oldState?.group !== "completed" && newState?.group !== "completed") {
|
if (oldState?.group !== "completed" && newState?.group !== "completed") {
|
||||||
trackEventServices.trackIssueMarkedAsDoneEvent({
|
trackEventServices.trackIssueMarkedAsDoneEvent(
|
||||||
workspaceSlug: issue.workspace_detail.slug,
|
{
|
||||||
workspaceId: issue.workspace_detail.id,
|
workspaceSlug: issue.workspace_detail.slug,
|
||||||
projectId: issue.project_detail.id,
|
workspaceId: issue.workspace_detail.id,
|
||||||
projectIdentifier: issue.project_detail.identifier,
|
projectId: issue.project_detail.id,
|
||||||
projectName: issue.project_detail.name,
|
projectIdentifier: issue.project_detail.identifier,
|
||||||
issueId: issue.id,
|
projectName: issue.project_detail.name,
|
||||||
});
|
issueId: issue.id,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
options={options}
|
options={options}
|
||||||
|
@ -17,7 +17,7 @@ import { Input, PrimaryButton, SecondaryButton } from "components/ui";
|
|||||||
// icons
|
// icons
|
||||||
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import type { IIssueLabels, IState } from "types";
|
import type { ICurrentUserResponse, IIssueLabels, IState } from "types";
|
||||||
// constants
|
// constants
|
||||||
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -26,6 +26,7 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultValues: Partial<IState> = {
|
const defaultValues: Partial<IState> = {
|
||||||
@ -33,7 +34,7 @@ const defaultValues: Partial<IState> = {
|
|||||||
color: "#858E96",
|
color: "#858E96",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CreateLabelModal: React.FC<Props> = ({ isOpen, projectId, handleClose }) => {
|
export const CreateLabelModal: React.FC<Props> = ({ isOpen, projectId, handleClose, user }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ export const CreateLabelModal: React.FC<Props> = ({ isOpen, projectId, handleClo
|
|||||||
if (!workspaceSlug) return;
|
if (!workspaceSlug) return;
|
||||||
|
|
||||||
await issuesService
|
await issuesService
|
||||||
.createIssueLabel(workspaceSlug as string, projectId as string, formData)
|
.createIssueLabel(workspaceSlug as string, projectId as string, formData, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IIssueLabels[]>(
|
mutate<IIssueLabels[]>(
|
||||||
PROJECT_ISSUE_LABELS(projectId),
|
PROJECT_ISSUE_LABELS(projectId),
|
||||||
|
@ -6,6 +6,8 @@ import { mutate } from "swr";
|
|||||||
|
|
||||||
// react-hook-form
|
// react-hook-form
|
||||||
import { Controller, SubmitHandler, useForm } from "react-hook-form";
|
import { Controller, SubmitHandler, useForm } from "react-hook-form";
|
||||||
|
// hooks
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// react-color
|
// react-color
|
||||||
import { TwitterPicker } from "react-color";
|
import { TwitterPicker } from "react-color";
|
||||||
// headless ui
|
// headless ui
|
||||||
@ -42,6 +44,8 @@ export const CreateUpdateLabelInline = forwardRef<Ref, Props>(function CreateUpd
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
control,
|
control,
|
||||||
@ -58,7 +62,7 @@ export const CreateUpdateLabelInline = forwardRef<Ref, Props>(function CreateUpd
|
|||||||
if (!workspaceSlug || !projectId || isSubmitting) return;
|
if (!workspaceSlug || !projectId || isSubmitting) return;
|
||||||
|
|
||||||
await issuesService
|
await issuesService
|
||||||
.createIssueLabel(workspaceSlug as string, projectId as string, formData)
|
.createIssueLabel(workspaceSlug as string, projectId as string, formData, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IIssueLabels[]>(
|
mutate<IIssueLabels[]>(
|
||||||
PROJECT_ISSUE_LABELS(projectId as string),
|
PROJECT_ISSUE_LABELS(projectId as string),
|
||||||
@ -78,7 +82,8 @@ export const CreateUpdateLabelInline = forwardRef<Ref, Props>(function CreateUpd
|
|||||||
workspaceSlug as string,
|
workspaceSlug as string,
|
||||||
projectId as string,
|
projectId as string,
|
||||||
labelToUpdate?.id ?? "",
|
labelToUpdate?.id ?? "",
|
||||||
formData
|
formData,
|
||||||
|
user
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
reset(defaultValues);
|
reset(defaultValues);
|
||||||
|
@ -15,7 +15,7 @@ import useToast from "hooks/use-toast";
|
|||||||
// ui
|
// ui
|
||||||
import { DangerButton, SecondaryButton } from "components/ui";
|
import { DangerButton, SecondaryButton } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import type { IIssueLabels } from "types";
|
import type { ICurrentUserResponse, IIssueLabels } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -23,9 +23,10 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
data: IIssueLabels | null;
|
data: IIssueLabels | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeleteLabelModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
|
export const DeleteLabelModal: React.FC<Props> = ({ isOpen, onClose, data, user }) => {
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -50,7 +51,7 @@ export const DeleteLabelModal: React.FC<Props> = ({ isOpen, onClose, data }) =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
await issuesService
|
await issuesService
|
||||||
.deleteIssueLabel(workspaceSlug.toString(), projectId.toString(), data.id)
|
.deleteIssueLabel(workspaceSlug.toString(), projectId.toString(), data.id, user)
|
||||||
.then(() => handleClose())
|
.then(() => handleClose())
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
setIsDeleteLoading(false);
|
setIsDeleteLoading(false);
|
||||||
|
@ -11,7 +11,7 @@ import { RectangleStackIcon, MagnifyingGlassIcon } from "@heroicons/react/24/out
|
|||||||
// services
|
// services
|
||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
// types
|
// types
|
||||||
import { IIssueLabels } from "types";
|
import { ICurrentUserResponse, IIssueLabels } from "types";
|
||||||
// constants
|
// constants
|
||||||
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -19,9 +19,10 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
parent: IIssueLabels | undefined;
|
parent: IIssueLabels | undefined;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LabelsListModal: React.FC<Props> = ({ isOpen, handleClose, parent }) => {
|
export const LabelsListModal: React.FC<Props> = ({ isOpen, handleClose, parent, user }) => {
|
||||||
const [query, setQuery] = useState("");
|
const [query, setQuery] = useState("");
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -58,9 +59,15 @@ export const LabelsListModal: React.FC<Props> = ({ isOpen, handleClose, parent }
|
|||||||
);
|
);
|
||||||
|
|
||||||
await issuesService
|
await issuesService
|
||||||
.patchIssueLabel(workspaceSlug as string, projectId as string, label.id, {
|
.patchIssueLabel(
|
||||||
parent: parent?.id ?? "",
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
label.id,
|
||||||
|
{
|
||||||
|
parent: parent?.id ?? "",
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => mutate());
|
.then(() => mutate());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import {
|
|||||||
TrashIcon,
|
TrashIcon,
|
||||||
} from "@heroicons/react/24/outline";
|
} from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import { IIssueLabels } from "types";
|
import { ICurrentUserResponse, IIssueLabels } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
import { PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -30,6 +30,7 @@ type Props = {
|
|||||||
addLabelToGroup: (parentLabel: IIssueLabels) => void;
|
addLabelToGroup: (parentLabel: IIssueLabels) => void;
|
||||||
editLabel: (label: IIssueLabels) => void;
|
editLabel: (label: IIssueLabels) => void;
|
||||||
handleLabelDelete: () => void;
|
handleLabelDelete: () => void;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SingleLabelGroup: React.FC<Props> = ({
|
export const SingleLabelGroup: React.FC<Props> = ({
|
||||||
@ -38,6 +39,7 @@ export const SingleLabelGroup: React.FC<Props> = ({
|
|||||||
addLabelToGroup,
|
addLabelToGroup,
|
||||||
editLabel,
|
editLabel,
|
||||||
handleLabelDelete,
|
handleLabelDelete,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
@ -57,9 +59,15 @@ export const SingleLabelGroup: React.FC<Props> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
issuesService
|
issuesService
|
||||||
.patchIssueLabel(workspaceSlug as string, projectId as string, label.id, {
|
.patchIssueLabel(
|
||||||
parent: null,
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
label.id,
|
||||||
|
{
|
||||||
|
parent: null,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(PROJECT_ISSUE_LABELS(projectId as string));
|
mutate(PROJECT_ISSUE_LABELS(projectId as string));
|
||||||
});
|
});
|
||||||
|
@ -15,7 +15,7 @@ import { SecondaryButton, DangerButton } from "components/ui";
|
|||||||
// icons
|
// icons
|
||||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import type { IModule } from "types";
|
import type { ICurrentUserResponse, IModule } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { MODULE_LIST } from "constants/fetch-keys";
|
import { MODULE_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -23,9 +23,10 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
data?: IModule;
|
data?: IModule;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeleteModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data }) => {
|
export const DeleteModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, user }) => {
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -50,7 +51,7 @@ export const DeleteModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data })
|
|||||||
);
|
);
|
||||||
|
|
||||||
await modulesService
|
await modulesService
|
||||||
.deleteModule(workspaceSlug as string, projectId as string, data.id)
|
.deleteModule(workspaceSlug as string, projectId as string, data.id, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
if (moduleId) router.push(`/${workspaceSlug}/projects/${data.project}/modules`);
|
if (moduleId) router.push(`/${workspaceSlug}/projects/${data.project}/modules`);
|
||||||
handleClose();
|
handleClose();
|
||||||
|
@ -15,7 +15,7 @@ import modulesService from "services/modules.service";
|
|||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
// types
|
// types
|
||||||
import type { IModule } from "types";
|
import type { ICurrentUserResponse, IModule } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { MODULE_LIST } from "constants/fetch-keys";
|
import { MODULE_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -23,6 +23,7 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
data?: IModule;
|
data?: IModule;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultValues: Partial<IModule> = {
|
const defaultValues: Partial<IModule> = {
|
||||||
@ -33,7 +34,7 @@ const defaultValues: Partial<IModule> = {
|
|||||||
members_list: [],
|
members_list: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data }) => {
|
export const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, data, user }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ export const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, da
|
|||||||
|
|
||||||
const createModule = async (payload: Partial<IModule>) => {
|
const createModule = async (payload: Partial<IModule>) => {
|
||||||
await modulesService
|
await modulesService
|
||||||
.createModule(workspaceSlug as string, projectId as string, payload)
|
.createModule(workspaceSlug as string, projectId as string, payload, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(MODULE_LIST(projectId as string));
|
mutate(MODULE_LIST(projectId as string));
|
||||||
handleClose();
|
handleClose();
|
||||||
@ -72,7 +73,7 @@ export const CreateUpdateModuleModal: React.FC<Props> = ({ isOpen, setIsOpen, da
|
|||||||
|
|
||||||
const updateModule = async (payload: Partial<IModule>) => {
|
const updateModule = async (payload: Partial<IModule>) => {
|
||||||
await modulesService
|
await modulesService
|
||||||
.updateModule(workspaceSlug as string, projectId as string, data?.id ?? "", payload)
|
.updateModule(workspaceSlug as string, projectId as string, data?.id ?? "", payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IModule[]>(
|
mutate<IModule[]>(
|
||||||
MODULE_LIST(projectId as string),
|
MODULE_LIST(projectId as string),
|
||||||
|
@ -37,7 +37,7 @@ import { LinkIcon } from "@heroicons/react/20/solid";
|
|||||||
import { renderDateFormat, renderShortDate } from "helpers/date-time.helper";
|
import { renderDateFormat, renderShortDate } from "helpers/date-time.helper";
|
||||||
import { capitalizeFirstLetter, copyTextToClipboard } from "helpers/string.helper";
|
import { capitalizeFirstLetter, copyTextToClipboard } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssue, IModule, ModuleLink } from "types";
|
import { ICurrentUserResponse, IIssue, IModule, ModuleLink } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { MODULE_DETAILS } from "constants/fetch-keys";
|
import { MODULE_DETAILS } from "constants/fetch-keys";
|
||||||
// constant
|
// constant
|
||||||
@ -56,9 +56,16 @@ type Props = {
|
|||||||
module?: IModule;
|
module?: IModule;
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
moduleIssues?: IIssue[];
|
moduleIssues?: IIssue[];
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ModuleDetailsSidebar: React.FC<Props> = ({ issues, module, isOpen, moduleIssues }) => {
|
export const ModuleDetailsSidebar: React.FC<Props> = ({
|
||||||
|
issues,
|
||||||
|
module,
|
||||||
|
isOpen,
|
||||||
|
moduleIssues,
|
||||||
|
user,
|
||||||
|
}) => {
|
||||||
const [moduleDeleteModal, setModuleDeleteModal] = useState(false);
|
const [moduleDeleteModal, setModuleDeleteModal] = useState(false);
|
||||||
const [moduleLinkModal, setModuleLinkModal] = useState(false);
|
const [moduleLinkModal, setModuleLinkModal] = useState(false);
|
||||||
|
|
||||||
@ -86,7 +93,7 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({ issues, module, isOpen,
|
|||||||
);
|
);
|
||||||
|
|
||||||
modulesService
|
modulesService
|
||||||
.patchModule(workspaceSlug as string, projectId as string, moduleId as string, data)
|
.patchModule(workspaceSlug as string, projectId as string, moduleId as string, data, user)
|
||||||
.then(() => mutate(MODULE_DETAILS(moduleId as string)))
|
.then(() => mutate(MODULE_DETAILS(moduleId as string)))
|
||||||
.catch((e) => console.log(e));
|
.catch((e) => console.log(e));
|
||||||
};
|
};
|
||||||
@ -181,6 +188,7 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({ issues, module, isOpen,
|
|||||||
isOpen={moduleDeleteModal}
|
isOpen={moduleDeleteModal}
|
||||||
setIsOpen={setModuleDeleteModal}
|
setIsOpen={setModuleDeleteModal}
|
||||||
data={module}
|
data={module}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={`fixed top-[66px] ${
|
className={`fixed top-[66px] ${
|
||||||
|
@ -27,16 +27,17 @@ import { CalendarMonthIcon, TargetIcon } from "components/icons";
|
|||||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||||
import { renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
import { renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
||||||
// types
|
// types
|
||||||
import { IModule } from "types";
|
import { ICurrentUserResponse, IModule } from "types";
|
||||||
// fetch-key
|
// fetch-key
|
||||||
import { MODULE_LIST } from "constants/fetch-keys";
|
import { MODULE_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
module: IModule;
|
module: IModule;
|
||||||
handleEditModule: () => void;
|
handleEditModule: () => void;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SingleModuleCard: React.FC<Props> = ({ module, handleEditModule }) => {
|
export const SingleModuleCard: React.FC<Props> = ({ module, handleEditModule, user }) => {
|
||||||
const [moduleDeleteModal, setModuleDeleteModal] = useState(false);
|
const [moduleDeleteModal, setModuleDeleteModal] = useState(false);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -128,6 +129,7 @@ export const SingleModuleCard: React.FC<Props> = ({ module, handleEditModule })
|
|||||||
isOpen={moduleDeleteModal}
|
isOpen={moduleDeleteModal}
|
||||||
setIsOpen={setModuleDeleteModal}
|
setIsOpen={setModuleDeleteModal}
|
||||||
data={module}
|
data={module}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<div className="flex flex-col divide-y divide-brand-base overflow-hidden rounded-[10px] border border-brand-base bg-brand-base text-xs">
|
<div className="flex flex-col divide-y divide-brand-base overflow-hidden rounded-[10px] border border-brand-base bg-brand-base text-xs">
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
|
@ -2,16 +2,17 @@
|
|||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
import workspaceService from "services/workspace.service";
|
import workspaceService from "services/workspace.service";
|
||||||
import { IUser } from "types";
|
import { ICurrentUserResponse, IUser } from "types";
|
||||||
// ui components
|
// ui components
|
||||||
import { MultiInput, PrimaryButton, SecondaryButton } from "components/ui";
|
import { MultiInput, PrimaryButton, SecondaryButton } from "components/ui";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
setStep: React.Dispatch<React.SetStateAction<number>>;
|
setStep: React.Dispatch<React.SetStateAction<number>>;
|
||||||
workspace: any;
|
workspace: any;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const InviteMembers: React.FC<Props> = ({ setStep, workspace }) => {
|
export const InviteMembers: React.FC<Props> = ({ setStep, workspace, user }) => {
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -23,7 +24,7 @@ export const InviteMembers: React.FC<Props> = ({ setStep, workspace }) => {
|
|||||||
|
|
||||||
const onSubmit = async (formData: IUser) => {
|
const onSubmit = async (formData: IUser) => {
|
||||||
await workspaceService
|
await workspaceService
|
||||||
.inviteWorkspace(workspace.slug, formData)
|
.inviteWorkspace(workspace.slug, formData, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "success",
|
type: "success",
|
||||||
|
@ -9,7 +9,7 @@ import { Tab } from "@headlessui/react";
|
|||||||
// services
|
// services
|
||||||
import workspaceService from "services/workspace.service";
|
import workspaceService from "services/workspace.service";
|
||||||
// types
|
// types
|
||||||
import { IWorkspaceMemberInvitation } from "types";
|
import { ICurrentUserResponse, IWorkspaceMemberInvitation } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { USER_WORKSPACE_INVITATIONS } from "constants/fetch-keys";
|
import { USER_WORKSPACE_INVITATIONS } from "constants/fetch-keys";
|
||||||
// constants
|
// constants
|
||||||
@ -21,9 +21,10 @@ import { getFirstCharacters, truncateText } from "helpers/string.helper";
|
|||||||
type Props = {
|
type Props = {
|
||||||
setStep: React.Dispatch<React.SetStateAction<number>>;
|
setStep: React.Dispatch<React.SetStateAction<number>>;
|
||||||
setWorkspace: React.Dispatch<React.SetStateAction<any>>;
|
setWorkspace: React.Dispatch<React.SetStateAction<any>>;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Workspace: React.FC<Props> = ({ setStep, setWorkspace }) => {
|
export const Workspace: React.FC<Props> = ({ setStep, setWorkspace, user }) => {
|
||||||
const [isJoiningWorkspaces, setIsJoiningWorkspaces] = useState(false);
|
const [isJoiningWorkspaces, setIsJoiningWorkspaces] = useState(false);
|
||||||
const [invitationsRespond, setInvitationsRespond] = useState<string[]>([]);
|
const [invitationsRespond, setInvitationsRespond] = useState<string[]>([]);
|
||||||
const [defaultValues, setDefaultValues] = useState({
|
const [defaultValues, setDefaultValues] = useState({
|
||||||
@ -98,7 +99,7 @@ export const Workspace: React.FC<Props> = ({ setStep, setWorkspace }) => {
|
|||||||
>
|
>
|
||||||
<Tab.List as="div" className="flex flex-col gap-3 px-7 pt-7 pb-3.5">
|
<Tab.List as="div" className="flex flex-col gap-3 px-7 pt-7 pb-3.5">
|
||||||
<div className="flex flex-col gap-2 justify-center">
|
<div className="flex flex-col gap-2 justify-center">
|
||||||
<h3 className="text-base font-semibold text-brand-base">Workspaces</h3>
|
<h3 className="text-base font-semibold text-brand-base">Workspace</h3>
|
||||||
<p className="text-sm text-brand-secondary">
|
<p className="text-sm text-brand-secondary">
|
||||||
Create or join the workspace to get started with Plane.
|
Create or join the workspace to get started with Plane.
|
||||||
</p>
|
</p>
|
||||||
@ -161,7 +162,10 @@ export const Workspace: React.FC<Props> = ({ setStep, setWorkspace }) => {
|
|||||||
{truncateText(invitation.workspace.name, 30)}
|
{truncateText(invitation.workspace.name, 30)}
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm text-brand-secondary">
|
<p className="text-sm text-brand-secondary">
|
||||||
Invited by {invitation.workspace.owner.first_name}
|
Invited by{" "}
|
||||||
|
{invitation.created_by_detail
|
||||||
|
? invitation.created_by_detail.first_name
|
||||||
|
: invitation.workspace.owner.first_name}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-shrink-0 self-center">
|
<div className="flex-shrink-0 self-center">
|
||||||
@ -237,6 +241,7 @@ export const Workspace: React.FC<Props> = ({ setStep, setWorkspace }) => {
|
|||||||
}}
|
}}
|
||||||
defaultValues={defaultValues}
|
defaultValues={defaultValues}
|
||||||
setDefaultValues={setDefaultValues}
|
setDefaultValues={setDefaultValues}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</Tab.Panel>
|
</Tab.Panel>
|
||||||
</Tab.Panels>
|
</Tab.Panels>
|
||||||
|
@ -16,7 +16,7 @@ import useToast from "hooks/use-toast";
|
|||||||
// ui
|
// ui
|
||||||
import { TextArea } from "components/ui";
|
import { TextArea } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import { IPageBlock } from "types";
|
import { ICurrentUserResponse, IPageBlock } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PAGE_BLOCKS_LIST } from "constants/fetch-keys";
|
import { PAGE_BLOCKS_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -24,7 +24,11 @@ const defaultValues = {
|
|||||||
name: "",
|
name: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CreateBlock = () => {
|
type Props = {
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const CreateBlock: React.FC<Props> = ({ user }) => {
|
||||||
const [blockTitle, setBlockTitle] = useState("");
|
const [blockTitle, setBlockTitle] = useState("");
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -49,9 +53,15 @@ export const CreateBlock = () => {
|
|||||||
if (!workspaceSlug || !projectId || !pageId) return;
|
if (!workspaceSlug || !projectId || !pageId) return;
|
||||||
|
|
||||||
await pagesService
|
await pagesService
|
||||||
.createPageBlock(workspaceSlug as string, projectId as string, pageId as string, {
|
.createPageBlock(
|
||||||
name: watch("name"),
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
pageId as string,
|
||||||
|
{
|
||||||
|
name: watch("name"),
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IPageBlock[]>(
|
mutate<IPageBlock[]>(
|
||||||
PAGE_BLOCKS_LIST(pageId as string),
|
PAGE_BLOCKS_LIST(pageId as string),
|
||||||
|
@ -20,7 +20,7 @@ import { GptAssistantModal } from "components/core";
|
|||||||
// ui
|
// ui
|
||||||
import { Loader, PrimaryButton, SecondaryButton, TextArea } from "components/ui";
|
import { Loader, PrimaryButton, SecondaryButton, TextArea } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import { IPageBlock } from "types";
|
import { ICurrentUserResponse, IPageBlock } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PAGE_BLOCKS_LIST } from "constants/fetch-keys";
|
import { PAGE_BLOCKS_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -30,6 +30,7 @@ type Props = {
|
|||||||
handleAiAssistance?: (response: string) => void;
|
handleAiAssistance?: (response: string) => void;
|
||||||
setIsSyncing?: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsSyncing?: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
focus?: keyof IPageBlock;
|
focus?: keyof IPageBlock;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultValues = {
|
const defaultValues = {
|
||||||
@ -61,6 +62,7 @@ export const CreateUpdateBlockInline: React.FC<Props> = ({
|
|||||||
handleAiAssistance,
|
handleAiAssistance,
|
||||||
setIsSyncing,
|
setIsSyncing,
|
||||||
focus,
|
focus,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const [iAmFeelingLucky, setIAmFeelingLucky] = useState(false);
|
const [iAmFeelingLucky, setIAmFeelingLucky] = useState(false);
|
||||||
const [gptAssistantModal, setGptAssistantModal] = useState(false);
|
const [gptAssistantModal, setGptAssistantModal] = useState(false);
|
||||||
@ -96,11 +98,17 @@ export const CreateUpdateBlockInline: React.FC<Props> = ({
|
|||||||
if (!workspaceSlug || !projectId || !pageId) return;
|
if (!workspaceSlug || !projectId || !pageId) return;
|
||||||
|
|
||||||
await pagesService
|
await pagesService
|
||||||
.createPageBlock(workspaceSlug as string, projectId as string, pageId as string, {
|
.createPageBlock(
|
||||||
name: formData.name,
|
workspaceSlug as string,
|
||||||
description: formData.description ?? "",
|
projectId as string,
|
||||||
description_html: formData.description_html ?? "<p></p>",
|
pageId as string,
|
||||||
})
|
{
|
||||||
|
name: formData.name,
|
||||||
|
description: formData.description ?? "",
|
||||||
|
description_html: formData.description_html ?? "<p></p>",
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IPageBlock[]>(
|
mutate<IPageBlock[]>(
|
||||||
PAGE_BLOCKS_LIST(pageId as string),
|
PAGE_BLOCKS_LIST(pageId as string),
|
||||||
@ -139,21 +147,34 @@ export const CreateUpdateBlockInline: React.FC<Props> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
await pagesService
|
await pagesService
|
||||||
.patchPageBlock(workspaceSlug as string, projectId as string, pageId as string, data.id, {
|
.patchPageBlock(
|
||||||
name: formData.name,
|
workspaceSlug as string,
|
||||||
description: formData.description,
|
projectId as string,
|
||||||
description_html: formData.description_html,
|
pageId as string,
|
||||||
})
|
data.id,
|
||||||
|
{
|
||||||
|
name: formData.name,
|
||||||
|
description: formData.description,
|
||||||
|
description_html: formData.description_html,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate(PAGE_BLOCKS_LIST(pageId as string));
|
mutate(PAGE_BLOCKS_LIST(pageId as string));
|
||||||
editorRef.current?.setEditorValue(res.description_html);
|
editorRef.current?.setEditorValue(res.description_html);
|
||||||
if (data.issue && data.sync)
|
if (data.issue && data.sync)
|
||||||
issuesService
|
issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, data.issue, {
|
.patchIssue(
|
||||||
name: res.name,
|
workspaceSlug as string,
|
||||||
description: res.description,
|
projectId as string,
|
||||||
description_html: res.description_html,
|
data.issue,
|
||||||
})
|
{
|
||||||
|
name: res.name,
|
||||||
|
description: res.description,
|
||||||
|
description_html: res.description_html,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
if (setIsSyncing) setIsSyncing(false);
|
if (setIsSyncing) setIsSyncing(false);
|
||||||
});
|
});
|
||||||
@ -169,10 +190,15 @@ export const CreateUpdateBlockInline: React.FC<Props> = ({
|
|||||||
setIAmFeelingLucky(true);
|
setIAmFeelingLucky(true);
|
||||||
|
|
||||||
aiService
|
aiService
|
||||||
.createGptTask(workspaceSlug as string, projectId as string, {
|
.createGptTask(
|
||||||
prompt: watch("name"),
|
workspaceSlug as string,
|
||||||
task: "Generate a proper description for this issue in context of a project management software.",
|
projectId as string,
|
||||||
})
|
{
|
||||||
|
prompt: watch("name"),
|
||||||
|
task: "Generate a proper description for this issue in context of a project management software.",
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.response === "")
|
if (res.response === "")
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
|
@ -13,7 +13,7 @@ import useToast from "hooks/use-toast";
|
|||||||
// components
|
// components
|
||||||
import { PageForm } from "./page-form";
|
import { PageForm } from "./page-form";
|
||||||
// types
|
// types
|
||||||
import { IPage } from "types";
|
import { ICurrentUserResponse, IPage } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import {
|
||||||
ALL_PAGES_LIST,
|
ALL_PAGES_LIST,
|
||||||
@ -26,9 +26,10 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
data?: IPage | null;
|
data?: IPage | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CreateUpdatePageModal: React.FC<Props> = ({ isOpen, handleClose, data }) => {
|
export const CreateUpdatePageModal: React.FC<Props> = ({ isOpen, handleClose, data, user }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ export const CreateUpdatePageModal: React.FC<Props> = ({ isOpen, handleClose, da
|
|||||||
|
|
||||||
const createPage = async (payload: IPage) => {
|
const createPage = async (payload: IPage) => {
|
||||||
await pagesService
|
await pagesService
|
||||||
.createPage(workspaceSlug as string, projectId as string, payload)
|
.createPage(workspaceSlug as string, projectId as string, payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate(RECENT_PAGES_LIST(projectId as string));
|
mutate(RECENT_PAGES_LIST(projectId as string));
|
||||||
mutate<IPage[]>(
|
mutate<IPage[]>(
|
||||||
@ -82,7 +83,7 @@ export const CreateUpdatePageModal: React.FC<Props> = ({ isOpen, handleClose, da
|
|||||||
|
|
||||||
const updatePage = async (payload: IPage) => {
|
const updatePage = async (payload: IPage) => {
|
||||||
await pagesService
|
await pagesService
|
||||||
.patchPage(workspaceSlug as string, projectId as string, data?.id ?? "", payload)
|
.patchPage(workspaceSlug as string, projectId as string, data?.id ?? "", payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate(RECENT_PAGES_LIST(projectId as string));
|
mutate(RECENT_PAGES_LIST(projectId as string));
|
||||||
mutate<IPage[]>(
|
mutate<IPage[]>(
|
||||||
|
@ -15,7 +15,7 @@ import { DangerButton, SecondaryButton } from "components/ui";
|
|||||||
// icons
|
// icons
|
||||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import type { IPage } from "types";
|
import type { ICurrentUserResponse, IPage } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import {
|
||||||
ALL_PAGES_LIST,
|
ALL_PAGES_LIST,
|
||||||
@ -28,12 +28,14 @@ type TConfirmPageDeletionProps = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
data?: IPage | null;
|
data?: IPage | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeletePageModal: React.FC<TConfirmPageDeletionProps> = ({
|
export const DeletePageModal: React.FC<TConfirmPageDeletionProps> = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
setIsOpen,
|
setIsOpen,
|
||||||
data,
|
data,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
|
||||||
@ -52,7 +54,7 @@ export const DeletePageModal: React.FC<TConfirmPageDeletionProps> = ({
|
|||||||
if (!data || !workspaceSlug || !projectId) return;
|
if (!data || !workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
await pagesService
|
await pagesService
|
||||||
.deletePage(workspaceSlug as string, data.project, data.id)
|
.deletePage(workspaceSlug as string, data.project, data.id, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(RECENT_PAGES_LIST(projectId as string));
|
mutate(RECENT_PAGES_LIST(projectId as string));
|
||||||
mutate<IPage[]>(
|
mutate<IPage[]>(
|
||||||
|
@ -8,6 +8,7 @@ import pagesService from "services/pages.service";
|
|||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// components
|
// components
|
||||||
import {
|
import {
|
||||||
CreateUpdatePageModal,
|
CreateUpdatePageModal,
|
||||||
@ -44,6 +45,8 @@ export const PagesView: React.FC<Props> = ({ pages, viewType }) => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const { data: people } = useSWR(
|
const { data: people } = useSWR(
|
||||||
@ -181,7 +184,7 @@ export const PagesView: React.FC<Props> = ({ pages, viewType }) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
pagesService
|
pagesService
|
||||||
.patchPage(workspaceSlug.toString(), projectId.toString(), page.id, formData)
|
.patchPage(workspaceSlug.toString(), projectId.toString(), page.id, formData, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(RECENT_PAGES_LIST(projectId.toString()));
|
mutate(RECENT_PAGES_LIST(projectId.toString()));
|
||||||
});
|
});
|
||||||
@ -193,11 +196,13 @@ export const PagesView: React.FC<Props> = ({ pages, viewType }) => {
|
|||||||
isOpen={createUpdatePageModal}
|
isOpen={createUpdatePageModal}
|
||||||
handleClose={() => setCreateUpdatePageModal(false)}
|
handleClose={() => setCreateUpdatePageModal(false)}
|
||||||
data={selectedPageToUpdate}
|
data={selectedPageToUpdate}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<DeletePageModal
|
<DeletePageModal
|
||||||
isOpen={deletePageModal}
|
isOpen={deletePageModal}
|
||||||
setIsOpen={setDeletePageModal}
|
setIsOpen={setDeletePageModal}
|
||||||
data={selectedPageToDelete}
|
data={selectedPageToDelete}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
{pages ? (
|
{pages ? (
|
||||||
<div className="space-y-4 h-full overflow-y-auto">
|
<div className="space-y-4 h-full overflow-y-auto">
|
||||||
|
@ -35,7 +35,7 @@ import {
|
|||||||
// helpers
|
// helpers
|
||||||
import { copyTextToClipboard } from "helpers/string.helper";
|
import { copyTextToClipboard } from "helpers/string.helper";
|
||||||
// types
|
// types
|
||||||
import { IIssue, IPageBlock, IProject } from "types";
|
import { ICurrentUserResponse, IIssue, IPageBlock, IProject } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PAGE_BLOCKS_LIST } from "constants/fetch-keys";
|
import { PAGE_BLOCKS_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -43,9 +43,10 @@ type Props = {
|
|||||||
block: IPageBlock;
|
block: IPageBlock;
|
||||||
projectDetails: IProject | undefined;
|
projectDetails: IProject | undefined;
|
||||||
index: number;
|
index: number;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SinglePageBlock: React.FC<Props> = ({ block, projectDetails, index }) => {
|
export const SinglePageBlock: React.FC<Props> = ({ block, projectDetails, index, user }) => {
|
||||||
const [isSyncing, setIsSyncing] = useState(false);
|
const [isSyncing, setIsSyncing] = useState(false);
|
||||||
const [createBlockForm, setCreateBlockForm] = useState(false);
|
const [createBlockForm, setCreateBlockForm] = useState(false);
|
||||||
const [iAmFeelingLucky, setIAmFeelingLucky] = useState(false);
|
const [iAmFeelingLucky, setIAmFeelingLucky] = useState(false);
|
||||||
@ -87,20 +88,33 @@ export const SinglePageBlock: React.FC<Props> = ({ block, projectDetails, index
|
|||||||
);
|
);
|
||||||
|
|
||||||
await pagesService
|
await pagesService
|
||||||
.patchPageBlock(workspaceSlug as string, projectId as string, pageId as string, block.id, {
|
.patchPageBlock(
|
||||||
name: formData.name,
|
workspaceSlug as string,
|
||||||
description: formData.description,
|
projectId as string,
|
||||||
description_html: formData.description_html,
|
pageId as string,
|
||||||
})
|
block.id,
|
||||||
|
{
|
||||||
|
name: formData.name,
|
||||||
|
description: formData.description,
|
||||||
|
description_html: formData.description_html,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate(PAGE_BLOCKS_LIST(pageId as string));
|
mutate(PAGE_BLOCKS_LIST(pageId as string));
|
||||||
if (block.issue && block.sync)
|
if (block.issue && block.sync)
|
||||||
issuesService
|
issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, block.issue, {
|
.patchIssue(
|
||||||
name: res.name,
|
workspaceSlug as string,
|
||||||
description: res.description,
|
projectId as string,
|
||||||
description_html: res.description_html,
|
block.issue,
|
||||||
})
|
{
|
||||||
|
name: res.name,
|
||||||
|
description: res.description,
|
||||||
|
description_html: res.description_html,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.finally(() => setIsSyncing(false));
|
.finally(() => setIsSyncing(false));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -113,7 +127,8 @@ export const SinglePageBlock: React.FC<Props> = ({ block, projectDetails, index
|
|||||||
workspaceSlug as string,
|
workspaceSlug as string,
|
||||||
projectId as string,
|
projectId as string,
|
||||||
pageId as string,
|
pageId as string,
|
||||||
block.id
|
block.id,
|
||||||
|
user
|
||||||
)
|
)
|
||||||
.then((res: IIssue) => {
|
.then((res: IIssue) => {
|
||||||
mutate<IPageBlock[]>(
|
mutate<IPageBlock[]>(
|
||||||
@ -152,7 +167,13 @@ export const SinglePageBlock: React.FC<Props> = ({ block, projectDetails, index
|
|||||||
);
|
);
|
||||||
|
|
||||||
await pagesService
|
await pagesService
|
||||||
.deletePageBlock(workspaceSlug as string, projectId as string, pageId as string, block.id)
|
.deletePageBlock(
|
||||||
|
workspaceSlug as string,
|
||||||
|
projectId as string,
|
||||||
|
pageId as string,
|
||||||
|
block.id,
|
||||||
|
user
|
||||||
|
)
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "error",
|
type: "error",
|
||||||
@ -168,10 +189,15 @@ export const SinglePageBlock: React.FC<Props> = ({ block, projectDetails, index
|
|||||||
setIAmFeelingLucky(true);
|
setIAmFeelingLucky(true);
|
||||||
|
|
||||||
aiService
|
aiService
|
||||||
.createGptTask(workspaceSlug as string, projectId as string, {
|
.createGptTask(
|
||||||
prompt: block.name,
|
workspaceSlug as string,
|
||||||
task: "Generate a proper description for this issue in context of a project management software.",
|
projectId as string,
|
||||||
})
|
{
|
||||||
|
prompt: block.name,
|
||||||
|
task: "Generate a proper description for this issue in context of a project management software.",
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.response === "")
|
if (res.response === "")
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
@ -243,7 +269,8 @@ export const SinglePageBlock: React.FC<Props> = ({ block, projectDetails, index
|
|||||||
block.id,
|
block.id,
|
||||||
{
|
{
|
||||||
sync: !block.sync,
|
sync: !block.sync,
|
||||||
}
|
},
|
||||||
|
user
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -281,6 +308,7 @@ export const SinglePageBlock: React.FC<Props> = ({ block, projectDetails, index
|
|||||||
data={block}
|
data={block}
|
||||||
setIsSyncing={setIsSyncing}
|
setIsSyncing={setIsSyncing}
|
||||||
focus="name"
|
focus="name"
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
@ -24,7 +24,7 @@ import EmojiIconPicker from "components/emoji-icon-picker";
|
|||||||
// helpers
|
// helpers
|
||||||
import { getRandomEmoji } from "helpers/common.helper";
|
import { getRandomEmoji } from "helpers/common.helper";
|
||||||
// types
|
// types
|
||||||
import { IProject } from "types";
|
import { ICurrentUserResponse, IProject } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECTS_LIST, WORKSPACE_MEMBERS_ME } from "constants/fetch-keys";
|
import { PROJECTS_LIST, WORKSPACE_MEMBERS_ME } from "constants/fetch-keys";
|
||||||
// constants
|
// constants
|
||||||
@ -33,6 +33,7 @@ import { NETWORK_CHOICES } from "constants/project";
|
|||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultValues: Partial<IProject> = {
|
const defaultValues: Partial<IProject> = {
|
||||||
@ -63,7 +64,7 @@ const IsGuestCondition: React.FC<{
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CreateProjectModal: React.FC<Props> = (props) => {
|
export const CreateProjectModal: React.FC<Props> = (props) => {
|
||||||
const { isOpen, setIsOpen } = props;
|
const { isOpen, setIsOpen, user } = props;
|
||||||
|
|
||||||
const [isChangeIdentifierRequired, setIsChangeIdentifierRequired] = useState(true);
|
const [isChangeIdentifierRequired, setIsChangeIdentifierRequired] = useState(true);
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ export const CreateProjectModal: React.FC<Props> = (props) => {
|
|||||||
else payload.emoji = formData.emoji_and_icon;
|
else payload.emoji = formData.emoji_and_icon;
|
||||||
|
|
||||||
await projectServices
|
await projectServices
|
||||||
.createProject(workspaceSlug as string, payload)
|
.createProject(workspaceSlug as string, payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IProject[]>(
|
mutate<IProject[]>(
|
||||||
PROJECTS_LIST(workspaceSlug as string),
|
PROJECTS_LIST(workspaceSlug as string),
|
||||||
|
@ -13,7 +13,7 @@ import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
|||||||
// ui
|
// ui
|
||||||
import { DangerButton, Input, SecondaryButton } from "components/ui";
|
import { DangerButton, Input, SecondaryButton } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import type { IProject, IWorkspace } from "types";
|
import type { ICurrentUserResponse, IProject, IWorkspace } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECTS_LIST } from "constants/fetch-keys";
|
import { PROJECTS_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ type TConfirmProjectDeletionProps = {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onSuccess?: () => void;
|
onSuccess?: () => void;
|
||||||
data: IProject | null;
|
data: IProject | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeleteProjectModal: React.FC<TConfirmProjectDeletionProps> = ({
|
export const DeleteProjectModal: React.FC<TConfirmProjectDeletionProps> = ({
|
||||||
@ -29,6 +30,7 @@ export const DeleteProjectModal: React.FC<TConfirmProjectDeletionProps> = ({
|
|||||||
data,
|
data,
|
||||||
onClose,
|
onClose,
|
||||||
onSuccess,
|
onSuccess,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
const [confirmProjectName, setConfirmProjectName] = useState("");
|
const [confirmProjectName, setConfirmProjectName] = useState("");
|
||||||
@ -65,7 +67,7 @@ export const DeleteProjectModal: React.FC<TConfirmProjectDeletionProps> = ({
|
|||||||
setIsDeleteLoading(true);
|
setIsDeleteLoading(true);
|
||||||
if (!data || !workspaceSlug || !canDelete) return;
|
if (!data || !workspaceSlug || !canDelete) return;
|
||||||
await projectService
|
await projectService
|
||||||
.deleteProject(workspaceSlug, data.id)
|
.deleteProject(workspaceSlug, data.id, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
handleClose();
|
handleClose();
|
||||||
mutate<IProject[]>(PROJECTS_LIST(workspaceSlug), (prevData) =>
|
mutate<IProject[]>(PROJECTS_LIST(workspaceSlug), (prevData) =>
|
||||||
|
@ -15,7 +15,7 @@ import useToast from "hooks/use-toast";
|
|||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
import workspaceService from "services/workspace.service";
|
import workspaceService from "services/workspace.service";
|
||||||
// types
|
// types
|
||||||
import { IProjectMemberInvitation } from "types";
|
import { ICurrentUserResponse, IProjectMemberInvitation } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_INVITATIONS, WORKSPACE_MEMBERS } from "constants/fetch-keys";
|
import { PROJECT_INVITATIONS, WORKSPACE_MEMBERS } from "constants/fetch-keys";
|
||||||
// constants
|
// constants
|
||||||
@ -25,6 +25,7 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
members: any[];
|
members: any[];
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ProjectMember = IProjectMemberInvitation & {
|
type ProjectMember = IProjectMemberInvitation & {
|
||||||
@ -40,7 +41,7 @@ const defaultValues: Partial<ProjectMember> = {
|
|||||||
user_id: "",
|
user_id: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
const SendProjectInvitationModal: React.FC<Props> = ({ isOpen, setIsOpen, members }) => {
|
const SendProjectInvitationModal: React.FC<Props> = ({ isOpen, setIsOpen, members, user }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ const SendProjectInvitationModal: React.FC<Props> = ({ isOpen, setIsOpen, member
|
|||||||
const onSubmit = async (formData: ProjectMember) => {
|
const onSubmit = async (formData: ProjectMember) => {
|
||||||
if (!workspaceSlug || !projectId || isSubmitting) return;
|
if (!workspaceSlug || !projectId || isSubmitting) return;
|
||||||
await projectService
|
await projectService
|
||||||
.inviteProject(workspaceSlug as string, projectId as string, formData)
|
.inviteProject(workspaceSlug as string, projectId as string, formData, user)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
mutate<any[]>(
|
mutate<any[]>(
|
||||||
|
@ -9,6 +9,7 @@ import { PlusIcon } from "@heroicons/react/24/outline";
|
|||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
import useTheme from "hooks/use-theme";
|
import useTheme from "hooks/use-theme";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// services
|
// services
|
||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
// components
|
// components
|
||||||
@ -29,6 +30,9 @@ export const ProjectSidebarList: FC = () => {
|
|||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
// states
|
// states
|
||||||
const [isCreateProjectModal, setCreateProjectModal] = useState(false);
|
const [isCreateProjectModal, setCreateProjectModal] = useState(false);
|
||||||
// theme
|
// theme
|
||||||
@ -136,11 +140,16 @@ export const ProjectSidebarList: FC = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CreateProjectModal isOpen={isCreateProjectModal} setIsOpen={setCreateProjectModal} />
|
<CreateProjectModal
|
||||||
|
isOpen={isCreateProjectModal}
|
||||||
|
setIsOpen={setCreateProjectModal}
|
||||||
|
user={user}
|
||||||
|
/>
|
||||||
<DeleteProjectModal
|
<DeleteProjectModal
|
||||||
isOpen={deleteProjectModal}
|
isOpen={deleteProjectModal}
|
||||||
onClose={() => setDeleteProjectModal(false)}
|
onClose={() => setDeleteProjectModal(false)}
|
||||||
data={projectToDelete}
|
data={projectToDelete}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<div className="mt-2.5 h-full overflow-y-auto border-t border-brand-base bg-brand-sidebar pt-2.5">
|
<div className="mt-2.5 h-full overflow-y-auto border-t border-brand-base bg-brand-sidebar pt-2.5">
|
||||||
{favoriteProjects && favoriteProjects.length > 0 && (
|
{favoriteProjects && favoriteProjects.length > 0 && (
|
||||||
|
@ -19,7 +19,7 @@ import { CustomSelect, Input, PrimaryButton, SecondaryButton, TextArea } from "c
|
|||||||
// icons
|
// icons
|
||||||
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
import { ChevronDownIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import type { IState, IStateResponse } from "types";
|
import type { ICurrentUserResponse, IState, IStateResponse } from "types";
|
||||||
// fetch keys
|
// fetch keys
|
||||||
import { STATES_LIST } from "constants/fetch-keys";
|
import { STATES_LIST } from "constants/fetch-keys";
|
||||||
// constants
|
// constants
|
||||||
@ -30,6 +30,7 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultValues: Partial<IState> = {
|
const defaultValues: Partial<IState> = {
|
||||||
@ -39,7 +40,7 @@ const defaultValues: Partial<IState> = {
|
|||||||
group: "backlog",
|
group: "backlog",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CreateStateModal: React.FC<Props> = ({ isOpen, projectId, handleClose }) => {
|
export const CreateStateModal: React.FC<Props> = ({ isOpen, projectId, handleClose, user }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
@ -69,7 +70,7 @@ export const CreateStateModal: React.FC<Props> = ({ isOpen, projectId, handleClo
|
|||||||
};
|
};
|
||||||
|
|
||||||
await stateService
|
await stateService
|
||||||
.createState(workspaceSlug as string, projectId, payload)
|
.createState(workspaceSlug as string, projectId, payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IStateResponse>(
|
mutate<IStateResponse>(
|
||||||
STATES_LIST(projectId.toString()),
|
STATES_LIST(projectId.toString()),
|
||||||
|
@ -17,7 +17,7 @@ import useToast from "hooks/use-toast";
|
|||||||
// ui
|
// ui
|
||||||
import { CustomSelect, Input, PrimaryButton, SecondaryButton } from "components/ui";
|
import { CustomSelect, Input, PrimaryButton, SecondaryButton } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import type { IState, IStateResponse } from "types";
|
import type { ICurrentUserResponse, IState, IStateResponse } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { STATES_LIST } from "constants/fetch-keys";
|
import { STATES_LIST } from "constants/fetch-keys";
|
||||||
// constants
|
// constants
|
||||||
@ -27,6 +27,7 @@ type Props = {
|
|||||||
data: IState | null;
|
data: IState | null;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
selectedGroup: StateGroup | null;
|
selectedGroup: StateGroup | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StateGroup = "backlog" | "unstarted" | "started" | "completed" | "cancelled" | null;
|
export type StateGroup = "backlog" | "unstarted" | "started" | "completed" | "cancelled" | null;
|
||||||
@ -37,7 +38,12 @@ const defaultValues: Partial<IState> = {
|
|||||||
group: "backlog",
|
group: "backlog",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CreateUpdateStateInline: React.FC<Props> = ({ data, onClose, selectedGroup }) => {
|
export const CreateUpdateStateInline: React.FC<Props> = ({
|
||||||
|
data,
|
||||||
|
onClose,
|
||||||
|
selectedGroup,
|
||||||
|
user,
|
||||||
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
@ -83,7 +89,7 @@ export const CreateUpdateStateInline: React.FC<Props> = ({ data, onClose, select
|
|||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
await stateService
|
await stateService
|
||||||
.createState(workspaceSlug.toString(), projectId.toString(), { ...payload })
|
.createState(workspaceSlug.toString(), projectId.toString(), { ...payload }, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IStateResponse>(
|
mutate<IStateResponse>(
|
||||||
STATES_LIST(projectId.toString()),
|
STATES_LIST(projectId.toString()),
|
||||||
@ -121,9 +127,15 @@ export const CreateUpdateStateInline: React.FC<Props> = ({ data, onClose, select
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await stateService
|
await stateService
|
||||||
.updateState(workspaceSlug.toString(), projectId.toString(), data.id, {
|
.updateState(
|
||||||
...payload,
|
workspaceSlug.toString(),
|
||||||
})
|
projectId.toString(),
|
||||||
|
data.id,
|
||||||
|
{
|
||||||
|
...payload,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(STATES_LIST(projectId.toString()));
|
mutate(STATES_LIST(projectId.toString()));
|
||||||
handleClose();
|
handleClose();
|
||||||
|
@ -15,7 +15,7 @@ import useToast from "hooks/use-toast";
|
|||||||
// ui
|
// ui
|
||||||
import { DangerButton, SecondaryButton } from "components/ui";
|
import { DangerButton, SecondaryButton } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import type { IState, IStateResponse } from "types";
|
import type { ICurrentUserResponse, IState, IStateResponse } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { STATES_LIST } from "constants/fetch-keys";
|
import { STATES_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -23,9 +23,10 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
data: IState | null;
|
data: IState | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeleteStateModal: React.FC<Props> = ({ isOpen, onClose, data }) => {
|
export const DeleteStateModal: React.FC<Props> = ({ isOpen, onClose, data, user }) => {
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -44,7 +45,7 @@ export const DeleteStateModal: React.FC<Props> = ({ isOpen, onClose, data }) =>
|
|||||||
setIsDeleteLoading(true);
|
setIsDeleteLoading(true);
|
||||||
|
|
||||||
await stateServices
|
await stateServices
|
||||||
.deleteState(workspaceSlug as string, data.project, data.id)
|
.deleteState(workspaceSlug as string, data.project, data.id, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate<IStateResponse>(
|
mutate<IStateResponse>(
|
||||||
STATES_LIST(data.project),
|
STATES_LIST(data.project),
|
||||||
|
@ -21,7 +21,7 @@ import { addSpaceIfCamelCase } from "helpers/string.helper";
|
|||||||
import { groupBy, orderArrayBy } from "helpers/array.helper";
|
import { groupBy, orderArrayBy } from "helpers/array.helper";
|
||||||
import { orderStateGroups } from "helpers/state.helper";
|
import { orderStateGroups } from "helpers/state.helper";
|
||||||
// types
|
// types
|
||||||
import { IState } from "types";
|
import { ICurrentUserResponse, IState } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { STATES_LIST } from "constants/fetch-keys";
|
import { STATES_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -31,6 +31,7 @@ type Props = {
|
|||||||
statesList: IState[];
|
statesList: IState[];
|
||||||
handleEditState: () => void;
|
handleEditState: () => void;
|
||||||
handleDeleteState: () => void;
|
handleDeleteState: () => void;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SingleState: React.FC<Props> = ({
|
export const SingleState: React.FC<Props> = ({
|
||||||
@ -39,6 +40,7 @@ export const SingleState: React.FC<Props> = ({
|
|||||||
statesList,
|
statesList,
|
||||||
handleEditState,
|
handleEditState,
|
||||||
handleDeleteState,
|
handleDeleteState,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
|
||||||
@ -67,14 +69,26 @@ export const SingleState: React.FC<Props> = ({
|
|||||||
|
|
||||||
if (currentDefaultState)
|
if (currentDefaultState)
|
||||||
stateService
|
stateService
|
||||||
.patchState(workspaceSlug as string, projectId as string, currentDefaultState?.id ?? "", {
|
.patchState(
|
||||||
default: false,
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
currentDefaultState?.id ?? "",
|
||||||
|
{
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
stateService
|
stateService
|
||||||
.patchState(workspaceSlug as string, projectId as string, state.id, {
|
.patchState(
|
||||||
default: true,
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
state.id,
|
||||||
|
{
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(STATES_LIST(projectId as string));
|
mutate(STATES_LIST(projectId as string));
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
@ -85,9 +99,15 @@ export const SingleState: React.FC<Props> = ({
|
|||||||
});
|
});
|
||||||
else
|
else
|
||||||
stateService
|
stateService
|
||||||
.patchState(workspaceSlug as string, projectId as string, state.id, {
|
.patchState(
|
||||||
default: true,
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
state.id,
|
||||||
|
{
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(STATES_LIST(projectId as string));
|
mutate(STATES_LIST(projectId as string));
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
@ -121,9 +141,15 @@ export const SingleState: React.FC<Props> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
stateService
|
stateService
|
||||||
.patchState(workspaceSlug as string, projectId as string, state.id, {
|
.patchState(
|
||||||
sequence: newSequence,
|
workspaceSlug as string,
|
||||||
})
|
projectId as string,
|
||||||
|
state.id,
|
||||||
|
{
|
||||||
|
sequence: newSequence,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
console.log(res);
|
console.log(res);
|
||||||
mutate(STATES_LIST(projectId as string));
|
mutate(STATES_LIST(projectId as string));
|
||||||
|
@ -15,7 +15,7 @@ import { DangerButton, SecondaryButton } from "components/ui";
|
|||||||
// icons
|
// icons
|
||||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||||
// types
|
// types
|
||||||
import type { IView } from "types";
|
import type { ICurrentUserResponse, IView } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { VIEWS_LIST } from "constants/fetch-keys";
|
import { VIEWS_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -23,9 +23,10 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
data: IView | null;
|
data: IView | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, setIsOpen }) => {
|
export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, setIsOpen, user }) => {
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -43,7 +44,7 @@ export const DeleteViewModal: React.FC<Props> = ({ isOpen, data, setIsOpen }) =>
|
|||||||
if (!workspaceSlug || !data || !projectId) return;
|
if (!workspaceSlug || !data || !projectId) return;
|
||||||
|
|
||||||
await viewsService
|
await viewsService
|
||||||
.deleteView(workspaceSlug as string, projectId as string, data.id)
|
.deleteView(workspaceSlug as string, projectId as string, data.id, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate<IView[]>(VIEWS_LIST(projectId as string), (views) =>
|
mutate<IView[]>(VIEWS_LIST(projectId as string), (views) =>
|
||||||
views?.filter((view) => view.id !== data.id)
|
views?.filter((view) => view.id !== data.id)
|
||||||
|
@ -13,7 +13,7 @@ import useToast from "hooks/use-toast";
|
|||||||
// components
|
// components
|
||||||
import { ViewForm } from "components/views";
|
import { ViewForm } from "components/views";
|
||||||
// types
|
// types
|
||||||
import { IView } from "types";
|
import { ICurrentUserResponse, IView } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { VIEWS_LIST } from "constants/fetch-keys";
|
import { VIEWS_LIST } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ type Props = {
|
|||||||
handleClose: () => void;
|
handleClose: () => void;
|
||||||
data?: IView | null;
|
data?: IView | null;
|
||||||
preLoadedData?: Partial<IView> | null;
|
preLoadedData?: Partial<IView> | null;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CreateUpdateViewModal: React.FC<Props> = ({
|
export const CreateUpdateViewModal: React.FC<Props> = ({
|
||||||
@ -29,6 +30,7 @@ export const CreateUpdateViewModal: React.FC<Props> = ({
|
|||||||
handleClose,
|
handleClose,
|
||||||
data,
|
data,
|
||||||
preLoadedData,
|
preLoadedData,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
@ -45,7 +47,7 @@ export const CreateUpdateViewModal: React.FC<Props> = ({
|
|||||||
query_data: payload.query,
|
query_data: payload.query,
|
||||||
};
|
};
|
||||||
await viewsService
|
await viewsService
|
||||||
.createView(workspaceSlug as string, projectId as string, payload)
|
.createView(workspaceSlug as string, projectId as string, payload, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(VIEWS_LIST(projectId as string));
|
mutate(VIEWS_LIST(projectId as string));
|
||||||
handleClose();
|
handleClose();
|
||||||
@ -71,7 +73,7 @@ export const CreateUpdateViewModal: React.FC<Props> = ({
|
|||||||
query_data: payload.query,
|
query_data: payload.query,
|
||||||
};
|
};
|
||||||
await viewsService
|
await viewsService
|
||||||
.updateView(workspaceSlug as string, projectId as string, data?.id ?? "", payloadData)
|
.updateView(workspaceSlug as string, projectId as string, data?.id ?? "", payloadData, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IView[]>(
|
mutate<IView[]>(
|
||||||
VIEWS_LIST(projectId as string),
|
VIEWS_LIST(projectId as string),
|
||||||
|
@ -11,7 +11,7 @@ import useToast from "hooks/use-toast";
|
|||||||
// ui
|
// ui
|
||||||
import { CustomSelect, Input, PrimaryButton } from "components/ui";
|
import { CustomSelect, Input, PrimaryButton } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import { IWorkspace } from "types";
|
import { ICurrentUserResponse, IWorkspace } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { USER_WORKSPACES } from "constants/fetch-keys";
|
import { USER_WORKSPACES } from "constants/fetch-keys";
|
||||||
// constants
|
// constants
|
||||||
@ -25,6 +25,7 @@ type Props = {
|
|||||||
company_size: number | null;
|
company_size: number | null;
|
||||||
};
|
};
|
||||||
setDefaultValues: Dispatch<SetStateAction<any>>;
|
setDefaultValues: Dispatch<SetStateAction<any>>;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const restrictedUrls = [
|
const restrictedUrls = [
|
||||||
@ -44,6 +45,7 @@ export const CreateWorkspaceForm: React.FC<Props> = ({
|
|||||||
onSubmit,
|
onSubmit,
|
||||||
defaultValues,
|
defaultValues,
|
||||||
setDefaultValues,
|
setDefaultValues,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const [slugError, setSlugError] = useState(false);
|
const [slugError, setSlugError] = useState(false);
|
||||||
const [invalidSlug, setInvalidSlug] = useState(false);
|
const [invalidSlug, setInvalidSlug] = useState(false);
|
||||||
@ -66,7 +68,7 @@ export const CreateWorkspaceForm: React.FC<Props> = ({
|
|||||||
if (res.status === true && !restrictedUrls.includes(formData.slug)) {
|
if (res.status === true && !restrictedUrls.includes(formData.slug)) {
|
||||||
setSlugError(false);
|
setSlugError(false);
|
||||||
await workspaceService
|
await workspaceService
|
||||||
.createWorkspace(formData)
|
.createWorkspace(formData, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "success",
|
type: "success",
|
||||||
|
@ -15,7 +15,7 @@ import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
|||||||
// ui
|
// ui
|
||||||
import { DangerButton, Input, SecondaryButton } from "components/ui";
|
import { DangerButton, Input, SecondaryButton } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import type { IWorkspace } from "types";
|
import type { ICurrentUserResponse, IWorkspace } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { USER_WORKSPACES } from "constants/fetch-keys";
|
import { USER_WORKSPACES } from "constants/fetch-keys";
|
||||||
|
|
||||||
@ -23,9 +23,10 @@ type Props = {
|
|||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
data: IWorkspace | null;
|
data: IWorkspace | null;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DeleteWorkspaceModal: React.FC<Props> = ({ isOpen, data, onClose }) => {
|
export const DeleteWorkspaceModal: React.FC<Props> = ({ isOpen, data, onClose, user }) => {
|
||||||
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
|
||||||
|
|
||||||
const [confirmWorkspaceName, setConfirmWorkspaceName] = useState("");
|
const [confirmWorkspaceName, setConfirmWorkspaceName] = useState("");
|
||||||
@ -57,7 +58,7 @@ export const DeleteWorkspaceModal: React.FC<Props> = ({ isOpen, data, onClose })
|
|||||||
setIsDeleteLoading(true);
|
setIsDeleteLoading(true);
|
||||||
if (!data || !canDelete) return;
|
if (!data || !canDelete) return;
|
||||||
await workspaceService
|
await workspaceService
|
||||||
.deleteWorkspace(data.slug)
|
.deleteWorkspace(data.slug, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
handleClose();
|
handleClose();
|
||||||
router.push("/");
|
router.push("/");
|
||||||
|
@ -10,7 +10,7 @@ import { CustomSelect, Input, PrimaryButton, SecondaryButton } from "components/
|
|||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
// types
|
// types
|
||||||
import { IWorkspaceMemberInvitation } from "types";
|
import { ICurrentUserResponse, IWorkspaceMemberInvitation } from "types";
|
||||||
// fetch keys
|
// fetch keys
|
||||||
import { WORKSPACE_INVITATIONS } from "constants/fetch-keys";
|
import { WORKSPACE_INVITATIONS } from "constants/fetch-keys";
|
||||||
// constants
|
// constants
|
||||||
@ -21,6 +21,7 @@ type Props = {
|
|||||||
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
setIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
workspace_slug: string;
|
workspace_slug: string;
|
||||||
members: any[];
|
members: any[];
|
||||||
|
user: ICurrentUserResponse | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultValues: Partial<IWorkspaceMemberInvitation> = {
|
const defaultValues: Partial<IWorkspaceMemberInvitation> = {
|
||||||
@ -33,6 +34,7 @@ const SendWorkspaceInvitationModal: React.FC<Props> = ({
|
|||||||
setIsOpen,
|
setIsOpen,
|
||||||
workspace_slug,
|
workspace_slug,
|
||||||
members,
|
members,
|
||||||
|
user,
|
||||||
}) => {
|
}) => {
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ const SendWorkspaceInvitationModal: React.FC<Props> = ({
|
|||||||
|
|
||||||
const onSubmit = async (formData: IWorkspaceMemberInvitation) => {
|
const onSubmit = async (formData: IWorkspaceMemberInvitation) => {
|
||||||
await workspaceService
|
await workspaceService
|
||||||
.inviteWorkspace(workspace_slug, { emails: [formData] })
|
.inviteWorkspace(workspace_slug, { emails: [formData] }, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
handleClose();
|
handleClose();
|
||||||
@ -101,7 +103,10 @@ const SendWorkspaceInvitationModal: React.FC<Props> = ({
|
|||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
<div>
|
<div>
|
||||||
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-brand-base">
|
<Dialog.Title
|
||||||
|
as="h3"
|
||||||
|
className="text-lg font-medium leading-6 text-brand-base"
|
||||||
|
>
|
||||||
Members
|
Members
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<p className="text-sm text-brand-secondary">
|
<p className="text-sm text-brand-secondary">
|
||||||
|
@ -46,7 +46,10 @@ const SingleInvitation: React.FC<Props> = ({
|
|||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<div className="text-sm font-medium">{truncateText(invitation.workspace.name, 30)}</div>
|
<div className="text-sm font-medium">{truncateText(invitation.workspace.name, 30)}</div>
|
||||||
<p className="text-sm text-brand-secondary">
|
<p className="text-sm text-brand-secondary">
|
||||||
Invited by {invitation.workspace.owner.first_name}
|
Invited by{" "}
|
||||||
|
{invitation.created_by_detail
|
||||||
|
? invitation.created_by_detail.first_name
|
||||||
|
: invitation.workspace.owner.first_name}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-shrink-0 self-center">
|
<div className="flex-shrink-0 self-center">
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
IProjectMember,
|
IProjectMember,
|
||||||
TIssueGroupByOptions,
|
TIssueGroupByOptions,
|
||||||
TIssueOrderByOptions,
|
TIssueOrderByOptions,
|
||||||
|
ICurrentUserResponse,
|
||||||
} from "types";
|
} from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import {
|
import {
|
||||||
@ -26,6 +27,7 @@ import {
|
|||||||
USER_PROJECT_VIEW,
|
USER_PROJECT_VIEW,
|
||||||
VIEW_DETAILS,
|
VIEW_DETAILS,
|
||||||
} from "constants/fetch-keys";
|
} from "constants/fetch-keys";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
|
|
||||||
export const issueViewContext = createContext<ContextType>({} as ContextType);
|
export const issueViewContext = createContext<ContextType>({} as ContextType);
|
||||||
|
|
||||||
@ -212,33 +214,54 @@ const saveCycleFilters = async (
|
|||||||
workspaceSlug: string,
|
workspaceSlug: string,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
cycleId: string,
|
cycleId: string,
|
||||||
state: any
|
state: any,
|
||||||
|
user: ICurrentUserResponse | undefined
|
||||||
) => {
|
) => {
|
||||||
await cyclesService.patchCycle(workspaceSlug, projectId, cycleId, {
|
await cyclesService.patchCycle(
|
||||||
...state,
|
workspaceSlug,
|
||||||
});
|
projectId,
|
||||||
|
cycleId,
|
||||||
|
{
|
||||||
|
...state,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveModuleFilters = async (
|
const saveModuleFilters = async (
|
||||||
workspaceSlug: string,
|
workspaceSlug: string,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
moduleId: string,
|
moduleId: string,
|
||||||
state: any
|
state: any,
|
||||||
|
user: ICurrentUserResponse | undefined
|
||||||
) => {
|
) => {
|
||||||
await modulesService.patchModule(workspaceSlug, projectId, moduleId, {
|
await modulesService.patchModule(
|
||||||
...state,
|
workspaceSlug,
|
||||||
});
|
projectId,
|
||||||
|
moduleId,
|
||||||
|
{
|
||||||
|
...state,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const saveViewFilters = async (
|
const saveViewFilters = async (
|
||||||
workspaceSlug: string,
|
workspaceSlug: string,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
viewId: string,
|
viewId: string,
|
||||||
state: any
|
state: any,
|
||||||
|
user: ICurrentUserResponse | undefined
|
||||||
) => {
|
) => {
|
||||||
await viewsService.patchView(workspaceSlug, projectId, viewId, {
|
await viewsService.patchView(
|
||||||
...state,
|
workspaceSlug,
|
||||||
});
|
projectId,
|
||||||
|
viewId,
|
||||||
|
{
|
||||||
|
...state,
|
||||||
|
},
|
||||||
|
user
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const setNewDefault = async (workspaceSlug: string, projectId: string, state: any) => {
|
const setNewDefault = async (workspaceSlug: string, projectId: string, state: any) => {
|
||||||
@ -267,6 +290,8 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query;
|
const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { data: myViewProps, mutate: mutateMyViewProps } = useSWR(
|
const { data: myViewProps, mutate: mutateMyViewProps } = useSWR(
|
||||||
workspaceSlug && projectId ? USER_PROJECT_VIEW(projectId as string) : null,
|
workspaceSlug && projectId ? USER_PROJECT_VIEW(projectId as string) : null,
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
@ -505,14 +530,20 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
|
|||||||
};
|
};
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
saveCycleFilters(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), {
|
saveCycleFilters(
|
||||||
view_props: {
|
workspaceSlug.toString(),
|
||||||
filters: {
|
projectId.toString(),
|
||||||
...state.filters,
|
cycleId.toString(),
|
||||||
...property,
|
{
|
||||||
|
view_props: {
|
||||||
|
filters: {
|
||||||
|
...state.filters,
|
||||||
|
...property,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
user
|
||||||
|
);
|
||||||
} else if (moduleId) {
|
} else if (moduleId) {
|
||||||
mutateModuleDetails((prevData: any) => {
|
mutateModuleDetails((prevData: any) => {
|
||||||
if (!prevData) return prevData;
|
if (!prevData) return prevData;
|
||||||
@ -528,14 +559,20 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
|
|||||||
};
|
};
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
saveModuleFilters(workspaceSlug.toString(), projectId.toString(), moduleId.toString(), {
|
saveModuleFilters(
|
||||||
view_props: {
|
workspaceSlug.toString(),
|
||||||
filters: {
|
projectId.toString(),
|
||||||
...state.filters,
|
moduleId.toString(),
|
||||||
...property,
|
{
|
||||||
|
view_props: {
|
||||||
|
filters: {
|
||||||
|
...state.filters,
|
||||||
|
...property,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
user
|
||||||
|
);
|
||||||
} else if (viewId) {
|
} else if (viewId) {
|
||||||
mutateViewDetails((prevData: any) => {
|
mutateViewDetails((prevData: any) => {
|
||||||
if (!prevData) return prevData;
|
if (!prevData) return prevData;
|
||||||
@ -548,12 +585,18 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
|
|||||||
};
|
};
|
||||||
}, false);
|
}, false);
|
||||||
if (saveToServer)
|
if (saveToServer)
|
||||||
saveViewFilters(workspaceSlug as string, projectId as string, viewId as string, {
|
saveViewFilters(
|
||||||
query_data: {
|
workspaceSlug as string,
|
||||||
...state.filters,
|
projectId as string,
|
||||||
...property,
|
viewId as string,
|
||||||
|
{
|
||||||
|
query_data: {
|
||||||
|
...state.filters,
|
||||||
|
...property,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
user
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
mutateMyViewProps((prevData) => {
|
mutateMyViewProps((prevData) => {
|
||||||
if (!prevData) return prevData;
|
if (!prevData) return prevData;
|
||||||
|
@ -6,6 +6,8 @@ import useSWR from "swr";
|
|||||||
|
|
||||||
// react-hook-form
|
// react-hook-form
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
// hooks
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// headless ui
|
// headless ui
|
||||||
import { Tab } from "@headlessui/react";
|
import { Tab } from "@headlessui/react";
|
||||||
// services
|
// services
|
||||||
@ -35,6 +37,8 @@ const Analytics = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { control, watch, setValue } = useForm<IAnalyticsParams>({ defaultValues });
|
const { control, watch, setValue } = useForm<IAnalyticsParams>({ defaultValues });
|
||||||
|
|
||||||
const params: IAnalyticsParams = {
|
const params: IAnalyticsParams = {
|
||||||
@ -59,7 +63,7 @@ const Analytics = () => {
|
|||||||
? "WORKSPACE_SCOPE_AND_DEMAND_ANALYTICS"
|
? "WORKSPACE_SCOPE_AND_DEMAND_ANALYTICS"
|
||||||
: "WORKSPACE_CUSTOM_ANALYTICS";
|
: "WORKSPACE_CUSTOM_ANALYTICS";
|
||||||
|
|
||||||
trackEventServices.trackAnalyticsEvent(eventPayload, eventType);
|
trackEventServices.trackAnalyticsEvent(eventPayload, eventType, user);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -67,7 +71,8 @@ const Analytics = () => {
|
|||||||
|
|
||||||
trackEventServices.trackAnalyticsEvent(
|
trackEventServices.trackAnalyticsEvent(
|
||||||
{ workspaceSlug: workspaceSlug?.toString() },
|
{ workspaceSlug: workspaceSlug?.toString() },
|
||||||
"WORKSPACE_SCOPE_AND_DEMAND_ANALYTICS"
|
"WORKSPACE_SCOPE_AND_DEMAND_ANALYTICS",
|
||||||
|
user
|
||||||
);
|
);
|
||||||
}, [workspaceSlug]);
|
}, [workspaceSlug]);
|
||||||
|
|
||||||
@ -119,6 +124,7 @@ const Analytics = () => {
|
|||||||
params={params}
|
params={params}
|
||||||
control={control}
|
control={control}
|
||||||
setValue={setValue}
|
setValue={setValue}
|
||||||
|
user={user}
|
||||||
fullScreen
|
fullScreen
|
||||||
/>
|
/>
|
||||||
</Tab.Panel>
|
</Tab.Panel>
|
||||||
|
@ -19,6 +19,7 @@ import cycleServices from "services/cycles.service";
|
|||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// components
|
// components
|
||||||
import { AnalyticsProjectModal } from "components/analytics";
|
import { AnalyticsProjectModal } from "components/analytics";
|
||||||
// ui
|
// ui
|
||||||
@ -44,6 +45,8 @@ const SingleCycle: React.FC = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, cycleId } = router.query;
|
const { workspaceSlug, projectId, cycleId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const { data: activeProject } = useSWR(
|
const { data: activeProject } = useSWR(
|
||||||
@ -94,7 +97,7 @@ const SingleCycle: React.FC = () => {
|
|||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
await issuesService
|
await issuesService
|
||||||
.addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, data)
|
.addIssueToCycle(workspaceSlug as string, projectId as string, cycleId as string, data, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(CYCLE_ISSUES(cycleId as string));
|
mutate(CYCLE_ISSUES(cycleId as string));
|
||||||
})
|
})
|
||||||
@ -185,6 +188,7 @@ const SingleCycle: React.FC = () => {
|
|||||||
cycle={cycleDetails}
|
cycle={cycleDetails}
|
||||||
isOpen={cycleSidebar}
|
isOpen={cycleSidebar}
|
||||||
isCompleted={cycleStatus === "completed" ?? false}
|
isCompleted={cycleStatus === "completed" ?? false}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</ProjectAuthorizationWrapper>
|
</ProjectAuthorizationWrapper>
|
||||||
</IssueViewContextProvider>
|
</IssueViewContextProvider>
|
||||||
|
@ -8,6 +8,7 @@ import useSWR from "swr";
|
|||||||
import { Tab } from "@headlessui/react";
|
import { Tab } from "@headlessui/react";
|
||||||
// hooks
|
// hooks
|
||||||
import useLocalStorage from "hooks/use-local-storage";
|
import useLocalStorage from "hooks/use-local-storage";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// services
|
// services
|
||||||
import cycleService from "services/cycles.service";
|
import cycleService from "services/cycles.service";
|
||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
@ -62,6 +63,8 @@ const ProjectCycles: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { data: activeProject } = useSWR(
|
const { data: activeProject } = useSWR(
|
||||||
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
|
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
@ -110,6 +113,7 @@ const ProjectCycles: NextPage = () => {
|
|||||||
isOpen={createUpdateCycleModal}
|
isOpen={createUpdateCycleModal}
|
||||||
handleClose={() => setCreateUpdateCycleModal(false)}
|
handleClose={() => setCreateUpdateCycleModal(false)}
|
||||||
data={selectedCycle}
|
data={selectedCycle}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<div className="space-y-5 p-8 h-full flex flex-col overflow-hidden">
|
<div className="space-y-5 p-8 h-full flex flex-col overflow-hidden">
|
||||||
<div className="flex gap-4 justify-between">
|
<div className="flex gap-4 justify-between">
|
||||||
|
@ -7,6 +7,8 @@ import useSWR, { mutate } from "swr";
|
|||||||
|
|
||||||
// react-hook-form
|
// react-hook-form
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
|
// hooks
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// services
|
// services
|
||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
// layouts
|
// layouts
|
||||||
@ -50,6 +52,8 @@ const IssueDetailsPage: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, issueId } = router.query;
|
const { workspaceSlug, projectId, issueId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { data: issueDetails, mutate: mutateIssueDetails } = useSWR<IIssue | undefined>(
|
const { data: issueDetails, mutate: mutateIssueDetails } = useSWR<IIssue | undefined>(
|
||||||
workspaceSlug && projectId && issueId ? ISSUE_DETAILS(issueId as string) : null,
|
workspaceSlug && projectId && issueId ? ISSUE_DETAILS(issueId as string) : null,
|
||||||
workspaceSlug && projectId && issueId
|
workspaceSlug && projectId && issueId
|
||||||
@ -92,7 +96,7 @@ const IssueDetailsPage: NextPage = () => {
|
|||||||
|
|
||||||
const payload = { ...formData };
|
const payload = { ...formData };
|
||||||
await issuesService
|
await issuesService
|
||||||
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload)
|
.patchIssue(workspaceSlug as string, projectId as string, issueId as string, payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutateIssueDetails();
|
mutateIssueDetails();
|
||||||
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
mutate(PROJECT_ISSUES_ACTIVITY(issueId as string));
|
||||||
@ -192,7 +196,7 @@ const IssueDetailsPage: NextPage = () => {
|
|||||||
) : null}
|
) : null}
|
||||||
<IssueDescriptionForm issue={issueDetails} handleFormSubmit={submitChanges} />
|
<IssueDescriptionForm issue={issueDetails} handleFormSubmit={submitChanges} />
|
||||||
<div className="mt-2 space-y-2">
|
<div className="mt-2 space-y-2">
|
||||||
<SubIssuesList parentIssue={issueDetails} />
|
<SubIssuesList parentIssue={issueDetails} user={user} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-3 py-3">
|
<div className="flex flex-col gap-3 py-3">
|
||||||
@ -204,8 +208,8 @@ const IssueDetailsPage: NextPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="space-y-5 pt-3">
|
<div className="space-y-5 pt-3">
|
||||||
<h3 className="text-lg text-brand-base">Comments/Activity</h3>
|
<h3 className="text-lg text-brand-base">Comments/Activity</h3>
|
||||||
<IssueActivitySection />
|
<IssueActivitySection user={user} />
|
||||||
<AddComment />
|
<AddComment user={user} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-1/3 space-y-5 border-l border-brand-base p-5">
|
<div className="basis-1/3 space-y-5 border-l border-brand-base p-5">
|
||||||
|
@ -17,6 +17,7 @@ import modulesService from "services/modules.service";
|
|||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// layouts
|
// layouts
|
||||||
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
|
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
|
||||||
// contexts
|
// contexts
|
||||||
@ -49,6 +50,8 @@ const SingleModule: React.FC = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId, moduleId } = router.query;
|
const { workspaceSlug, projectId, moduleId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const { data: issues } = useSWR(
|
const { data: issues } = useSWR(
|
||||||
@ -95,7 +98,13 @@ const SingleModule: React.FC = () => {
|
|||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
|
||||||
await modulesService
|
await modulesService
|
||||||
.addIssuesToModule(workspaceSlug as string, projectId as string, moduleId as string, data)
|
.addIssuesToModule(
|
||||||
|
workspaceSlug as string,
|
||||||
|
projectId as string,
|
||||||
|
moduleId as string,
|
||||||
|
data,
|
||||||
|
user
|
||||||
|
)
|
||||||
.then(() => mutate(MODULE_ISSUES(moduleId as string)))
|
.then(() => mutate(MODULE_ISSUES(moduleId as string)))
|
||||||
.catch(() =>
|
.catch(() =>
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
@ -186,6 +195,7 @@ const SingleModule: React.FC = () => {
|
|||||||
module={moduleDetails}
|
module={moduleDetails}
|
||||||
isOpen={moduleSidebar}
|
isOpen={moduleSidebar}
|
||||||
moduleIssues={moduleIssues}
|
moduleIssues={moduleIssues}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</ProjectAuthorizationWrapper>
|
</ProjectAuthorizationWrapper>
|
||||||
</IssueViewContextProvider>
|
</IssueViewContextProvider>
|
||||||
|
@ -6,6 +6,8 @@ import useSWR from "swr";
|
|||||||
|
|
||||||
// layouts
|
// layouts
|
||||||
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
|
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
|
||||||
|
// hooks
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// services
|
// services
|
||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
import modulesService from "services/modules.service";
|
import modulesService from "services/modules.service";
|
||||||
@ -37,6 +39,8 @@ const ProjectModules: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { data: activeProject } = useSWR(
|
const { data: activeProject } = useSWR(
|
||||||
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
|
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
@ -89,6 +93,7 @@ const ProjectModules: NextPage = () => {
|
|||||||
isOpen={createUpdateModule}
|
isOpen={createUpdateModule}
|
||||||
setIsOpen={setCreateUpdateModule}
|
setIsOpen={setCreateUpdateModule}
|
||||||
data={selectedModule}
|
data={selectedModule}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
{modules ? (
|
{modules ? (
|
||||||
modules.length > 0 ? (
|
modules.length > 0 ? (
|
||||||
@ -126,6 +131,7 @@ const ProjectModules: NextPage = () => {
|
|||||||
key={module.id}
|
key={module.id}
|
||||||
module={module}
|
module={module}
|
||||||
handleEditModule={() => handleEditModule(module)}
|
handleEditModule={() => handleEditModule(module)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -116,7 +116,7 @@ const SinglePage: NextPage = () => {
|
|||||||
if (!formData.name || formData.name.length === 0 || formData.name === "") return;
|
if (!formData.name || formData.name.length === 0 || formData.name === "") return;
|
||||||
|
|
||||||
await pagesService
|
await pagesService
|
||||||
.patchPage(workspaceSlug as string, projectId as string, pageId as string, formData)
|
.patchPage(workspaceSlug as string, projectId as string, pageId as string, formData, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate<IPage>(
|
mutate<IPage>(
|
||||||
PAGE_DETAILS(pageId as string),
|
PAGE_DETAILS(pageId as string),
|
||||||
@ -143,7 +143,7 @@ const SinglePage: NextPage = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await pagesService
|
await pagesService
|
||||||
.patchPage(workspaceSlug as string, projectId as string, pageId as string, formData)
|
.patchPage(workspaceSlug as string, projectId as string, pageId as string, formData, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(PAGE_DETAILS(pageId as string));
|
mutate(PAGE_DETAILS(pageId as string));
|
||||||
});
|
});
|
||||||
@ -237,7 +237,8 @@ const SinglePage: NextPage = () => {
|
|||||||
result.draggableId,
|
result.draggableId,
|
||||||
{
|
{
|
||||||
sort_order: newSortOrder,
|
sort_order: newSortOrder,
|
||||||
}
|
},
|
||||||
|
user
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -529,6 +530,7 @@ const SinglePage: NextPage = () => {
|
|||||||
block={block}
|
block={block}
|
||||||
projectDetails={projectDetails}
|
projectDetails={projectDetails}
|
||||||
index={index}
|
index={index}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{provided.placeholder}
|
{provided.placeholder}
|
||||||
@ -542,6 +544,7 @@ const SinglePage: NextPage = () => {
|
|||||||
<CreateUpdateBlockInline
|
<CreateUpdateBlockInline
|
||||||
handleClose={() => setCreateBlockForm(false)}
|
handleClose={() => setCreateBlockForm(false)}
|
||||||
focus="name"
|
focus="name"
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -550,6 +553,7 @@ const SinglePage: NextPage = () => {
|
|||||||
isOpen={labelModal}
|
isOpen={labelModal}
|
||||||
handleClose={() => setLabelModal(false)}
|
handleClose={() => setLabelModal(false)}
|
||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
@ -562,7 +566,7 @@ const SinglePage: NextPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<CreateBlock />
|
<CreateBlock user={user} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
@ -27,6 +27,7 @@ import { TPageViewProps } from "types";
|
|||||||
import type { NextPage } from "next";
|
import type { NextPage } from "next";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECT_DETAILS } from "constants/fetch-keys";
|
import { PROJECT_DETAILS } from "constants/fetch-keys";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
|
|
||||||
const AllPagesList = dynamic<TPagesListProps>(
|
const AllPagesList = dynamic<TPagesListProps>(
|
||||||
() => import("components/pages").then((a) => a.AllPagesList),
|
() => import("components/pages").then((a) => a.AllPagesList),
|
||||||
@ -66,6 +67,8 @@ const ProjectPages: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { storedValue: pageTab, setValue: setPageTab } = useLocalStorage("pageTab", "Recent");
|
const { storedValue: pageTab, setValue: setPageTab } = useLocalStorage("pageTab", "Recent");
|
||||||
|
|
||||||
const { data: projectDetails } = useSWR(
|
const { data: projectDetails } = useSWR(
|
||||||
@ -98,6 +101,7 @@ const ProjectPages: NextPage = () => {
|
|||||||
<CreateUpdatePageModal
|
<CreateUpdatePageModal
|
||||||
isOpen={createUpdatePageModal}
|
isOpen={createUpdatePageModal}
|
||||||
handleClose={() => setCreateUpdatePageModal(false)}
|
handleClose={() => setCreateUpdatePageModal(false)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<ProjectAuthorizationWrapper
|
<ProjectAuthorizationWrapper
|
||||||
breadcrumbs={
|
breadcrumbs={
|
||||||
|
@ -13,6 +13,7 @@ import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
|
|||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// components
|
// components
|
||||||
import { SettingsHeader } from "components/project";
|
import { SettingsHeader } from "components/project";
|
||||||
// ui
|
// ui
|
||||||
@ -35,6 +36,8 @@ const ControlSettings: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { data: projectDetails } = useSWR<IProject>(
|
const { data: projectDetails } = useSWR<IProject>(
|
||||||
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
|
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
@ -65,7 +68,7 @@ const ControlSettings: NextPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
await projectService
|
await projectService
|
||||||
.updateProject(workspaceSlug as string, projectId as string, payload)
|
.updateProject(workspaceSlug as string, projectId as string, payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate(PROJECT_DETAILS(projectId as string));
|
mutate(PROJECT_DETAILS(projectId as string));
|
||||||
mutate(PROJECTS_LIST(workspaceSlug as string));
|
mutate(PROJECTS_LIST(workspaceSlug as string));
|
||||||
|
@ -16,6 +16,7 @@ import { CreateUpdateEstimateModal, SingleEstimate } from "components/estimates"
|
|||||||
import { SettingsHeader } from "components/project";
|
import { SettingsHeader } from "components/project";
|
||||||
//hooks
|
//hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// ui
|
// ui
|
||||||
import { EmptyState, Loader, SecondaryButton } from "components/ui";
|
import { EmptyState, Loader, SecondaryButton } from "components/ui";
|
||||||
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs";
|
||||||
@ -37,6 +38,8 @@ const EstimatesSettings: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const { projectDetails } = useProjectDetails();
|
const { projectDetails } = useProjectDetails();
|
||||||
@ -63,7 +66,7 @@ const EstimatesSettings: NextPage = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
estimatesService
|
estimatesService
|
||||||
.deleteEstimate(workspaceSlug as string, projectId as string, estimateId)
|
.deleteEstimate(workspaceSlug as string, projectId as string, estimateId, user)
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "error",
|
type: "error",
|
||||||
@ -87,7 +90,7 @@ const EstimatesSettings: NextPage = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
projectService
|
projectService
|
||||||
.updateProject(workspaceSlug as string, projectId as string, { estimate: null })
|
.updateProject(workspaceSlug as string, projectId as string, { estimate: null }, user)
|
||||||
.catch(() =>
|
.catch(() =>
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "error",
|
type: "error",
|
||||||
@ -106,6 +109,7 @@ const EstimatesSettings: NextPage = () => {
|
|||||||
setEstimateFormOpen(false);
|
setEstimateFormOpen(false);
|
||||||
setEstimateToUpdate(undefined);
|
setEstimateToUpdate(undefined);
|
||||||
}}
|
}}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<ProjectAuthorizationWrapper
|
<ProjectAuthorizationWrapper
|
||||||
breadcrumbs={
|
breadcrumbs={
|
||||||
@ -149,6 +153,7 @@ const EstimatesSettings: NextPage = () => {
|
|||||||
estimate={estimate}
|
estimate={estimate}
|
||||||
editEstimate={(estimate) => editEstimate(estimate)}
|
editEstimate={(estimate) => editEstimate(estimate)}
|
||||||
handleEstimateDelete={(estimateId) => removeEstimate(estimateId)}
|
handleEstimateDelete={(estimateId) => removeEstimate(estimateId)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</section>
|
</section>
|
||||||
|
@ -11,6 +11,7 @@ import trackEventServices, { MiscellaneousEventType } from "services/track-event
|
|||||||
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
|
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// components
|
// components
|
||||||
import { SettingsHeader } from "components/project";
|
import { SettingsHeader } from "components/project";
|
||||||
// ui
|
// ui
|
||||||
@ -75,6 +76,8 @@ const FeaturesSettings: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const { data: projectDetails } = useSWR(
|
const { data: projectDetails } = useSWR(
|
||||||
@ -134,7 +137,7 @@ const FeaturesSettings: NextPage = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
await projectService
|
await projectService
|
||||||
.updateProject(workspaceSlug as string, projectId as string, formData)
|
.updateProject(workspaceSlug as string, projectId as string, formData, user)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
mutate(
|
mutate(
|
||||||
projectDetails.is_favorite
|
projectDetails.is_favorite
|
||||||
@ -194,7 +197,8 @@ const FeaturesSettings: NextPage = () => {
|
|||||||
},
|
},
|
||||||
!projectDetails?.[feature.property as keyof IProject]
|
!projectDetails?.[feature.property as keyof IProject]
|
||||||
? getEventType(feature.title, true)
|
? getEventType(feature.title, true)
|
||||||
: getEventType(feature.title, false)
|
: getEventType(feature.title, false),
|
||||||
|
user
|
||||||
);
|
);
|
||||||
handleSubmit({
|
handleSubmit({
|
||||||
[feature.property]: !projectDetails?.[feature.property as keyof IProject],
|
[feature.property]: !projectDetails?.[feature.property as keyof IProject],
|
||||||
|
@ -17,6 +17,7 @@ import { ImagePickerPopover } from "components/core";
|
|||||||
import EmojiIconPicker from "components/emoji-icon-picker";
|
import EmojiIconPicker from "components/emoji-icon-picker";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// ui
|
// ui
|
||||||
import {
|
import {
|
||||||
Input,
|
Input,
|
||||||
@ -45,6 +46,8 @@ const defaultValues: Partial<IProject> = {
|
|||||||
const GeneralSettings: NextPage = () => {
|
const GeneralSettings: NextPage = () => {
|
||||||
const [selectProject, setSelectedProject] = useState<string | null>(null);
|
const [selectProject, setSelectedProject] = useState<string | null>(null);
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -83,7 +86,7 @@ const GeneralSettings: NextPage = () => {
|
|||||||
if (!workspaceSlug || !projectDetails) return;
|
if (!workspaceSlug || !projectDetails) return;
|
||||||
|
|
||||||
await projectService
|
await projectService
|
||||||
.updateProject(workspaceSlug as string, projectDetails.id, payload)
|
.updateProject(workspaceSlug as string, projectDetails.id, payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IProject>(
|
mutate<IProject>(
|
||||||
PROJECT_DETAILS(projectDetails.id),
|
PROJECT_DETAILS(projectDetails.id),
|
||||||
@ -154,6 +157,7 @@ const GeneralSettings: NextPage = () => {
|
|||||||
onSuccess={() => {
|
onSuccess={() => {
|
||||||
router.push(`/${workspaceSlug}/projects`);
|
router.push(`/${workspaceSlug}/projects`);
|
||||||
}}
|
}}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<form onSubmit={handleSubmit(onSubmit)} className="p-8">
|
<form onSubmit={handleSubmit(onSubmit)} className="p-8">
|
||||||
<SettingsHeader />
|
<SettingsHeader />
|
||||||
|
@ -4,6 +4,8 @@ import { useRouter } from "next/router";
|
|||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
|
// hooks
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// services
|
// services
|
||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
import issuesService from "services/issues.service";
|
import issuesService from "services/issues.service";
|
||||||
@ -47,6 +49,8 @@ const LabelsSettings: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const scrollToRef = useRef<HTMLDivElement>(null);
|
const scrollToRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const { data: projectDetails } = useSWR(
|
const { data: projectDetails } = useSWR(
|
||||||
@ -85,11 +89,13 @@ const LabelsSettings: NextPage = () => {
|
|||||||
isOpen={labelsListModal}
|
isOpen={labelsListModal}
|
||||||
handleClose={() => setLabelsListModal(false)}
|
handleClose={() => setLabelsListModal(false)}
|
||||||
parent={parentLabel}
|
parent={parentLabel}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<DeleteLabelModal
|
<DeleteLabelModal
|
||||||
isOpen={!!selectDeleteLabel}
|
isOpen={!!selectDeleteLabel}
|
||||||
data={selectDeleteLabel ?? null}
|
data={selectDeleteLabel ?? null}
|
||||||
onClose={() => setSelectDeleteLabel(null)}
|
onClose={() => setSelectDeleteLabel(null)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<ProjectAuthorizationWrapper
|
<ProjectAuthorizationWrapper
|
||||||
breadcrumbs={
|
breadcrumbs={
|
||||||
@ -160,6 +166,7 @@ const LabelsSettings: NextPage = () => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
handleLabelDelete={() => setSelectDeleteLabel(label)}
|
handleLabelDelete={() => setSelectDeleteLabel(label)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
|
@ -135,6 +135,7 @@ const MembersSettings: NextPage = () => {
|
|||||||
isOpen={inviteModal}
|
isOpen={inviteModal}
|
||||||
setIsOpen={setInviteModal}
|
setIsOpen={setInviteModal}
|
||||||
members={members}
|
members={members}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<ProjectAuthorizationWrapper
|
<ProjectAuthorizationWrapper
|
||||||
breadcrumbs={
|
breadcrumbs={
|
||||||
|
@ -8,6 +8,7 @@ import useSWR from "swr";
|
|||||||
import stateService from "services/state.service";
|
import stateService from "services/state.service";
|
||||||
// hooks
|
// hooks
|
||||||
import useProjectDetails from "hooks/use-project-details";
|
import useProjectDetails from "hooks/use-project-details";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// layouts
|
// layouts
|
||||||
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
|
import { ProjectAuthorizationWrapper } from "layouts/auth-layout";
|
||||||
// components
|
// components
|
||||||
@ -38,6 +39,8 @@ const StatesSettings: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { projectDetails } = useProjectDetails();
|
const { projectDetails } = useProjectDetails();
|
||||||
|
|
||||||
const { data: states } = useSWR(
|
const { data: states } = useSWR(
|
||||||
@ -55,6 +58,7 @@ const StatesSettings: NextPage = () => {
|
|||||||
isOpen={!!selectDeleteState}
|
isOpen={!!selectDeleteState}
|
||||||
data={statesList?.find((s) => s.id === selectDeleteState) ?? null}
|
data={statesList?.find((s) => s.id === selectDeleteState) ?? null}
|
||||||
onClose={() => setSelectDeleteState(null)}
|
onClose={() => setSelectDeleteState(null)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<ProjectAuthorizationWrapper
|
<ProjectAuthorizationWrapper
|
||||||
breadcrumbs={
|
breadcrumbs={
|
||||||
@ -100,6 +104,7 @@ const StatesSettings: NextPage = () => {
|
|||||||
}}
|
}}
|
||||||
data={null}
|
data={null}
|
||||||
selectedGroup={key as keyof StateGroup}
|
selectedGroup={key as keyof StateGroup}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{orderedStateGroups[key].map((state, index) =>
|
{orderedStateGroups[key].map((state, index) =>
|
||||||
@ -111,6 +116,7 @@ const StatesSettings: NextPage = () => {
|
|||||||
statesList={statesList}
|
statesList={statesList}
|
||||||
handleEditState={() => setSelectedState(state.id)}
|
handleEditState={() => setSelectedState(state.id)}
|
||||||
handleDeleteState={() => setSelectDeleteState(state.id)}
|
handleDeleteState={() => setSelectDeleteState(state.id)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
@ -126,6 +132,7 @@ const StatesSettings: NextPage = () => {
|
|||||||
statesList?.find((state) => state.id === selectedState) ?? null
|
statesList?.find((state) => state.id === selectedState) ?? null
|
||||||
}
|
}
|
||||||
selectedGroup={key as keyof StateGroup}
|
selectedGroup={key as keyof StateGroup}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -4,6 +4,8 @@ import { useRouter } from "next/router";
|
|||||||
|
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
|
// hooks
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// services
|
// services
|
||||||
import viewsService from "services/views.service";
|
import viewsService from "services/views.service";
|
||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
@ -34,6 +36,8 @@ const ProjectViews: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug, projectId } = router.query;
|
const { workspaceSlug, projectId } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { data: activeProject } = useSWR(
|
const { data: activeProject } = useSWR(
|
||||||
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
|
workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null,
|
||||||
workspaceSlug && projectId
|
workspaceSlug && projectId
|
||||||
@ -86,11 +90,13 @@ const ProjectViews: NextPage = () => {
|
|||||||
isOpen={createUpdateViewModal}
|
isOpen={createUpdateViewModal}
|
||||||
handleClose={() => setCreateUpdateViewModal(false)}
|
handleClose={() => setCreateUpdateViewModal(false)}
|
||||||
data={selectedViewToUpdate}
|
data={selectedViewToUpdate}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<DeleteViewModal
|
<DeleteViewModal
|
||||||
isOpen={deleteViewModal}
|
isOpen={deleteViewModal}
|
||||||
data={selectedViewToDelete}
|
data={selectedViewToDelete}
|
||||||
setIsOpen={setDeleteViewModal}
|
setIsOpen={setDeleteViewModal}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
{views ? (
|
{views ? (
|
||||||
views.length > 0 ? (
|
views.length > 0 ? (
|
||||||
|
@ -9,6 +9,7 @@ import projectService from "services/project.service";
|
|||||||
// hooks
|
// hooks
|
||||||
import useProjects from "hooks/use-projects";
|
import useProjects from "hooks/use-projects";
|
||||||
import useWorkspaces from "hooks/use-workspaces";
|
import useWorkspaces from "hooks/use-workspaces";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// layouts
|
// layouts
|
||||||
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
||||||
// components
|
// components
|
||||||
@ -30,6 +31,8 @@ const ProjectsPage: NextPage = () => {
|
|||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
// context data
|
// context data
|
||||||
const { activeWorkspace } = useWorkspaces();
|
const { activeWorkspace } = useWorkspaces();
|
||||||
const { projects } = useProjects();
|
const { projects } = useProjects();
|
||||||
@ -81,6 +84,7 @@ const ProjectsPage: NextPage = () => {
|
|||||||
isOpen={!!deleteProject}
|
isOpen={!!deleteProject}
|
||||||
onClose={() => setDeleteProject(null)}
|
onClose={() => setDeleteProject(null)}
|
||||||
data={projects?.find((item) => item.id === deleteProject) ?? null}
|
data={projects?.find((item) => item.id === deleteProject) ?? null}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
{projects ? (
|
{projects ? (
|
||||||
<div className="p-8">
|
<div className="p-8">
|
||||||
|
@ -12,6 +12,7 @@ import workspaceService from "services/workspace.service";
|
|||||||
import fileService from "services/file.service";
|
import fileService from "services/file.service";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// layouts
|
// layouts
|
||||||
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
||||||
import SettingsNavbar from "layouts/settings-navbar";
|
import SettingsNavbar from "layouts/settings-navbar";
|
||||||
@ -49,6 +50,8 @@ const WorkspaceSettings: NextPage = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
|
||||||
|
const { user } = useUserAuth();
|
||||||
|
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const { data: activeWorkspace } = useSWR(
|
const { data: activeWorkspace } = useSWR(
|
||||||
@ -82,7 +85,7 @@ const WorkspaceSettings: NextPage = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
await workspaceService
|
await workspaceService
|
||||||
.updateWorkspace(activeWorkspace.slug, payload)
|
.updateWorkspace(activeWorkspace.slug, payload, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
mutate<IWorkspace[]>(USER_WORKSPACES, (prevData) =>
|
mutate<IWorkspace[]>(USER_WORKSPACES, (prevData) =>
|
||||||
prevData?.map((workspace) => (workspace.id === res.id ? res : workspace))
|
prevData?.map((workspace) => (workspace.id === res.id ? res : workspace))
|
||||||
@ -114,7 +117,7 @@ const WorkspaceSettings: NextPage = () => {
|
|||||||
|
|
||||||
fileService.deleteFile(asset).then(() => {
|
fileService.deleteFile(asset).then(() => {
|
||||||
workspaceService
|
workspaceService
|
||||||
.updateWorkspace(activeWorkspace.slug, { logo: "" })
|
.updateWorkspace(activeWorkspace.slug, { logo: "" }, user)
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "success",
|
type: "success",
|
||||||
@ -169,6 +172,7 @@ const WorkspaceSettings: NextPage = () => {
|
|||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
}}
|
}}
|
||||||
data={activeWorkspace ?? null}
|
data={activeWorkspace ?? null}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<div className="p-8">
|
<div className="p-8">
|
||||||
<SettingsHeader />
|
<SettingsHeader />
|
||||||
|
@ -135,6 +135,7 @@ const MembersSettings: NextPage = () => {
|
|||||||
setIsOpen={setInviteModal}
|
setIsOpen={setInviteModal}
|
||||||
workspace_slug={workspaceSlug as string}
|
workspace_slug={workspaceSlug as string}
|
||||||
members={members}
|
members={members}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
<WorkspaceAuthorizationLayout
|
<WorkspaceAuthorizationLayout
|
||||||
breadcrumbs={
|
breadcrumbs={
|
||||||
|
@ -10,28 +10,12 @@ const jitsu = createClient({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
const { eventName, extra } = req.body;
|
const { eventName, user, extra } = req.body;
|
||||||
|
|
||||||
if (!eventName) {
|
if (!eventName) {
|
||||||
return res.status(400).json({ message: "Bad request" });
|
return res.status(400).json({ message: "Bad request" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const cookie = convertCookieStringToObject(req.headers.cookie);
|
|
||||||
const accessToken = cookie?.accessToken;
|
|
||||||
|
|
||||||
if (!accessToken) return res.status(401).json({ message: "Unauthorized" });
|
|
||||||
|
|
||||||
const user = await fetch(`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/users/me/`, {
|
|
||||||
method: "GET",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${accessToken}`,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((data) => data.user)
|
|
||||||
.catch(() => res.status(401).json({ message: "Unauthorized" }));
|
|
||||||
|
|
||||||
if (!user) return res.status(401).json({ message: "Unauthorized" });
|
if (!user) return res.status(401).json({ message: "Unauthorized" });
|
||||||
|
|
||||||
// TODO: cache user info
|
// TODO: cache user info
|
||||||
|
@ -47,6 +47,7 @@ const CreateWorkspace: NextPage = () => {
|
|||||||
defaultValues={defaultValues}
|
defaultValues={defaultValues}
|
||||||
setDefaultValues={() => {}}
|
setDefaultValues={() => {}}
|
||||||
onSubmit={(res) => router.push(`/${res.slug}`)}
|
onSubmit={(res) => router.push(`/${res.slug}`)}
|
||||||
|
user={user}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -95,21 +95,21 @@ const HomePage: NextPage = () => {
|
|||||||
<Spinner />
|
<Spinner />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-screen w-full items-center justify-center overflow-auto bg-gray-50">
|
<div className="flex h-screen w-full items-center justify-center overflow-auto">
|
||||||
<div className="flex min-h-full w-full flex-col justify-center py-12 px-6 lg:px-8">
|
<div className="flex min-h-full w-full flex-col justify-center py-12 px-6 lg:px-8">
|
||||||
<div className="flex flex-col gap-10 sm:mx-auto sm:w-full sm:max-w-md">
|
<div className="flex flex-col gap-10 sm:mx-auto sm:w-full sm:max-w-md">
|
||||||
<div className="flex flex-col items-center justify-center gap-10">
|
<div className="flex flex-col items-center justify-center gap-10">
|
||||||
<Image src={Logo} height={80} width={80} alt="Plane Web Logo" />
|
<Image src={Logo} height={80} width={80} alt="Plane Web Logo" />
|
||||||
<div className="text-center text-xl font-medium text-black">
|
<div className="text-center text-xl font-medium text-brand-base">
|
||||||
Sign In to your Plane Account
|
Sign In to your Plane Account
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col rounded-[10px] bg-white shadow-md">
|
<div className="flex flex-col rounded-[10px] bg-brand-base shadow-md">
|
||||||
{parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0") ? (
|
{parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0") ? (
|
||||||
<>
|
<>
|
||||||
<EmailCodeForm />
|
<EmailCodeForm />
|
||||||
<div className="flex flex-col gap-3 py-5 px-5 border-t items-center justify-center border-gray-300 ">
|
<div className="flex flex-col items-center justify-center gap-3 border-t border-brand-base py-5 px-5">
|
||||||
<GoogleLoginButton handleSignIn={handleGoogleSignIn} />
|
<GoogleLoginButton handleSignIn={handleGoogleSignIn} />
|
||||||
<GithubLoginButton handleSignIn={handleGithubSignIn} />
|
<GithubLoginButton handleSignIn={handleGithubSignIn} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -124,7 +124,7 @@ const OnBoard: NextPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : workspaces && workspaces.length > 0 ? (
|
) : workspaces && workspaces.length > 0 ? (
|
||||||
<div className="flex flex-col gap-y-3">
|
<div className="flex flex-col w-full overflow-auto gap-y-3">
|
||||||
<h2 className="mb-4 text-xl font-medium">Your workspaces</h2>
|
<h2 className="mb-4 text-xl font-medium">Your workspaces</h2>
|
||||||
{workspaces.map((workspace) => (
|
{workspaces.map((workspace) => (
|
||||||
<Link key={workspace.id} href={workspace.slug}>
|
<Link key={workspace.id} href={workspace.slug}>
|
||||||
|
@ -49,18 +49,18 @@ const MagicSignIn: NextPage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<DefaultLayout>
|
<DefaultLayout>
|
||||||
<div className="flex h-screen w-full items-center justify-center overflow-auto bg-gray-50">
|
<div className="h-screen w-full overflow-auto bg-brand-surface-1">
|
||||||
{isSigningIn ? (
|
{isSigningIn ? (
|
||||||
<div className="flex h-full w-full flex-col items-center justify-center gap-y-2">
|
<div className="flex h-full w-full flex-col items-center justify-center gap-y-2">
|
||||||
<h2 className="text-4xl">Signing you in...</h2>
|
<h2 className="text-4xl">Signing you in...</h2>
|
||||||
<p className="text-sm text-gray-600">
|
<p className="text-sm text-brand-secondary">
|
||||||
Please wait while we are preparing your take off.
|
Please wait while we are preparing your take off.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
) : errorSigningIn ? (
|
) : errorSigningIn ? (
|
||||||
<div className="flex h-full w-full flex-col items-center justify-center gap-y-2">
|
<div className="flex h-full w-full flex-col items-center justify-center gap-y-2">
|
||||||
<h2 className="text-4xl">Error</h2>
|
<h2 className="text-4xl">Error</h2>
|
||||||
<p className="text-sm text-gray-600">
|
<p className="text-sm text-brand-secondary">
|
||||||
{errorSigningIn}.
|
{errorSigningIn}.
|
||||||
<span
|
<span
|
||||||
className="cursor-pointer underline"
|
className="cursor-pointer underline"
|
||||||
@ -90,7 +90,7 @@ const MagicSignIn: NextPage = () => {
|
|||||||
) : (
|
) : (
|
||||||
<div className="flex h-full w-full flex-col items-center justify-center gap-y-2">
|
<div className="flex h-full w-full flex-col items-center justify-center gap-y-2">
|
||||||
<h2 className="text-4xl">Success</h2>
|
<h2 className="text-4xl">Success</h2>
|
||||||
<p className="text-sm text-gray-600">Redirecting you to the app...</p>
|
<p className="text-sm text-brand-secondary">Redirecting you to the app...</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -53,9 +53,9 @@ const Onboarding: NextPage = () => {
|
|||||||
{step === 1 ? (
|
{step === 1 ? (
|
||||||
<UserDetails user={user} setStep={setStep} setUserRole={setUserRole} />
|
<UserDetails user={user} setStep={setStep} setUserRole={setUserRole} />
|
||||||
) : step === 2 ? (
|
) : step === 2 ? (
|
||||||
<Workspace setStep={setStep} setWorkspace={setWorkspace} />
|
<Workspace setStep={setStep} setWorkspace={setWorkspace} user={user} />
|
||||||
) : (
|
) : (
|
||||||
<InviteMembers setStep={setStep} workspace={workspace} />
|
<InviteMembers setStep={setStep} workspace={workspace} user={user} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@ -80,7 +80,7 @@ const Onboarding: NextPage = () => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (step === 8) {
|
if (step === 8) {
|
||||||
userService
|
userService
|
||||||
.updateUserOnBoard({ userRole })
|
.updateUserOnBoard({ userRole }, user)
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
mutate<ICurrentUserResponse>(
|
mutate<ICurrentUserResponse>(
|
||||||
CURRENT_USER,
|
CURRENT_USER,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user