style: updated layouts UI in the space app (#2671)

* style: updated layouts UI in space

* fix: build error
This commit is contained in:
Aaryan Khandelwal 2023-11-06 20:43:34 +05:30 committed by GitHub
parent a6dea3af23
commit 1dce72cb3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 56 additions and 379 deletions

View File

@ -1 +0,0 @@
export * from "./state-group";

View File

@ -1,23 +0,0 @@
import React from "react";
// types
import type { Props } from "../types";
// constants
import { issueGroupColors } from "constants/data";
export const BacklogStateIcon: React.FC<Props> = ({
width = "14",
height = "14",
className,
color = issueGroupColors["backlog"],
}) => (
<svg
width={width}
height={height}
className={className}
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle cx="10" cy="10" r="9" stroke={color} strokeLinecap="round" strokeDasharray="4 4" />
</svg>
);

View File

@ -1,74 +0,0 @@
import React from "react";
// types
import type { Props } from "../types";
// constants
import { issueGroupColors } from "constants/data";
export const CancelledStateIcon: React.FC<Props> = ({
width = "14",
height = "14",
className,
color = issueGroupColors["cancelled"],
}) => (
<svg width={width} height={height} className={className} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84.36 84.36">
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<path
className="cls-1"
fill="none"
strokeWidth={3}
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
d="M20.45,7.69a39.74,39.74,0,0,1,43.43.54"
/>
<path
className="cls-1"
fill="none"
strokeWidth={3}
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
d="M76.67,20.45a39.76,39.76,0,0,1-.53,43.43"
/>
<path
className="cls-1"
fill="none"
strokeWidth={3}
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
d="M63.92,76.67a39.78,39.78,0,0,1-43.44-.53"
/>
<path
className="cls-1"
fill="none"
strokeWidth={3}
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
d="M7.69,63.92a39.75,39.75,0,0,1,.54-43.44"
/>
<circle className="cls-2" fill={color} cx="42.18" cy="42.18" r="31.04" />
<path
className="cls-3"
fill="none"
strokeWidth={3}
stroke="#ffffff"
strokeLinecap="square"
strokeMiterlimit={10}
d="M32.64,32.44q9.54,9.75,19.09,19.48"
/>
<path
className="cls-3"
fill="none"
strokeWidth={3}
stroke="#ffffff"
strokeLinecap="square"
strokeMiterlimit={10}
d="M32.64,51.92,51.73,32.44"
/>
</g>
</g>
</svg>
);

View File

@ -1,65 +0,0 @@
import React from "react";
// types
import type { Props } from "../types";
// constants
import { issueGroupColors } from "constants/data";
export const CompletedStateIcon: React.FC<Props> = ({
width = "14",
height = "14",
className,
color = issueGroupColors["completed"],
}) => (
<svg width={width} height={height} className={className} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84.36 84.36">
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<path
className="cls-1"
fill="none"
strokeWidth={3}
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
d="M20.45,7.69a39.74,39.74,0,0,1,43.43.54"
/>
<path
className="cls-1"
fill="none"
strokeWidth={3}
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
d="M76.67,20.45a39.76,39.76,0,0,1-.53,43.43"
/>
<path
className="cls-1"
fill="none"
strokeWidth={3}
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
d="M63.92,76.67a39.78,39.78,0,0,1-43.44-.53"
/>
<path
className="cls-1"
fill="none"
strokeWidth={3}
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
d="M7.69,63.92a39.75,39.75,0,0,1,.54-43.44"
/>
<circle className="cls-2" fill={color} cx="42.18" cy="42.18" r="31.04" />
<path
className="cls-3"
fill="none"
strokeWidth={3}
stroke="#ffffff"
strokeLinecap="square"
strokeMiterlimit={10}
d="M30.45,43.75l6.61,6.61L53.92,34"
/>
</g>
</g>
</svg>
);

View File

@ -1,6 +0,0 @@
export * from "./backlog-state-icon";
export * from "./cancelled-state-icon";
export * from "./completed-state-icon";
export * from "./started-state-icon";
export * from "./state-group-icon";
export * from "./unstarted-state-icon";

View File

@ -1,73 +0,0 @@
import React from "react";
// types
import type { Props } from "../types";
// constants
import { issueGroupColors } from "constants/data";
export const StartedStateIcon: React.FC<Props> = ({
width = "14",
height = "14",
className,
color = issueGroupColors["started"],
}) => (
<svg width={width} height={height} className={className} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 83.36 83.36">
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<path
className="cls-1"
fill="none"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M20,7.19a39.74,39.74,0,0,1,43.43.54"
/>
<path
className="cls-1"
fill="none"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M76.17,20a39.76,39.76,0,0,1-.53,43.43"
/>
<path
className="cls-1"
fill="none"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M63.42,76.17A39.78,39.78,0,0,1,20,75.64"
/>
<path
className="cls-1"
fill="none"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M7.19,63.42A39.75,39.75,0,0,1,7.73,20"
/>
<path
className="cls-2"
fill={color}
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M42.32,41.21q9.57-14.45,19.13-28.9a35.8,35.8,0,0,0-39.09,0Z"
/>
<path
className="cls-2"
fill={color}
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M42.32,41.7,61.45,70.6a35.75,35.75,0,0,1-39.09,0Z"
/>
</g>
</g>
</svg>
);

View File

@ -1,29 +0,0 @@
// icons
import {
BacklogStateIcon,
CancelledStateIcon,
CompletedStateIcon,
StartedStateIcon,
UnstartedStateIcon,
} from "components/icons";
import { TIssueGroupKey } from "types/issue";
type Props = {
stateGroup: TIssueGroupKey;
color: string;
className?: string;
height?: string;
width?: string;
};
export const StateGroupIcon: React.FC<Props> = ({ stateGroup, className, color, height = "12px", width = "12px" }) => {
if (stateGroup === "backlog")
return <BacklogStateIcon className={className} color={color} height={height} width={width} />;
else if (stateGroup === "cancelled")
return <CancelledStateIcon className={className} color={color} height={height} width={width} />;
else if (stateGroup === "completed")
return <CompletedStateIcon className={className} color={color} height={height} width={width} />;
else if (stateGroup === "started")
return <StartedStateIcon className={className} color={color} height={height} width={width} />;
else return <UnstartedStateIcon className={className} color={color} height={height} width={width} />;
};

View File

@ -1,55 +0,0 @@
import React from "react";
// types
import type { Props } from "../types";
// constants
import { issueGroupColors } from "constants/data";
export const UnstartedStateIcon: React.FC<Props> = ({
width = "14",
height = "14",
className,
color = issueGroupColors["unstarted"],
}) => (
<svg width={width} height={height} className={className} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 84.36 84.36">
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<path
className="cls-1"
fill="none"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M20.45,7.69a39.74,39.74,0,0,1,43.43.54"
/>
<path
className="cls-1"
fill="none"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M76.67,20.45a39.76,39.76,0,0,1-.53,43.43"
/>
<path
className="cls-1"
fill="none"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M63.92,76.67a39.78,39.78,0,0,1-43.44-.53"
/>
<path
className="cls-1"
fill="none"
stroke={color}
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={3}
d="M7.69,63.92a39.75,39.75,0,0,1,.54-43.44"
/>
</g>
</g>
</svg>
);

View File

@ -1,6 +0,0 @@
export type Props = {
width?: string | number;
height?: string | number;
color?: string;
className?: string;
};

View File

@ -1,3 +1,5 @@
// ui
import { StateGroupIcon } from "@plane/ui";
// constants // constants
import { issueGroupFilter } from "constants/data"; import { issueGroupFilter } from "constants/data";
@ -8,7 +10,7 @@ export const IssueBlockState = ({ state }: any) => {
return ( return (
<div className="flex items-center justify-between gap-1 w-full rounded shadow-sm border-[0.5px] border-custom-border-300 duration-300 focus:outline-none px-2.5 py-1 text-xs"> <div className="flex items-center justify-between gap-1 w-full rounded shadow-sm border-[0.5px] border-custom-border-300 duration-300 focus:outline-none px-2.5 py-1 text-xs">
<div className="flex items-center w-full gap-1.5 text-custom-text-200"> <div className="flex items-center w-full gap-1.5 text-custom-text-200">
<stateGroup.icon /> <StateGroupIcon stateGroup={state.group} color={state.color} />
<div className="text-xs">{state?.name}</div> <div className="text-xs">{state?.name}</div>
</div> </div>
</div> </div>

View File

@ -7,7 +7,6 @@ import { useMobxStore } from "lib/mobx/store-provider";
// components // components
import { IssueBlockPriority } from "components/issues/board-views/block-priority"; import { IssueBlockPriority } from "components/issues/board-views/block-priority";
import { IssueBlockState } from "components/issues/board-views/block-state"; import { IssueBlockState } from "components/issues/board-views/block-state";
import { IssueBlockLabels } from "components/issues/board-views/block-labels";
import { IssueBlockDueDate } from "components/issues/board-views/block-due-date"; import { IssueBlockDueDate } from "components/issues/board-views/block-due-date";
// interfaces // interfaces
import { IIssue } from "types/issue"; import { IIssue } from "types/issue";
@ -37,7 +36,7 @@ export const IssueListBlock = observer(({ issue }: { issue: IIssue }) => {
}; };
return ( return (
<div className="py-3 px-4 h-[118px] flex flex-col gap-1.5 bg-custom-background-100 rounded shadow-custom-shadow-sm border-[0.5px] border-custom-border-200"> <div className="py-2 px-3 flex flex-col gap-1.5 bg-custom-background-100 rounded shadow-custom-shadow-2xs border-[0.5px] border-custom-border-200 space-y-2 text-sm">
{/* id */} {/* id */}
<div className="text-xs text-custom-text-300 break-words"> <div className="text-xs text-custom-text-300 break-words">
{projectStore?.project?.identifier}-{issue?.sequence_id} {projectStore?.project?.identifier}-{issue?.sequence_id}

View File

@ -4,8 +4,8 @@ import { observer } from "mobx-react-lite";
import { IIssueState } from "types/issue"; import { IIssueState } from "types/issue";
// constants // constants
import { issueGroupFilter } from "constants/data"; import { issueGroupFilter } from "constants/data";
// icons // ui
import { StateGroupIcon } from "components/icons"; import { StateGroupIcon } from "@plane/ui";
// mobx hook // mobx hook
import { useMobxStore } from "lib/mobx/store-provider"; import { useMobxStore } from "lib/mobx/store-provider";
import { RootStore } from "store/root"; import { RootStore } from "store/root";
@ -18,11 +18,11 @@ export const IssueListHeader = observer(({ state }: { state: IIssueState }) => {
if (stateGroup === null) return <></>; if (stateGroup === null) return <></>;
return ( return (
<div className="pb-2 px-2 flex items-center"> <div className="pb-2 px-2 flex items-center gap-2">
<div className="w-4 h-4 flex justify-center items-center flex-shrink-0"> <div className="w-3.5 h-3.5 flex justify-center items-center flex-shrink-0">
<StateGroupIcon stateGroup={state.group} color={state.color} /> <StateGroupIcon stateGroup={state.group} color={state.color} height="14" width="14" />
</div> </div>
<div className="font-semibold text-custom-text-200 capitalize ml-2 mr-3 truncate">{state?.name}</div> <div className="font-semibold text-custom-text-200 capitalize mr-1 truncate">{state?.name}</div>
<span className="text-custom-text-300 rounded-full flex-shrink-0"> <span className="text-custom-text-300 rounded-full flex-shrink-0">
{store.issue.getCountOfIssuesByState(state.id)} {store.issue.getCountOfIssuesByState(state.id)}
</span> </span>

View File

@ -38,10 +38,10 @@ export const IssueListBlock: FC<{ issue: IIssue }> = observer((props) => {
}; };
return ( return (
<div className="flex items-center px-6 py-3.5 relative gap-10 bg-custom-background-100"> <div className="flex items-center p-3 relative gap-10 bg-custom-background-100">
<div className="relative flex items-center gap-5 w-full flex-grow overflow-hidden"> <div className="relative flex items-center gap-3 w-full flex-grow overflow-hidden">
{/* id */} {/* id */}
<div className="flex-shrink-0 text-sm text-custom-text-300"> <div className="flex-shrink-0 text-xs text-custom-text-300 font-medium">
{projectStore?.project?.identifier}-{issue?.sequence_id} {projectStore?.project?.identifier}-{issue?.sequence_id}
</div> </div>
{/* name */} {/* name */}

View File

@ -2,8 +2,8 @@
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
// interfaces // interfaces
import { IIssueState } from "types/issue"; import { IIssueState } from "types/issue";
// icons // ui
import { StateGroupIcon } from "components/icons"; import { StateGroupIcon } from "@plane/ui";
// constants // constants
import { issueGroupFilter } from "constants/data"; import { issueGroupFilter } from "constants/data";
// mobx hook // mobx hook
@ -18,12 +18,12 @@ export const IssueListHeader = observer(({ state }: { state: IIssueState }) => {
if (stateGroup === null) return <></>; if (stateGroup === null) return <></>;
return ( return (
<div className="px-6 py-2 flex items-center"> <div className="p-3 flex items-center gap-2">
<div className="w-4 h-4 flex justify-center items-center"> <div className="w-3.5 h-3.5 flex justify-center items-center">
<StateGroupIcon stateGroup={state.group} color={state.color} /> <StateGroupIcon stateGroup={state.group} color={state.color} height="14" width="14" />
</div> </div>
<div className="font-semibold capitalize ml-2 mr-3">{state?.name}</div> <div className="font-medium capitalize mr-1">{state?.name}</div>
<div className="text-custom-text-200">{store.issue.getCountOfIssuesByState(state.id)}</div> <div className="text-custom-text-200 text-sm font-medium">{store.issue.getCountOfIssuesByState(state.id)}</div>
</div> </div>
); );
}); });

View File

@ -27,9 +27,7 @@ export const IssueListView = observer(() => {
))} ))}
</div> </div>
) : ( ) : (
<div className="px-6 py-3.5 text-sm text-custom-text-200 bg-custom-background-100"> <div className="p-3 text-sm text-custom-text-400 bg-custom-background-100">No issues.</div>
No Issues are available.
</div>
)} )}
</div> </div>
))} ))}

View File

@ -7,7 +7,7 @@ import { useMobxStore } from "lib/mobx/store-provider";
// hooks // hooks
import useToast from "hooks/use-toast"; import useToast from "hooks/use-toast";
// ui // ui
import { SecondaryButton } from "components/ui"; import { Button } from "@plane/ui";
// types // types
import { Comment } from "types/issue"; import { Comment } from "types/issue";
// components // components
@ -29,7 +29,6 @@ export const AddComment: React.FC<Props> = observer((props) => {
const { const {
handleSubmit, handleSubmit,
control, control,
setValue,
watch, watch,
formState: { isSubmitting }, formState: { isSubmitting },
reset, reset,
@ -85,27 +84,30 @@ export const AddComment: React.FC<Props> = observer((props) => {
? watch("comment_html") ? watch("comment_html")
: value : value
} }
customClassName="p-3 min-h-[50px] shadow-sm" customClassName="p-2"
editorContentCustomClassNames="min-h-[35px]"
debouncedUpdatesEnabled={false} debouncedUpdatesEnabled={false}
onChange={(comment_json: Object, comment_html: string) => { onChange={(comment_json: Object, comment_html: string) => {
onChange(comment_html); onChange(comment_html);
}} }}
submitButton={
<Button
disabled={isSubmitting || disabled}
variant="primary"
type="submit"
className="!px-2.5 !py-1.5 !text-xs"
onClick={(e) => {
userStore.requiredLogin(() => {
handleSubmit(onSubmit)(e);
});
}}
>
{isSubmitting ? "Adding..." : "Comment"}
</Button>
}
/> />
)} )}
/> />
<SecondaryButton
onClick={(e) => {
userStore.requiredLogin(() => {
handleSubmit(onSubmit)(e);
});
}}
type="submit"
disabled={isSubmitting || disabled}
className="mt-2"
>
{isSubmitting ? "Adding..." : "Comment"}
</SecondaryButton>
</div> </div>
</div> </div>
); );

View File

@ -88,7 +88,8 @@ export const AddComment: React.FC<Props> = ({ disabled = false, onSubmit, showAc
deleteFile={fileService.deleteImage} deleteFile={fileService.deleteImage}
ref={editorRef} ref={editorRef}
value={!commentValue || commentValue === "" ? "<p></p>" : commentValue} value={!commentValue || commentValue === "" ? "<p></p>" : commentValue}
customClassName="p-3 min-h-[100px] shadow-sm" customClassName="p-2 h-full"
editorContentCustomClassNames="min-h-[35px]"
debouncedUpdatesEnabled={false} debouncedUpdatesEnabled={false}
onChange={(comment_json: Object, comment_html: string) => onCommentChange(comment_html)} onChange={(comment_json: Object, comment_html: string) => onCommentChange(comment_html)}
commentAccessSpecifier={ commentAccessSpecifier={
@ -98,15 +99,21 @@ export const AddComment: React.FC<Props> = ({ disabled = false, onSubmit, showAc
} }
mentionSuggestions={editorSuggestions.mentionSuggestions} mentionSuggestions={editorSuggestions.mentionSuggestions}
mentionHighlights={editorSuggestions.mentionHighlights} mentionHighlights={editorSuggestions.mentionHighlights}
submitButton={
<Button
variant="primary"
type="submit"
className="!px-2.5 !py-1.5 !text-xs"
disabled={isSubmitting || disabled}
>
{isSubmitting ? "Adding..." : "Comment"}
</Button>
}
/> />
)} )}
/> />
)} )}
/> />
<Button variant="neutral-primary" type="submit" disabled={isSubmitting || disabled}>
{isSubmitting ? "Adding..." : "Comment"}
</Button>
</div> </div>
</form> </form>
</div> </div>

View File

@ -61,7 +61,7 @@ export const KanbanIssueBlock: React.FC<IssueBlockProps> = (props) => {
)} )}
</div> </div>
<div <div
className={`text-sm rounded p-2 px-3 shadow-custom-shadow-2xs space-y-[8px] border transition-all bg-custom-background-100 ${ className={`text-sm rounded py-2 px-3 shadow-custom-shadow-2xs space-y-2 border-[0.5px] border-custom-border-200 transition-all bg-custom-background-100 ${
isDragDisabled ? "" : "hover:cursor-grab" isDragDisabled ? "" : "hover:cursor-grab"
} ${snapshot.isDragging ? `border-custom-primary-100` : `border-transparent`}`} } ${snapshot.isDragging ? `border-custom-primary-100` : `border-transparent`}`}
> >

View File

@ -55,7 +55,7 @@ const GroupByKanBan: React.FC<IGroupByKanBan> = observer((props) => {
kanBanToggle?.groupByHeaderMinMax.includes(getValueFromObject(_list, listKey) as string); kanBanToggle?.groupByHeaderMinMax.includes(getValueFromObject(_list, listKey) as string);
return ( return (
<div className="relative w-full h-full flex"> <div className="relative w-full h-full flex gap-3">
{list && {list &&
list.length > 0 && list.length > 0 &&
list.map((_list: any) => ( list.map((_list: any) => (

View File

@ -17,7 +17,7 @@ export interface IStateGroupHeader {
} }
export const Icon = ({ stateGroup, color }: { stateGroup: any; color?: any }) => ( export const Icon = ({ stateGroup, color }: { stateGroup: any; color?: any }) => (
<div className="w-[14px] h-[14px] rounded-full"> <div className="w-3.5 h-3.5 rounded-full">
<StateGroupIcon stateGroup={stateGroup} color={color || null} width="14" height="14" /> <StateGroupIcon stateGroup={stateGroup} color={color || null} width="14" height="14" />
</div> </div>
); );

View File

@ -90,6 +90,7 @@ export const IssueCommentEditor: React.FC<IIssueCommentEditor> = (props) => {
ref={editorRef} ref={editorRef}
value={!commentValue || commentValue === "" ? "<p></p>" : commentValue} value={!commentValue || commentValue === "" ? "<p></p>" : commentValue}
customClassName="p-2 h-full" customClassName="p-2 h-full"
editorContentCustomClassNames="min-h-[35px]"
debouncedUpdatesEnabled={false} debouncedUpdatesEnabled={false}
mentionSuggestions={editorSuggestions.mentionSuggestions} mentionSuggestions={editorSuggestions.mentionSuggestions}
mentionHighlights={editorSuggestions.mentionHighlights} mentionHighlights={editorSuggestions.mentionHighlights}

View File

@ -250,7 +250,7 @@ export const IssueView: FC<IIssueView> = observer((props) => {
issue && ( issue && (
<> <>
{["side-peek", "modal"].includes(peekMode) ? ( {["side-peek", "modal"].includes(peekMode) ? (
<div className="flex flex-col gap-3 px-10 py-6"> <div className="flex flex-col gap-3 py-6 px-8">
<PeekOverviewIssueDetails <PeekOverviewIssueDetails
workspaceSlug={workspaceSlug} workspaceSlug={workspaceSlug}
issue={issue} issue={issue}