mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
Kanban DnD improvement
This commit is contained in:
parent
f5b7964c6b
commit
9870be61bb
@ -76,6 +76,8 @@ export const BaseKanBanRoot: React.FC<IBaseKanBanLayout> = observer((props: IBas
|
|||||||
const sub_group_by = displayFilters?.sub_group_by;
|
const sub_group_by = displayFilters?.sub_group_by;
|
||||||
const group_by = displayFilters?.group_by;
|
const group_by = displayFilters?.group_by;
|
||||||
|
|
||||||
|
const orderBy = displayFilters?.order_by;
|
||||||
|
|
||||||
const userDisplayFilters = displayFilters || null;
|
const userDisplayFilters = displayFilters || null;
|
||||||
|
|
||||||
const KanBanView = sub_group_by ? KanBanSwimLanes : KanBan;
|
const KanBanView = sub_group_by ? KanBanSwimLanes : KanBan;
|
||||||
@ -158,7 +160,8 @@ export const BaseKanBanRoot: React.FC<IBaseKanBanLayout> = observer((props: IBas
|
|||||||
issues.getIssueIds,
|
issues.getIssueIds,
|
||||||
updateIssue,
|
updateIssue,
|
||||||
group_by,
|
group_by,
|
||||||
sub_group_by
|
sub_group_by,
|
||||||
|
orderBy !== "sort_order"
|
||||||
).catch((err) => {
|
).catch((err) => {
|
||||||
setToast({
|
setToast({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
@ -259,6 +262,7 @@ export const BaseKanBanRoot: React.FC<IBaseKanBanLayout> = observer((props: IBas
|
|||||||
displayProperties={displayProperties}
|
displayProperties={displayProperties}
|
||||||
sub_group_by={sub_group_by}
|
sub_group_by={sub_group_by}
|
||||||
group_by={group_by}
|
group_by={group_by}
|
||||||
|
orderBy={orderBy}
|
||||||
updateIssue={updateIssue}
|
updateIssue={updateIssue}
|
||||||
quickActions={renderQuickActions}
|
quickActions={renderQuickActions}
|
||||||
handleKanbanFilters={handleKanbanFilters}
|
handleKanbanFilters={handleKanbanFilters}
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
TUnGroupedIssues,
|
TUnGroupedIssues,
|
||||||
TIssueKanbanFilters,
|
TIssueKanbanFilters,
|
||||||
TIssueGroupByOptions,
|
TIssueGroupByOptions,
|
||||||
|
TIssueOrderByOptions,
|
||||||
} from "@plane/types";
|
} from "@plane/types";
|
||||||
// constants
|
// constants
|
||||||
// hooks
|
// hooks
|
||||||
@ -39,6 +40,7 @@ export interface IGroupByKanBan {
|
|||||||
displayProperties: IIssueDisplayProperties | undefined;
|
displayProperties: IIssueDisplayProperties | undefined;
|
||||||
sub_group_by: TIssueGroupByOptions | undefined;
|
sub_group_by: TIssueGroupByOptions | undefined;
|
||||||
group_by: TIssueGroupByOptions | undefined;
|
group_by: TIssueGroupByOptions | undefined;
|
||||||
|
orderBy: TIssueOrderByOptions | undefined;
|
||||||
sub_group_id: string;
|
sub_group_id: string;
|
||||||
isDragDisabled: boolean;
|
isDragDisabled: boolean;
|
||||||
updateIssue: ((projectId: string, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined;
|
updateIssue: ((projectId: string, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined;
|
||||||
@ -87,6 +89,7 @@ const GroupByKanBan: React.FC<IGroupByKanBan> = observer((props) => {
|
|||||||
handleOnDrop,
|
handleOnDrop,
|
||||||
showEmptyGroup = true,
|
showEmptyGroup = true,
|
||||||
subGroupIssueHeaderCount,
|
subGroupIssueHeaderCount,
|
||||||
|
orderBy,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const member = useMember();
|
const member = useMember();
|
||||||
@ -180,6 +183,7 @@ const GroupByKanBan: React.FC<IGroupByKanBan> = observer((props) => {
|
|||||||
displayProperties={displayProperties}
|
displayProperties={displayProperties}
|
||||||
sub_group_by={sub_group_by}
|
sub_group_by={sub_group_by}
|
||||||
group_by={group_by}
|
group_by={group_by}
|
||||||
|
orderBy={orderBy}
|
||||||
sub_group_id={sub_group_id}
|
sub_group_id={sub_group_id}
|
||||||
isDragDisabled={isDragDisabled}
|
isDragDisabled={isDragDisabled}
|
||||||
updateIssue={updateIssue}
|
updateIssue={updateIssue}
|
||||||
@ -206,6 +210,7 @@ export interface IKanBan {
|
|||||||
displayProperties: IIssueDisplayProperties | undefined;
|
displayProperties: IIssueDisplayProperties | undefined;
|
||||||
sub_group_by: TIssueGroupByOptions | undefined;
|
sub_group_by: TIssueGroupByOptions | undefined;
|
||||||
group_by: TIssueGroupByOptions | undefined;
|
group_by: TIssueGroupByOptions | undefined;
|
||||||
|
orderBy: TIssueOrderByOptions | undefined;
|
||||||
sub_group_id?: string;
|
sub_group_id?: string;
|
||||||
updateIssue: ((projectId: string, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined;
|
updateIssue: ((projectId: string, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined;
|
||||||
quickActions: (issue: TIssue, customActionButton?: React.ReactElement) => React.ReactNode;
|
quickActions: (issue: TIssue, customActionButton?: React.ReactElement) => React.ReactNode;
|
||||||
@ -252,6 +257,7 @@ export const KanBan: React.FC<IKanBan> = observer((props) => {
|
|||||||
handleOnDrop,
|
handleOnDrop,
|
||||||
showEmptyGroup,
|
showEmptyGroup,
|
||||||
subGroupIssueHeaderCount,
|
subGroupIssueHeaderCount,
|
||||||
|
orderBy,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const issueKanBanView = useKanbanView();
|
const issueKanBanView = useKanbanView();
|
||||||
@ -263,6 +269,7 @@ export const KanBan: React.FC<IKanBan> = observer((props) => {
|
|||||||
displayProperties={displayProperties}
|
displayProperties={displayProperties}
|
||||||
group_by={group_by}
|
group_by={group_by}
|
||||||
sub_group_by={sub_group_by}
|
sub_group_by={sub_group_by}
|
||||||
|
orderBy={orderBy}
|
||||||
sub_group_id={sub_group_id}
|
sub_group_id={sub_group_id}
|
||||||
isDragDisabled={!issueKanBanView?.getCanUserDragDrop(group_by, sub_group_by)}
|
isDragDisabled={!issueKanBanView?.getCanUserDragDrop(group_by, sub_group_by)}
|
||||||
updateIssue={updateIssue}
|
updateIssue={updateIssue}
|
||||||
|
@ -11,13 +11,19 @@ import {
|
|||||||
TSubGroupedIssues,
|
TSubGroupedIssues,
|
||||||
TUnGroupedIssues,
|
TUnGroupedIssues,
|
||||||
TIssueGroupByOptions,
|
TIssueGroupByOptions,
|
||||||
|
TIssueOrderByOptions,
|
||||||
} from "@plane/types";
|
} from "@plane/types";
|
||||||
// helpers
|
// helpers
|
||||||
import { cn } from "@/helpers/common.helper";
|
import { cn } from "@/helpers/common.helper";
|
||||||
// hooks
|
// hooks
|
||||||
import { useProjectState } from "@/hooks/store";
|
import { useProjectState } from "@/hooks/store";
|
||||||
//components
|
//components
|
||||||
import { KanbanDropLocation, getSourceFromDropPayload, getDestinationFromDropPayload } from "./utils";
|
import {
|
||||||
|
KanbanDropLocation,
|
||||||
|
getSourceFromDropPayload,
|
||||||
|
getDestinationFromDropPayload,
|
||||||
|
highlightIssueOnDrop,
|
||||||
|
} from "./utils";
|
||||||
import { KanbanIssueBlocksList, KanBanQuickAddIssueForm } from ".";
|
import { KanbanIssueBlocksList, KanBanQuickAddIssueForm } from ".";
|
||||||
|
|
||||||
interface IKanbanGroup {
|
interface IKanbanGroup {
|
||||||
@ -45,6 +51,7 @@ interface IKanbanGroup {
|
|||||||
groupByVisibilityToggle?: boolean;
|
groupByVisibilityToggle?: boolean;
|
||||||
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
||||||
handleOnDrop: (source: KanbanDropLocation, destination: KanbanDropLocation) => Promise<void>;
|
handleOnDrop: (source: KanbanDropLocation, destination: KanbanDropLocation) => Promise<void>;
|
||||||
|
orderBy: TIssueOrderByOptions | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const KanbanGroup = (props: IKanbanGroup) => {
|
export const KanbanGroup = (props: IKanbanGroup) => {
|
||||||
@ -52,6 +59,7 @@ export const KanbanGroup = (props: IKanbanGroup) => {
|
|||||||
groupId,
|
groupId,
|
||||||
sub_group_id,
|
sub_group_id,
|
||||||
group_by,
|
group_by,
|
||||||
|
orderBy,
|
||||||
sub_group_by,
|
sub_group_by,
|
||||||
issuesMap,
|
issuesMap,
|
||||||
displayProperties,
|
displayProperties,
|
||||||
@ -102,13 +110,15 @@ export const KanbanGroup = (props: IKanbanGroup) => {
|
|||||||
if (!source || !destination) return;
|
if (!source || !destination) return;
|
||||||
|
|
||||||
handleOnDrop(source, destination);
|
handleOnDrop(source, destination);
|
||||||
|
|
||||||
|
highlightIssueOnDrop(payload.source.element.id, orderBy !== "sort_order");
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
autoScrollForElements({
|
autoScrollForElements({
|
||||||
element,
|
element,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}, [columnRef?.current, groupId, sub_group_id, setIsDraggingOverColumn]);
|
}, [columnRef?.current, groupId, sub_group_id, setIsDraggingOverColumn, orderBy]);
|
||||||
|
|
||||||
const prePopulateQuickAddData = (
|
const prePopulateQuickAddData = (
|
||||||
groupByKey: string | undefined,
|
groupByKey: string | undefined,
|
||||||
@ -162,16 +172,28 @@ export const KanbanGroup = (props: IKanbanGroup) => {
|
|||||||
return preloadedData;
|
return preloadedData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const shouldOverlay = isDraggingOverColumn && orderBy !== "sort_order";
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
id={`${groupId}__${sub_group_id}`}
|
id={`${groupId}__${sub_group_id}`}
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative h-full transition-all min-h-[50px]",
|
"relative h-full transition-all min-h-[50px]",
|
||||||
{ "bg-custom-background-80": isDraggingOverColumn },
|
{ "bg-custom-background-80": isDraggingOverColumn },
|
||||||
{ "vertical-scrollbar scrollbar-md": !sub_group_by }
|
{ "vertical-scrollbar scrollbar-md": !sub_group_by && !shouldOverlay }
|
||||||
)}
|
)}
|
||||||
ref={columnRef}
|
ref={columnRef}
|
||||||
>
|
>
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"absolute top-0 left-0 h-full w-full justify-center items-center text-sm text-custom-text-100",
|
||||||
|
{
|
||||||
|
"flex bg-custom-primary-10 border-[2px] border-custom-primary-40 rounded z-[2]": shouldOverlay,
|
||||||
|
},
|
||||||
|
{ hidden: !shouldOverlay }
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<span>Drop here to move issue</span>
|
||||||
|
</div>
|
||||||
<KanbanIssueBlocksList
|
<KanbanIssueBlocksList
|
||||||
sub_group_id={sub_group_id}
|
sub_group_id={sub_group_id}
|
||||||
columnId={groupId}
|
columnId={groupId}
|
||||||
|
@ -11,6 +11,7 @@ import {
|
|||||||
TUnGroupedIssues,
|
TUnGroupedIssues,
|
||||||
TIssueKanbanFilters,
|
TIssueKanbanFilters,
|
||||||
TIssueGroupByOptions,
|
TIssueGroupByOptions,
|
||||||
|
TIssueOrderByOptions,
|
||||||
} from "@plane/types";
|
} from "@plane/types";
|
||||||
// components
|
// components
|
||||||
import { useCycle, useLabel, useMember, useModule, useProject, useProjectState } from "@/hooks/store";
|
import { useCycle, useLabel, useMember, useModule, useProject, useProjectState } from "@/hooks/store";
|
||||||
@ -113,6 +114,7 @@ interface ISubGroupSwimlane extends ISubGroupSwimlaneHeader {
|
|||||||
disableIssueCreation?: boolean;
|
disableIssueCreation?: boolean;
|
||||||
storeType: KanbanStoreType;
|
storeType: KanbanStoreType;
|
||||||
enableQuickIssueCreate: boolean;
|
enableQuickIssueCreate: boolean;
|
||||||
|
orderBy: TIssueOrderByOptions | undefined;
|
||||||
canEditProperties: (projectId: string | undefined) => boolean;
|
canEditProperties: (projectId: string | undefined) => boolean;
|
||||||
addIssuesToView?: (issueIds: string[]) => Promise<TIssue>;
|
addIssuesToView?: (issueIds: string[]) => Promise<TIssue>;
|
||||||
quickAddCallback?: (
|
quickAddCallback?: (
|
||||||
@ -145,6 +147,7 @@ const SubGroupSwimlane: React.FC<ISubGroupSwimlane> = observer((props) => {
|
|||||||
viewId,
|
viewId,
|
||||||
scrollableContainerRef,
|
scrollableContainerRef,
|
||||||
handleOnDrop,
|
handleOnDrop,
|
||||||
|
orderBy,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const calculateIssueCount = (column_id: string) => {
|
const calculateIssueCount = (column_id: string) => {
|
||||||
@ -180,7 +183,7 @@ const SubGroupSwimlane: React.FC<ISubGroupSwimlane> = observer((props) => {
|
|||||||
if (subGroupByVisibilityToggle.showGroup === false) return <></>;
|
if (subGroupByVisibilityToggle.showGroup === false) return <></>;
|
||||||
return (
|
return (
|
||||||
<div key={_list.id} className="flex flex-shrink-0 flex-col">
|
<div key={_list.id} className="flex flex-shrink-0 flex-col">
|
||||||
<div className="sticky top-[50px] z-[1] py-1 flex w-full items-center bg-custom-background-100 border-y-[0.5px] border-custom-border-200">
|
<div className="sticky top-[50px] z-[3] py-1 flex w-full items-center bg-custom-background-100 border-y-[0.5px] border-custom-border-200">
|
||||||
<div className="sticky left-0 flex-shrink-0">
|
<div className="sticky left-0 flex-shrink-0">
|
||||||
<HeaderSubGroupByCard
|
<HeaderSubGroupByCard
|
||||||
column_id={_list.id}
|
column_id={_list.id}
|
||||||
@ -215,6 +218,7 @@ const SubGroupSwimlane: React.FC<ISubGroupSwimlane> = observer((props) => {
|
|||||||
viewId={viewId}
|
viewId={viewId}
|
||||||
scrollableContainerRef={scrollableContainerRef}
|
scrollableContainerRef={scrollableContainerRef}
|
||||||
handleOnDrop={handleOnDrop}
|
handleOnDrop={handleOnDrop}
|
||||||
|
orderBy={orderBy}
|
||||||
subGroupIssueHeaderCount={(groupByListId: string) =>
|
subGroupIssueHeaderCount={(groupByListId: string) =>
|
||||||
getSubGroupHeaderIssuesCount(issueIds as TSubGroupedIssues, groupByListId)
|
getSubGroupHeaderIssuesCount(issueIds as TSubGroupedIssues, groupByListId)
|
||||||
}
|
}
|
||||||
@ -253,6 +257,7 @@ export interface IKanBanSwimLanes {
|
|||||||
viewId?: string;
|
viewId?: string;
|
||||||
canEditProperties: (projectId: string | undefined) => boolean;
|
canEditProperties: (projectId: string | undefined) => boolean;
|
||||||
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
scrollableContainerRef?: MutableRefObject<HTMLDivElement | null>;
|
||||||
|
orderBy: TIssueOrderByOptions | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const KanBanSwimLanes: React.FC<IKanBanSwimLanes> = observer((props) => {
|
export const KanBanSwimLanes: React.FC<IKanBanSwimLanes> = observer((props) => {
|
||||||
@ -262,6 +267,7 @@ export const KanBanSwimLanes: React.FC<IKanBanSwimLanes> = observer((props) => {
|
|||||||
displayProperties,
|
displayProperties,
|
||||||
sub_group_by,
|
sub_group_by,
|
||||||
group_by,
|
group_by,
|
||||||
|
orderBy,
|
||||||
updateIssue,
|
updateIssue,
|
||||||
storeType,
|
storeType,
|
||||||
quickActions,
|
quickActions,
|
||||||
@ -312,7 +318,7 @@ export const KanBanSwimLanes: React.FC<IKanBanSwimLanes> = observer((props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div className="sticky top-0 z-[2] h-[50px] bg-custom-background-90 px-2">
|
<div className="sticky top-0 z-[4] h-[50px] bg-custom-background-90 px-2">
|
||||||
<SubGroupSwimlaneHeader
|
<SubGroupSwimlaneHeader
|
||||||
issueIds={issueIds}
|
issueIds={issueIds}
|
||||||
group_by={group_by}
|
group_by={group_by}
|
||||||
@ -333,6 +339,7 @@ export const KanBanSwimLanes: React.FC<IKanBanSwimLanes> = observer((props) => {
|
|||||||
displayProperties={displayProperties}
|
displayProperties={displayProperties}
|
||||||
group_by={group_by}
|
group_by={group_by}
|
||||||
sub_group_by={sub_group_by}
|
sub_group_by={sub_group_by}
|
||||||
|
orderBy={orderBy}
|
||||||
updateIssue={updateIssue}
|
updateIssue={updateIssue}
|
||||||
quickActions={quickActions}
|
quickActions={quickActions}
|
||||||
kanbanFilters={kanbanFilters}
|
kanbanFilters={kanbanFilters}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import pull from "lodash/pull";
|
import pull from "lodash/pull";
|
||||||
|
import scrollIntoView from "smooth-scroll-into-view-if-needed";
|
||||||
import { IPragmaticDropPayload, TIssue, TIssueGroupByOptions } from "@plane/types";
|
import { IPragmaticDropPayload, TIssue, TIssueGroupByOptions } from "@plane/types";
|
||||||
import { ISSUE_FILTER_DEFAULT_DATA } from "@/store/issue/helpers/issue-helper.store";
|
import { ISSUE_FILTER_DEFAULT_DATA } from "@/store/issue/helpers/issue-helper.store";
|
||||||
|
|
||||||
@ -87,14 +88,17 @@ export const getDestinationFromDropPayload = (payload: IPragmaticDropPayload): K
|
|||||||
const handleSortOrder = (
|
const handleSortOrder = (
|
||||||
destinationIssues: string[],
|
destinationIssues: string[],
|
||||||
destinationIssueId: string | undefined,
|
destinationIssueId: string | undefined,
|
||||||
getIssueById: (issueId: string) => TIssue | undefined
|
getIssueById: (issueId: string) => TIssue | undefined,
|
||||||
|
shouldAddIssueAtTop = false
|
||||||
) => {
|
) => {
|
||||||
const sortOrderDefaultValue = 65535;
|
const sortOrderDefaultValue = 65535;
|
||||||
let currentIssueState = {};
|
let currentIssueState = {};
|
||||||
|
|
||||||
const destinationIndex = destinationIssueId
|
const destinationIndex = destinationIssueId
|
||||||
? destinationIssues.indexOf(destinationIssueId)
|
? destinationIssues.indexOf(destinationIssueId)
|
||||||
: destinationIssues.length;
|
: shouldAddIssueAtTop
|
||||||
|
? 0
|
||||||
|
: destinationIssues.length;
|
||||||
|
|
||||||
if (destinationIssues && destinationIssues.length > 0) {
|
if (destinationIssues && destinationIssues.length > 0) {
|
||||||
if (destinationIndex === 0) {
|
if (destinationIndex === 0) {
|
||||||
@ -145,7 +149,8 @@ export const handleDragDrop = async (
|
|||||||
getIssueIds: (groupId?: string, subGroupId?: string) => string[] | undefined,
|
getIssueIds: (groupId?: string, subGroupId?: string) => string[] | undefined,
|
||||||
updateIssue: ((projectId: string, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined,
|
updateIssue: ((projectId: string, issueId: string, data: Partial<TIssue>) => Promise<void>) | undefined,
|
||||||
groupBy: TIssueGroupByOptions | undefined,
|
groupBy: TIssueGroupByOptions | undefined,
|
||||||
subGroupBy: TIssueGroupByOptions | undefined
|
subGroupBy: TIssueGroupByOptions | undefined,
|
||||||
|
shouldAddIssueAtTop = false
|
||||||
) => {
|
) => {
|
||||||
if (!source.id || !groupBy || (subGroupBy && (!source.subGroupId || !destination.subGroupId))) return;
|
if (!source.id || !groupBy || (subGroupBy && (!source.subGroupId || !destination.subGroupId))) return;
|
||||||
|
|
||||||
@ -165,7 +170,7 @@ export const handleDragDrop = async (
|
|||||||
// for both horizontal and vertical dnd
|
// for both horizontal and vertical dnd
|
||||||
updatedIssue = {
|
updatedIssue = {
|
||||||
...updatedIssue,
|
...updatedIssue,
|
||||||
...handleSortOrder(destinationIssues, destination.id, getIssueById),
|
...handleSortOrder(destinationIssues, destination.id, getIssueById, shouldAddIssueAtTop),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (source.groupId && destination.groupId && source.groupId !== destination.groupId) {
|
if (source.groupId && destination.groupId && source.groupId !== destination.groupId) {
|
||||||
@ -207,3 +212,18 @@ export const handleDragDrop = async (
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const highlightIssueOnDrop = (elementId: string | undefined, shouldScrollIntoView = true) => {
|
||||||
|
setTimeout(async () => {
|
||||||
|
const sourceElementId = elementId ?? "";
|
||||||
|
const sourceElement = document.getElementById(sourceElementId);
|
||||||
|
if (shouldScrollIntoView && sourceElement)
|
||||||
|
await scrollIntoView(sourceElement, { behavior: "smooth", block: "center" });
|
||||||
|
sourceElement?.classList?.add("highlight");
|
||||||
|
setTimeout(() => {
|
||||||
|
const sourceElementId = elementId ?? "";
|
||||||
|
const sourceElement = document.getElementById(sourceElementId);
|
||||||
|
sourceElement?.classList?.remove("highlight");
|
||||||
|
}, 1000);
|
||||||
|
}, 200);
|
||||||
|
};
|
||||||
|
@ -58,6 +58,7 @@
|
|||||||
"react-markdown": "^8.0.7",
|
"react-markdown": "^8.0.7",
|
||||||
"react-popper": "^2.3.0",
|
"react-popper": "^2.3.0",
|
||||||
"sharp": "^0.32.1",
|
"sharp": "^0.32.1",
|
||||||
|
"smooth-scroll-into-view-if-needed": "^2.0.2",
|
||||||
"swr": "^2.1.3",
|
"swr": "^2.1.3",
|
||||||
"tailwind-merge": "^2.0.0",
|
"tailwind-merge": "^2.0.0",
|
||||||
"use-debounce": "^9.0.4",
|
"use-debounce": "^9.0.4",
|
||||||
|
@ -630,3 +630,8 @@ div.web-view-spinner div.bar12 {
|
|||||||
.scrollbar-lg::-webkit-scrollbar-thumb {
|
.scrollbar-lg::-webkit-scrollbar-thumb {
|
||||||
border: 4px solid rgba(0, 0, 0, 0);
|
border: 4px solid rgba(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* highlight class */
|
||||||
|
.highlight {
|
||||||
|
border: 1px solid rgb(var(--color-primary-100));
|
||||||
|
}
|
21
yarn.lock
21
yarn.lock
@ -2755,7 +2755,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/react" "*"
|
"@types/react" "*"
|
||||||
|
|
||||||
"@types/react@*", "@types/react@18.2.42", "@types/react@^18.2.42":
|
"@types/react@*", "@types/react@^18.2.42":
|
||||||
version "18.2.42"
|
version "18.2.42"
|
||||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.42.tgz#6f6b11a904f6d96dda3c2920328a97011a00aba7"
|
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.42.tgz#6f6b11a904f6d96dda3c2920328a97011a00aba7"
|
||||||
integrity sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA==
|
integrity sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA==
|
||||||
@ -3699,6 +3699,11 @@ commondir@^1.0.1:
|
|||||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||||
integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
|
integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
|
||||||
|
|
||||||
|
compute-scroll-into-view@^3.0.2:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz#753f11d972596558d8fe7c6bcbc8497690ab4c87"
|
||||||
|
integrity sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==
|
||||||
|
|
||||||
concat-map@0.0.1:
|
concat-map@0.0.1:
|
||||||
version "0.0.1"
|
version "0.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
@ -7633,6 +7638,13 @@ schema-utils@^3.1.1:
|
|||||||
ajv "^6.12.5"
|
ajv "^6.12.5"
|
||||||
ajv-keywords "^3.5.2"
|
ajv-keywords "^3.5.2"
|
||||||
|
|
||||||
|
scroll-into-view-if-needed@^3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz#fa9524518c799b45a2ef6bbffb92bcad0296d01f"
|
||||||
|
integrity sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==
|
||||||
|
dependencies:
|
||||||
|
compute-scroll-into-view "^3.0.2"
|
||||||
|
|
||||||
selecto@~1.26.3:
|
selecto@~1.26.3:
|
||||||
version "1.26.3"
|
version "1.26.3"
|
||||||
resolved "https://registry.yarnpkg.com/selecto/-/selecto-1.26.3.tgz#12f259112b943d395731524e3bb0115da7372212"
|
resolved "https://registry.yarnpkg.com/selecto/-/selecto-1.26.3.tgz#12f259112b943d395731524e3bb0115da7372212"
|
||||||
@ -7774,6 +7786,13 @@ slash@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||||
|
|
||||||
|
smooth-scroll-into-view-if-needed@^2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/smooth-scroll-into-view-if-needed/-/smooth-scroll-into-view-if-needed-2.0.2.tgz#5bd4ebef668474d6618ce8704650082e93068371"
|
||||||
|
integrity sha512-z54WzUSlM+xHHvJu3lMIsh+1d1kA4vaakcAtQvqzeGJ5Ffau7EKjpRrMHh1/OBo5zyU2h30ZYEt77vWmPHqg7Q==
|
||||||
|
dependencies:
|
||||||
|
scroll-into-view-if-needed "^3.1.0"
|
||||||
|
|
||||||
snake-case@^3.0.4:
|
snake-case@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c"
|
resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c"
|
||||||
|
Loading…
Reference in New Issue
Block a user