feat: estimates revamp and space app refactor (#4742)
* Move code from EE to CE repo * chore: folder structure updates * Move sortabla and radio input to packages/ui * chore: updated empty and loading screens * chore: delete an estimate point * chore: estimate point response change * chore: updated create estimate and handled the build error * chore: migration fixes * chore: updated create estimate * chore: create estimate workflow update * chore: editing and deleting the existing estimate updates * chore: updating the new estinates in update modal * chore: ui changed * chore: response changes of get and post * chore: new field added in estimates * chore: individual endpoint for estimate points * chore: typo changes * chore: create estimate point * chore: integrated new endpoints * chore: update key value pair * chore: update sorting in the estimates * Add custom option in the estimate templates * chore: handled current project active estimate * chore: handle estimate update worklfow * chore: handled estimates switch * chore: handled estimate edit * chore: handled close button in estimate edit * chore: updated ceate estimare workflow * chore: updated switch estimate * chore: UI and typos * chore: resolved build error * chore: updated delete dropdown and handled the repeated values while creating and updating the estimate point * chore: handled inline errors in the estimate switch * chore: handled active and availability vadilation * chore: handled create and update components in projecr estimates * chore: added migration * Add category specific values for custom template * chore: estimate dropdown handled in issues * chore: estimate alerts * chore: updated alerts * Extract the list row actions * fix: updated and handled the estimate points * fix: upgrader ee banner * Fix issues with sortable * Fix sortable spacing issue in create estimate modal * fix: updated the issue create sorting * chore: removed radio button from ui and updated in the estimates * chore: resolved import error in packaged ui * chore: handled props in create modal * chore: removed ee files * chore: changed default analytics * chore: removed the migration file * chore: estimate point value in graph * chore: estimate point key change * chore: squashed migration (#4634) * chore: squashed migration * chore: removed instance migraion * chore: key changes * chore: issue activity back migration * dev: replaced estimate key with estimate id and replaced estimate type from number to string in issue * chore: estimate point value field * chore: estimate point activity * chore: removed the unused function * chore: resolved merge conflicts * chore: deploy board keys changed * chore: yarn lock file change * chore: resolved frontend build --------- Co-authored-by: guru_sainath <gurusainath007@gmail.com> * [WEB-1516] refactor: space app routing and layouts (#4705) * dev: change layout * chore: replace workspace slug and project id with anchor * chore: migration fixes * chore: update filtering logic * chore: endpoint changes * chore: update endpoint * chore: changed url pratterns * chore: use client side for layout and page * chore: issue vote changes * chore: project deploy board response change * refactor: publish project store and components * fix: update layout options after fetching settings * chore: remove unnecessary types * style: peek overview * refactor: components folder structure * fix: redirect from old path * chore: make the whole issue block clickable * chore: removed the migration file * chore: add server side redirection for old routes * chore: is enabled key change * chore: update types * chore: removed the migration file --------- Co-authored-by: NarayanBavisetti <narayan3119@gmail.com> * Merge develop into revamp-estimates-ce * chore: removed migration file and updated the estimate system order and removed ee banner * chore: initial radio select in create estimate * chore: space key changes * Fix sortable component as the sort order was broken. * [WEB-1516] refactor: publish project modal and types (#4716) * refacotr: project publish * chore: rename service names * chore: is_deployed changed to anchor * chore: update is_deployed key --------- Co-authored-by: NarayanBavisetti <narayan3119@gmail.com> * [WEB-412] chore: estimates analytics (#4730) * chore: estimate points in modules and cycle * chore: burn down chart analytics * chore: module serializer change * dev: handled y-axis estimates in analytics, implemented estimate points on modules * chore: burn down analytics * chore: state estimate point analytics * chore: updated the burn down values * Remove check mark from estimate point edit field in create estimate flow --------- Co-authored-by: guru_sainath <gurusainath007@gmail.com> Co-authored-by: Satish Gandham <satish.iitg@gmail.com> --------- Co-authored-by: Satish Gandham <satish.iitg@gmail.com> Co-authored-by: guru_sainath <gurusainath007@gmail.com> Co-authored-by: NarayanBavisetti <narayan3119@gmail.com> Co-authored-by: Bavisetti Narayan <72156168+NarayanBavisetti@users.noreply.github.com> Co-authored-by: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Co-authored-by: pushya22 <130810100+pushya22@users.noreply.github.com>
This commit is contained in:
parent
fb2b4ae303
commit
59fdd611e4
223 changed files with 6874 additions and 4658 deletions
|
|
@ -2,7 +2,7 @@ import { FC } from "react";
|
|||
import { observer } from "mobx-react";
|
||||
import { Triangle } from "lucide-react";
|
||||
// hooks
|
||||
import { useEstimate, useIssueDetail } from "@/hooks/store";
|
||||
import { useIssueDetail } from "@/hooks/store";
|
||||
// components
|
||||
import { IssueActivityBlockComponent, IssueLink } from "./";
|
||||
|
||||
|
|
@ -14,15 +14,11 @@ export const IssueEstimateActivity: FC<TIssueEstimateActivity> = observer((props
|
|||
const {
|
||||
activity: { getActivityById },
|
||||
} = useIssueDetail();
|
||||
const { areEstimatesEnabledForCurrentProject, getEstimatePointValue } = useEstimate();
|
||||
|
||||
const activity = getActivityById(activityId);
|
||||
|
||||
if (!activity) return <></>;
|
||||
|
||||
const estimateValue = getEstimatePointValue(Number(activity.new_value), null);
|
||||
const currentPoint = Number(activity.new_value) + 1;
|
||||
|
||||
return (
|
||||
<IssueActivityBlockComponent
|
||||
icon={<Triangle size={14} color="#6b7280" aria-hidden="true" />}
|
||||
|
|
@ -31,15 +27,7 @@ export const IssueEstimateActivity: FC<TIssueEstimateActivity> = observer((props
|
|||
>
|
||||
<>
|
||||
{activity.new_value ? `set the estimate point to ` : `removed the estimate point `}
|
||||
{activity.new_value && (
|
||||
<>
|
||||
<span className="font-medium text-custom-text-100">
|
||||
{areEstimatesEnabledForCurrentProject
|
||||
? estimateValue
|
||||
: `${currentPoint} ${currentPoint > 1 ? "points" : "point"}`}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
{activity.new_value ? activity.new_value : activity?.old_value || ""}
|
||||
{showIssue && (activity.new_value ? ` to ` : ` from `)}
|
||||
{showIssue && <IssueLink activityId={activityId} />}.
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ export const IssueActivity: FC<TIssueActivity> = observer((props) => {
|
|||
workspaceSlug={workspaceSlug}
|
||||
issueId={issueId}
|
||||
activityOperations={activityOperations}
|
||||
showAccessSpecifier={project.is_deployed}
|
||||
showAccessSpecifier={!!project.anchor}
|
||||
disabled={disabled}
|
||||
/>
|
||||
{!disabled && (
|
||||
|
|
@ -150,7 +150,7 @@ export const IssueActivity: FC<TIssueActivity> = observer((props) => {
|
|||
projectId={projectId}
|
||||
workspaceSlug={workspaceSlug}
|
||||
activityOperations={activityOperations}
|
||||
showAccessSpecifier={project.is_deployed}
|
||||
showAccessSpecifier={!!project.anchor}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -161,7 +161,7 @@ export const IssueActivity: FC<TIssueActivity> = observer((props) => {
|
|||
workspaceSlug={workspaceSlug}
|
||||
issueId={issueId}
|
||||
activityOperations={activityOperations}
|
||||
showAccessSpecifier={project.is_deployed}
|
||||
showAccessSpecifier={!!project.anchor}
|
||||
disabled={disabled}
|
||||
/>
|
||||
{!disabled && (
|
||||
|
|
@ -170,7 +170,7 @@ export const IssueActivity: FC<TIssueActivity> = observer((props) => {
|
|||
projectId={projectId}
|
||||
workspaceSlug={workspaceSlug}
|
||||
activityOperations={activityOperations}
|
||||
showAccessSpecifier={project.is_deployed}
|
||||
showAccessSpecifier={!!project.anchor}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ import { getDate, renderFormattedPayloadDate } from "@/helpers/date-time.helper"
|
|||
import { shouldHighlightIssueDueDate } from "@/helpers/issue.helper";
|
||||
import { copyTextToClipboard } from "@/helpers/string.helper";
|
||||
// types
|
||||
import { useEstimate, useIssueDetail, useProject, useProjectState, useUser } from "@/hooks/store";
|
||||
import { useProjectEstimates, useIssueDetail, useProject, useProjectState, useUser } from "@/hooks/store";
|
||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// components
|
||||
import type { TIssueOperations } from "./root";
|
||||
|
|
@ -82,7 +82,7 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||
// store hooks
|
||||
const { getProjectById } = useProject();
|
||||
const { data: currentUser } = useUser();
|
||||
const { areEstimatesEnabledForCurrentProject } = useEstimate();
|
||||
const { areEstimateEnabledByProjectId } = useProjectEstimates();
|
||||
const {
|
||||
issue: { getIssueById },
|
||||
} = useIssueDetail();
|
||||
|
|
@ -311,15 +311,17 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||
/>
|
||||
</div>
|
||||
|
||||
{areEstimatesEnabledForCurrentProject && (
|
||||
{projectId && areEstimateEnabledByProjectId(projectId) && (
|
||||
<div className="flex h-8 items-center gap-2">
|
||||
<div className="flex w-2/5 flex-shrink-0 items-center gap-1 text-sm text-custom-text-300">
|
||||
<Triangle className="h-4 w-4 flex-shrink-0" />
|
||||
<span>Estimate</span>
|
||||
</div>
|
||||
<EstimateDropdown
|
||||
value={issue?.estimate_point !== null ? issue.estimate_point : null}
|
||||
onChange={(val) => issueOperations.update(workspaceSlug, projectId, issueId, { estimate_point: val })}
|
||||
value={issue?.estimate_point ?? undefined}
|
||||
onChange={(val: string | undefined) =>
|
||||
issueOperations.update(workspaceSlug, projectId, issueId, { estimate_point: val })
|
||||
}
|
||||
projectId={projectId}
|
||||
disabled={!isEditable}
|
||||
buttonVariant="transparent-with-text"
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import { cn } from "@/helpers/common.helper";
|
|||
import { getDate, renderFormattedPayloadDate } from "@/helpers/date-time.helper";
|
||||
import { shouldHighlightIssueDueDate } from "@/helpers/issue.helper";
|
||||
// hooks
|
||||
import { useEventTracker, useEstimate, useLabel, useIssues, useProjectState, useProject } from "@/hooks/store";
|
||||
import { useEventTracker, useLabel, useIssues, useProjectState, useProject, useProjectEstimates } from "@/hooks/store";
|
||||
import { usePlatformOS } from "@/hooks/use-platform-os";
|
||||
// local components
|
||||
import { IssuePropertyLabels } from "../properties/labels";
|
||||
|
|
@ -42,6 +42,9 @@ export interface IIssueProperties {
|
|||
}
|
||||
|
||||
export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
const { issue, updateIssue, displayProperties, activeLayout, isReadOnly, className } = props;
|
||||
// store hooks
|
||||
const { getProjectById } = useProject();
|
||||
|
|
@ -53,13 +56,10 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
|||
const {
|
||||
issues: { addCycleToIssue, removeCycleFromIssue },
|
||||
} = useIssues(EIssuesStoreType.CYCLE);
|
||||
const { areEstimatesEnabledForCurrentProject } = useEstimate();
|
||||
const { areEstimateEnabledByProjectId } = useProjectEstimates();
|
||||
const { getStateById } = useProjectState();
|
||||
const { isMobile } = usePlatformOS();
|
||||
const projectDetails = getProjectById(issue.project_id);
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { workspaceSlug } = router.query;
|
||||
const currentLayout = `${activeLayout} layout`;
|
||||
// derived values
|
||||
const stateDetails = getStateById(issue.state_id);
|
||||
|
|
@ -220,7 +220,7 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
|||
);
|
||||
};
|
||||
|
||||
const handleEstimate = (value: number | null) => {
|
||||
const handleEstimate = (value: string | undefined) => {
|
||||
updateIssue &&
|
||||
updateIssue(issue.project_id, issue.id, { estimate_point: value }).then(() => {
|
||||
captureIssueEvent({
|
||||
|
|
@ -394,11 +394,11 @@ export const IssueProperties: React.FC<IIssueProperties> = observer((props) => {
|
|||
)}
|
||||
|
||||
{/* estimates */}
|
||||
{areEstimatesEnabledForCurrentProject && (
|
||||
{projectId && areEstimateEnabledByProjectId(projectId?.toString()) && (
|
||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="estimate">
|
||||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<EstimateDropdown
|
||||
value={issue.estimate_point}
|
||||
value={issue.estimate_point ?? undefined}
|
||||
onChange={handleEstimate}
|
||||
projectId={issue.project_id}
|
||||
disabled={isReadOnly}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ export const SpreadsheetEstimateColumn: React.FC<Props> = observer((props: Props
|
|||
return (
|
||||
<div className="h-11 border-b-[0.5px] border-custom-border-200">
|
||||
<EstimateDropdown
|
||||
value={issue.estimate_point}
|
||||
value={issue.estimate_point || undefined}
|
||||
onChange={(data) =>
|
||||
onChange(issue, { estimate_point: data }, { changed_property: "estimate_point", change_details: data })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -499,7 +499,7 @@ export const handleGroupDragDrop = async (
|
|||
// update updatedIssue values based on the source and destination groupIds
|
||||
if (source.groupId && destination.groupId && source.groupId !== destination.groupId) {
|
||||
const groupKey = ISSUE_FILTER_DEFAULT_DATA[groupBy];
|
||||
let groupValue = clone(sourceIssue[groupKey]);
|
||||
let groupValue: any = clone(sourceIssue[groupKey]);
|
||||
|
||||
// If groupValues is an array, remove source groupId and add destination groupId
|
||||
if (Array.isArray(groupValue)) {
|
||||
|
|
@ -519,7 +519,7 @@ export const handleGroupDragDrop = async (
|
|||
// update updatedIssue values based on the source and destination subGroupIds
|
||||
if (subGroupBy && source.subGroupId && destination.subGroupId && source.subGroupId !== destination.subGroupId) {
|
||||
const subGroupKey = ISSUE_FILTER_DEFAULT_DATA[subGroupBy];
|
||||
let subGroupValue = clone(sourceIssue[subGroupKey]);
|
||||
let subGroupValue: any = clone(sourceIssue[subGroupKey]);
|
||||
|
||||
// If subGroupValue is an array, remove source subGroupId and add destination subGroupId
|
||||
if (Array.isArray(subGroupValue)) {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,14 @@ import { renderFormattedPayloadDate, getDate } from "@/helpers/date-time.helper"
|
|||
import { getChangedIssuefields, getDescriptionPlaceholder } from "@/helpers/issue.helper";
|
||||
import { shouldRenderProject } from "@/helpers/project.helper";
|
||||
// hooks
|
||||
import { useAppRouter, useEstimate, useInstance, useIssueDetail, useProject, useWorkspace } from "@/hooks/store";
|
||||
import {
|
||||
useAppRouter,
|
||||
useProjectEstimates,
|
||||
useInstance,
|
||||
useIssueDetail,
|
||||
useProject,
|
||||
useWorkspace,
|
||||
} from "@/hooks/store";
|
||||
import useKeypress from "@/hooks/use-keypress";
|
||||
import { useProjectIssueProperties } from "@/hooks/use-project-issue-properties";
|
||||
// services
|
||||
|
|
@ -120,7 +127,7 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
|
|||
const { projectId: routeProjectId } = useAppRouter();
|
||||
const { config } = useInstance();
|
||||
const { getProjectById } = useProject();
|
||||
const { areEstimatesEnabledForProject } = useEstimate();
|
||||
const { areEstimateEnabledByProjectId } = useProjectEstimates();
|
||||
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (editorRef.current?.isEditorReadyToDiscard()) {
|
||||
|
|
@ -659,14 +666,14 @@ export const IssueFormRoot: FC<IssueFormProps> = observer((props) => {
|
|||
)}
|
||||
/>
|
||||
)}
|
||||
{areEstimatesEnabledForProject(projectId) && (
|
||||
{projectId && areEstimateEnabledByProjectId(projectId) && (
|
||||
<Controller
|
||||
control={control}
|
||||
name="estimate_point"
|
||||
render={({ field: { value, onChange } }) => (
|
||||
<div className="h-7">
|
||||
<EstimateDropdown
|
||||
value={value}
|
||||
value={value || undefined}
|
||||
onChange={(estimatePoint) => {
|
||||
onChange(estimatePoint);
|
||||
handleFormChange();
|
||||
|
|
|
|||
|
|
@ -197,14 +197,14 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
|||
<span>Estimate</span>
|
||||
</div>
|
||||
<EstimateDropdown
|
||||
value={issue?.estimate_point !== null ? issue.estimate_point : null}
|
||||
value={issue.estimate_point ?? undefined}
|
||||
onChange={(val) => issueOperations.update(workspaceSlug, projectId, issueId, { estimate_point: val })}
|
||||
projectId={projectId}
|
||||
disabled={disabled}
|
||||
buttonVariant="transparent-with-text"
|
||||
className="w-3/4 flex-grow group"
|
||||
buttonContainerClassName="w-full text-left"
|
||||
buttonClassName={`text-sm ${issue?.estimate_point !== null ? "" : "text-custom-text-400"}`}
|
||||
buttonClassName={`text-sm ${issue?.estimate_point !== undefined ? "" : "text-custom-text-400"}`}
|
||||
placeholder="None"
|
||||
hideIcon
|
||||
dropdownArrow
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue