chore: no estimates option, estimates activity (#838)

This commit is contained in:
Aaryan Khandelwal 2023-04-17 11:30:48 +05:30 committed by GitHub
parent 61761fedc5
commit e23075b7b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 97 additions and 53 deletions

View File

@ -73,6 +73,10 @@ const activityDetails: {
message: "updated the description.",
icon: <ChatBubbleBottomCenterTextIcon className="h-3 w-3 text-gray-500" aria-hidden="true" />,
},
estimate_point: {
message: "set the estimate point to",
icon: <PlayIcon className="h-3 w-3 text-gray-500 -rotate-90" aria-hidden="true" />,
},
target_date: {
message: "set the due date to",
icon: <CalendarDaysIcon className="h-3 w-3 text-gray-500" aria-hidden="true" />,
@ -136,8 +140,6 @@ export const Feeds: React.FC<any> = ({ activities }) => (
action = `${activity.verb} the`;
} else if (activity.field === "link") {
action = `${activity.verb} the`;
} else if (activity.field === "estimate") {
action = "updated the";
}
// for values that are after the action clause
let value: any = activity.new_value ? activity.new_value : activity.old_value;
@ -188,8 +190,10 @@ export const Feeds: React.FC<any> = ({ activities }) => (
value = "attachment";
} else if (activity.field === "link") {
value = "link";
} else if (activity.field === "estimate") {
value = "estimate";
} else if (activity.field === "estimate_point") {
value = activity.new_value
? activity.new_value + ` Point${parseInt(activity.new_value ?? "", 10) > 1 ? "s" : ""}`
: "None";
}
if (activity.field === "comment") {

View File

@ -388,36 +388,33 @@ export const IssuesView: React.FC<Props> = ({
handleClose={() => setTransferIssuesModal(false)}
isOpen={transferIssuesModal}
/>
<div>
<div className="flex items-center justify-between gap-2">
<FilterList filters={filters} setFilters={setFilters} />
{Object.keys(filters).length > 0 &&
nullFilters.length !== Object.keys(filters).length && (
<PrimaryButton
onClick={() => {
if (viewId) {
setFilters({}, true);
setToastAlert({
title: "View updated",
message: "Your view has been updated",
type: "success",
});
} else
setCreateViewModal({
query: filters,
});
}}
className="flex items-center gap-2 text-sm"
>
{!viewId && <PlusIcon className="h-4 w-4" />}
{viewId ? "Update" : "Save"} view
</PrimaryButton>
)}
</div>
<div className="flex items-center justify-between gap-2 -mt-2">
<FilterList filters={filters} setFilters={setFilters} />
{Object.keys(filters).length > 0 && nullFilters.length !== Object.keys(filters).length && (
<PrimaryButton
onClick={() => {
if (viewId) {
setFilters({}, true);
setToastAlert({
title: "View updated",
message: "Your view has been updated",
type: "success",
});
} else
setCreateViewModal({
query: filters,
});
}}
className="flex items-center gap-2 text-sm"
>
{!viewId && <PlusIcon className="h-4 w-4" />}
{viewId ? "Update" : "Save"} view
</PrimaryButton>
)}
</div>
{Object.keys(filters).length > 0 && nullFilters.length !== Object.keys(filters).length && (
<div className="mb-5 border-t" />
<div className="my-4 border-t" />
)}
<DragDropContext onDragEnd={handleOnDragEnd}>

View File

@ -29,6 +29,7 @@ import { addSpaceIfCamelCase } from "helpers/string.helper";
// types
import { IIssueComment, IIssueLabels } from "types";
import { PROJECT_ISSUES_ACTIVITY, PROJECT_ISSUE_LABELS } from "constants/fetch-keys";
import useEstimateOption from "hooks/use-estimate-option";
const activityDetails: {
[key: string]: {
@ -56,6 +57,10 @@ const activityDetails: {
message: "set the cycle to",
icon: <CyclesIcon height="12" width="12" color="#6b7280" />,
},
estimate_point: {
message: "set the estimate point to",
icon: <PlayIcon className="h-3 w-3 text-gray-500 -rotate-90" aria-hidden="true" />,
},
labels: {
icon: <TagIcon height="12" width="12" color="#6b7280" />,
},
@ -107,6 +112,8 @@ export const IssueActivitySection: React.FC<Props> = () => {
const router = useRouter();
const { workspaceSlug, projectId, issueId } = router.query;
const { isEstimateActive, estimatePoints } = useEstimateOption();
const { data: issueActivities, mutate: mutateIssueActivities } = useSWR(
workspaceSlug && projectId && issueId ? PROJECT_ISSUES_ACTIVITY(issueId as string) : null,
workspaceSlug && projectId && issueId
@ -278,8 +285,14 @@ export const IssueActivitySection: React.FC<Props> = () => {
value = "attachment";
} else if (activityItem.field === "link") {
value = "link";
} else if (activityItem.field === "estimate") {
value = "estimate";
} else if (activityItem.field === "estimate_point") {
value = activityItem.new_value
? isEstimateActive
? estimatePoints.find((e) => e.key === parseInt(activityItem.new_value ?? "", 10))
?.value
: activityItem.new_value +
` Point${parseInt(activityItem.new_value ?? "", 10) > 1 ? "s" : ""}`
: "None";
}
if ("field" in activityItem && activityItem.field !== "updated_by") {

View File

@ -48,7 +48,7 @@ const defaultValues: Partial<IIssue> = {
name: "",
description: "",
description_html: "<p></p>",
estimate_point: 0,
estimate_point: null,
state: "",
cycle: null,
priority: null,

View File

@ -8,8 +8,8 @@ import { PlayIcon } from "@heroicons/react/24/outline";
import useEstimateOption from "hooks/use-estimate-option";
type Props = {
value: number;
onChange: (value: number) => void;
value: number | null;
onChange: (value: number | null) => void;
};
export const IssueEstimateSelect: React.FC<Props> = ({ value, onChange }) => {
@ -24,18 +24,26 @@ export const IssueEstimateSelect: React.FC<Props> = ({ value, onChange }) => {
<div className="flex items-center gap-2 text-xs">
<PlayIcon className="h-4 w-4 text-gray-500 -rotate-90" />
<span className={`${value ? "text-gray-600" : "text-gray-500"}`}>
{estimatePoints?.find((e) => e.key === value)?.value ?? "Estimate points"}
{estimatePoints?.find((e) => e.key === value)?.value ?? "Estimate"}
</span>
</div>
}
onChange={onChange}
position="right"
width="w-full min-w-[6rem]"
width="w-full min-w-[8rem]"
noChevron
>
<CustomSelect.Option value={null}>
<>
<span>
<PlayIcon className="h-4 w-4 -rotate-90" />
</span>
None
</>
</CustomSelect.Option>
{estimatePoints &&
estimatePoints.map((point) => (
<CustomSelect.Option className="w-full " key={point.key} value={point.key}>
<CustomSelect.Option key={point.key} value={point.key}>
<>
<span>
<PlayIcon className="h-4 w-4 -rotate-90" />

View File

@ -1,17 +1,17 @@
import React from "react";
// hooks
import useEstimateOption from "hooks/use-estimate-option";
// ui
import { CustomSelect } from "components/ui";
// icons
import { BanknotesIcon, PlayIcon } from "@heroicons/react/24/outline";
import { PlayIcon } from "@heroicons/react/24/outline";
// types
import { UserAuth } from "types";
import useEstimateOption from "hooks/use-estimate-option";
// constants
type Props = {
value: number;
onChange: (val: number) => void;
value: number | null;
onChange: (val: number | null) => void;
userAuth: UserAuth;
};
@ -35,7 +35,7 @@ export const SidebarEstimateSelect: React.FC<Props> = ({ value, onChange, userAu
<div className="flex items-center gap-2 text-xs">
<PlayIcon className="h-4 w-4 text-gray-700 -rotate-90" />
<span className={`${value ? "text-gray-600" : "text-gray-500"}`}>
{estimatePoints?.find((e) => e.key === value)?.value ?? "Estimate points"}
{estimatePoints?.find((e) => e.key === value)?.value ?? "Estimate"}
</span>
</div>
}
@ -44,9 +44,17 @@ export const SidebarEstimateSelect: React.FC<Props> = ({ value, onChange, userAu
width="w-full"
disabled={isNotAllowed}
>
<CustomSelect.Option value={null}>
<>
<span>
<PlayIcon className="h-4 w-4 -rotate-90" />
</span>
None
</>
</CustomSelect.Option>
{estimatePoints &&
estimatePoints.map((point) => (
<CustomSelect.Option className="w-full " key={point.key} value={point.key}>
<CustomSelect.Option key={point.key} value={point.key}>
<>
<span>
<PlayIcon className="h-4 w-4 -rotate-90" />

View File

@ -294,7 +294,7 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
render={({ field: { value } }) => (
<SidebarEstimateSelect
value={value}
onChange={(val: number) => submitChanges({ estimate_point: val })}
onChange={(val: number | null) => submitChanges({ estimate_point: val })}
userAuth={memberRole}
/>
)}

View File

@ -58,7 +58,7 @@ export const ViewEstimateSelect: React.FC<Props> = ({
<Tooltip tooltipHeading="Estimate" tooltipContent={estimateValue}>
<div className="flex items-center gap-1 text-gray-500">
<PlayIcon className="h-3.5 w-3.5 -rotate-90" />
{estimateValue}
{estimateValue ?? "Estimate"}
</div>
</Tooltip>
}
@ -67,11 +67,24 @@ export const ViewEstimateSelect: React.FC<Props> = ({
disabled={isNotAllowed}
position={position}
selfPositioned={selfPositioned}
width="w-full min-w-[6rem]"
width="w-full min-w-[8rem]"
>
<CustomSelect.Option value={null}>
<>
<span>
<PlayIcon className="h-4 w-4 -rotate-90" />
</span>
None
</>
</CustomSelect.Option>
{estimatePoints?.map((estimate) => (
<CustomSelect.Option key={estimate.id} value={estimate.key} className="capitalize">
<>{estimate.value}</>
<CustomSelect.Option key={estimate.id} value={estimate.key}>
<>
<span>
<PlayIcon className="h-4 w-4 -rotate-90" />
</span>
{estimate.value}
</>
</CustomSelect.Option>
))}
</CustomSelect>

View File

@ -13,7 +13,7 @@ import { orderArrayBy } from "helpers/array.helper";
// fetch-keys
import { ESTIMATE_POINTS_LIST } from "constants/fetch-keys";
const useEstimateOption = (estimateKey?: number) => {
const useEstimateOption = (estimateKey?: number | null) => {
const router = useRouter();
const { workspaceSlug, projectId } = router.query;

View File

@ -34,6 +34,7 @@ const defaultValues = {
name: "",
description: "",
description_html: "",
estimate_point: null,
state: "",
assignees_list: [],
priority: "low",

View File

@ -87,7 +87,7 @@ export interface IIssue {
description: any;
description_html: any;
description_stripped: any;
estimate_point: number;
estimate_point: number | null;
id: string;
issue_cycle: IIssueCycle | null;
issue_link: {