UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: перенос режимов проекта в нижнюю панель
This commit is contained in:
parent
ae262487ac
commit
119d503d96
|
|
@ -13,6 +13,7 @@ import { WorkItemsIcon } from "@plane/propel/icons";
|
||||||
import { Breadcrumbs, Header } from "@plane/ui";
|
import { Breadcrumbs, Header } from "@plane/ui";
|
||||||
// components
|
// components
|
||||||
import { BreadcrumbLink } from "@/components/common/breadcrumb-link";
|
import { BreadcrumbLink } from "@/components/common/breadcrumb-link";
|
||||||
|
import { HeaderFilters } from "@/components/issues/filters";
|
||||||
import { IssueDetailQuickActions } from "@/components/issues/issue-detail/issue-detail-quick-actions";
|
import { IssueDetailQuickActions } from "@/components/issues/issue-detail/issue-detail-quick-actions";
|
||||||
// hooks
|
// hooks
|
||||||
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
|
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
|
||||||
|
|
@ -62,6 +63,14 @@ export const WorkItemDetailsHeader = observer(function WorkItemDetailsHeader() {
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
</Header.LeftItem>
|
</Header.LeftItem>
|
||||||
<Header.RightItem>
|
<Header.RightItem>
|
||||||
|
<div className="hidden items-center gap-2 md:flex">
|
||||||
|
<HeaderFilters
|
||||||
|
projectId={projectId.toString()}
|
||||||
|
currentProjectDetails={projectDetails}
|
||||||
|
workspaceSlug={workspaceSlug.toString()}
|
||||||
|
canUserCreateIssue={undefined}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
{projectId && issueId && (
|
{projectId && issueId && (
|
||||||
<IssueDetailQuickActions
|
<IssueDetailQuickActions
|
||||||
workspaceSlug={workspaceSlug?.toString()}
|
workspaceSlug={workspaceSlug?.toString()}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ import {
|
||||||
DisplayFiltersSelection,
|
DisplayFiltersSelection,
|
||||||
FiltersDropdown,
|
FiltersDropdown,
|
||||||
LayoutSelection,
|
LayoutSelection,
|
||||||
MobileLayoutSelection,
|
|
||||||
} from "@/components/issues/issue-layouts/filters";
|
} from "@/components/issues/issue-layouts/filters";
|
||||||
import { WorkItemFiltersToggle } from "@/components/work-item-filters/filters-toggle";
|
import { WorkItemFiltersToggle } from "@/components/work-item-filters/filters-toggle";
|
||||||
// hooks
|
// hooks
|
||||||
|
|
@ -185,32 +184,17 @@ export const CycleIssuesHeader = observer(function CycleIssuesHeader() {
|
||||||
</Header.LeftItem>
|
</Header.LeftItem>
|
||||||
<Header.RightItem className="items-center">
|
<Header.RightItem className="items-center">
|
||||||
<div className="hidden items-center gap-2 md:flex">
|
<div className="hidden items-center gap-2 md:flex">
|
||||||
<div className="hidden @4xl:flex">
|
<LayoutSelection
|
||||||
<LayoutSelection
|
layouts={[
|
||||||
layouts={[
|
EIssueLayoutTypes.LIST,
|
||||||
EIssueLayoutTypes.LIST,
|
EIssueLayoutTypes.KANBAN,
|
||||||
EIssueLayoutTypes.KANBAN,
|
EIssueLayoutTypes.CALENDAR,
|
||||||
EIssueLayoutTypes.CALENDAR,
|
EIssueLayoutTypes.SPREADSHEET,
|
||||||
EIssueLayoutTypes.SPREADSHEET,
|
EIssueLayoutTypes.GANTT,
|
||||||
EIssueLayoutTypes.GANTT,
|
]}
|
||||||
]}
|
onChange={(layout) => handleLayoutChange(layout)}
|
||||||
onChange={(layout) => handleLayoutChange(layout)}
|
selectedLayout={activeLayout}
|
||||||
selectedLayout={activeLayout}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex @4xl:hidden">
|
|
||||||
<MobileLayoutSelection
|
|
||||||
layouts={[
|
|
||||||
EIssueLayoutTypes.LIST,
|
|
||||||
EIssueLayoutTypes.KANBAN,
|
|
||||||
EIssueLayoutTypes.CALENDAR,
|
|
||||||
EIssueLayoutTypes.SPREADSHEET,
|
|
||||||
EIssueLayoutTypes.GANTT,
|
|
||||||
]}
|
|
||||||
onChange={(layout) => handleLayoutChange(layout)}
|
|
||||||
activeLayout={activeLayout}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<WorkItemFiltersToggle entityType={EIssuesStoreType.CYCLE} entityId={cycleId} />
|
<WorkItemFiltersToggle entityType={EIssuesStoreType.CYCLE} entityId={cycleId} />
|
||||||
<FiltersDropdown
|
<FiltersDropdown
|
||||||
title={t("common.display")}
|
title={t("common.display")}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { WorkItemsModal } from "@/components/analytics/work-items/modal";
|
||||||
import {
|
import {
|
||||||
DisplayFiltersSelection,
|
DisplayFiltersSelection,
|
||||||
FiltersDropdown,
|
FiltersDropdown,
|
||||||
MobileLayoutSelection,
|
LayoutSelection,
|
||||||
} from "@/components/issues/issue-layouts/filters";
|
} from "@/components/issues/issue-layouts/filters";
|
||||||
// hooks
|
// hooks
|
||||||
import { useCycle } from "@/hooks/store/use-cycle";
|
import { useCycle } from "@/hooks/store/use-cycle";
|
||||||
|
|
@ -93,9 +93,15 @@ export const CycleIssuesMobileHeader = observer(function CycleIssuesMobileHeader
|
||||||
cycleDetails={cycleDetails ?? undefined}
|
cycleDetails={cycleDetails ?? undefined}
|
||||||
/>
|
/>
|
||||||
<div className="flex justify-evenly border-b border-subtle bg-surface-1 py-2 md:hidden">
|
<div className="flex justify-evenly border-b border-subtle bg-surface-1 py-2 md:hidden">
|
||||||
<MobileLayoutSelection
|
<LayoutSelection
|
||||||
activeLayout={activeLayout}
|
selectedLayout={activeLayout}
|
||||||
layouts={[EIssueLayoutTypes.LIST, EIssueLayoutTypes.KANBAN, EIssueLayoutTypes.CALENDAR]}
|
layouts={[
|
||||||
|
EIssueLayoutTypes.LIST,
|
||||||
|
EIssueLayoutTypes.KANBAN,
|
||||||
|
EIssueLayoutTypes.CALENDAR,
|
||||||
|
EIssueLayoutTypes.SPREADSHEET,
|
||||||
|
EIssueLayoutTypes.GANTT,
|
||||||
|
]}
|
||||||
onChange={handleLayoutChange}
|
onChange={handleLayoutChange}
|
||||||
/>
|
/>
|
||||||
<div className="flex flex-grow items-center justify-center border-l border-subtle text-13 text-secondary">
|
<div className="flex flex-grow items-center justify-center border-l border-subtle text-13 text-secondary">
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { WorkItemsModal } from "@/components/analytics/work-items/modal";
|
||||||
import {
|
import {
|
||||||
DisplayFiltersSelection,
|
DisplayFiltersSelection,
|
||||||
FiltersDropdown,
|
FiltersDropdown,
|
||||||
MobileLayoutSelection,
|
LayoutSelection,
|
||||||
} from "@/components/issues/issue-layouts/filters";
|
} from "@/components/issues/issue-layouts/filters";
|
||||||
// hooks
|
// hooks
|
||||||
import { useIssues } from "@/hooks/store/use-issues";
|
import { useIssues } from "@/hooks/store/use-issues";
|
||||||
|
|
@ -69,9 +69,16 @@ export const ProjectIssuesMobileHeader = observer(function ProjectIssuesMobileHe
|
||||||
projectDetails={currentProjectDetails ?? undefined}
|
projectDetails={currentProjectDetails ?? undefined}
|
||||||
/>
|
/>
|
||||||
<div className="z-[13] flex justify-evenly border-b border-subtle bg-surface-1 py-2 md:hidden">
|
<div className="z-[13] flex justify-evenly border-b border-subtle bg-surface-1 py-2 md:hidden">
|
||||||
<MobileLayoutSelection
|
<LayoutSelection
|
||||||
layouts={[EIssueLayoutTypes.LIST, EIssueLayoutTypes.KANBAN, EIssueLayoutTypes.CALENDAR]}
|
layouts={[
|
||||||
|
EIssueLayoutTypes.LIST,
|
||||||
|
EIssueLayoutTypes.KANBAN,
|
||||||
|
EIssueLayoutTypes.CALENDAR,
|
||||||
|
EIssueLayoutTypes.SPREADSHEET,
|
||||||
|
EIssueLayoutTypes.GANTT,
|
||||||
|
]}
|
||||||
onChange={handleLayoutChange}
|
onChange={handleLayoutChange}
|
||||||
|
selectedLayout={activeLayout}
|
||||||
/>
|
/>
|
||||||
<div className="flex flex-grow items-center justify-center border-l border-subtle text-13 text-secondary">
|
<div className="flex flex-grow items-center justify-center border-l border-subtle text-13 text-secondary">
|
||||||
<FiltersDropdown
|
<FiltersDropdown
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import {
|
||||||
DisplayFiltersSelection,
|
DisplayFiltersSelection,
|
||||||
FiltersDropdown,
|
FiltersDropdown,
|
||||||
LayoutSelection,
|
LayoutSelection,
|
||||||
MobileLayoutSelection,
|
|
||||||
} from "@/components/issues/issue-layouts/filters";
|
} from "@/components/issues/issue-layouts/filters";
|
||||||
import { ModuleQuickActions } from "@/components/modules";
|
import { ModuleQuickActions } from "@/components/modules";
|
||||||
import { WorkItemFiltersToggle } from "@/components/work-item-filters/filters-toggle";
|
import { WorkItemFiltersToggle } from "@/components/work-item-filters/filters-toggle";
|
||||||
|
|
@ -179,32 +178,17 @@ export const ModuleIssuesHeader = observer(function ModuleIssuesHeader() {
|
||||||
</Header.LeftItem>
|
</Header.LeftItem>
|
||||||
<Header.RightItem className="items-center">
|
<Header.RightItem className="items-center">
|
||||||
<div className="hidden gap-2 md:flex">
|
<div className="hidden gap-2 md:flex">
|
||||||
<div className="hidden @4xl:flex">
|
<LayoutSelection
|
||||||
<LayoutSelection
|
layouts={[
|
||||||
layouts={[
|
EIssueLayoutTypes.LIST,
|
||||||
EIssueLayoutTypes.LIST,
|
EIssueLayoutTypes.KANBAN,
|
||||||
EIssueLayoutTypes.KANBAN,
|
EIssueLayoutTypes.CALENDAR,
|
||||||
EIssueLayoutTypes.CALENDAR,
|
EIssueLayoutTypes.SPREADSHEET,
|
||||||
EIssueLayoutTypes.SPREADSHEET,
|
EIssueLayoutTypes.GANTT,
|
||||||
EIssueLayoutTypes.GANTT,
|
]}
|
||||||
]}
|
onChange={(layout) => handleLayoutChange(layout)}
|
||||||
onChange={(layout) => handleLayoutChange(layout)}
|
selectedLayout={activeLayout}
|
||||||
selectedLayout={activeLayout}
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex @4xl:hidden">
|
|
||||||
<MobileLayoutSelection
|
|
||||||
layouts={[
|
|
||||||
EIssueLayoutTypes.LIST,
|
|
||||||
EIssueLayoutTypes.KANBAN,
|
|
||||||
EIssueLayoutTypes.CALENDAR,
|
|
||||||
EIssueLayoutTypes.SPREADSHEET,
|
|
||||||
EIssueLayoutTypes.GANTT,
|
|
||||||
]}
|
|
||||||
onChange={(layout) => handleLayoutChange(layout)}
|
|
||||||
activeLayout={activeLayout}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
{moduleId && <WorkItemFiltersToggle entityType={EIssuesStoreType.MODULE} entityId={moduleId} />}
|
{moduleId && <WorkItemFiltersToggle entityType={EIssuesStoreType.MODULE} entityId={moduleId} />}
|
||||||
<FiltersDropdown
|
<FiltersDropdown
|
||||||
title="Display"
|
title="Display"
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import { WorkItemsModal } from "@/components/analytics/work-items/modal";
|
||||||
import {
|
import {
|
||||||
DisplayFiltersSelection,
|
DisplayFiltersSelection,
|
||||||
FiltersDropdown,
|
FiltersDropdown,
|
||||||
MobileLayoutSelection,
|
LayoutSelection,
|
||||||
} from "@/components/issues/issue-layouts/filters";
|
} from "@/components/issues/issue-layouts/filters";
|
||||||
// hooks
|
// hooks
|
||||||
import { useIssues } from "@/hooks/store/use-issues";
|
import { useIssues } from "@/hooks/store/use-issues";
|
||||||
|
|
@ -75,9 +75,15 @@ export const ModuleIssuesMobileHeader = observer(function ModuleIssuesMobileHead
|
||||||
projectDetails={currentProjectDetails}
|
projectDetails={currentProjectDetails}
|
||||||
/>
|
/>
|
||||||
<div className="flex justify-evenly border-b border-subtle bg-surface-1 py-2">
|
<div className="flex justify-evenly border-b border-subtle bg-surface-1 py-2">
|
||||||
<MobileLayoutSelection
|
<LayoutSelection
|
||||||
activeLayout={activeLayout}
|
selectedLayout={activeLayout}
|
||||||
layouts={[EIssueLayoutTypes.LIST, EIssueLayoutTypes.KANBAN, EIssueLayoutTypes.CALENDAR]}
|
layouts={[
|
||||||
|
EIssueLayoutTypes.LIST,
|
||||||
|
EIssueLayoutTypes.KANBAN,
|
||||||
|
EIssueLayoutTypes.CALENDAR,
|
||||||
|
EIssueLayoutTypes.SPREADSHEET,
|
||||||
|
EIssueLayoutTypes.GANTT,
|
||||||
|
]}
|
||||||
onChange={handleLayoutChange}
|
onChange={handleLayoutChange}
|
||||||
/>
|
/>
|
||||||
<div className="flex flex-grow items-center justify-center border-l border-subtle text-13 text-secondary">
|
<div className="flex flex-grow items-center justify-center border-l border-subtle text-13 text-secondary">
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import {
|
||||||
DisplayFiltersSelection,
|
DisplayFiltersSelection,
|
||||||
FiltersDropdown,
|
FiltersDropdown,
|
||||||
LayoutSelection,
|
LayoutSelection,
|
||||||
MobileLayoutSelection,
|
|
||||||
} from "./issue-layouts/filters";
|
} from "./issue-layouts/filters";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
@ -104,15 +103,10 @@ export const HeaderFilters = observer(function HeaderFilters(props: Props) {
|
||||||
[workspaceSlug, projectId, updateFilters]
|
[workspaceSlug, projectId, updateFilters]
|
||||||
);
|
);
|
||||||
|
|
||||||
const layoutSelection = (
|
const dockLayoutSelection = (
|
||||||
<>
|
<div className="nodedc-project-layout-controls pointer-events-auto flex">
|
||||||
<div className="pointer-events-auto hidden @4xl:flex">
|
<LayoutSelection layouts={LAYOUTS} onChange={(layout) => handleLayoutChange(layout)} selectedLayout={activeLayout} />
|
||||||
<LayoutSelection layouts={LAYOUTS} onChange={(layout) => handleLayoutChange(layout)} selectedLayout={activeLayout} />
|
</div>
|
||||||
</div>
|
|
||||||
<div className="pointer-events-auto flex @4xl:hidden">
|
|
||||||
<MobileLayoutSelection layouts={LAYOUTS} onChange={(layout) => handleLayoutChange(layout)} activeLayout={activeLayout} />
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const headerTools = (
|
const headerTools = (
|
||||||
|
|
@ -143,7 +137,7 @@ export const HeaderFilters = observer(function HeaderFilters(props: Props) {
|
||||||
!isCompactToolbar && expandedToolbarTarget
|
!isCompactToolbar && expandedToolbarTarget
|
||||||
? createPortal(
|
? createPortal(
|
||||||
<div className="nodedc-expanded-header-filters">
|
<div className="nodedc-expanded-header-filters">
|
||||||
{layoutSelection}
|
{dockLayoutSelection}
|
||||||
{headerTools}
|
{headerTools}
|
||||||
</div>,
|
</div>,
|
||||||
expandedToolbarTarget
|
expandedToolbarTarget
|
||||||
|
|
@ -155,28 +149,28 @@ export const HeaderFilters = observer(function HeaderFilters(props: Props) {
|
||||||
{expandedToolbarControls}
|
{expandedToolbarControls}
|
||||||
{!isCompactToolbar && expandedToolbarTarget ? null : (
|
{!isCompactToolbar && expandedToolbarTarget ? null : (
|
||||||
<>
|
<>
|
||||||
<div className="pointer-events-none absolute top-1/2 left-1/2 z-[1] flex -translate-x-1/2 -translate-y-1/2 items-center">
|
<div className="pointer-events-none absolute top-1/2 left-1/2 z-[1] flex -translate-x-1/2 -translate-y-1/2 items-center">
|
||||||
{layoutSelection}
|
{dockLayoutSelection}
|
||||||
</div>
|
</div>
|
||||||
<div className="nodedc-top-toolbar-cluster flex items-center gap-2">
|
<div className="nodedc-top-toolbar-cluster flex items-center gap-2">
|
||||||
<WorkItemFiltersToggle entityType={storeType} entityId={projectId} />
|
<WorkItemFiltersToggle entityType={storeType} entityId={projectId} />
|
||||||
<FiltersDropdown
|
<FiltersDropdown
|
||||||
miniIcon={<SlidersHorizontal className="size-3.5" />}
|
miniIcon={<SlidersHorizontal className="size-3.5" />}
|
||||||
title={t("common.display")}
|
title={t("common.display")}
|
||||||
placement="bottom-end"
|
placement="bottom-end"
|
||||||
>
|
>
|
||||||
<DisplayFiltersSelection
|
<DisplayFiltersSelection
|
||||||
layoutDisplayFiltersOptions={layoutDisplayFiltersOptions}
|
layoutDisplayFiltersOptions={layoutDisplayFiltersOptions}
|
||||||
displayFilters={issueFilters?.displayFilters ?? {}}
|
displayFilters={issueFilters?.displayFilters ?? {}}
|
||||||
handleDisplayFiltersUpdate={handleDisplayFilters}
|
handleDisplayFiltersUpdate={handleDisplayFilters}
|
||||||
displayProperties={issueFilters?.displayProperties ?? {}}
|
displayProperties={issueFilters?.displayProperties ?? {}}
|
||||||
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
handleDisplayPropertiesUpdate={handleDisplayProperties}
|
||||||
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
cycleViewDisabled={!currentProjectDetails?.cycle_view}
|
||||||
moduleViewDisabled={!currentProjectDetails?.module_view}
|
moduleViewDisabled={!currentProjectDetails?.module_view}
|
||||||
isEpic={storeType === EIssuesStoreType.EPIC}
|
isEpic={storeType === EIssuesStoreType.EPIC}
|
||||||
/>
|
/>
|
||||||
</FiltersDropdown>
|
</FiltersDropdown>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,8 @@ export function FiltersDropdown(props: Props) {
|
||||||
ref={setReferenceElement}
|
ref={setReferenceElement}
|
||||||
className={menuButtonWrapperClassName}
|
className={menuButtonWrapperClassName}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
data-active={isOpen}
|
||||||
|
aria-pressed={isOpen}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
onClick={toggleDropdown}
|
onClick={toggleDropdown}
|
||||||
>
|
>
|
||||||
|
|
@ -162,6 +164,7 @@ export function FiltersDropdown(props: Props) {
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
className="nodedc-toolbar-pill nodedc-toolbar-pill-wide"
|
className="nodedc-toolbar-pill nodedc-toolbar-pill-wide"
|
||||||
|
data-active={isOpen}
|
||||||
size="lg"
|
size="lg"
|
||||||
>
|
>
|
||||||
{miniIcon || title}
|
{miniIcon || title}
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ export const TopNavPowerK = observer((props: TTopNavPowerKProps) => {
|
||||||
left: number;
|
left: number;
|
||||||
top: number;
|
top: number;
|
||||||
width: number;
|
width: number;
|
||||||
|
listMaxHeight: number;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
|
||||||
const sidebarSearchPortalRef = useRef<HTMLDivElement>(null);
|
const sidebarSearchPortalRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
@ -133,13 +134,21 @@ export const TopNavPowerK = observer((props: TTopNavPowerKProps) => {
|
||||||
const rect = sidebarSearchButtonRef.current.getBoundingClientRect();
|
const rect = sidebarSearchButtonRef.current.getBoundingClientRect();
|
||||||
const width = 320;
|
const width = 320;
|
||||||
const viewportPadding = 16;
|
const viewportPadding = 16;
|
||||||
const left = Math.min(rect.left, window.innerWidth - width - viewportPadding);
|
const topSafetyOffset = 88;
|
||||||
const top = rect.bottom + 10;
|
const inputHeight = 32;
|
||||||
|
const inputToListGap = 12;
|
||||||
|
const dockGap = 18;
|
||||||
|
const availableAboveDock = Math.max(260, rect.top - topSafetyOffset - inputHeight - inputToListGap - dockGap);
|
||||||
|
const listMaxHeight = Math.min(window.innerHeight * 0.7, availableAboveDock);
|
||||||
|
const panelHeight = inputHeight + inputToListGap + listMaxHeight;
|
||||||
|
const left = Math.max(viewportPadding, Math.min(rect.left, window.innerWidth - width - viewportPadding));
|
||||||
|
const top = Math.max(topSafetyOffset, rect.top - panelHeight - dockGap);
|
||||||
|
|
||||||
setSidebarSearchPosition({
|
setSidebarSearchPosition({
|
||||||
left,
|
left,
|
||||||
top,
|
top,
|
||||||
width,
|
width,
|
||||||
|
listMaxHeight,
|
||||||
});
|
});
|
||||||
}, [variant]);
|
}, [variant]);
|
||||||
|
|
||||||
|
|
@ -292,37 +301,6 @@ export const TopNavPowerK = observer((props: TTopNavPowerKProps) => {
|
||||||
{isWideSearch ? (
|
{isWideSearch ? (
|
||||||
isExpandedToolbar ? (
|
isExpandedToolbar ? (
|
||||||
<div className="nodedc-expanded-search-control" data-open={isOpen}>
|
<div className="nodedc-expanded-search-control" data-open={isOpen}>
|
||||||
<div
|
|
||||||
className="nodedc-expanded-search-line-panel"
|
|
||||||
onClick={() => {
|
|
||||||
openPanel();
|
|
||||||
requestAnimationFrame(() => inputRef.current?.focus());
|
|
||||||
}}
|
|
||||||
role="button"
|
|
||||||
>
|
|
||||||
<div className="nodedc-expanded-search-input-wrap">
|
|
||||||
<input
|
|
||||||
ref={inputRef}
|
|
||||||
type="text"
|
|
||||||
value={searchTerm}
|
|
||||||
onChange={(e) => {
|
|
||||||
setSearchTerm(e.target.value);
|
|
||||||
if (!isOpen) openPanel();
|
|
||||||
}}
|
|
||||||
onMouseDown={handleMouseDown}
|
|
||||||
onFocus={handleFocus}
|
|
||||||
onKeyDown={handleKeyDown}
|
|
||||||
placeholder=""
|
|
||||||
tabIndex={isOpen ? 0 : -1}
|
|
||||||
className="nodedc-expanded-search-input placeholder-text-placeholder min-w-0 flex-1 bg-transparent outline-none"
|
|
||||||
/>
|
|
||||||
{searchTerm && (
|
|
||||||
<button type="button" onClick={handleClear} className="nodedc-expanded-search-clear">
|
|
||||||
<CloseIcon className="size-3.5" />
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="nodedc-expanded-tool-button nodedc-expanded-search-trigger"
|
className="nodedc-expanded-tool-button nodedc-expanded-search-trigger"
|
||||||
|
|
@ -414,7 +392,34 @@ export const TopNavPowerK = observer((props: TTopNavPowerKProps) => {
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{isOpen && searchCommandContent}
|
{isOpen && (
|
||||||
|
<>
|
||||||
|
<div className="nodedc-expanded-search-floating-input mx-3 mb-3 flex h-11 items-center rounded-full px-4">
|
||||||
|
<SearchIcon className="mr-2 size-3.5 shrink-0 text-placeholder" />
|
||||||
|
<input
|
||||||
|
ref={inputRef}
|
||||||
|
type="text"
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={(e) => {
|
||||||
|
setSearchTerm(e.target.value);
|
||||||
|
if (!isOpen) openPanel();
|
||||||
|
}}
|
||||||
|
onMouseDown={handleMouseDown}
|
||||||
|
onFocus={handleFocus}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
|
placeholder={t("power_k.search_menu.quick_command_placeholder")}
|
||||||
|
className="placeholder-text-placeholder min-w-0 flex-1 bg-transparent text-13 text-primary outline-none"
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
{searchTerm && (
|
||||||
|
<button type="button" onClick={handleClear} className="ml-2 shrink-0 text-placeholder hover:text-primary">
|
||||||
|
<CloseIcon className="size-3.5" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{searchCommandContent}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{isWideSearch && !isExpandedToolbar && (
|
{isWideSearch && !isExpandedToolbar && (
|
||||||
|
|
@ -469,7 +474,10 @@ export const TopNavPowerK = observer((props: TTopNavPowerKProps) => {
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="nodedc-glass-modal nodedc-glass-popup-surface absolute top-full left-0 mt-3 flex max-h-[70vh] w-full flex-col overflow-hidden rounded-[1.5rem] pt-3">
|
<div
|
||||||
|
className="nodedc-glass-modal nodedc-glass-popup-surface absolute top-full left-0 mt-3 flex w-full flex-col overflow-hidden rounded-[1.5rem] pt-3"
|
||||||
|
style={{ maxHeight: `${sidebarSearchPosition.listMaxHeight}px` }}
|
||||||
|
>
|
||||||
<div className="px-4 pb-2">
|
<div className="px-4 pb-2">
|
||||||
<div className="text-[13px] font-medium text-secondary">
|
<div className="text-[13px] font-medium text-secondary">
|
||||||
{t("power_k.search_menu.quick_access_title")}
|
{t("power_k.search_menu.quick_access_title")}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ export const FiltersToggle = observer(function FiltersToggle<P extends TFilterPr
|
||||||
icon={showFilterRowChangesPill ? FilterAppliedIcon : FilterIcon}
|
icon={showFilterRowChangesPill ? FilterAppliedIcon : FilterIcon}
|
||||||
onClick={handleToggleFilter}
|
onClick={handleToggleFilter}
|
||||||
className={buttonClassName}
|
className={buttonClassName}
|
||||||
data-active={showFilterRowChangesPill}
|
data-active={showFilterRowChangesPill || isFilterRowVisible}
|
||||||
iconClassName={cn("translate-y-[3px]", iconClassName)}
|
iconClassName={cn("translate-y-[3px]", iconClassName)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1682,6 +1682,11 @@
|
||||||
bottom: calc(100% + 0.85rem);
|
bottom: calc(100% + 0.85rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nodedc-expanded-search-floating-input {
|
||||||
|
background: rgba(255, 255, 255, 0.055);
|
||||||
|
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.045);
|
||||||
|
}
|
||||||
|
|
||||||
.nodedc-expanded-notification-button {
|
.nodedc-expanded-notification-button {
|
||||||
height: 2.78rem;
|
height: 2.78rem;
|
||||||
width: 2.78rem;
|
width: 2.78rem;
|
||||||
|
|
@ -2324,6 +2329,42 @@
|
||||||
color: rgb(var(--nodedc-accent-rgb)) !important;
|
color: rgb(var(--nodedc-accent-rgb)) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nodedc-bottom-dock .nodedc-project-layout-controls .nodedc-toolbar-group {
|
||||||
|
min-height: 2.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-icon-button,
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-filter-toggle {
|
||||||
|
background: rgba(255, 255, 255, 0.04) !important;
|
||||||
|
color: rgba(255, 255, 255, 0.72) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-icon-button:hover,
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-icon-button:focus-visible,
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-filter-toggle:hover,
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-filter-toggle:focus-visible {
|
||||||
|
background: rgba(255, 255, 255, 0.08) !important;
|
||||||
|
color: rgba(255, 255, 255, 0.94) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-icon-button[data-active="true"],
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-filter-toggle[data-active="true"],
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-pill[data-active="true"] {
|
||||||
|
background: rgba(255, 255, 255, 0.94) !important;
|
||||||
|
color: rgba(8, 8, 10, 0.94) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-icon-button[data-active="true"] .nodedc-toolbar-icon-active-dot {
|
||||||
|
background: transparent !important;
|
||||||
|
color: rgba(8, 8, 10, 0.94) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-icon-button[data-active="true"] svg,
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-filter-toggle[data-active="true"] svg,
|
||||||
|
.nodedc-bottom-dock .nodedc-toolbar-pill[data-active="true"] svg {
|
||||||
|
color: rgba(8, 8, 10, 0.94) !important;
|
||||||
|
}
|
||||||
|
|
||||||
.nodedc-filter-row-shell {
|
.nodedc-filter-row-shell {
|
||||||
background:
|
background:
|
||||||
linear-gradient(180deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%), rgba(8, 8, 11, 0.84);
|
linear-gradient(180deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%), rgba(8, 8, 11, 0.84);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue