feat: quick add (#2240)

* feat: quick add

* style: made text color muted
This commit is contained in:
Dakshesh Jain 2023-09-22 15:31:54 +05:30 committed by GitHub
parent daa0b16960
commit 771ca585db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 847 additions and 99 deletions

View file

@ -2,3 +2,4 @@ export * from "./calendar-header";
export * from "./calendar";
export * from "./single-date";
export * from "./single-issue";
export * from "./inline-create-issue-form";

View file

@ -0,0 +1,91 @@
import { useEffect, useRef, useState } from "react";
// react hook form
import { useFormContext } from "react-hook-form";
import { InlineCreateIssueFormWrapper } from "components/core";
// hooks
import useProjectDetails from "hooks/use-project-details";
// types
import { IIssue } from "types";
type Props = {
isOpen: boolean;
handleClose: () => void;
onSuccess?: (data: IIssue) => Promise<void> | void;
prePopulatedData?: Partial<IIssue>;
};
const useCheckIfThereIsSpaceOnRight = (ref: React.RefObject<HTMLDivElement>) => {
const [isThereSpaceOnRight, setIsThereSpaceOnRight] = useState(true);
useEffect(() => {
if (!ref.current) return;
const { right } = ref.current.getBoundingClientRect();
const width = right + 250;
if (width > window.innerWidth) setIsThereSpaceOnRight(false);
else setIsThereSpaceOnRight(true);
}, [ref]);
return isThereSpaceOnRight;
};
const InlineInput = () => {
const { projectDetails } = useProjectDetails();
const { register, setFocus } = useFormContext();
useEffect(() => {
setFocus("name");
}, [setFocus]);
return (
<>
<h4 className="text-sm font-medium leading-5 text-custom-text-400">
{projectDetails?.identifier ?? "..."}
</h4>
<input
type="text"
autoComplete="off"
placeholder="Issue Title"
{...register("name", {
required: "Issue title is required.",
})}
className="w-full px-2 py-1.5 rounded-md bg-transparent text-sm font-medium leading-5 text-custom-text-200 outline-none"
/>
</>
);
};
export const CalendarInlineCreateIssueForm: React.FC<Props> = (props) => {
const { isOpen } = props;
const ref = useRef<HTMLDivElement>(null);
const isSpaceOnRight = useCheckIfThereIsSpaceOnRight(ref);
return (
<>
<div
ref={ref}
className={`absolute -translate-x-1 top-5 transition-all z-20 ${
isOpen ? "opacity-100 scale-100" : "opacity-0 pointer-events-none scale-95"
} ${isSpaceOnRight ? "left-full" : "right-0"}`}
>
<InlineCreateIssueFormWrapper
{...props}
className="flex w-60 p-1 px-1.5 rounded items-center gap-x-3 bg-custom-background-100 shadow-custom-shadow-md transition-opacity"
>
<InlineInput />
</InlineCreateIssueFormWrapper>
</div>
{/* Added to make any other element as outside click. This will make input also to be outside. */}
{isOpen && <div className="w-screen h-screen fixed inset-0 z-10" />}
</>
);
};

View file

@ -1,10 +1,14 @@
import React, { useState } from "react";
// next
import { useRouter } from "next/router";
// react-beautiful-dnd
import { Draggable } from "react-beautiful-dnd";
// component
import StrictModeDroppable from "components/dnd/StrictModeDroppable";
import { SingleCalendarIssue } from "./single-issue";
import { CalendarInlineCreateIssueForm } from "./inline-create-issue-form";
// icons
import { PlusSmallIcon } from "@heroicons/react/24/outline";
// helper
@ -26,17 +30,14 @@ type Props = {
isNotAllowed: boolean;
};
export const SingleCalendarDate: React.FC<Props> = ({
handleIssueAction,
date,
index,
addIssueToDate,
isMonthlyView,
showWeekEnds,
user,
isNotAllowed,
}) => {
export const SingleCalendarDate: React.FC<Props> = (props) => {
const { handleIssueAction, date, index, isMonthlyView, showWeekEnds, user, isNotAllowed } = props;
const router = useRouter();
const { cycleId, moduleId } = router.query;
const [showAllIssues, setShowAllIssues] = useState(false);
const [isCreateIssueFormOpen, setIsCreateIssueFormOpen] = useState(false);
const totalIssues = date.issues.length;
@ -78,6 +79,17 @@ export const SingleCalendarDate: React.FC<Props> = ({
)}
</Draggable>
))}
<CalendarInlineCreateIssueForm
isOpen={isCreateIssueFormOpen}
handleClose={() => setIsCreateIssueFormOpen(false)}
prePopulatedData={{
target_date: date.date,
...(cycleId && { cycle: cycleId.toString() }),
...(moduleId && { module: moduleId.toString() }),
}}
/>
{totalIssues > 4 && (
<button
type="button"
@ -93,7 +105,7 @@ export const SingleCalendarDate: React.FC<Props> = ({
>
<button
className="flex items-center justify-center gap-1 text-center"
onClick={() => addIssueToDate(date.date)}
onClick={() => setIsCreateIssueFormOpen(true)}
>
<PlusSmallIcon className="h-4 w-4 text-custom-text-200" />
Add issue