Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: components restructure and improvements #5383

Merged
merged 8 commits into from
Aug 19, 2024
1 change: 1 addition & 0 deletions packages/types/src/common.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ export type TLogoProps = {
icon?: {
name?: string;
color?: string;
background_color?: string;
};
};
1 change: 1 addition & 0 deletions packages/types/src/issues.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export interface IIssueActivity {
name: string;
priority: string | null;
sequence_id: string;
type_id: string;
} | null;
new_identifier: string | null;
new_value: string | null;
Expand Down
5 changes: 5 additions & 0 deletions packages/types/src/issues/activity/base.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,9 @@ export type TIssueActivityComment =
id: string;
activity_type: "WORKLOG";
created_at?: string;
}
| {
id: string;
activity_type: "ISSUE_ADDITIONAL_PROPERTIES_ACTIVITY";
created_at?: string;
};
1 change: 1 addition & 0 deletions packages/types/src/project/projects.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,5 @@ export interface ISearchIssueResponse {
state__group: TStateGroups;
state__name: string;
workspace__slug: string;
type_id: string;
}
4 changes: 2 additions & 2 deletions packages/ui/src/emoji/emoji-icon-picker-new.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export const EmojiIconPicker: React.FC<TCustomEmojiPicker> = (props) => {
type: EmojiIconPickerTypes.EMOJI,
value: val,
});
if (closeOnSelect) close();
if (closeOnSelect) handleToggle(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AnmolBhatia1001 , check this.

}}
height="20rem"
width="100%"
Expand All @@ -120,7 +120,7 @@ export const EmojiIconPicker: React.FC<TCustomEmojiPicker> = (props) => {
type: EmojiIconPickerTypes.ICON,
value: val,
});
if (closeOnSelect) close();
if (closeOnSelect) handleToggle(false);
}}
/>
</Tab.Panel>
Expand Down
11 changes: 4 additions & 7 deletions packages/ui/src/emoji/logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import useFontFaceObserver from "use-font-face-observer";
import { LUCIDE_ICONS_LIST } from "./icons";
// helpers
import { emojiCodeToUnicode } from "./helpers";
import { cn } from "../../helpers";

type TLogoProps = {
in_use: "emoji" | "icon";
Expand All @@ -23,11 +22,10 @@ type Props = {
logo: TLogoProps;
size?: number;
type?: "lucide" | "material";
customColor?: string;
};

export const Logo: FC<Props> = (props) => {
const { logo, size = 16, customColor, type = "material" } = props;
const { logo, size = 16, type = "material" } = props;

// destructuring the logo object
const { in_use, emoji, icon } = logo;
Expand Down Expand Up @@ -74,20 +72,19 @@ export const Logo: FC<Props> = (props) => {
{lucideIcon && (
<lucideIcon.element
style={{
color: !customColor ? color : undefined,
color: color,
height: size,
width: size,
}}
className={cn(customColor)}
/>
)}
</>
) : (
<span
className={cn("material-symbols-rounded", customColor)}
className="material-symbols-rounded"
style={{
fontSize: size,
color: !customColor ? color : undefined,
color: color,
scale: "115%",
}}
>
Expand Down
35 changes: 25 additions & 10 deletions packages/ui/src/sortable/sortable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ import React, { Fragment, useEffect, useMemo } from "react";
import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
import { Draggable } from "./draggable";

type TEnhancedData<T> = T & { __uuid__?: string };

type Props<T> = {
data: T[];
data: TEnhancedData<T>[];
render: (item: T, index: number) => React.ReactNode;
onChange: (data: T[], movedItem?: T) => void;
keyExtractor: (item: T, index: number) => string;
Expand All @@ -12,9 +14,9 @@ type Props<T> = {
};

const moveItem = <T,>(
data: T[],
source: T,
destination: T & Record<symbol, string>,
data: TEnhancedData<T>[],
source: TEnhancedData<T>,
destination: TEnhancedData<T> & Record<symbol, string>,
keyExtractor: (item: T, index: number) => string
): {
newData: T[];
Expand Down Expand Up @@ -44,7 +46,16 @@ const moveItem = <T,>(

newData.splice(adjustedDestinationIndex, 0, movedItem);

return { newData, movedItem };
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { __uuid__: movedItemId, ...movedItemData } = movedItem;
return {
newData: newData.map((item) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { __uuid__: uuid, ...rest } = item;
return rest as T;
}),
movedItem: movedItemData as T,
};
};

export const Sortable = <T,>({ data, render, onChange, keyExtractor, containerClassName, id }: Props<T>) => {
Expand All @@ -55,8 +66,8 @@ export const Sortable = <T,>({ data, render, onChange, keyExtractor, containerCl
if (!destination) return;
const { newData, movedItem } = moveItem(
data,
source.data as T,
destination.data as T & { closestEdge: string },
source.data as TEnhancedData<T>,
destination.data as TEnhancedData<T> & { closestEdge: string },
keyExtractor
);
onChange(newData, movedItem);
Expand All @@ -76,9 +87,13 @@ export const Sortable = <T,>({ data, render, onChange, keyExtractor, containerCl

return (
<>
{enhancedData.map((item, index) => (
<Draggable key={keyExtractor(item, index)} data={item} className={containerClassName}>
<Fragment>{render(item, index)} </Fragment>
{data.map((item, index) => (
<Draggable
key={keyExtractor(enhancedData[index], index)}
data={enhancedData[index]}
className={containerClassName}
>
<Fragment>{render(item, index)}</Fragment>
</Draggable>
))}
</>
Expand Down
1 change: 1 addition & 0 deletions web/ce/components/issues/issue-details/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./issue-identifier";
export * from "./issue-properties-activity";
33 changes: 25 additions & 8 deletions web/ce/components/issues/issue-details/issue-identifier.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,44 @@
import { observer } from "mobx-react";
// helpers
import { cn } from "@/helpers/common.helper";
// hooks
import { useIssueDetail, useProject } from "@/hooks/store";

type TIssueIdentifierProps = {
issueId: string;
type TIssueIdentifierBaseProps = {
projectId: string;
size?: "xs" | "sm" | "md" | "lg";
textContainerClassName?: string;
};

type TIssueIdentifierFromStore = TIssueIdentifierBaseProps & {
issueId: string;
};

type TIssueIdentifierWithDetails = TIssueIdentifierBaseProps & {
issueTypeId?: string | null;
projectIdentifier: string;
issueSequenceId: string | number;
};

type TIssueIdentifierProps = TIssueIdentifierFromStore | TIssueIdentifierWithDetails;
export const IssueIdentifier: React.FC<TIssueIdentifierProps> = observer((props) => {
const { issueId, projectId } = props;
const { projectId, textContainerClassName } = props;
// store hooks
const { getProjectById } = useProject();
const { getProjectIdentifierById } = useProject();
const {
issue: { getIssueById },
} = useIssueDetail();
// Determine if the component is using store data or not
const isUsingStoreData = "issueId" in props;
// derived values
const issue = getIssueById(issueId);
const projectDetails = getProjectById(projectId);
const issue = isUsingStoreData ? getIssueById(props.issueId) : null;
const projectIdentifier = isUsingStoreData ? getProjectIdentifierById(projectId) : props.projectIdentifier;
const issueSequenceId = isUsingStoreData ? issue?.sequence_id : props.issueSequenceId;

return (
<div className="flex items-center space-x-2">
<span className="text-base font-medium text-custom-text-300">
{projectDetails?.identifier}-{issue?.sequence_id}
<span className={cn("text-base font-medium text-custom-text-300", textContainerClassName)}>
{projectIdentifier}-{issueSequenceId}
</span>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./root";
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { FC } from "react";

type TIssueAdditionalPropertiesActivity = {
activityId: string;
ends: "top" | "bottom" | undefined;
};

export const IssueAdditionalPropertiesActivity: FC<TIssueAdditionalPropertiesActivity> = () => <></>;
SatishGandham marked this conversation as resolved.
Show resolved Hide resolved
34 changes: 20 additions & 14 deletions web/core/components/command-palette/command-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import { useParams } from "next/navigation";
import useSWR from "swr";
import { FolderPlus, Search, Settings } from "lucide-react";
import { Dialog, Transition } from "@headlessui/react";
// icons
// types
import { IWorkspaceSearchResults } from "@plane/types";
// hooks
// ui
import { LayersIcon, Loader, ToggleSwitch, Tooltip } from "@plane/ui";
// components
import {
ChangeIssueAssignee,
ChangeIssuePriority,
Expand All @@ -23,28 +24,28 @@ import {
CommandPaletteWorkspaceSettingsActions,
} from "@/components/command-palette";
import { EmptyState } from "@/components/empty-state";
// constants
import { EmptyStateType } from "@/constants/empty-state";
// fetch-keys
import { ISSUE_DETAILS } from "@/constants/fetch-keys";
// hooks
import { useCommandPalette, useEventTracker, useProject, useUser } from "@/hooks/store";
import { useAppRouter } from "@/hooks/use-app-router";
import useDebounce from "@/hooks/use-debounce";
import { usePlatformOS } from "@/hooks/use-platform-os";
// services
// plane web components
import { IssueIdentifier } from "@/plane-web/components/issues";
// plane web services
import { WorkspaceService } from "@/plane-web/services";
// services
import { IssueService } from "@/services/issue";

// ui
// components
// types
// fetch-keys
// constants

const workspaceService = new WorkspaceService();
const issueService = new IssueService();

export const CommandModal: React.FC = observer(() => {
// hooks
const { getProjectById, workspaceProjectIds } = useProject();
const { workspaceProjectIds } = useProject();
const { isMobile } = usePlatformOS();
const { canPerformAnyCreateAction } = useUser();
// states
Expand Down Expand Up @@ -141,8 +142,6 @@ export const CommandModal: React.FC = observer(() => {
[debouncedSearchTerm, isWorkspaceLevel, projectId, workspaceSlug] // Only call effect if debounced search term changes
);

const projectDetails = getProjectById(issueDetails?.project_id ?? "");

return (
<Transition.Root show={isCommandPaletteOpen} afterLeave={() => setSearchTerm("")} as={React.Fragment}>
<Dialog as="div" className="relative z-30" onClose={() => closePalette()}>
Expand Down Expand Up @@ -198,8 +197,15 @@ export const CommandModal: React.FC = observer(() => {
}`}
>
{issueDetails && (
<div className="overflow-hidden truncate rounded-md bg-custom-background-80 p-2 text-xs font-medium text-custom-text-200">
{projectDetails?.identifier}-{issueDetails.sequence_id} {issueDetails.name}
<div className="flex gap-2 items-center overflow-hidden truncate rounded-md bg-custom-background-80 p-2 text-xs font-medium text-custom-text-200">
{issueDetails.project_id && (
<IssueIdentifier
issueId={issueDetails.id}
projectId={issueDetails.project_id}
textContainerClassName="text-xs font-medium text-custom-text-200"
/>
)}
{issueDetails.name}
</div>
)}
{projectId && (
Expand Down
21 changes: 13 additions & 8 deletions web/core/components/command-palette/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import {
IWorkspaceProjectSearchResult,
IWorkspaceSearchResult,
} from "@plane/types";
import { ContrastIcon, DiceIcon, LayersIcon } from "@plane/ui";
// ui
import { ContrastIcon, DiceIcon } from "@plane/ui";
// plane web components
import { IssueIdentifier } from "@/plane-web/components/issues";

export const commandGroups: {
[key: string]: {
icon: JSX.Element;
icon: JSX.Element | null;
itemName: (item: any) => React.ReactNode;
path: (item: any, projectId: string | undefined) => string;
title: string;
Expand All @@ -31,14 +34,16 @@ export const commandGroups: {
title: "Cycles",
},
issue: {
icon: <LayersIcon className="h-3 w-3" />,
icon: null,
itemName: (issue: IWorkspaceIssueSearchResult) => (
<h6>
<span className="text-xs text-custom-text-300">
{issue.project__identifier}-{issue.sequence_id}
</span>{" "}
<div className="flex gap-2">
<IssueIdentifier
issueId={issue.id}
projectId={issue.project_id}
textContainerClassName="text-xs"
/>{" "}
{issue.name}
</h6>
</div>
),
path: (issue: IWorkspaceIssueSearchResult) =>
`/${issue?.workspace__slug}/projects/${issue?.project_id}/issues/${issue?.id}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import { observer } from "mobx-react";
import { Combobox } from "@headlessui/react";
// hooks
import { ISearchIssueResponse } from "@plane/types";
// plane web hooks
import { IssueIdentifier } from "@/plane-web/components/issues";

interface Props {
issue: ISearchIssueResponse;
canDeleteIssueIds: boolean;
identifier: string | undefined;
}

export const BulkDeleteIssuesModalItem: React.FC<Props> = observer((props: Props) => {
const { issue, canDeleteIssueIds, identifier } = props;
const { issue, canDeleteIssueIds } = props;

const color = issue.state__color;

Expand All @@ -20,7 +21,7 @@ export const BulkDeleteIssuesModalItem: React.FC<Props> = observer((props: Props
as="div"
value={issue.id}
className={({ active }) =>
`flex cursor-pointer select-none items-center justify-between rounded-md px-3 py-2 ${
`flex cursor-pointer select-none items-center justify-between rounded-md px-3 py-2 my-0.5 ${
active ? "bg-custom-background-80 text-custom-text-100" : ""
}`
}
Expand All @@ -33,9 +34,7 @@ export const BulkDeleteIssuesModalItem: React.FC<Props> = observer((props: Props
backgroundColor: color,
}}
/>
<span className="flex-shrink-0 text-xs">
{identifier}-{issue.sequence_id}
</span>
<IssueIdentifier issueId={issue.id} projectId={issue.project_id} textContainerClassName="text-xs" />
<span>{issue.name}</span>
</div>
</Combobox.Option>
Expand Down
Loading
Loading