fix: module date picker (#6691)
* fix: Handled workspace switcher closing on click * fix: reverted module date picker changes
This commit is contained in:
parent
392a6e0137
commit
0188cabbde
3 changed files with 75 additions and 113 deletions
|
|
@ -6,7 +6,6 @@ import { useParams } from "next/navigation";
|
|||
import { Controller, useForm } from "react-hook-form";
|
||||
import {
|
||||
ArchiveRestoreIcon,
|
||||
CalendarCheck2,
|
||||
CalendarClock,
|
||||
ChevronDown,
|
||||
ChevronRight,
|
||||
|
|
@ -43,7 +42,7 @@ import {
|
|||
TextArea,
|
||||
} from "@plane/ui";
|
||||
// components
|
||||
import { DateDropdown, MemberDropdown } from "@/components/dropdowns";
|
||||
import { DateRangeDropdown, MemberDropdown } from "@/components/dropdowns";
|
||||
import {
|
||||
ArchiveModuleModal,
|
||||
DeleteModuleModal,
|
||||
|
|
@ -105,7 +104,7 @@ export const ModuleAnalyticsSidebar: React.FC<Props> = observer((props) => {
|
|||
const estimateType = areEstimateEnabled && currentActiveEstimateId && estimateById(currentActiveEstimateId);
|
||||
const isEstimatePointValid = estimateType && estimateType?.type == EEstimateSystem.POINTS ? true : false;
|
||||
|
||||
const { reset, control, getValues } = useForm({
|
||||
const { reset, control } = useForm({
|
||||
defaultValues,
|
||||
});
|
||||
|
||||
|
|
@ -195,8 +194,11 @@ export const ModuleAnalyticsSidebar: React.FC<Props> = observer((props) => {
|
|||
});
|
||||
};
|
||||
|
||||
const handleDateChange = async (data: Partial<IModule>) => {
|
||||
submitChanges(data);
|
||||
const handleDateChange = async (startDate: Date | undefined, targetDate: Date | undefined) => {
|
||||
submitChanges({
|
||||
start_date: startDate ? renderFormattedPayloadDate(startDate) : null,
|
||||
target_date: targetDate ? renderFormattedPayloadDate(targetDate) : null,
|
||||
});
|
||||
setToast({
|
||||
type: TOAST_TYPE.SUCCESS,
|
||||
title: "Success!",
|
||||
|
|
@ -413,59 +415,40 @@ export const ModuleAnalyticsSidebar: React.FC<Props> = observer((props) => {
|
|||
<div className="flex items-center justify-start gap-1">
|
||||
<div className="flex w-2/5 items-center justify-start gap-2 text-custom-text-300">
|
||||
<CalendarClock className="h-4 w-4" />
|
||||
<span className="text-base">Start date</span>
|
||||
<span className="text-base">{t("date_range")}</span>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<div className="h-7 w-3/5">
|
||||
<Controller
|
||||
control={control}
|
||||
name="start_date"
|
||||
control={control}
|
||||
rules={{ required: "Please select a date" }}
|
||||
render={({ field: { value, onChange } }) => (
|
||||
<DateDropdown
|
||||
value={value ?? null}
|
||||
onChange={(val) => {
|
||||
console.log(val);
|
||||
onChange(renderFormattedPayloadDate(val));
|
||||
handleDateChange({ start_date: val ? renderFormattedPayloadDate(val) : null });
|
||||
render={({ field: { value: startDateValue, onChange: onChangeStartDate } }) => (
|
||||
<Controller
|
||||
control={control}
|
||||
name="target_date"
|
||||
render={({ field: { value: endDateValue, onChange: onChangeEndDate } }) => {
|
||||
const startDate = getDate(startDateValue);
|
||||
const endDate = getDate(endDateValue);
|
||||
return (
|
||||
<DateRangeDropdown
|
||||
buttonContainerClassName="w-full"
|
||||
buttonVariant="background-with-text"
|
||||
value={{
|
||||
from: startDate,
|
||||
to: endDate,
|
||||
}}
|
||||
onSelect={(val) => {
|
||||
onChangeStartDate(val?.from ? renderFormattedPayloadDate(val.from) : null);
|
||||
onChangeEndDate(val?.to ? renderFormattedPayloadDate(val.to) : null);
|
||||
handleDateChange(val?.from, val?.to);
|
||||
}}
|
||||
placeholder={{
|
||||
from: t("start_date"),
|
||||
to: t("target_date"),
|
||||
}}
|
||||
disabled={!isEditingAllowed || isArchived}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
placeholder={t("common.order_by.start_date")}
|
||||
icon={<CalendarClock className="h-3 w-3 flex-shrink-0" />}
|
||||
buttonVariant={value ? "border-with-text" : "border-without-text"}
|
||||
buttonContainerClassName={`h-6 w-full flex ${!isEditingAllowed || isArchived ? "cursor-not-allowed" : "cursor-pointer"} items-center gap-1.5 text-custom-text-300 rounded text-xs`}
|
||||
optionsClassName="z-30"
|
||||
disabled={!isEditingAllowed || isArchived}
|
||||
showTooltip
|
||||
maxDate={getDate(getValues("target_date"))}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-start gap-1">
|
||||
<div className="flex w-2/5 items-center justify-start gap-2 text-custom-text-300">
|
||||
<CalendarClock className="h-4 w-4" />
|
||||
<span className="text-base">Due date</span>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Controller
|
||||
name="target_date"
|
||||
control={control}
|
||||
rules={{ required: "Please select a date" }}
|
||||
render={({ field: { value, onChange } }) => (
|
||||
<DateDropdown
|
||||
value={getDate(value) ?? null}
|
||||
onChange={(val) => {
|
||||
onChange(renderFormattedPayloadDate(val));
|
||||
handleDateChange({ target_date: val ? renderFormattedPayloadDate(val) : null });
|
||||
}}
|
||||
placeholder={t("common.order_by.due_date")}
|
||||
icon={<CalendarCheck2 className="h-3 w-3 flex-shrink-0" />}
|
||||
buttonVariant={value ? "border-with-text" : "border-without-text"}
|
||||
buttonContainerClassName={`h-6 w-full flex ${!isEditingAllowed || isArchived ? "cursor-not-allowed" : "cursor-pointer"} items-center gap-1.5 text-custom-text-300 rounded text-xs`}
|
||||
optionsClassName="z-30"
|
||||
disabled={!isEditingAllowed || isArchived}
|
||||
showTooltip
|
||||
minDate={getDate(getValues("start_date"))}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import React, { SyntheticEvent, useRef } from "react";
|
|||
import { observer } from "mobx-react";
|
||||
import Link from "next/link";
|
||||
import { useParams, usePathname, useSearchParams } from "next/navigation";
|
||||
import { CalendarCheck2, CalendarClock, Info, SquareUser } from "lucide-react";
|
||||
import { Info, SquareUser } from "lucide-react";
|
||||
// plane package imports
|
||||
import {
|
||||
MODULE_STATUS,
|
||||
|
|
@ -14,7 +14,6 @@ import {
|
|||
EUserPermissions,
|
||||
EUserPermissionsLevel,
|
||||
} from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
import { IModule } from "@plane/types";
|
||||
import {
|
||||
Card,
|
||||
|
|
@ -27,7 +26,7 @@ import {
|
|||
setToast,
|
||||
} from "@plane/ui";
|
||||
// components
|
||||
import { DateDropdown } from "@/components/dropdowns";
|
||||
import { DateRangeDropdown } from "@/components/dropdowns";
|
||||
import { ButtonAvatars } from "@/components/dropdowns/member/avatar";
|
||||
import { ModuleQuickActions } from "@/components/modules";
|
||||
import { ModuleStatusDropdown } from "@/components/modules/module-status-dropdown";
|
||||
|
|
@ -59,7 +58,7 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
const { getModuleById, addModuleToFavorites, removeModuleFromFavorites, updateModuleDetails } = useModule();
|
||||
const { getUserDetails } = useMember();
|
||||
const { captureEvent } = useEventTracker();
|
||||
const { t } = useTranslation();
|
||||
|
||||
// derived values
|
||||
const moduleDetails = getModuleById(moduleId);
|
||||
const isEditingAllowed = allowPermissions(
|
||||
|
|
@ -67,6 +66,7 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
EUserPermissionsLevel.PROJECT
|
||||
);
|
||||
const isDisabled = !isEditingAllowed || !!moduleDetails?.archived_at;
|
||||
const renderIcon = Boolean(moduleDetails?.start_date) || Boolean(moduleDetails?.target_date);
|
||||
|
||||
const { isMobile } = usePlatformOS();
|
||||
const handleAddToFavorites = (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
|
|
@ -236,38 +236,27 @@ export const ModuleCardItem: React.FC<Props> = observer((props) => {
|
|||
)}
|
||||
</div>
|
||||
<LinearProgressIndicator size="lg" data={progressIndicatorData} />
|
||||
<div className="flex items-center gap-2 py-0.5" onClick={handleEventPropagation}>
|
||||
<DateDropdown
|
||||
value={moduleDetails.start_date}
|
||||
onChange={(val) => {
|
||||
<div className="flex items-center justify-between py-0.5" onClick={handleEventPropagation}>
|
||||
<DateRangeDropdown
|
||||
buttonContainerClassName={`h-6 w-full flex ${isDisabled ? "cursor-not-allowed" : "cursor-pointer"} items-center gap-1.5 text-custom-text-300 border-[0.5px] border-custom-border-300 rounded text-xs`}
|
||||
buttonVariant="transparent-with-text"
|
||||
className="h-7"
|
||||
value={{
|
||||
from: getDate(moduleDetails.start_date),
|
||||
to: getDate(moduleDetails.target_date),
|
||||
}}
|
||||
onSelect={(val) => {
|
||||
handleModuleDetailsChange({
|
||||
start_date: val ? renderFormattedPayloadDate(val) : null,
|
||||
start_date: val?.from ? renderFormattedPayloadDate(val.from) : null,
|
||||
target_date: val?.to ? renderFormattedPayloadDate(val.to) : null,
|
||||
});
|
||||
}}
|
||||
placeholder={t("common.order_by.start_date")}
|
||||
icon={<CalendarClock className="h-3 w-3 flex-shrink-0" />}
|
||||
buttonVariant={moduleDetails.start_date ? "border-with-text" : "border-without-text"}
|
||||
buttonContainerClassName={`h-6 w-full flex ${isDisabled ? "cursor-not-allowed" : "cursor-pointer"} items-center gap-1.5 text-custom-text-300 rounded text-xs`}
|
||||
optionsClassName="z-10"
|
||||
disabled={isDisabled}
|
||||
showTooltip
|
||||
maxDate={getDate(moduleDetails.target_date)}
|
||||
/>
|
||||
<DateDropdown
|
||||
value={moduleDetails.target_date}
|
||||
onChange={(val) => {
|
||||
handleModuleDetailsChange({
|
||||
target_date: val ? renderFormattedPayloadDate(val) : null,
|
||||
});
|
||||
placeholder={{
|
||||
from: "Start date",
|
||||
to: "End date",
|
||||
}}
|
||||
placeholder={t("common.order_by.due_date")}
|
||||
icon={<CalendarCheck2 className="h-3 w-3 flex-shrink-0" />}
|
||||
buttonVariant={moduleDetails.target_date ? "border-with-text" : "border-without-text"}
|
||||
buttonContainerClassName={`h-6 w-full flex ${isDisabled ? "cursor-not-allowed" : "cursor-pointer"} items-center gap-1.5 text-custom-text-300 rounded text-xs`}
|
||||
optionsClassName="z-10"
|
||||
disabled={isDisabled}
|
||||
showTooltip
|
||||
minDate={getDate(moduleDetails.start_date)}
|
||||
hideIcon={{ from: renderIcon ?? true, to: renderIcon }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import React, { FC } from "react";
|
|||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
// icons
|
||||
import { CalendarCheck2, CalendarClock, SquareUser } from "lucide-react";
|
||||
import { SquareUser } from "lucide-react";
|
||||
// types
|
||||
import {
|
||||
MODULE_STATUS,
|
||||
|
|
@ -18,7 +18,7 @@ import { IModule } from "@plane/types";
|
|||
// ui
|
||||
import { FavoriteStar, TOAST_TYPE, Tooltip, setPromiseToast, setToast } from "@plane/ui";
|
||||
// components
|
||||
import { DateDropdown } from "@/components/dropdowns";
|
||||
import { DateRangeDropdown } from "@/components/dropdowns";
|
||||
import { ModuleQuickActions } from "@/components/modules";
|
||||
import { ModuleStatusDropdown } from "@/components/modules/module-status-dropdown";
|
||||
// constants
|
||||
|
|
@ -138,38 +138,28 @@ export const ModuleListItemAction: FC<Props> = observer((props) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<DateDropdown
|
||||
value={moduleDetails.start_date}
|
||||
onChange={(val) => {
|
||||
<DateRangeDropdown
|
||||
buttonContainerClassName={`h-6 w-full flex ${isDisabled ? "cursor-not-allowed" : "cursor-pointer"} items-center gap-1.5 text-custom-text-300 border-[0.5px] border-custom-border-300 rounded text-xs`}
|
||||
buttonVariant="transparent-with-text"
|
||||
className="h-7"
|
||||
value={{
|
||||
from: getDate(moduleDetails.start_date),
|
||||
to: getDate(moduleDetails.target_date),
|
||||
}}
|
||||
onSelect={(val) => {
|
||||
handleModuleDetailsChange({
|
||||
start_date: val ? renderFormattedPayloadDate(val) : null,
|
||||
start_date: val?.from ? renderFormattedPayloadDate(val.from) : null,
|
||||
target_date: val?.to ? renderFormattedPayloadDate(val.to) : null,
|
||||
});
|
||||
}}
|
||||
placeholder={t("common.order_by.start_date")}
|
||||
icon={<CalendarClock className="h-3 w-3 flex-shrink-0" />}
|
||||
buttonVariant={moduleDetails.start_date ? "border-with-text" : "border-without-text"}
|
||||
buttonContainerClassName={`h-6 w-full flex ${isDisabled ? "cursor-not-allowed" : "cursor-pointer"} items-center gap-1.5 text-custom-text-300 rounded text-xs`}
|
||||
optionsClassName="z-10"
|
||||
disabled={isDisabled}
|
||||
showTooltip
|
||||
maxDate={getDate(moduleDetails.target_date)}
|
||||
/>
|
||||
<DateDropdown
|
||||
value={moduleDetails.target_date}
|
||||
onChange={(val) => {
|
||||
handleModuleDetailsChange({
|
||||
target_date: val ? renderFormattedPayloadDate(val) : null,
|
||||
});
|
||||
placeholder={{
|
||||
from: t("start_date"),
|
||||
to: t("end_date"),
|
||||
}}
|
||||
placeholder={t("common.order_by.due_date")}
|
||||
icon={<CalendarCheck2 className="h-3 w-3 flex-shrink-0" />}
|
||||
buttonVariant={moduleDetails.target_date ? "border-with-text" : "border-without-text"}
|
||||
buttonContainerClassName={`h-6 w-full flex ${isDisabled ? "cursor-not-allowed" : "cursor-pointer"} items-center gap-1.5 text-custom-text-300 rounded text-xs`}
|
||||
optionsClassName="z-10"
|
||||
disabled={isDisabled}
|
||||
showTooltip
|
||||
minDate={getDate(moduleDetails.start_date)}
|
||||
hideIcon={{ from: renderIcon ?? true, to: renderIcon }}
|
||||
/>
|
||||
|
||||
{moduleStatus && (
|
||||
<ModuleStatusDropdown
|
||||
isDisabled={isDisabled}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue