mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: update border colors
This commit is contained in:
parent
5e110e2684
commit
52d1db26ea
@ -89,7 +89,7 @@ export const CycleMobileHeader = () => {
|
|||||||
onClose={() => setAnalyticsModal(false)}
|
onClose={() => setAnalyticsModal(false)}
|
||||||
cycleDetails={cycleDetails ?? undefined}
|
cycleDetails={cycleDetails ?? undefined}
|
||||||
/>
|
/>
|
||||||
<div className="flex justify-evenly py-2 border-b border-custom-border-200">
|
<div className="flex justify-evenly py-2 border-b border-neutral-border-medium">
|
||||||
<CustomMenu
|
<CustomMenu
|
||||||
maxHeight={"md"}
|
maxHeight={"md"}
|
||||||
className="flex flex-grow justify-center text-custom-text-200 text-sm"
|
className="flex flex-grow justify-center text-custom-text-200 text-sm"
|
||||||
@ -110,7 +110,7 @@ export const CycleMobileHeader = () => {
|
|||||||
</CustomMenu.MenuItem>
|
</CustomMenu.MenuItem>
|
||||||
))}
|
))}
|
||||||
</CustomMenu>
|
</CustomMenu>
|
||||||
<div className="flex flex-grow justify-center border-l border-custom-border-200 items-center text-custom-text-200 text-sm">
|
<div className="flex flex-grow justify-center border-l border-neutral-border-medium items-center text-custom-text-200 text-sm">
|
||||||
<FiltersDropdown
|
<FiltersDropdown
|
||||||
title="Filters"
|
title="Filters"
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
@ -133,7 +133,7 @@ export const CycleMobileHeader = () => {
|
|||||||
/>
|
/>
|
||||||
</FiltersDropdown>
|
</FiltersDropdown>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-grow justify-center border-l border-custom-border-200 items-center text-custom-text-200 text-sm">
|
<div className="flex flex-grow justify-center border-l border-neutral-border-medium items-center text-custom-text-200 text-sm">
|
||||||
<FiltersDropdown
|
<FiltersDropdown
|
||||||
title="Display"
|
title="Display"
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
@ -158,7 +158,7 @@ export const CycleMobileHeader = () => {
|
|||||||
|
|
||||||
<span
|
<span
|
||||||
onClick={() => setAnalyticsModal(true)}
|
onClick={() => setAnalyticsModal(true)}
|
||||||
className="flex flex-grow justify-center text-custom-text-200 text-sm border-l border-custom-border-200"
|
className="flex flex-grow justify-center text-custom-text-200 text-sm border-l border-neutral-border-medium"
|
||||||
>
|
>
|
||||||
Analytics
|
Analytics
|
||||||
</span>
|
</span>
|
||||||
|
@ -159,7 +159,7 @@ export const CyclesListItem: FC<TCyclesListItem> = (props) => {
|
|||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
/>
|
/>
|
||||||
<Link href={`/${workspaceSlug}/projects/${projectId}/cycles/${cycleDetails.id}`}>
|
<Link href={`/${workspaceSlug}/projects/${projectId}/cycles/${cycleDetails.id}`}>
|
||||||
<div className="group flex flex-col md:flex-row w-full items-center justify-between gap-5 border-b border-custom-border-100 bg-custom-background-100 px-5 py-6 text-sm hover:bg-custom-background-90">
|
<div className="group flex flex-col md:flex-row w-full items-center justify-between gap-5 border-b border-neutral-border-subtle bg-custom-background-100 px-5 py-6 text-sm hover:bg-custom-background-90">
|
||||||
<div className="relative w-full flex items-center justify-between gap-3 overflow-hidden">
|
<div className="relative w-full flex items-center justify-between gap-3 overflow-hidden">
|
||||||
<div className="relative w-full flex items-center gap-3 overflow-hidden">
|
<div className="relative w-full flex items-center gap-3 overflow-hidden">
|
||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
|
@ -531,7 +531,7 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="flex w-full flex-col items-center justify-start gap-2 border-t border-custom-border-200 px-1.5 py-5">
|
<div className="flex w-full flex-col items-center justify-start gap-2 border-t border-neutral-border-medium px-1.5 py-5">
|
||||||
<Disclosure defaultOpen>
|
<Disclosure defaultOpen>
|
||||||
{({ open }) => (
|
{({ open }) => (
|
||||||
<div className={`relative flex h-full w-full flex-col ${open ? "" : "flex-row"}`}>
|
<div className={`relative flex h-full w-full flex-col ${open ? "" : "flex-row"}`}>
|
||||||
@ -597,7 +597,7 @@ export const CycleDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
""
|
""
|
||||||
)}
|
)}
|
||||||
{cycleDetails.total_issues > 0 && cycleDetails.distribution && (
|
{cycleDetails.total_issues > 0 && cycleDetails.distribution && (
|
||||||
<div className="h-full w-full border-t border-custom-border-200 pt-5">
|
<div className="h-full w-full border-t border-neutral-border-medium pt-5">
|
||||||
<SidebarProgressStats
|
<SidebarProgressStats
|
||||||
distribution={cycleDetails.distribution}
|
distribution={cycleDetails.distribution}
|
||||||
groupedIssues={{
|
groupedIssues={{
|
||||||
|
@ -71,7 +71,7 @@ export const AssignedIssuesWidget: React.FC<WidgetProps> = observer((props) => {
|
|||||||
if (!widgetDetails || !widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />;
|
if (!widgetDetails || !widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-custom-background-100 rounded-xl border-[0.5px] border-custom-border-200 w-full hover:shadow-custom-shadow-4xl duration-300 flex flex-col min-h-96">
|
<div className="bg-custom-background-100 rounded-xl border-[0.5px] border-neutral-border-medium w-full hover:shadow-custom-shadow-4xl duration-300 flex flex-col min-h-96">
|
||||||
<div className="flex items-center justify-between gap-2 p-6 pl-7">
|
<div className="flex items-center justify-between gap-2 p-6 pl-7">
|
||||||
<Link
|
<Link
|
||||||
href={`/${workspaceSlug}/workspace-views/assigned/${filterParams}`}
|
href={`/${workspaceSlug}/workspace-views/assigned/${filterParams}`}
|
||||||
|
@ -68,7 +68,7 @@ export const CreatedIssuesWidget: React.FC<WidgetProps> = observer((props) => {
|
|||||||
if (!widgetDetails || !widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />;
|
if (!widgetDetails || !widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-custom-background-100 rounded-xl border-[0.5px] border-custom-border-200 w-full hover:shadow-custom-shadow-4xl duration-300 flex flex-col min-h-96">
|
<div className="bg-custom-background-100 rounded-xl border-[0.5px] border-neutral-border-medium w-full hover:shadow-custom-shadow-4xl duration-300 flex flex-col min-h-96">
|
||||||
<div className="flex items-center justify-between gap-2 p-6 pl-7">
|
<div className="flex items-center justify-between gap-2 p-6 pl-7">
|
||||||
<Link
|
<Link
|
||||||
href={`/${workspaceSlug}/workspace-views/created/${filterParams}`}
|
href={`/${workspaceSlug}/workspace-views/created/${filterParams}`}
|
||||||
|
@ -21,7 +21,7 @@ export const TabsList: React.FC<Props> = observer((props) => {
|
|||||||
return (
|
return (
|
||||||
<Tab.List
|
<Tab.List
|
||||||
as="div"
|
as="div"
|
||||||
className="relative border-[0.5px] border-custom-border-200 rounded bg-custom-background-80 grid"
|
className="relative border-[0.5px] border-neutral-border-medium rounded bg-custom-background-80 grid"
|
||||||
style={{
|
style={{
|
||||||
gridTemplateColumns: `repeat(${tabsList.length}, 1fr)`,
|
gridTemplateColumns: `repeat(${tabsList.length}, 1fr)`,
|
||||||
}}
|
}}
|
||||||
|
@ -130,7 +130,7 @@ export const IssuesByPriorityWidget: React.FC<WidgetProps> = observer((props) =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-custom-background-100 rounded-xl border-[0.5px] border-custom-border-200 w-full py-6 hover:shadow-custom-shadow-4xl duration-300 overflow-hidden min-h-96 flex flex-col">
|
<div className="bg-custom-background-100 rounded-xl border-[0.5px] border-neutral-border-medium w-full py-6 hover:shadow-custom-shadow-4xl duration-300 overflow-hidden min-h-96 flex flex-col">
|
||||||
<div className="flex items-center justify-between gap-2 pl-7 pr-6">
|
<div className="flex items-center justify-between gap-2 pl-7 pr-6">
|
||||||
<Link
|
<Link
|
||||||
href={`/${workspaceSlug}/workspace-views/assigned`}
|
href={`/${workspaceSlug}/workspace-views/assigned`}
|
||||||
|
@ -129,7 +129,7 @@ export const IssuesByStateGroupWidget: React.FC<WidgetProps> = observer((props)
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-custom-background-100 rounded-xl border-[0.5px] border-custom-border-200 w-full py-6 hover:shadow-custom-shadow-4xl duration-300 overflow-hidden min-h-96 flex flex-col">
|
<div className="bg-custom-background-100 rounded-xl border-[0.5px] border-neutral-border-medium w-full py-6 hover:shadow-custom-shadow-4xl duration-300 overflow-hidden min-h-96 flex flex-col">
|
||||||
<div className="flex items-center justify-between gap-2 pl-7 pr-6">
|
<div className="flex items-center justify-between gap-2 pl-7 pr-6">
|
||||||
<Link
|
<Link
|
||||||
href={`/${workspaceSlug}/workspace-views/assigned`}
|
href={`/${workspaceSlug}/workspace-views/assigned`}
|
||||||
|
@ -64,10 +64,10 @@ export const OverviewStatsWidget: React.FC<WidgetProps> = observer((props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="bg-custom-background-100 rounded-xl border-[0.5px] border-custom-border-200 w-full grid lg:grid-cols-4 md:grid-cols-2 sm:grid-cols-2 grid-cols-2 p-0.5 hover:shadow-custom-shadow-4xl duration-300
|
className="bg-custom-background-100 rounded-xl border-[0.5px] border-neutral-border-medium w-full grid lg:grid-cols-4 md:grid-cols-2 sm:grid-cols-2 grid-cols-2 p-0.5 hover:shadow-custom-shadow-4xl duration-300
|
||||||
[&>div>a>div]:border-r
|
[&>div>a>div]:border-r
|
||||||
[&>div:last-child>a>div]:border-0
|
[&>div:last-child>a>div]:border-0
|
||||||
[&>div>a>div]:border-custom-border-200
|
[&>div>a>div]:border-neutral-border-medium
|
||||||
[&>div:nth-child(2)>a>div]:border-0
|
[&>div:nth-child(2)>a>div]:border-0
|
||||||
[&>div:nth-child(2)>a>div]:lg:border-r
|
[&>div:nth-child(2)>a>div]:lg:border-r
|
||||||
"
|
"
|
||||||
|
@ -54,7 +54,7 @@ const BorderButton: React.FC<ButtonProps> = (props) => {
|
|||||||
<Tooltip tooltipHeading={tooltipHeading} tooltipContent={tooltipContent} disabled={!showTooltip}>
|
<Tooltip tooltipHeading={tooltipHeading} tooltipContent={tooltipContent} disabled={!showTooltip}>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
"h-full flex items-center gap-1.5 border-[0.5px] border-neutral-border-medium hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
||||||
{ "bg-custom-background-80": isActive },
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
|
@ -184,12 +184,12 @@ export const WorkspaceMemberDropdown: React.FC<MemberDropdownProps> = observer((
|
|||||||
{isOpen && (
|
{isOpen && (
|
||||||
<Combobox.Options className="fixed z-10" static>
|
<Combobox.Options className="fixed z-10" static>
|
||||||
<div
|
<div
|
||||||
className="my-1 w-48 rounded border-[0.5px] border-custom-border-300 bg-custom-background-100 px-2 py-2.5 text-xs shadow-custom-shadow-rg focus:outline-none"
|
className="my-1 w-48 rounded border-[0.5px] border-neutral-border-medium bg-custom-background-100 px-2 py-2.5 text-xs shadow-custom-shadow-rg focus:outline-none"
|
||||||
ref={setPopperElement}
|
ref={setPopperElement}
|
||||||
style={styles.popper}
|
style={styles.popper}
|
||||||
{...attributes.popper}
|
{...attributes.popper}
|
||||||
>
|
>
|
||||||
<div className="flex items-center gap-1.5 rounded border border-custom-border-100 bg-custom-background-90 px-2">
|
<div className="flex items-center gap-1.5 rounded border border-neutral-border-subtle bg-custom-background-90 px-2">
|
||||||
<Search className="h-3.5 w-3.5 text-custom-text-400" strokeWidth={1.5} />
|
<Search className="h-3.5 w-3.5 text-custom-text-400" strokeWidth={1.5} />
|
||||||
<Combobox.Input
|
<Combobox.Input
|
||||||
className="w-full bg-transparent py-1 text-xs text-custom-text-200 placeholder:text-custom-text-400 focus:outline-none"
|
className="w-full bg-transparent py-1 text-xs text-custom-text-200 placeholder:text-custom-text-400 focus:outline-none"
|
||||||
|
@ -76,7 +76,7 @@ export const ChartAddBlock: React.FC<Props> = (props) => {
|
|||||||
<Tooltip tooltipContent={buttonStartDate && renderFormattedDate(buttonStartDate)}>
|
<Tooltip tooltipContent={buttonStartDate && renderFormattedDate(buttonStartDate)}>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="absolute top-1/2 -translate-x-1/2 -translate-y-1/2 h-8 w-8 bg-custom-background-80 p-1.5 rounded border border-custom-border-300 grid place-items-center text-custom-text-200 hover:text-custom-text-100"
|
className="absolute top-1/2 -translate-x-1/2 -translate-y-1/2 h-8 w-8 bg-custom-background-80 p-1.5 rounded border border-neutral-border-medium grid place-items-center text-custom-text-200 hover:text-custom-text-100"
|
||||||
style={{
|
style={{
|
||||||
marginLeft: `${buttonXPosition}px`,
|
marginLeft: `${buttonXPosition}px`,
|
||||||
}}
|
}}
|
||||||
|
@ -150,7 +150,7 @@ export const CycleIssuesHeader: React.FC = observer(() => {
|
|||||||
cycleDetails={cycleDetails ?? undefined}
|
cycleDetails={cycleDetails ?? undefined}
|
||||||
/>
|
/>
|
||||||
<div className="relative z-10 w-full items-center gap-x-2 gap-y-4">
|
<div className="relative z-10 w-full items-center gap-x-2 gap-y-4">
|
||||||
<div className="flex justify-between border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
<div className="flex justify-between border-b border-neutral-border-medium bg-custom-sidebar-background-100 p-4">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<SidebarHamburgerToggle />
|
<SidebarHamburgerToggle />
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
|
@ -46,7 +46,7 @@ export const CyclesHeader: FC = observer(() => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative z-10 items-center justify-between gap-x-2 gap-y-4">
|
<div className="relative z-10 items-center justify-between gap-x-2 gap-y-4">
|
||||||
<div className="flex border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
<div className="flex border-b border-neutral-border-medium bg-custom-sidebar-background-100 p-4">
|
||||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||||
<SidebarHamburgerToggle />
|
<SidebarHamburgerToggle />
|
||||||
<div>
|
<div>
|
||||||
@ -99,7 +99,7 @@ export const CyclesHeader: FC = observer(() => {
|
|||||||
<div className="flex justify-center sm:hidden">
|
<div className="flex justify-center sm:hidden">
|
||||||
<CustomMenu
|
<CustomMenu
|
||||||
maxHeight={"md"}
|
maxHeight={"md"}
|
||||||
className="flex flex-grow justify-center text-custom-text-200 text-sm py-2 border-b border-custom-border-200 bg-custom-sidebar-background-100"
|
className="flex flex-grow justify-center text-custom-text-200 text-sm py-2 border-b border-neutral-border-medium bg-custom-sidebar-background-100"
|
||||||
// placement="bottom-start"
|
// placement="bottom-start"
|
||||||
customButton={
|
customButton={
|
||||||
<span className="flex items-center gap-2">
|
<span className="flex items-center gap-2">
|
||||||
|
@ -107,7 +107,7 @@ export const GlobalIssuesHeader: React.FC<Props> = observer((props) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<CreateUpdateWorkspaceViewModal isOpen={createViewModal} onClose={() => setCreateViewModal(false)} />
|
<CreateUpdateWorkspaceViewModal isOpen={createViewModal} onClose={() => setCreateViewModal(false)} />
|
||||||
<div className="relative z-10 flex h-[3.75rem] w-full items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
<div className="relative z-10 flex h-[3.75rem] w-full items-center justify-between gap-x-2 gap-y-4 border-b border-neutral-border-medium bg-custom-sidebar-background-100 p-4">
|
||||||
<div className="relative flex gap-2">
|
<div className="relative flex gap-2">
|
||||||
<SidebarHamburgerToggle />
|
<SidebarHamburgerToggle />
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
|
@ -153,7 +153,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
|
|||||||
moduleDetails={moduleDetails ?? undefined}
|
moduleDetails={moduleDetails ?? undefined}
|
||||||
/>
|
/>
|
||||||
<div className="relative z-10 items-center gap-x-2 gap-y-4">
|
<div className="relative z-10 items-center gap-x-2 gap-y-4">
|
||||||
<div className="flex justify-between border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
<div className="flex justify-between border-b border-neutral-border-medium bg-custom-sidebar-background-100 p-4">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<SidebarHamburgerToggle />
|
<SidebarHamburgerToggle />
|
||||||
<Breadcrumbs>
|
<Breadcrumbs>
|
||||||
|
@ -116,7 +116,7 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
projectDetails={currentProjectDetails ?? undefined}
|
projectDetails={currentProjectDetails ?? undefined}
|
||||||
/>
|
/>
|
||||||
<div className="relative z-10 items-center gap-x-2 gap-y-4">
|
<div className="relative z-10 items-center gap-x-2 gap-y-4">
|
||||||
<div className="flex items-center gap-2 p-4 border-b border-custom-border-200 bg-custom-sidebar-background-100">
|
<div className="flex items-center gap-2 p-4 border-b border-neutral-border-medium bg-custom-sidebar-background-100">
|
||||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||||
<SidebarHamburgerToggle />
|
<SidebarHamburgerToggle />
|
||||||
<div>
|
<div>
|
||||||
@ -209,7 +209,7 @@ export const ProjectIssuesHeader: React.FC = observer(() => {
|
|||||||
<Button variant="neutral-primary" size="sm" className="relative">
|
<Button variant="neutral-primary" size="sm" className="relative">
|
||||||
Inbox
|
Inbox
|
||||||
{inboxDetails?.pending_issue_count > 0 && (
|
{inboxDetails?.pending_issue_count > 0 && (
|
||||||
<span className="absolute -right-1.5 -top-1.5 h-4 w-4 rounded-full border border-custom-sidebar-border-200 bg-custom-sidebar-background-80 text-custom-text-100">
|
<span className="absolute -right-1.5 -top-1.5 h-4 w-4 rounded-full border border-sidebar-neutral-border-medium bg-custom-sidebar-background-80 text-custom-text-100">
|
||||||
{inboxDetails?.pending_issue_count}
|
{inboxDetails?.pending_issue_count}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
@ -31,7 +31,7 @@ export const ProjectSettingHeader: FC<IProjectSettingHeader> = observer((props)
|
|||||||
if (currentProjectRole && currentProjectRole <= EUserProjectRoles.VIEWER) return null;
|
if (currentProjectRole && currentProjectRole <= EUserProjectRoles.VIEWER) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-neutral-border-medium bg-custom-sidebar-background-100 p-4">
|
||||||
<SidebarHamburgerToggle />
|
<SidebarHamburgerToggle />
|
||||||
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
<div className="flex w-full flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||||
<div>
|
<div>
|
||||||
@ -67,7 +67,7 @@ export const ProjectSettingHeader: FC<IProjectSettingHeader> = observer((props)
|
|||||||
className="flex-shrink-0 block sm:block md:hidden lg:hidden"
|
className="flex-shrink-0 block sm:block md:hidden lg:hidden"
|
||||||
maxHeight="lg"
|
maxHeight="lg"
|
||||||
customButton={
|
customButton={
|
||||||
<span className="text-xs px-1.5 py-1 border rounded-md text-custom-text-200 border-custom-border-300">
|
<span className="text-xs px-1.5 py-1 border rounded-md text-custom-text-200 border-neutral-border-medium">
|
||||||
{title}
|
{title}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ export const ProjectsHeader = observer(() => {
|
|||||||
const isAuthorizedUser = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER;
|
const isAuthorizedUser = !!currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-neutral-border-medium bg-custom-sidebar-background-100 p-4">
|
||||||
<div className="flex flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
<div className="flex flex-grow items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||||
<SidebarHamburgerToggle />
|
<SidebarHamburgerToggle />
|
||||||
<div>
|
<div>
|
||||||
@ -36,7 +36,7 @@ export const ProjectsHeader = observer(() => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex w-full justify-end items-center gap-3">
|
<div className="flex w-full justify-end items-center gap-3">
|
||||||
{workspaceProjectIds && workspaceProjectIds?.length > 0 && (
|
{workspaceProjectIds && workspaceProjectIds?.length > 0 && (
|
||||||
<div className=" flex items-center justify-start gap-1 rounded-md border border-custom-border-200 bg-custom-background-100 px-2.5 py-1.5 text-custom-text-400">
|
<div className=" flex items-center justify-start gap-1 rounded-md border border-neutral-border-medium bg-custom-background-100 px-2.5 py-1.5 text-custom-text-400">
|
||||||
<Search className="h-3.5" />
|
<Search className="h-3.5" />
|
||||||
<input
|
<input
|
||||||
className="border-none w-full bg-transparent text-sm focus:outline-none"
|
className="border-none w-full bg-transparent text-sm focus:outline-none"
|
||||||
|
@ -15,7 +15,7 @@ export const WorkspaceDashboardHeader = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="relative z-[15] flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
|
<div className="relative z-[15] flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-neutral-border-medium bg-custom-sidebar-background-100 p-4">
|
||||||
<div className="flex items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
<div className="flex items-center gap-2 overflow-ellipsis whitespace-nowrap">
|
||||||
<SidebarHamburgerToggle />
|
<SidebarHamburgerToggle />
|
||||||
<div>
|
<div>
|
||||||
|
@ -45,7 +45,7 @@ export const WorkspaceSettingHeader: FC<IWorkspaceSettingHeader> = observer((pro
|
|||||||
className="flex-shrink-0 block sm:block md:hidden lg:hidden"
|
className="flex-shrink-0 block sm:block md:hidden lg:hidden"
|
||||||
maxHeight="lg"
|
maxHeight="lg"
|
||||||
customButton={
|
customButton={
|
||||||
<span className="text-xs px-1.5 py-1 border rounded-md text-custom-text-200 border-custom-border-300">
|
<span className="text-xs px-1.5 py-1 border rounded-md text-custom-text-200 border-neutral-border-medium">
|
||||||
{title}
|
{title}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ export const CalendarIssueBlocks: React.FC<Props> = observer((props) => {
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"group/calendar-block flex h-8 w-full items-center justify-between gap-1.5 rounded border-[0.5px] border-custom-border-200 hover:border-custom-border-400 px-1 py-1.5 ",
|
"group/calendar-block flex h-8 w-full items-center justify-between gap-1.5 rounded border-[0.5px] border-neutral-border-medium hover:border-neutral-border-strong px-1 py-1.5 ",
|
||||||
{
|
{
|
||||||
"bg-custom-background-90 shadow-custom-shadow-rg border-custom-primary-100":
|
"bg-custom-background-90 shadow-custom-shadow-rg border-custom-primary-100":
|
||||||
snapshot.isDragging,
|
snapshot.isDragging,
|
||||||
|
@ -134,7 +134,7 @@ export const KanbanIssueBlock: React.FC<IssueBlockProps> = memo((props) => {
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"space-y-2 rounded border-[0.5px] border-custom-border-200 bg-custom-background-100 px-3 py-2 text-sm transition-all hover:border-custom-border-400",
|
"space-y-2 rounded border-[0.5px] border-neutral-border-medium bg-custom-background-100 px-3 py-2 text-sm transition-all hover:border-neutral-border-strong",
|
||||||
{ "hover:cursor-grab": !isDragDisabled },
|
{ "hover:cursor-grab": !isDragDisabled },
|
||||||
{ "border-custom-primary-100": snapshot.isDragging },
|
{ "border-custom-primary-100": snapshot.isDragging },
|
||||||
{ "border border-custom-primary-70 hover:border-custom-primary-70": peekIssueId === issue.id }
|
{ "border border-custom-primary-70 hover:border-custom-primary-70": peekIssueId === issue.id }
|
||||||
|
@ -27,7 +27,7 @@ export const SpreadsheetLabelColumn: React.FC<Props> = observer((props: Props) =
|
|||||||
value={issue.label_ids}
|
value={issue.label_ids}
|
||||||
defaultOptions={defaultLabelOptions}
|
defaultOptions={defaultLabelOptions}
|
||||||
onChange={(data) => onChange(issue, { label_ids: data }, { changed_property: "labels", change_details: data })}
|
onChange={(data) => onChange(issue, { label_ids: data }, { changed_property: "labels", change_details: data })}
|
||||||
className="h-11 w-full border-b-[0.5px] border-custom-border-200 hover:bg-custom-background-80"
|
className="h-11 w-full border-b-[0.5px] border-neutral-border-medium hover:bg-custom-background-80"
|
||||||
buttonClassName="px-2.5 h-full"
|
buttonClassName="px-2.5 h-full"
|
||||||
hideDropdownArrow
|
hideDropdownArrow
|
||||||
maxRender={1}
|
maxRender={1}
|
||||||
|
@ -38,7 +38,7 @@ export const IssueColumn = observer((props: Props) => {
|
|||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
className="h-11 w-full min-w-[8rem] bg-custom-background-100 text-sm after:absolute after:w-full after:bottom-[-1px] after:border after:border-custom-border-100 border-r-[1px] border-custom-border-100 focus:border-custom-primary-70"
|
className="h-11 w-full min-w-[8rem] bg-custom-background-100 text-sm after:absolute after:w-full after:bottom-[-1px] after:border after:border-neutral-border-subtle border-r-[1px] border-neutral-border-subtle focus:border-custom-primary-70"
|
||||||
ref={tableCellRef}
|
ref={tableCellRef}
|
||||||
>
|
>
|
||||||
<Column
|
<Column
|
||||||
|
@ -106,7 +106,7 @@ export const SpreadsheetIssueRow = observer((props: Props) => {
|
|||||||
{/* first column/ issue name and key column */}
|
{/* first column/ issue name and key column */}
|
||||||
<td
|
<td
|
||||||
className={cn(
|
className={cn(
|
||||||
"sticky group left-0 h-11 w-[28rem] flex items-center bg-custom-background-100 text-sm after:absolute border-r-[0.5px] border-custom-border-200 focus:border-custom-primary-70",
|
"sticky group left-0 h-11 w-[28rem] flex items-center bg-custom-background-100 text-sm after:absolute border-r-[0.5px] border-neutral-border-medium focus:border-custom-primary-70",
|
||||||
{
|
{
|
||||||
"border-b-[0.5px]": peekIssue?.issueId !== issueDetail.id,
|
"border-b-[0.5px]": peekIssue?.issueId !== issueDetail.id,
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export const SpreadsheetHeaderColumn = observer((props: Props) => {
|
|||||||
shouldRenderProperty={shouldRenderProperty}
|
shouldRenderProperty={shouldRenderProperty}
|
||||||
>
|
>
|
||||||
<th
|
<th
|
||||||
className="h-11 w-full min-w-[8rem] items-center bg-custom-background-90 text-sm font-medium px-4 py-1 border border-b-0 border-t-0 border-custom-border-100 focus:border-custom-primary-70"
|
className="h-11 w-full min-w-[8rem] items-center bg-custom-background-90 text-sm font-medium px-4 py-1 border border-b-0 border-t-0 border-neutral-border-subtle focus:border-custom-primary-70"
|
||||||
ref={tableHeaderCellRef}
|
ref={tableHeaderCellRef}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
>
|
>
|
||||||
|
@ -22,7 +22,7 @@ export const SpreadsheetHeader = (props: Props) => {
|
|||||||
<thead className="sticky top-0 left-0 z-[1] border-b-[0.5px] border-neutral-border-subtle">
|
<thead className="sticky top-0 left-0 z-[1] border-b-[0.5px] border-neutral-border-subtle">
|
||||||
<tr>
|
<tr>
|
||||||
<th
|
<th
|
||||||
className="sticky left-0 z-[1] h-11 w-[28rem] flex items-center bg-custom-background-90 text-sm font-medium before:absolute before:h-full before:right-0 before:border-[0.5px] before:border-custom-border-100"
|
className="sticky left-0 z-[1] h-11 w-[28rem] flex items-center bg-custom-background-90 text-sm font-medium before:absolute before:h-full before:right-0 before:border-[0.5px] before:border-neutral-border-subtle"
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
>
|
>
|
||||||
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="key">
|
<WithDisplayPropertiesHOC displayProperties={displayProperties} displayPropertyKey="key">
|
||||||
|
@ -14,153 +14,153 @@ import { IIssueDisplayFilterOptions, IIssueDisplayProperties, IIssueFilterOption
|
|||||||
import { ProjectAnalyticsModal } from "components/analytics";
|
import { ProjectAnalyticsModal } from "components/analytics";
|
||||||
|
|
||||||
export const IssuesMobileHeader = () => {
|
export const IssuesMobileHeader = () => {
|
||||||
const layouts = [
|
const layouts = [
|
||||||
{ key: "list", title: "List", icon: List },
|
{ key: "list", title: "List", icon: List },
|
||||||
{ key: "kanban", title: "Kanban", icon: Kanban },
|
{ key: "kanban", title: "Kanban", icon: Kanban },
|
||||||
{ key: "calendar", title: "Calendar", icon: Calendar },
|
{ key: "calendar", title: "Calendar", icon: Calendar },
|
||||||
];
|
];
|
||||||
const [analyticsModal, setAnalyticsModal] = useState(false);
|
const [analyticsModal, setAnalyticsModal] = useState(false);
|
||||||
const { workspaceSlug, projectId } = router.query as {
|
const { workspaceSlug, projectId } = router.query as {
|
||||||
workspaceSlug: string;
|
workspaceSlug: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
const { currentProjectDetails } = useProject();
|
const { currentProjectDetails } = useProject();
|
||||||
const { projectStates } = useProjectState();
|
const { projectStates } = useProjectState();
|
||||||
const { projectLabels } = useLabel();
|
const { projectLabels } = useLabel();
|
||||||
|
|
||||||
// store hooks
|
// store hooks
|
||||||
const {
|
const {
|
||||||
issuesFilter: { issueFilters, updateFilters },
|
issuesFilter: { issueFilters, updateFilters },
|
||||||
} = useIssues(EIssuesStoreType.PROJECT);
|
} = useIssues(EIssuesStoreType.PROJECT);
|
||||||
const {
|
const {
|
||||||
project: { projectMemberIds },
|
project: { projectMemberIds },
|
||||||
} = useMember();
|
} = useMember();
|
||||||
const activeLayout = issueFilters?.displayFilters?.layout;
|
const activeLayout = issueFilters?.displayFilters?.layout;
|
||||||
|
|
||||||
const handleLayoutChange = useCallback(
|
const handleLayoutChange = useCallback(
|
||||||
(layout: TIssueLayouts) => {
|
(layout: TIssueLayouts) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout });
|
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout });
|
||||||
},
|
},
|
||||||
[workspaceSlug, projectId, updateFilters]
|
[workspaceSlug, projectId, updateFilters]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleFiltersUpdate = useCallback(
|
const handleFiltersUpdate = useCallback(
|
||||||
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
const newValues = issueFilters?.filters?.[key] ?? [];
|
const newValues = issueFilters?.filters?.[key] ?? [];
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
value.forEach((val) => {
|
value.forEach((val) => {
|
||||||
if (!newValues.includes(val)) newValues.push(val);
|
if (!newValues.includes(val)) newValues.push(val);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
||||||
else newValues.push(value);
|
else newValues.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFilters(workspaceSlug, projectId, EIssueFilterType.FILTERS, { [key]: newValues });
|
||||||
|
},
|
||||||
|
[workspaceSlug, projectId, issueFilters, updateFilters]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDisplayFilters = useCallback(
|
||||||
|
(updatedDisplayFilter: Partial<IIssueDisplayFilterOptions>) => {
|
||||||
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, updatedDisplayFilter);
|
||||||
|
},
|
||||||
|
[workspaceSlug, projectId, updateFilters]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDisplayProperties = useCallback(
|
||||||
|
(property: Partial<IIssueDisplayProperties>) => {
|
||||||
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_PROPERTIES, property);
|
||||||
|
},
|
||||||
|
[workspaceSlug, projectId, updateFilters]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ProjectAnalyticsModal
|
||||||
|
isOpen={analyticsModal}
|
||||||
|
onClose={() => setAnalyticsModal(false)}
|
||||||
|
projectDetails={currentProjectDetails ?? undefined}
|
||||||
|
/>
|
||||||
|
<div className="flex justify-evenly py-2 border-b border-neutral-border-medium">
|
||||||
|
<CustomMenu
|
||||||
|
maxHeight={"md"}
|
||||||
|
className="flex flex-grow justify-center text-custom-text-200 text-sm"
|
||||||
|
placement="bottom-start"
|
||||||
|
customButton={<span className="flex flex-grow justify-center text-custom-text-200 text-sm">Layout</span>}
|
||||||
|
customButtonClassName="flex flex-grow justify-center text-custom-text-200 text-sm"
|
||||||
|
closeOnSelect
|
||||||
|
>
|
||||||
|
{layouts.map((layout, index) => (
|
||||||
|
<CustomMenu.MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
handleLayoutChange(ISSUE_LAYOUTS[index].key);
|
||||||
|
}}
|
||||||
|
className="flex items-center gap-2"
|
||||||
|
>
|
||||||
|
<layout.icon className="w-3 h-3" />
|
||||||
|
<div className="text-custom-text-300">{layout.title}</div>
|
||||||
|
</CustomMenu.MenuItem>
|
||||||
|
))}
|
||||||
|
</CustomMenu>
|
||||||
|
<div className="flex flex-grow justify-center border-l border-neutral-border-medium items-center text-custom-text-200 text-sm">
|
||||||
|
<FiltersDropdown
|
||||||
|
title="Filters"
|
||||||
|
placement="bottom-end"
|
||||||
|
menuButton={
|
||||||
|
<span className="flex items-center text-custom-text-200 text-sm">
|
||||||
|
Filters
|
||||||
|
<ChevronDown className="text-custom-text-200 h-4 w-4 ml-2" />
|
||||||
|
</span>
|
||||||
}
|
}
|
||||||
|
>
|
||||||
updateFilters(workspaceSlug, projectId, EIssueFilterType.FILTERS, { [key]: newValues });
|
<FilterSelection
|
||||||
},
|
filters={issueFilters?.filters ?? {}}
|
||||||
[workspaceSlug, projectId, issueFilters, updateFilters]
|
handleFiltersUpdate={handleFiltersUpdate}
|
||||||
);
|
layoutDisplayFiltersOptions={
|
||||||
|
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
|
||||||
const handleDisplayFilters = useCallback(
|
}
|
||||||
(updatedDisplayFilter: Partial<IIssueDisplayFilterOptions>) => {
|
labels={projectLabels}
|
||||||
if (!workspaceSlug || !projectId) return;
|
memberIds={projectMemberIds ?? undefined}
|
||||||
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, updatedDisplayFilter);
|
states={projectStates}
|
||||||
},
|
|
||||||
[workspaceSlug, projectId, updateFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleDisplayProperties = useCallback(
|
|
||||||
(property: Partial<IIssueDisplayProperties>) => {
|
|
||||||
if (!workspaceSlug || !projectId) return;
|
|
||||||
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_PROPERTIES, property);
|
|
||||||
},
|
|
||||||
[workspaceSlug, projectId, updateFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<ProjectAnalyticsModal
|
|
||||||
isOpen={analyticsModal}
|
|
||||||
onClose={() => setAnalyticsModal(false)}
|
|
||||||
projectDetails={currentProjectDetails ?? undefined}
|
|
||||||
/>
|
/>
|
||||||
<div className="flex justify-evenly py-2 border-b border-custom-border-200">
|
</FiltersDropdown>
|
||||||
<CustomMenu
|
</div>
|
||||||
maxHeight={"md"}
|
<div className="flex flex-grow justify-center border-l border-neutral-border-medium items-center text-custom-text-200 text-sm">
|
||||||
className="flex flex-grow justify-center text-custom-text-200 text-sm"
|
<FiltersDropdown
|
||||||
placement="bottom-start"
|
title="Display"
|
||||||
customButton={<span className="flex flex-grow justify-center text-custom-text-200 text-sm">Layout</span>}
|
placement="bottom-end"
|
||||||
customButtonClassName="flex flex-grow justify-center text-custom-text-200 text-sm"
|
menuButton={
|
||||||
closeOnSelect
|
<span className="flex items-center text-custom-text-200 text-sm">
|
||||||
>
|
Display
|
||||||
{layouts.map((layout, index) => (
|
<ChevronDown className="text-custom-text-200 h-4 w-4 ml-2" />
|
||||||
<CustomMenu.MenuItem
|
</span>
|
||||||
onClick={() => {
|
}
|
||||||
handleLayoutChange(ISSUE_LAYOUTS[index].key);
|
>
|
||||||
}}
|
<DisplayFiltersSelection
|
||||||
className="flex items-center gap-2"
|
layoutDisplayFiltersOptions={
|
||||||
>
|
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
|
||||||
<layout.icon className="w-3 h-3" />
|
}
|
||||||
<div className="text-custom-text-300">{layout.title}</div>
|
displayFilters={issueFilters?.displayFilters ?? {}}
|
||||||
</CustomMenu.MenuItem>
|
handleDisplayFiltersUpdate={handleDisplayFilters}
|
||||||
))}
|
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||||
</CustomMenu>
|
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||||
<div className="flex flex-grow justify-center border-l border-custom-border-200 items-center text-custom-text-200 text-sm">
|
/>
|
||||||
<FiltersDropdown
|
</FiltersDropdown>
|
||||||
title="Filters"
|
</div>
|
||||||
placement="bottom-end"
|
|
||||||
menuButton={
|
|
||||||
<span className="flex items-center text-custom-text-200 text-sm">
|
|
||||||
Filters
|
|
||||||
<ChevronDown className="text-custom-text-200 h-4 w-4 ml-2" />
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<FilterSelection
|
|
||||||
filters={issueFilters?.filters ?? {}}
|
|
||||||
handleFiltersUpdate={handleFiltersUpdate}
|
|
||||||
layoutDisplayFiltersOptions={
|
|
||||||
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
|
|
||||||
}
|
|
||||||
labels={projectLabels}
|
|
||||||
memberIds={projectMemberIds ?? undefined}
|
|
||||||
states={projectStates}
|
|
||||||
/>
|
|
||||||
</FiltersDropdown>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-grow justify-center border-l border-custom-border-200 items-center text-custom-text-200 text-sm">
|
|
||||||
<FiltersDropdown
|
|
||||||
title="Display"
|
|
||||||
placement="bottom-end"
|
|
||||||
menuButton={
|
|
||||||
<span className="flex items-center text-custom-text-200 text-sm">
|
|
||||||
Display
|
|
||||||
<ChevronDown className="text-custom-text-200 h-4 w-4 ml-2" />
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<DisplayFiltersSelection
|
|
||||||
layoutDisplayFiltersOptions={
|
|
||||||
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
|
|
||||||
}
|
|
||||||
displayFilters={issueFilters?.displayFilters ?? {}}
|
|
||||||
handleDisplayFiltersUpdate={handleDisplayFilters}
|
|
||||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
|
||||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
|
||||||
/>
|
|
||||||
</FiltersDropdown>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => setAnalyticsModal(true)}
|
onClick={() => setAnalyticsModal(true)}
|
||||||
className="flex flex-grow justify-center text-custom-text-200 text-sm border-l border-custom-border-200"
|
className="flex flex-grow justify-center text-custom-text-200 text-sm border-l border-neutral-border-medium"
|
||||||
>
|
>
|
||||||
Analytics
|
Analytics
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -307,7 +307,7 @@ export const SubIssuesRoot: FC<ISubIssuesRoot> = observer((props) => {
|
|||||||
{!disabled && (
|
{!disabled && (
|
||||||
<div className="ml-auto flex flex-shrink-0 select-none items-center gap-2">
|
<div className="ml-auto flex flex-shrink-0 select-none items-center gap-2">
|
||||||
<div
|
<div
|
||||||
className="cursor-pointer rounded border border-custom-border-100 p-1.5 px-2 shadow transition-all hover:bg-custom-background-80"
|
className="cursor-pointer rounded border border-neutral-border-subtle p-1.5 px-2 shadow transition-all hover:bg-custom-background-80"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setTrackElement("Issue detail add sub-issue");
|
setTrackElement("Issue detail add sub-issue");
|
||||||
handleIssueCrudState("create", parentIssueId, null);
|
handleIssueCrudState("create", parentIssueId, null);
|
||||||
@ -316,7 +316,7 @@ export const SubIssuesRoot: FC<ISubIssuesRoot> = observer((props) => {
|
|||||||
Add sub-issue
|
Add sub-issue
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="cursor-pointer rounded border border-custom-border-100 p-1.5 px-2 shadow transition-all hover:bg-custom-background-80"
|
className="cursor-pointer rounded border border-neutral-border-subtle p-1.5 px-2 shadow transition-all hover:bg-custom-background-80"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setTrackElement("Issue detail add sub-issue");
|
setTrackElement("Issue detail add sub-issue");
|
||||||
handleIssueCrudState("existing", parentIssueId, null);
|
handleIssueCrudState("existing", parentIssueId, null);
|
||||||
|
@ -9,154 +9,154 @@ import router from "next/router";
|
|||||||
import { useCallback, useState } from "react";
|
import { useCallback, useState } from "react";
|
||||||
|
|
||||||
export const ModuleMobileHeader = () => {
|
export const ModuleMobileHeader = () => {
|
||||||
const [analyticsModal, setAnalyticsModal] = useState(false);
|
const [analyticsModal, setAnalyticsModal] = useState(false);
|
||||||
const { getModuleById } = useModule();
|
const { getModuleById } = useModule();
|
||||||
const layouts = [
|
const layouts = [
|
||||||
{ key: "list", title: "List", icon: List },
|
{ key: "list", title: "List", icon: List },
|
||||||
{ key: "kanban", title: "Kanban", icon: Kanban },
|
{ key: "kanban", title: "Kanban", icon: Kanban },
|
||||||
{ key: "calendar", title: "Calendar", icon: Calendar },
|
{ key: "calendar", title: "Calendar", icon: Calendar },
|
||||||
];
|
];
|
||||||
const { workspaceSlug, projectId, moduleId } = router.query as {
|
const { workspaceSlug, projectId, moduleId } = router.query as {
|
||||||
workspaceSlug: string;
|
workspaceSlug: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
moduleId: string;
|
moduleId: string;
|
||||||
};
|
};
|
||||||
const moduleDetails = moduleId ? getModuleById(moduleId.toString()) : undefined;
|
const moduleDetails = moduleId ? getModuleById(moduleId.toString()) : undefined;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
issuesFilter: { issueFilters, updateFilters },
|
issuesFilter: { issueFilters, updateFilters },
|
||||||
} = useIssues(EIssuesStoreType.MODULE);
|
} = useIssues(EIssuesStoreType.MODULE);
|
||||||
const activeLayout = issueFilters?.displayFilters?.layout;
|
const activeLayout = issueFilters?.displayFilters?.layout;
|
||||||
const { projectStates } = useProjectState();
|
const { projectStates } = useProjectState();
|
||||||
const { projectLabels } = useLabel();
|
const { projectLabels } = useLabel();
|
||||||
const {
|
const {
|
||||||
project: { projectMemberIds },
|
project: { projectMemberIds },
|
||||||
} = useMember();
|
} = useMember();
|
||||||
|
|
||||||
const handleLayoutChange = useCallback(
|
const handleLayoutChange = useCallback(
|
||||||
(layout: TIssueLayouts) => {
|
(layout: TIssueLayouts) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout }, moduleId);
|
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, { layout: layout }, moduleId);
|
||||||
},
|
},
|
||||||
[workspaceSlug, projectId, moduleId, updateFilters]
|
[workspaceSlug, projectId, moduleId, updateFilters]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleFiltersUpdate = useCallback(
|
const handleFiltersUpdate = useCallback(
|
||||||
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
(key: keyof IIssueFilterOptions, value: string | string[]) => {
|
||||||
if (!workspaceSlug || !projectId) return;
|
if (!workspaceSlug || !projectId) return;
|
||||||
const newValues = issueFilters?.filters?.[key] ?? [];
|
const newValues = issueFilters?.filters?.[key] ?? [];
|
||||||
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
value.forEach((val) => {
|
value.forEach((val) => {
|
||||||
if (!newValues.includes(val)) newValues.push(val);
|
if (!newValues.includes(val)) newValues.push(val);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
if (issueFilters?.filters?.[key]?.includes(value)) newValues.splice(newValues.indexOf(value), 1);
|
||||||
else newValues.push(value);
|
else newValues.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateFilters(workspaceSlug, projectId, EIssueFilterType.FILTERS, { [key]: newValues }, moduleId);
|
||||||
|
},
|
||||||
|
[workspaceSlug, projectId, moduleId, issueFilters, updateFilters]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDisplayFilters = useCallback(
|
||||||
|
(updatedDisplayFilter: Partial<IIssueDisplayFilterOptions>) => {
|
||||||
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, updatedDisplayFilter, moduleId);
|
||||||
|
},
|
||||||
|
[workspaceSlug, projectId, moduleId, updateFilters]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleDisplayProperties = useCallback(
|
||||||
|
(property: Partial<IIssueDisplayProperties>) => {
|
||||||
|
if (!workspaceSlug || !projectId) return;
|
||||||
|
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_PROPERTIES, property, moduleId);
|
||||||
|
},
|
||||||
|
[workspaceSlug, projectId, moduleId, updateFilters]
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="block md:hidden">
|
||||||
|
<ProjectAnalyticsModal
|
||||||
|
isOpen={analyticsModal}
|
||||||
|
onClose={() => setAnalyticsModal(false)}
|
||||||
|
moduleDetails={moduleDetails ?? undefined}
|
||||||
|
/>
|
||||||
|
<div className="flex justify-evenly py-2 border-b border-neutral-border-medium">
|
||||||
|
<CustomMenu
|
||||||
|
maxHeight={"md"}
|
||||||
|
className="flex flex-grow justify-center text-custom-text-200 text-sm"
|
||||||
|
placement="bottom-start"
|
||||||
|
customButton={<span className="flex flex-grow justify-center text-custom-text-200 text-sm">Layout</span>}
|
||||||
|
customButtonClassName="flex flex-grow justify-center text-custom-text-200 text-sm"
|
||||||
|
closeOnSelect
|
||||||
|
>
|
||||||
|
{layouts.map((layout, index) => (
|
||||||
|
<CustomMenu.MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
handleLayoutChange(ISSUE_LAYOUTS[index].key);
|
||||||
|
}}
|
||||||
|
className="flex items-center gap-2"
|
||||||
|
>
|
||||||
|
<layout.icon className="w-3 h-3" />
|
||||||
|
<div className="text-custom-text-300">{layout.title}</div>
|
||||||
|
</CustomMenu.MenuItem>
|
||||||
|
))}
|
||||||
|
</CustomMenu>
|
||||||
|
<div className="flex flex-grow justify-center border-l border-neutral-border-medium items-center text-custom-text-200 text-sm">
|
||||||
|
<FiltersDropdown
|
||||||
|
title="Filters"
|
||||||
|
placement="bottom-end"
|
||||||
|
menuButton={
|
||||||
|
<span className="flex items-center text-custom-text-200 text-sm">
|
||||||
|
Filters
|
||||||
|
<ChevronDown className="text-custom-text-200 h-4 w-4 ml-2" />
|
||||||
|
</span>
|
||||||
}
|
}
|
||||||
|
>
|
||||||
updateFilters(workspaceSlug, projectId, EIssueFilterType.FILTERS, { [key]: newValues }, moduleId);
|
<FilterSelection
|
||||||
},
|
filters={issueFilters?.filters ?? {}}
|
||||||
[workspaceSlug, projectId, moduleId, issueFilters, updateFilters]
|
handleFiltersUpdate={handleFiltersUpdate}
|
||||||
);
|
layoutDisplayFiltersOptions={
|
||||||
|
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
|
||||||
const handleDisplayFilters = useCallback(
|
}
|
||||||
(updatedDisplayFilter: Partial<IIssueDisplayFilterOptions>) => {
|
labels={projectLabels}
|
||||||
if (!workspaceSlug || !projectId) return;
|
memberIds={projectMemberIds ?? undefined}
|
||||||
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_FILTERS, updatedDisplayFilter, moduleId);
|
states={projectStates}
|
||||||
},
|
|
||||||
[workspaceSlug, projectId, moduleId, updateFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleDisplayProperties = useCallback(
|
|
||||||
(property: Partial<IIssueDisplayProperties>) => {
|
|
||||||
if (!workspaceSlug || !projectId) return;
|
|
||||||
updateFilters(workspaceSlug, projectId, EIssueFilterType.DISPLAY_PROPERTIES, property, moduleId);
|
|
||||||
},
|
|
||||||
[workspaceSlug, projectId, moduleId, updateFilters]
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="block md:hidden">
|
|
||||||
<ProjectAnalyticsModal
|
|
||||||
isOpen={analyticsModal}
|
|
||||||
onClose={() => setAnalyticsModal(false)}
|
|
||||||
moduleDetails={moduleDetails ?? undefined}
|
|
||||||
/>
|
/>
|
||||||
<div className="flex justify-evenly py-2 border-b border-custom-border-200">
|
</FiltersDropdown>
|
||||||
<CustomMenu
|
|
||||||
maxHeight={"md"}
|
|
||||||
className="flex flex-grow justify-center text-custom-text-200 text-sm"
|
|
||||||
placement="bottom-start"
|
|
||||||
customButton={<span className="flex flex-grow justify-center text-custom-text-200 text-sm">Layout</span>}
|
|
||||||
customButtonClassName="flex flex-grow justify-center text-custom-text-200 text-sm"
|
|
||||||
closeOnSelect
|
|
||||||
>
|
|
||||||
{layouts.map((layout, index) => (
|
|
||||||
<CustomMenu.MenuItem
|
|
||||||
onClick={() => {
|
|
||||||
handleLayoutChange(ISSUE_LAYOUTS[index].key);
|
|
||||||
}}
|
|
||||||
className="flex items-center gap-2"
|
|
||||||
>
|
|
||||||
<layout.icon className="w-3 h-3" />
|
|
||||||
<div className="text-custom-text-300">{layout.title}</div>
|
|
||||||
</CustomMenu.MenuItem>
|
|
||||||
))}
|
|
||||||
</CustomMenu>
|
|
||||||
<div className="flex flex-grow justify-center border-l border-custom-border-200 items-center text-custom-text-200 text-sm">
|
|
||||||
<FiltersDropdown
|
|
||||||
title="Filters"
|
|
||||||
placement="bottom-end"
|
|
||||||
menuButton={
|
|
||||||
<span className="flex items-center text-custom-text-200 text-sm">
|
|
||||||
Filters
|
|
||||||
<ChevronDown className="text-custom-text-200 h-4 w-4 ml-2" />
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<FilterSelection
|
|
||||||
filters={issueFilters?.filters ?? {}}
|
|
||||||
handleFiltersUpdate={handleFiltersUpdate}
|
|
||||||
layoutDisplayFiltersOptions={
|
|
||||||
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
|
|
||||||
}
|
|
||||||
labels={projectLabels}
|
|
||||||
memberIds={projectMemberIds ?? undefined}
|
|
||||||
states={projectStates}
|
|
||||||
/>
|
|
||||||
</FiltersDropdown>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-grow justify-center border-l border-custom-border-200 items-center text-custom-text-200 text-sm">
|
|
||||||
<FiltersDropdown
|
|
||||||
title="Display"
|
|
||||||
placement="bottom-end"
|
|
||||||
menuButton={
|
|
||||||
<span className="flex items-center text-custom-text-200 text-sm">
|
|
||||||
Display
|
|
||||||
<ChevronDown className="text-custom-text-200 h-4 w-4 ml-2" />
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<DisplayFiltersSelection
|
|
||||||
layoutDisplayFiltersOptions={
|
|
||||||
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
|
|
||||||
}
|
|
||||||
displayFilters={issueFilters?.displayFilters ?? {}}
|
|
||||||
handleDisplayFiltersUpdate={handleDisplayFilters}
|
|
||||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
|
||||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
|
||||||
/>
|
|
||||||
</FiltersDropdown>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={() => setAnalyticsModal(true)}
|
|
||||||
className="flex flex-grow justify-center text-custom-text-200 text-sm border-l border-custom-border-200"
|
|
||||||
>
|
|
||||||
Analytics
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
<div className="flex flex-grow justify-center border-l border-neutral-border-medium items-center text-custom-text-200 text-sm">
|
||||||
|
<FiltersDropdown
|
||||||
|
title="Display"
|
||||||
|
placement="bottom-end"
|
||||||
|
menuButton={
|
||||||
|
<span className="flex items-center text-custom-text-200 text-sm">
|
||||||
|
Display
|
||||||
|
<ChevronDown className="text-custom-text-200 h-4 w-4 ml-2" />
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<DisplayFiltersSelection
|
||||||
|
layoutDisplayFiltersOptions={
|
||||||
|
activeLayout ? ISSUE_DISPLAY_FILTERS_BY_LAYOUT.issues[activeLayout] : undefined
|
||||||
|
}
|
||||||
|
displayFilters={issueFilters?.displayFilters ?? {}}
|
||||||
|
handleDisplayFiltersUpdate={handleDisplayFilters}
|
||||||
|
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||||
|
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||||
|
/>
|
||||||
|
</FiltersDropdown>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={() => setAnalyticsModal(true)}
|
||||||
|
className="flex flex-grow justify-center text-custom-text-200 text-sm border-l border-neutral-border-medium"
|
||||||
|
>
|
||||||
|
Analytics
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
@ -291,7 +291,7 @@ export const WorkspaceSidebarDropdown = observer(() => {
|
|||||||
>
|
>
|
||||||
<Menu.Items
|
<Menu.Items
|
||||||
className="absolute left-0 z-20 mt-1 flex w-52 origin-top-left flex-col divide-y
|
className="absolute left-0 z-20 mt-1 flex w-52 origin-top-left flex-col divide-y
|
||||||
divide-custom-sidebar-border-200 rounded-md border border-custom-sidebar-border-200 bg-custom-sidebar-background-100 px-1 py-2 text-xs shadow-lg outline-none"
|
divide-custom-sidebar-border-200 rounded-md border border-sidebar-neutral-border-medium bg-custom-sidebar-background-100 px-1 py-2 text-xs shadow-lg outline-none"
|
||||||
ref={setPopperElement}
|
ref={setPopperElement}
|
||||||
style={styles.popper}
|
style={styles.popper}
|
||||||
{...attributes.popper}
|
{...attributes.popper}
|
||||||
|
@ -42,7 +42,7 @@ export const AppSidebar: FC<IAppSidebar> = observer(() => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`inset-y-0 z-20 flex h-full flex-shrink-0 flex-grow-0 flex-col border-r border-custom-sidebar-border-200 bg-custom-sidebar-background-100 duration-300
|
className={`inset-y-0 z-20 flex h-full flex-shrink-0 flex-grow-0 flex-col border-r border-sidebar-neutral-border-medium bg-custom-sidebar-background-100 duration-300
|
||||||
fixed md:relative
|
fixed md:relative
|
||||||
${themStore.sidebarCollapsed ? "-ml-[280px]" : ""}
|
${themStore.sidebarCollapsed ? "-ml-[280px]" : ""}
|
||||||
sm:${themStore.sidebarCollapsed ? "-ml-[280px]" : ""}
|
sm:${themStore.sidebarCollapsed ? "-ml-[280px]" : ""}
|
||||||
|
Loading…
Reference in New Issue
Block a user