mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
[WEB-579] style: scrollbar implementation (#3835)
* style: scrollbar added in profile summary and sidebar * style: scrollbar added in modals * style: scrollbar added in project setting screens * style: scrollbar added in workspace and profile settings * style: scrollbar added in dropdowns and filters
This commit is contained in:
parent
4d0f641ee0
commit
c06ef4d1d7
@ -33,7 +33,7 @@ export const CustomAnalyticsMainContent: React.FC<Props> = (props) => {
|
||||
{!error ? (
|
||||
analytics ? (
|
||||
analytics.total > 0 ? (
|
||||
<div className="h-full overflow-y-auto">
|
||||
<div className="h-full overflow-y-auto vertical-scrollbar scrollbar-md">
|
||||
<AnalyticsGraph
|
||||
analytics={analytics}
|
||||
barGraphData={barGraphData}
|
||||
|
@ -19,7 +19,7 @@ export const CustomAnalyticsSidebarProjectsList: React.FC<Props> = observer((pro
|
||||
return (
|
||||
<div className="relative flex flex-col gap-4 h-full">
|
||||
<h4 className="font-medium">Selected Projects</h4>
|
||||
<div className="relative space-y-6 overflow-hidden overflow-y-auto">
|
||||
<div className="relative space-y-6 overflow-hidden overflow-y-auto vertical-scrollbar scrollbar-md">
|
||||
{projectIds.map((projectId) => {
|
||||
const project = getProjectById(projectId);
|
||||
|
||||
@ -42,7 +42,7 @@ export const CustomAnalyticsSidebarProjectsList: React.FC<Props> = observer((pro
|
||||
<span className="ml-1 text-xs text-custom-text-200">({project.identifier})</span>
|
||||
</h5>
|
||||
</div>
|
||||
<div className="mt-4 w-full space-y-3 pl-2">
|
||||
<div className="mt-4 w-full space-y-3 px-2">
|
||||
<div className="flex items-center justify-between gap-2 text-xs">
|
||||
<div className="flex items-center gap-2">
|
||||
<Users className="text-custom-text-200" size={14} strokeWidth={2} />
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useEffect, } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { observer } from "mobx-react-lite";
|
||||
import { mutate } from "swr";
|
||||
|
@ -187,7 +187,7 @@ export const ImagePickerPopover: React.FC<Props> = observer((props) => {
|
||||
);
|
||||
})}
|
||||
</Tab.List>
|
||||
<Tab.Panels className="h-full w-full flex-1 overflow-y-auto overflow-x-hidden">
|
||||
<Tab.Panels className="h-full w-full flex-1 overflow-y-auto overflow-x-hidden vertical-scrollbar scrollbar-md">
|
||||
{(unsplashImages || !unsplashError) && (
|
||||
<Tab.Panel className="mt-4 h-full w-full space-y-4">
|
||||
<div className="flex gap-x-2">
|
||||
|
@ -184,7 +184,7 @@ export const ExistingIssuesListModal: React.FC<Props> = (props) => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Combobox.Options static className="max-h-80 scroll-py-2 overflow-y-auto">
|
||||
<Combobox.Options static className="max-h-80 scroll-py-2 overflow-y-auto vertical-scrollbar scrollbar-md">
|
||||
{searchTerm !== "" && (
|
||||
<h5 className="mx-2 text-[0.825rem] text-custom-text-200">
|
||||
Search results for{" "}
|
||||
|
@ -94,7 +94,7 @@ const EmojiIconPicker: React.FC<Props> = (props) => {
|
||||
</Tab>
|
||||
))}
|
||||
</Tab.List>
|
||||
<Tab.Panels className="flex-1 overflow-y-auto">
|
||||
<Tab.Panels className="flex-1 overflow-y-auto vertical-scrollbar scrollbar-sm">
|
||||
<Tab.Panel>
|
||||
{recentEmojis.length > 0 && (
|
||||
<div className="py-2">
|
||||
|
@ -37,7 +37,7 @@ export const DisplayFiltersSelection: React.FC<Props> = observer((props) => {
|
||||
Object.keys(layoutDisplayFiltersOptions?.display_filters ?? {}).includes(displayFilter);
|
||||
|
||||
return (
|
||||
<div className="relative h-full w-full divide-y divide-custom-border-200 overflow-hidden overflow-y-auto px-2.5">
|
||||
<div className="relative h-full w-full divide-y divide-custom-border-200 overflow-hidden overflow-y-auto px-2.5 vertical-scrollbar scrollbar-sm">
|
||||
{/* display properties */}
|
||||
{layoutDisplayFiltersOptions?.display_properties && (
|
||||
<div className="py-2">
|
||||
|
@ -63,7 +63,7 @@ export const FilterSelection: React.FC<Props> = observer((props) => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-full w-full divide-y divide-custom-border-200 overflow-y-auto px-2.5">
|
||||
<div className="h-full w-full divide-y divide-custom-border-200 overflow-y-auto px-2.5 vertical-scrollbar scrollbar-sm">
|
||||
{/* priority */}
|
||||
{isFilterEnabled("priority") && (
|
||||
<div className="py-2">
|
||||
|
@ -136,7 +136,10 @@ export const ParentIssuesListModal: React.FC<Props> = ({
|
||||
</div>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Combobox.Options static className="max-h-80 scroll-py-2 overflow-y-auto">
|
||||
<Combobox.Options
|
||||
static
|
||||
className="max-h-80 scroll-py-2 overflow-y-auto vertical-scrollbar scrollbar-md"
|
||||
>
|
||||
{searchTerm !== "" && (
|
||||
<h5 className="mx-2 text-[0.825rem] text-custom-text-200">
|
||||
Search results for{" "}
|
||||
|
@ -76,7 +76,7 @@ export const ProfileSidebar = observer(() => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`flex-shrink-0 overflow-hidden overflow-y-auto shadow-custom-shadow-sm border-l border-custom-border-100 bg-custom-sidebar-background-100 h-full z-[5] fixed md:relative transition-all w-full md:w-[300px]`}
|
||||
className={`flex-shrink-0 overflow-hidden overflow-y-auto vertical-scrollbar scrollbar-md shadow-custom-shadow-sm border-l border-custom-border-100 bg-custom-sidebar-background-100 h-full z-[5] fixed md:relative transition-all w-full md:w-[300px]`}
|
||||
style={themeStore.profileSidebarCollapsed ? { marginLeft: `${window?.innerWidth || 0}px` } : {}}
|
||||
>
|
||||
{userProjectsData ? (
|
||||
@ -162,12 +162,13 @@ export const ProfileSidebar = observer(() => {
|
||||
{project.assigned_issues > 0 && (
|
||||
<Tooltip tooltipContent="Completion percentage" position="left">
|
||||
<div
|
||||
className={`rounded px-1 py-0.5 text-xs font-medium ${completedIssuePercentage <= 35
|
||||
? "bg-red-500/10 text-red-500"
|
||||
: completedIssuePercentage <= 70
|
||||
className={`rounded px-1 py-0.5 text-xs font-medium ${
|
||||
completedIssuePercentage <= 35
|
||||
? "bg-red-500/10 text-red-500"
|
||||
: completedIssuePercentage <= 70
|
||||
? "bg-yellow-500/10 text-yellow-500"
|
||||
: "bg-green-500/10 text-green-500"
|
||||
}`}
|
||||
}`}
|
||||
>
|
||||
{completedIssuePercentage}%
|
||||
</div>
|
||||
|
@ -21,7 +21,9 @@ export const ProfileSettingsLayout: FC<IProfileSettingsLayout> = (props) => {
|
||||
<ProfileLayoutSidebar />
|
||||
<main className="relative flex h-full w-full flex-col overflow-hidden bg-custom-background-100">
|
||||
{header}
|
||||
<div className="h-full w-full overflow-x-hidden overflow-y-scroll">{children}</div>
|
||||
<div className="h-full w-full overflow-x-hidden overflow-y-scroll">
|
||||
{children}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</UserAuthWrapper>
|
||||
|
@ -73,7 +73,9 @@ export const ProfilePreferenceSettingsLayout: FC<IProfilePreferenceSettingsLayou
|
||||
<ProfilePreferenceSettingsSidebar />
|
||||
<main className="relative flex h-full w-full flex-col overflow-hidden bg-custom-background-100">
|
||||
{header}
|
||||
<div className="h-full w-full overflow-x-hidden overflow-y-scroll">{children}</div>
|
||||
<div className="h-full w-full overflow-x-hidden overflow-y-scroll vertical-scrollbar scrollbar-md">
|
||||
{children}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</ProfileSettingsLayout>
|
||||
|
@ -129,7 +129,7 @@ export const ProfileLayoutSidebar = observer(() => {
|
||||
{!sidebarCollapsed && (
|
||||
<h6 className="rounded px-1.5 text-sm font-semibold text-custom-sidebar-text-400">Your account</h6>
|
||||
)}
|
||||
<div className="mt-2 h-full space-y-1.5 overflow-y-auto">
|
||||
<div className="mt-2 h-full space-y-1.5 overflow-y-auto vertical-scrollbar scrollbar-sm">
|
||||
{PROFILE_ACTION_LINKS.map((link) => {
|
||||
if (link.key === "change-password" && currentUser?.is_password_autoset) return null;
|
||||
|
||||
@ -157,7 +157,7 @@ export const ProfileLayoutSidebar = observer(() => {
|
||||
<h6 className="rounded px-1.5 text-sm font-semibold text-custom-sidebar-text-400">Workspaces</h6>
|
||||
)}
|
||||
{workspacesList && workspacesList.length > 0 && (
|
||||
<div className="mt-2 h-full space-y-1.5 overflow-y-auto">
|
||||
<div className="mt-2 h-full space-y-1.5 overflow-y-auto vertical-scrollbar scrollbar-sm">
|
||||
{workspacesList.map((workspace) => (
|
||||
<Link
|
||||
key={workspace.id}
|
||||
|
@ -45,7 +45,9 @@ export const ProjectSettingLayout: FC<IProjectSettingLayout> = observer((props)
|
||||
<div className="w-80 flex-shrink-0 overflow-y-hidden pt-8 sm:hidden hidden md:block lg:block">
|
||||
<ProjectSettingsSidebar />
|
||||
</div>
|
||||
<div className="w-full pl-10 sm:pl-10 md:pl-0 lg:pl-0 overflow-x-hidden overflow-y-scroll">{children}</div>
|
||||
<div className="w-full pl-10 sm:pl-10 md:pl-0 lg:pl-0 overflow-x-hidden overflow-y-scroll vertical-scrollbar scrollbar-md">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
@ -10,11 +10,11 @@ export const WorkspaceSettingLayout: FC<IWorkspaceSettingLayout> = (props) => {
|
||||
const { children } = props;
|
||||
|
||||
return (
|
||||
<div className="inset-y-0 z-20 flex h-full w-full gap-2 overflow-x-hidden overflow-y-scroll">
|
||||
<div className="inset-y-0 z-20 flex h-full w-full gap-2">
|
||||
<div className="w-80 flex-shrink-0 overflow-y-hidden pt-8 sm:hidden hidden md:block lg:block">
|
||||
<WorkspaceSettingsSidebar />
|
||||
</div>
|
||||
<div className="w-full pl-10 sm:pl-10 md:pl-0 lg:pl-0">
|
||||
<div className="w-full pl-10 sm:pl-10 md:pl-0 lg:pl-0 overflow-x-hidden overflow-y-scroll vertical-scrollbar scrollbar-md">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,7 +45,7 @@ const ProfileOverviewPage: NextPageWithLayout = () => {
|
||||
return (
|
||||
<>
|
||||
<PageHead title="Profile - Summary" />
|
||||
<div className="h-full w-full space-y-7 overflow-y-auto px-5 py-5 md:px-9">
|
||||
<div className="h-full w-full space-y-7 overflow-y-auto px-5 py-5 md:px-9 vertical-scrollbar scrollbar-md">
|
||||
<ProfileStats userProfile={userProfile} />
|
||||
<ProfileWorkload stateDistribution={stateDistribution} />
|
||||
<div className="grid grid-cols-1 items-stretch gap-5 xl:grid-cols-2">
|
||||
|
@ -26,7 +26,7 @@ const EstimatesSettingsPage: NextPageWithLayout = observer(() => {
|
||||
return (
|
||||
<>
|
||||
<PageHead title={pageTitle} />
|
||||
<div className={`h-full w-full overflow-y-auto py-8 pr-9 ${isAdmin ? "" : "pointer-events-none opacity-60"}`}>
|
||||
<div className={`w-full overflow-y-auto py-8 pr-9 ${isAdmin ? "" : "pointer-events-none opacity-60"}`}>
|
||||
<EstimatesList />
|
||||
</div>
|
||||
</>
|
||||
|
@ -56,7 +56,7 @@ const ProjectIntegrationsPage: NextPageWithLayout = observer(() => {
|
||||
return (
|
||||
<>
|
||||
<PageHead title={pageTitle} />
|
||||
<div className={`h-full w-full gap-10 overflow-y-auto py-8 pr-9 ${isAdmin ? "" : "opacity-60"}`}>
|
||||
<div className={`w-full gap-10 overflow-y-auto py-8 pr-9 ${isAdmin ? "" : "opacity-60"}`}>
|
||||
<div className="flex items-center border-b border-custom-border-100 py-3.5">
|
||||
<h3 className="text-xl font-medium">Integrations</h3>
|
||||
</div>
|
||||
|
@ -19,7 +19,7 @@ const LabelsSettingsPage: NextPageWithLayout = observer(() => {
|
||||
return (
|
||||
<>
|
||||
<PageHead title={pageTitle} />
|
||||
<div className="h-full w-full gap-10 overflow-y-auto py-8 pr-9">
|
||||
<div className="w-full gap-10 overflow-y-auto py-8 pr-9">
|
||||
<ProjectSettingsLabelList />
|
||||
</div>
|
||||
</>
|
||||
|
@ -71,7 +71,7 @@ const ApiTokensPage: NextPageWithLayout = observer(() => {
|
||||
<>
|
||||
<PageHead title={pageTitle} />
|
||||
<CreateApiTokenModal isOpen={isCreateTokenModalOpen} onClose={() => setIsCreateTokenModalOpen(false)} />
|
||||
<section className="h-full w-full overflow-y-auto py-8 pr-9">
|
||||
<section className="w-full overflow-y-auto py-8 pr-9 ">
|
||||
{tokens.length > 0 ? (
|
||||
<>
|
||||
<div className="flex items-center justify-between border-b border-custom-border-200 py-3.5">
|
||||
|
@ -70,7 +70,7 @@ const WebhooksListPage: NextPageWithLayout = observer(() => {
|
||||
return (
|
||||
<>
|
||||
<PageHead title={pageTitle} />
|
||||
<div className="h-full w-full overflow-hidden py-8 pr-9">
|
||||
<div className="w-full overflow-y-auto py-8 pr-9">
|
||||
<CreateWebhookModal
|
||||
createWebhook={createWebhook}
|
||||
clearSecretKey={clearSecretKey}
|
||||
|
@ -40,7 +40,7 @@ const ProfileActivityPage: NextPageWithLayout = observer(() => {
|
||||
<h3 className="text-xl font-medium">Activity</h3>
|
||||
</div>
|
||||
{userActivity ? (
|
||||
<div className="flex h-full w-full flex-col gap-2 overflow-y-auto">
|
||||
<div className="flex h-full w-full flex-col gap-2 overflow-y-auto vertical-scrollbar scrollbar-md">
|
||||
<ul role="list" className="-mb-4">
|
||||
{userActivity.results.map((activityItem: any) => {
|
||||
if (activityItem.field === "comment") {
|
||||
|
@ -163,7 +163,7 @@ const ProfileSettingsPage: NextPageWithLayout = observer(() => {
|
||||
)}
|
||||
/>
|
||||
<DeactivateAccountModal isOpen={deactivateAccountModal} onClose={() => setDeactivateAccountModal(false)} />
|
||||
<div className="mx-auto flex h-full w-full flex-col space-y-10 overflow-y-auto pt-10 md:pt-16 px-8 pb-8 lg:w-3/5">
|
||||
<div className="mx-auto flex h-full w-full flex-col space-y-10 overflow-y-auto pt-10 md:pt-16 px-8 pb-8 lg:w-3/5 vertical-scrollbar scrollbar-md">
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="flex w-full flex-col gap-8">
|
||||
<div className="relative h-44 w-full">
|
||||
|
@ -28,7 +28,7 @@ const ProfilePreferencesThemePage: NextPageWithLayout = () => {
|
||||
return (
|
||||
<>
|
||||
<PageHead title="Profile - Email Preference" />
|
||||
<div className="mx-auto mt-8 h-full w-full overflow-y-auto px-6 lg:px-20 pb-8">
|
||||
<div className="mx-auto mt-8 h-full w-full px-6 lg:px-20 pb-8">
|
||||
<EmailNotificationForm data={data} />
|
||||
</div>
|
||||
</>
|
||||
|
Loading…
Reference in New Issue
Block a user