UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: quick-add, composer внешнего контура и range-календарь
This commit is contained in:
parent
85bd24c45b
commit
312fc1eca4
|
|
@ -360,6 +360,10 @@ export const ExternalContoursBoardItem = observer(function ExternalContoursBoard
|
|||
|
||||
<DateDropdown
|
||||
value={issue.target_date}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={(targetDate) =>
|
||||
void handleCardUpdate({
|
||||
target_date: targetDate ? renderFormattedPayloadDate(targetDate) : null,
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ export const ExternalContoursIssueMainContent = observer(function ExternalContou
|
|||
</div>
|
||||
|
||||
<div className="nodedc-external-section overflow-visible px-4 py-4">
|
||||
<IssueActivity workspaceSlug={workspaceSlug} projectId={targetProjectId} issueId={issue.id} />
|
||||
<IssueActivity workspaceSlug={workspaceSlug} projectId={targetProjectId} issueId={issue.id} compactComposer />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -34,11 +34,17 @@ export const AppHeader = observer(function AppHeader(props: AppHeaderProps) {
|
|||
|
||||
const updateDockBounds = () => {
|
||||
const { left, width } = main.getBoundingClientRect();
|
||||
const height = container?.getBoundingClientRect().height ?? 0;
|
||||
|
||||
setDockStyle({
|
||||
left,
|
||||
width,
|
||||
});
|
||||
|
||||
document.documentElement.style.setProperty(
|
||||
"--nodedc-bottom-dock-offset",
|
||||
`${Math.max(height, 0)}px`
|
||||
);
|
||||
};
|
||||
|
||||
updateDockBounds();
|
||||
|
|
@ -50,12 +56,18 @@ export const AppHeader = observer(function AppHeader(props: AppHeaderProps) {
|
|||
return () => {
|
||||
resizeObserver.disconnect();
|
||||
window.removeEventListener("resize", updateDockBounds);
|
||||
document.documentElement.style.removeProperty("--nodedc-bottom-dock-offset");
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className={cn("fixed right-0 bottom-0 z-[18]", className)} style={dockStyle}>
|
||||
<Row className={cn("nodedc-bottom-dock flex h-11 w-full items-center gap-2", rowClassName)}>
|
||||
<Row
|
||||
className={cn(
|
||||
"nodedc-bottom-dock flex h-[var(--nodedc-bottom-dock-height)] w-full items-center gap-2",
|
||||
rowClassName
|
||||
)}
|
||||
>
|
||||
<ExtendedAppHeader header={header} />
|
||||
</Row>
|
||||
{mobileHeader && mobileHeader}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ export function DateFilterModal({ title, handleClose, isOpen, onSelect }: Props)
|
|||
const date2Value = getDate(watch("date2"));
|
||||
return (
|
||||
<Calendar
|
||||
className="rounded-md border border-subtle p-3"
|
||||
className="nodedc-calendar-shell"
|
||||
captionLayout="dropdown"
|
||||
selected={dateValue}
|
||||
defaultMonth={dateValue}
|
||||
|
|
@ -94,8 +94,8 @@ export function DateFilterModal({ title, handleClose, isOpen, onSelect }: Props)
|
|||
const dateValue = getDate(value);
|
||||
const date1Value = getDate(watch("date1"));
|
||||
return (
|
||||
<Calendar
|
||||
className="rounded-md border border-subtle p-3"
|
||||
<Calendar
|
||||
className="nodedc-calendar-shell"
|
||||
captionLayout="dropdown"
|
||||
selected={dateValue}
|
||||
defaultMonth={dateValue}
|
||||
|
|
|
|||
|
|
@ -263,15 +263,16 @@ export const DateRangeDropdown = observer(function DateRangeDropdown(props: Prop
|
|||
const comboOptions = (
|
||||
<Combobox.Options data-prevent-outside-click static>
|
||||
<div
|
||||
className="z-30 my-1 overflow-hidden rounded-md border-[0.5px] border-subtle-1 bg-surface-1"
|
||||
className="nodedc-dropdown-surface z-30 my-1 overflow-hidden"
|
||||
ref={setPopperElement}
|
||||
style={styles.popper}
|
||||
{...attributes.popper}
|
||||
>
|
||||
<Calendar
|
||||
className="rounded-md border border-subtle p-3 text-12"
|
||||
className="nodedc-calendar-shell"
|
||||
captionLayout="dropdown"
|
||||
selected={dateRange}
|
||||
defaultMonth={dateRange.from ?? dateRange.to}
|
||||
onSelect={(val: DateRange | undefined) => {
|
||||
onSelect?.(val);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import React, { useRef, useState } from "react";
|
||||
import React, { useMemo, useRef, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { usePopper } from "react-popper";
|
||||
|
|
@ -38,6 +38,10 @@ type Props = TDropdownProps & {
|
|||
maxDate?: Date;
|
||||
onChange: (val: Date | null) => void;
|
||||
onClose?: () => void;
|
||||
rangePreview?: {
|
||||
from?: Date | string | null;
|
||||
to?: Date | string | null;
|
||||
};
|
||||
value: Date | string | null;
|
||||
closeOnSelect?: boolean;
|
||||
formatToken?: string;
|
||||
|
|
@ -64,6 +68,7 @@ export const DateDropdown = observer(function DateDropdown(props: Props) {
|
|||
maxDate,
|
||||
onChange,
|
||||
onClose,
|
||||
rangePreview,
|
||||
placeholder = "Date",
|
||||
placement,
|
||||
showTooltip = false,
|
||||
|
|
@ -122,6 +127,15 @@ export const DateDropdown = observer(function DateDropdown(props: Props) {
|
|||
if (minDate) disabledDays.push({ before: minDate });
|
||||
if (maxDate) disabledDays.push({ after: maxDate });
|
||||
|
||||
const rangePreviewValue = useMemo(() => {
|
||||
const from = getDate(rangePreview?.from ?? null);
|
||||
const to = getDate(rangePreview?.to ?? null);
|
||||
|
||||
if (!from || !to) return undefined;
|
||||
if (from <= to) return { from, to };
|
||||
return { from: to, to: from };
|
||||
}, [rangePreview?.from, rangePreview?.to]);
|
||||
|
||||
const comboButton = (
|
||||
<>
|
||||
{button ? (
|
||||
|
|
@ -207,21 +221,40 @@ export const DateDropdown = observer(function DateDropdown(props: Props) {
|
|||
style={styles.popper}
|
||||
{...attributes.popper}
|
||||
>
|
||||
<Calendar
|
||||
className="nodedc-calendar-shell"
|
||||
captionLayout="dropdown"
|
||||
selected={getDate(value)}
|
||||
defaultMonth={getDate(value)}
|
||||
onSelect={(date: Date | undefined) => {
|
||||
dropdownOnChange(date ?? null);
|
||||
}}
|
||||
showOutsideDays
|
||||
initialFocus
|
||||
disabled={disabledDays}
|
||||
mode="single"
|
||||
fixedWeeks
|
||||
weekStartsOn={startOfWeek}
|
||||
/>
|
||||
{rangePreviewValue ? (
|
||||
<Calendar
|
||||
className="nodedc-calendar-shell"
|
||||
captionLayout="dropdown"
|
||||
selected={rangePreviewValue}
|
||||
defaultMonth={getDate(value) ?? rangePreviewValue.to ?? rangePreviewValue.from}
|
||||
onDayClick={(date: Date, modifiers) => {
|
||||
if (modifiers.disabled) return;
|
||||
dropdownOnChange(date ?? null);
|
||||
}}
|
||||
showOutsideDays
|
||||
initialFocus
|
||||
disabled={disabledDays}
|
||||
mode="range"
|
||||
fixedWeeks
|
||||
weekStartsOn={startOfWeek}
|
||||
/>
|
||||
) : (
|
||||
<Calendar
|
||||
className="nodedc-calendar-shell"
|
||||
captionLayout="dropdown"
|
||||
selected={getDate(value)}
|
||||
defaultMonth={getDate(value)}
|
||||
onSelect={(date: Date | undefined) => {
|
||||
dropdownOnChange(date ?? null);
|
||||
}}
|
||||
showOutsideDays
|
||||
initialFocus
|
||||
disabled={disabledDays}
|
||||
mode="single"
|
||||
fixedWeeks
|
||||
weekStartsOn={startOfWeek}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Combobox.Options>,
|
||||
document.body
|
||||
|
|
|
|||
|
|
@ -169,6 +169,10 @@ export const SubIssuesListItemProperties = observer(function SubIssuesListItemPr
|
|||
<div className="h-5">
|
||||
<DateDropdown
|
||||
value={issue.start_date ?? null}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={handleStartDate}
|
||||
maxDate={maxDate}
|
||||
placeholder={t("common.order_by.start_date")}
|
||||
|
|
@ -190,6 +194,10 @@ export const SubIssuesListItemProperties = observer(function SubIssuesListItemPr
|
|||
<div className="h-5">
|
||||
<DateDropdown
|
||||
value={issue?.target_date ?? null}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={handleTargetDate}
|
||||
minDate={minDate}
|
||||
placeholder={t("common.order_by.due_date")}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,10 @@ export const IssueDetailsSidebar = observer(function IssueDetailsSidebar(props:
|
|||
<DateDropdown
|
||||
placeholder={t("issue.add.start_date")}
|
||||
value={issue.start_date}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={(val) =>
|
||||
issueOperations.update(workspaceSlug, projectId, issueId, {
|
||||
start_date: val ? renderFormattedPayloadDate(val) : null,
|
||||
|
|
@ -167,6 +171,10 @@ export const IssueDetailsSidebar = observer(function IssueDetailsSidebar(props:
|
|||
<DateDropdown
|
||||
placeholder={t("issue.add.due_date")}
|
||||
value={issue.target_date}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={(val) =>
|
||||
issueOperations.update(workspaceSlug, projectId, issueId, {
|
||||
target_date: val ? renderFormattedPayloadDate(val) : null,
|
||||
|
|
|
|||
|
|
@ -172,6 +172,10 @@ export const InternalContourKanbanCard = observer(function InternalContourKanban
|
|||
<div className="flex items-center justify-end">
|
||||
<DateDropdown
|
||||
value={issue.target_date}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={(targetDate) =>
|
||||
updateIssue?.(issue.project_id ?? null, issue.id, {
|
||||
target_date: targetDate ? renderFormattedPayloadDate(targetDate) : null,
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ export const KanbanGroup = observer(function KanbanGroup(props: IKanbanGroup) {
|
|||
<KanbanIssueBlockLoader />
|
||||
) : (
|
||||
<div
|
||||
className="sticky bottom-0 w-full cursor-pointer p-3 text-13 font-medium text-accent-primary hover:text-accent-secondary hover:underline"
|
||||
className="nodedc-bottom-dock-sticky-offset sticky z-[1] w-full cursor-pointer p-3 text-13 font-medium text-accent-primary hover:text-accent-secondary hover:underline"
|
||||
onClick={loadMoreIssuesInThisGroup}
|
||||
>
|
||||
{t("common.load_more")} ↓
|
||||
|
|
@ -278,6 +278,10 @@ export const KanbanGroup = observer(function KanbanGroup(props: IKanbanGroup) {
|
|||
!!group_by &&
|
||||
DRAG_ALLOWED_GROUPS.includes(group_by) &&
|
||||
(sub_group_by ? DRAG_ALLOWED_GROUPS.includes(sub_group_by) : true);
|
||||
const shouldShowQuickAdd =
|
||||
!!enableQuickIssueCreate &&
|
||||
!disableIssueCreation &&
|
||||
!getIsWorkflowWorkItemCreationDisabled(groupId, sub_group_id);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
|
@ -299,49 +303,49 @@ export const KanbanGroup = observer(function KanbanGroup(props: IKanbanGroup) {
|
|||
isDraggingOverColumn={isDraggingOverColumn}
|
||||
isEpic={isEpic}
|
||||
/>
|
||||
<KanbanIssueBlocksList
|
||||
sub_group_id={sub_group_id}
|
||||
groupId={groupId}
|
||||
issuesMap={issuesMap}
|
||||
issueIds={issueIds || []}
|
||||
displayProperties={displayProperties}
|
||||
updateIssue={updateIssue}
|
||||
quickActions={quickActions}
|
||||
canEditProperties={canEditProperties}
|
||||
cardVariant={cardVariant}
|
||||
scrollableContainerRef={scrollableContainerRef}
|
||||
canDropOverIssue={!canOverlayBeVisible}
|
||||
canDragIssuesInCurrentGrouping={canDragIssuesInCurrentGrouping}
|
||||
isEpic={isEpic}
|
||||
/>
|
||||
<div className={cn({ "nodedc-bottom-dock-aware-padding": shouldShowQuickAdd })}>
|
||||
<KanbanIssueBlocksList
|
||||
sub_group_id={sub_group_id}
|
||||
groupId={groupId}
|
||||
issuesMap={issuesMap}
|
||||
issueIds={issueIds || []}
|
||||
displayProperties={displayProperties}
|
||||
updateIssue={updateIssue}
|
||||
quickActions={quickActions}
|
||||
canEditProperties={canEditProperties}
|
||||
cardVariant={cardVariant}
|
||||
scrollableContainerRef={scrollableContainerRef}
|
||||
canDropOverIssue={!canOverlayBeVisible}
|
||||
canDragIssuesInCurrentGrouping={canDragIssuesInCurrentGrouping}
|
||||
isEpic={isEpic}
|
||||
/>
|
||||
|
||||
{shouldLoadMore &&
|
||||
(isSubGroup ? (
|
||||
<>{loadMore}</>
|
||||
) : (
|
||||
<div className="flex flex-col gap-2">
|
||||
{Array.from({ length: 2 }).map((_, index) => (
|
||||
<KanbanIssueBlockLoader key={index} />
|
||||
))}
|
||||
<KanbanIssueBlockLoader ref={setIntersectionElement} />
|
||||
</div>
|
||||
))}
|
||||
{shouldLoadMore &&
|
||||
(isSubGroup ? (
|
||||
<>{loadMore}</>
|
||||
) : (
|
||||
<div className="flex flex-col gap-2">
|
||||
{Array.from({ length: 2 }).map((_, index) => (
|
||||
<KanbanIssueBlockLoader key={index} />
|
||||
))}
|
||||
<KanbanIssueBlockLoader ref={setIntersectionElement} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{enableQuickIssueCreate &&
|
||||
!disableIssueCreation &&
|
||||
!getIsWorkflowWorkItemCreationDisabled(groupId, sub_group_id) && (
|
||||
<div className="sticky bottom-0 w-full bg-surface-2 py-0.5">
|
||||
<QuickAddIssueRoot
|
||||
layout={EIssueLayoutTypes.KANBAN}
|
||||
QuickAddButton={KanbanQuickAddIssueButton}
|
||||
prePopulatedData={{
|
||||
...(group_by && prePopulateQuickAddData(group_by, sub_group_by, groupId, sub_group_id)),
|
||||
}}
|
||||
quickAddCallback={quickAddCallback}
|
||||
isEpic={isEpic}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{shouldShowQuickAdd && (
|
||||
<div className="nodedc-bottom-dock-sticky-offset sticky z-[2] w-full bg-surface-2 py-0.5">
|
||||
<QuickAddIssueRoot
|
||||
layout={EIssueLayoutTypes.KANBAN}
|
||||
QuickAddButton={KanbanQuickAddIssueButton}
|
||||
prePopulatedData={{
|
||||
...(group_by && prePopulateQuickAddData(group_by, sub_group_by, groupId, sub_group_id)),
|
||||
}}
|
||||
quickAddCallback={quickAddCallback}
|
||||
isEpic={isEpic}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ export const ListGroup = observer(function ListGroup(props: Props) {
|
|||
!isGroupByCreatedBy &&
|
||||
!isCompletedCycle &&
|
||||
!isWorkflowIssueCreationDisabled && (
|
||||
<div className="sticky bottom-0 z-[1] w-full flex-shrink-0">
|
||||
<div className="nodedc-bottom-dock-sticky-offset sticky z-[1] w-full flex-shrink-0">
|
||||
<QuickAddIssueRoot
|
||||
layout={EIssueLayoutTypes.LIST}
|
||||
QuickAddButton={ListQuickAddIssueButton}
|
||||
|
|
|
|||
|
|
@ -268,6 +268,10 @@ export const IssueProperties = observer(function IssueProperties(props: IIssuePr
|
|||
<div className="h-5" onFocus={handleEventPropagation} onClick={handleEventPropagation}>
|
||||
<DateDropdown
|
||||
value={issue.start_date ?? null}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={handleStartDate}
|
||||
maxDate={maxDate}
|
||||
placeholder={t("common.order_by.start_date")}
|
||||
|
|
@ -291,6 +295,10 @@ export const IssueProperties = observer(function IssueProperties(props: IIssuePr
|
|||
<div className="h-5" onFocus={handleEventPropagation} onClick={handleEventPropagation}>
|
||||
<DateDropdown
|
||||
value={issue?.target_date ?? null}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={handleTargetDate}
|
||||
minDate={minDate}
|
||||
placeholder={t("common.order_by.due_date")}
|
||||
|
|
|
|||
|
|
@ -34,6 +34,10 @@ export const SpreadsheetDueDateColumn = observer(function SpreadsheetDueDateColu
|
|||
<div className="h-11 border-b-[0.5px] border-subtle">
|
||||
<DateDropdown
|
||||
value={issue.target_date}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
minDate={getDate(issue.start_date)}
|
||||
onChange={(data) => {
|
||||
const targetDate = data ? renderFormattedPayloadDate(data) : null;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,10 @@ export const SpreadsheetStartDateColumn = observer(function SpreadsheetStartDate
|
|||
<div className="h-11 border-b-[0.5px] border-subtle">
|
||||
<DateDropdown
|
||||
value={issue.start_date}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
maxDate={getDate(issue.target_date)}
|
||||
onChange={(data) => {
|
||||
const startDate = data ? renderFormattedPayloadDate(data) : null;
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export const SpreadsheetView = observer(function SpreadsheetView(props: Props) {
|
|||
/>
|
||||
</div>
|
||||
<div className="border-t border-subtle">
|
||||
<div className="sticky bottom-0 left-0 z-5">
|
||||
<div className="nodedc-bottom-dock-sticky-offset sticky bottom-0 left-0 z-5">
|
||||
{enableQuickCreateIssue && !disableIssueCreation && (
|
||||
<QuickAddIssueRoot
|
||||
layout={EIssueLayoutTypes.SPREADSHEET}
|
||||
|
|
|
|||
|
|
@ -191,6 +191,10 @@ export const IssueDefaultProperties = observer(function IssueDefaultProperties(p
|
|||
<div className="h-7">
|
||||
<DateDropdown
|
||||
value={value}
|
||||
rangePreview={{
|
||||
from: startDate,
|
||||
to: targetDate,
|
||||
}}
|
||||
onChange={(date) => {
|
||||
onChange(date ? renderFormattedPayloadDate(date) : null);
|
||||
handleFormChange();
|
||||
|
|
@ -211,6 +215,10 @@ export const IssueDefaultProperties = observer(function IssueDefaultProperties(p
|
|||
<div className="h-7">
|
||||
<DateDropdown
|
||||
value={value}
|
||||
rangePreview={{
|
||||
from: startDate,
|
||||
to: targetDate,
|
||||
}}
|
||||
onChange={(date) => {
|
||||
onChange(date ? renderFormattedPayloadDate(date) : null);
|
||||
handleFormChange();
|
||||
|
|
|
|||
|
|
@ -146,6 +146,10 @@ export const PeekOverviewProperties = observer(function PeekOverviewProperties(p
|
|||
<SidebarPropertyListItem icon={StartDatePropertyIcon} label={t("common.order_by.start_date")}>
|
||||
<DateDropdown
|
||||
value={issue.start_date}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={(val) =>
|
||||
issueOperations.update(workspaceSlug, projectId, issueId, {
|
||||
start_date: val ? renderFormattedPayloadDate(val) : null,
|
||||
|
|
@ -167,6 +171,10 @@ export const PeekOverviewProperties = observer(function PeekOverviewProperties(p
|
|||
<div className="flex w-full items-center gap-2">
|
||||
<DateDropdown
|
||||
value={issue.target_date}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={(val) =>
|
||||
issueOperations.update(workspaceSlug, projectId, issueId, {
|
||||
target_date: val ? renderFormattedPayloadDate(val) : null,
|
||||
|
|
|
|||
|
|
@ -38,25 +38,25 @@ export const WorkItemPreviewCard = observer(function WorkItemPreviewCard(props:
|
|||
const stateName = stateDetails?.name ?? fallbackStateDetails?.name;
|
||||
|
||||
return (
|
||||
<div className="w-72 space-y-2 rounded-lg border-[0.5px] border-strong bg-surface-1 p-3 shadow-raised-200">
|
||||
<div className="flex items-center justify-between gap-3 text-secondary">
|
||||
<div className="nodedc-dropdown-surface w-80 space-y-3 p-4 shadow-[0_24px_48px_rgba(0,0,0,0.32)]">
|
||||
<div className="flex items-center justify-between gap-3 text-tertiary">
|
||||
<IssueIdentifier
|
||||
size="xs"
|
||||
variant="secondary"
|
||||
variant="tertiary"
|
||||
projectId={projectId}
|
||||
projectIdentifier={projectIdentifier}
|
||||
issueSequenceId={workItem.sequence_id}
|
||||
issueTypeId={workItem.type_id}
|
||||
/>
|
||||
<div className="flex shrink-0 items-center gap-1">
|
||||
<div className="flex shrink-0 items-center gap-1 rounded-full bg-black/20 px-2 py-1">
|
||||
<StateGroupIcon stateGroup={stateGroup} className="size-3 shrink-0" />
|
||||
<p className="text-11 font-medium">{stateName}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h6 className="text-13 wrap-break-word">{workItem.name}</h6>
|
||||
<h6 className="wrap-break-word text-[15px] font-semibold leading-5 text-primary">{workItem.name}</h6>
|
||||
</div>
|
||||
<div className="flex h-5 items-center gap-1">
|
||||
<div className="flex min-h-8 items-center gap-1.5 rounded-full bg-black/15 px-2.5 py-1.5 text-secondary">
|
||||
<PriorityIcon priority={workItem.priority} withContainer />
|
||||
<WorkItemPreviewCardDate
|
||||
startDate={workItem.start_date}
|
||||
|
|
|
|||
|
|
@ -180,6 +180,10 @@ export const DraftIssueProperties = observer(function DraftIssueProperties(props
|
|||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<DateDropdown
|
||||
value={issue.start_date ?? null}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={handleStartDate}
|
||||
maxDate={maxDate}
|
||||
placeholder={t("start_date")}
|
||||
|
|
@ -195,6 +199,10 @@ export const DraftIssueProperties = observer(function DraftIssueProperties(props
|
|||
<div className="h-5" onClick={handleEventPropagation}>
|
||||
<DateDropdown
|
||||
value={issue?.target_date ?? null}
|
||||
rangePreview={{
|
||||
from: issue.start_date,
|
||||
to: issue.target_date,
|
||||
}}
|
||||
onChange={handleTargetDate}
|
||||
minDate={minDate}
|
||||
placeholder={t("due_date")}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@
|
|||
--nodedc-on-card-passive-rgb: 245 247 251;
|
||||
--nodedc-card-active-rgb: 195 255 102;
|
||||
--nodedc-on-card-active-rgb: 11 17 23;
|
||||
--nodedc-bottom-dock-height: 2.75rem;
|
||||
--nodedc-bottom-dock-offset: 2.75rem;
|
||||
--nodedc-bottom-dock-visual-overlap: 0.625rem;
|
||||
--nodedc-quick-add-reserve: 2.5rem;
|
||||
--brand-default: rgb(var(--nodedc-accent-rgb));
|
||||
--brand-300: color-mix(in srgb, rgb(var(--nodedc-accent-rgb)) 65%, white);
|
||||
--brand-700: color-mix(in srgb, rgb(var(--nodedc-accent-rgb)) 75%, black);
|
||||
|
|
@ -276,6 +280,20 @@
|
|||
backdrop-filter: blur(34px);
|
||||
}
|
||||
|
||||
.nodedc-bottom-dock-aware-padding {
|
||||
padding-bottom: calc(var(--nodedc-quick-add-reserve, 2.5rem) + 0.5rem);
|
||||
}
|
||||
|
||||
.nodedc-bottom-dock-sticky-offset {
|
||||
bottom: max(
|
||||
calc(
|
||||
var(--nodedc-bottom-dock-offset, var(--nodedc-bottom-dock-height, 2.75rem)) -
|
||||
var(--nodedc-bottom-dock-visual-overlap, 0.625rem)
|
||||
),
|
||||
0px
|
||||
);
|
||||
}
|
||||
|
||||
.nodedc-bottom-dock [class~="bg-surface-1"] {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
|
@ -1042,7 +1060,6 @@
|
|||
@apply bg-transparent;
|
||||
}
|
||||
|
||||
.nodedc-calendar-shell .rdp-day_button,
|
||||
.nodedc-calendar-shell .rdp-button_previous,
|
||||
.nodedc-calendar-shell .rdp-button_next,
|
||||
.nodedc-calendar-shell .rdp-dropdown_root {
|
||||
|
|
@ -1052,6 +1069,13 @@
|
|||
border-radius: 0.95rem !important;
|
||||
}
|
||||
|
||||
.nodedc-calendar-shell .rdp-day_button {
|
||||
border: 0 !important;
|
||||
outline: none !important;
|
||||
box-shadow: none !important;
|
||||
border-radius: 999px !important;
|
||||
}
|
||||
|
||||
.nodedc-auth-shell {
|
||||
width: 100%;
|
||||
max-width: 32rem;
|
||||
|
|
|
|||
|
|
@ -8,15 +8,17 @@
|
|||
/* Font size for the caption labels. */
|
||||
--rdp-caption-navigation-size: 1.25rem;
|
||||
/* Font size for the caption labels. */
|
||||
--rdp-accent-color: var(--background-color-accent-primary);
|
||||
--rdp-accent-color: rgb(var(--nodedc-accent-rgb, 51 163 255));
|
||||
/* Accent color for the background of selected days. */
|
||||
--rdp-background-color: --alpha(var(--background-color-accent-primary) / 50%);
|
||||
--rdp-background-color: color-mix(in srgb, var(--rdp-accent-color) 18%, transparent);
|
||||
/* Background color for the hovered/focused elements. */
|
||||
--rdp-dark-background-color: var(--background-color-accent-primary-hover);
|
||||
--rdp-dark-background-color: color-mix(in srgb, var(--rdp-accent-color) 82%, white);
|
||||
--rdp-range-background-color: var(--rdp-accent-color);
|
||||
/* Background color for the hovered/focused, already selected elements. */
|
||||
--rdp-outline: 2px solid var(--rdp-accent-color);
|
||||
/* Outline border for focused elements */
|
||||
--rdp-selected-color: var(--text-color-on-color);
|
||||
--rdp-selected-color: rgb(var(--nodedc-on-card-active-rgb, 11 17 23));
|
||||
--rdp-today-outline-color: rgb(var(--nodedc-on-card-active-rgb, 11 17 23));
|
||||
/* Color of selected day text */
|
||||
|
||||
background: transparent;
|
||||
|
|
@ -34,6 +36,7 @@
|
|||
.rdp-day_button {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
|
|
@ -43,6 +46,20 @@
|
|||
margin: 0;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 50%;
|
||||
transition:
|
||||
background-color 160ms ease,
|
||||
color 160ms ease,
|
||||
box-shadow 160ms ease,
|
||||
border-color 160ms ease;
|
||||
}
|
||||
|
||||
.rdp-month_grid {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.rdp-day {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.rdp-day.rdp-outside:not(.rdp-selected) .rdp-day_button {
|
||||
|
|
@ -87,22 +104,25 @@
|
|||
.rdp-week {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: var(--rdp-cell-size);
|
||||
}
|
||||
|
||||
.rdp-today:not(.rdp-outside) {
|
||||
position: relative;
|
||||
.rdp-today:not(.rdp-outside) .rdp-day_button {
|
||||
border-radius: 999px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.rdp-today:not(.rdp-outside)::after {
|
||||
.rdp-today.rdp-selected .rdp-day_button {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.rdp-today:not(.rdp-outside) .rdp-day_button::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 2px;
|
||||
width: 0.5em;
|
||||
height: 0.5em;
|
||||
background-color: var(--rdp-background-color);
|
||||
border-radius: 100%;
|
||||
transform: translate(-50%, 0);
|
||||
inset: 4px;
|
||||
border: 1.5px solid var(--rdp-today-outline-color);
|
||||
border-radius: 999px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.rdp-selected .rdp-day_button:focus-visible,
|
||||
|
|
@ -274,40 +294,46 @@
|
|||
.rdp-range_end::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background-color: var(--rdp-background-color);
|
||||
top: 50%;
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
transform: translate(0, -50%);
|
||||
background-color: var(--rdp-range-background-color);
|
||||
top: -1px;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: -1;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.rdp-range_start::before {
|
||||
left: 50%;
|
||||
border-radius: 999px 0 0 999px;
|
||||
}
|
||||
|
||||
.rdp-range_middle::before {
|
||||
left: 50%;
|
||||
width: 100%;
|
||||
transform: translate(-50%, -50%);
|
||||
.rdp-week .rdp-range_middle:first-child::before {
|
||||
border-radius: 999px 0 0 999px;
|
||||
}
|
||||
|
||||
.rdp-range_end::before {
|
||||
right: 50%;
|
||||
border-radius: 0 999px 999px 0;
|
||||
}
|
||||
|
||||
.rdp-week .rdp-range_middle:last-child::before {
|
||||
border-radius: 0 999px 999px 0;
|
||||
}
|
||||
|
||||
.rdp-range_start.rdp-range_end::before {
|
||||
display: none;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.rdp-range_middle .rdp-day_button {
|
||||
.rdp-range_start .rdp-day_button,
|
||||
.rdp-range_middle .rdp-day_button,
|
||||
.rdp-range_end .rdp-day_button {
|
||||
color: var(--rdp-selected-color);
|
||||
background-color: transparent;
|
||||
color: inherit;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.rdp-day.rdp-range_middle .rdp-day_button:hover,
|
||||
.rdp-day.rdp-range_middle .rdp-day_button:focus-visible {
|
||||
background-color: var(--rdp-background-color);
|
||||
color: inherit;
|
||||
background-color: transparent;
|
||||
color: var(--rdp-selected-color);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue