diff --git a/plane-src/apps/web/app/(all)/[workspaceSlug]/(projects)/analytics/[tabId]/page.tsx b/plane-src/apps/web/app/(all)/[workspaceSlug]/(projects)/analytics/[tabId]/page.tsx index 6332135..7add1bb 100644 --- a/plane-src/apps/web/app/(all)/[workspaceSlug]/(projects)/analytics/[tabId]/page.tsx +++ b/plane-src/apps/web/app/(all)/[workspaceSlug]/(projects)/analytics/[tabId]/page.tsx @@ -74,20 +74,20 @@ function AnalyticsPage({ params }: Route.ComponentProps) { {workspaceProjectIds.length > 0 || loader === "init-loader" ? (
• {subtitle}
{subtitle}
{t("common.search.no_matches_found")}
{t("common.loading")}
{t("common.search.no_matching_results")}
{t("no_matching_results")}
{t("loading")}
["buttonConfig"]> = { label: !hasAnyConditions ? t("common.filters") : null, + appearance: "modal", + className: "!min-h-7 !px-3 !py-0 text-12 font-medium", }; const handleUpdate = useCallback(async () => { @@ -92,42 +93,41 @@ export const FiltersRow = observer(function FiltersRow - {t("common.clear")} - + - {filter.saveViewOptions?.label ?? "Сохранить вид"} - + - {isUpdating ? "Подтверждение..." : (filter.updateViewOptions?.label ?? "Обновить вид")} - + > ); const mainContent = ( - + {leftContent} ); - const ModalVariant = {mainContent}; + const ModalVariant = ( + + {mainContent} + + ); const HeaderVariant = ( @@ -160,7 +164,35 @@ export const FiltersRow = observer(function FiltersRow{variant === "modal" ? ModalVariant : HeaderVariant}; }); -const COMMON_OPERATION_BUTTON_CLASSNAME = "min-h-9 px-4 py-1"; +const COMMON_OPERATION_BUTTON_CLASSNAME = "px-6 py-0 text-[14px] font-medium"; + +type TDockActionButtonProps = React.ButtonHTMLAttributes & { + children: React.ReactNode; + variant: "primary" | "secondary"; +}; + +function DockActionButton(props: TDockActionButtonProps) { + const { children, className, disabled, variant, type = "button", ...buttonProps } = props; + + return ( + + {children} + + ); +} type TElementTransitionProps = { children: React.ReactNode; diff --git a/plane-src/apps/web/core/components/stickies/layout/stickies-infinite.tsx b/plane-src/apps/web/core/components/stickies/layout/stickies-infinite.tsx index ea7029a..bc73d40 100644 --- a/plane-src/apps/web/core/components/stickies/layout/stickies-infinite.tsx +++ b/plane-src/apps/web/core/components/stickies/layout/stickies-infinite.tsx @@ -43,7 +43,7 @@ export const StickiesInfinite = observer(function StickiesInfinite() { useIntersectionObserver(containerRef, shouldObserve ? elementRef : null, handleLoadMore); return ( - + - + diff --git a/plane-src/apps/web/core/components/views/form.tsx b/plane-src/apps/web/core/components/views/form.tsx index c247317..633062e 100644 --- a/plane-src/apps/web/core/components/views/form.tsx +++ b/plane-src/apps/web/core/components/views/form.tsx @@ -22,7 +22,7 @@ import type { } from "@plane/types"; import { EViewAccess, EIssuesStoreType } from "@plane/types"; import { Input, TextArea } from "@plane/ui"; -import { getComputedDisplayFilters, getComputedDisplayProperties, getTabIndex } from "@plane/utils"; +import { cn, getComputedDisplayFilters, getComputedDisplayProperties, getTabIndex } from "@plane/utils"; // components import { DisplayFiltersSelection, FiltersDropdown } from "@/components/issues/issue-layouts/filters"; import { WorkItemFiltersRow } from "@/components/work-item-filters/filters-row"; @@ -88,6 +88,7 @@ export const ProjectViewForm = observer(function ProjectViewForm(props: Props) { kanbanFilters: undefined, }; const { getIndex } = getTabIndex(ETabIndices.PROJECT_VIEW, isMobile); + const viewPropertyButtonClassName = "nodedc-work-item-property-button !min-h-7 !px-3 !py-0 text-12 font-medium"; const handleCreateUpdateView = async (formData: IProjectView) => { await handleFormSubmit({ @@ -106,8 +107,8 @@ export const ProjectViewForm = observer(function ProjectViewForm(props: Props) { }; return ( - - + + {data ? t("view.update.label") : t("view.create.label")} @@ -118,7 +119,7 @@ export const ProjectViewForm = observer(function ProjectViewForm(props: Props) { className="flex-shrink0 flex items-center justify-center" buttonClassName="flex items-center justify-center" label={ - + <> {logoValue?.in_use ? ( @@ -171,7 +172,7 @@ export const ProjectViewForm = observer(function ProjectViewForm(props: Props) { onChange={onChange} hasError={Boolean(errors.name)} placeholder={t("common.title")} - className="w-full text-14" + className="nodedc-modal-input w-full !px-4 !py-3 text-13" tabIndex={getIndex("name")} autoFocus /> @@ -189,7 +190,7 @@ export const ProjectViewForm = observer(function ProjectViewForm(props: Props) { id="description" name="description" placeholder={t("common.description")} - className="min-h-24 w-full resize-none text-14" + className="nodedc-modal-input min-h-[9.5rem] w-full resize-none !rounded-[1.5rem] !px-4 !py-4 text-13" hasError={Boolean(errors?.description)} value={value} onChange={onChange} @@ -198,7 +199,7 @@ export const ProjectViewForm = observer(function ProjectViewForm(props: Props) { )} /> - + {/* display filters dropdown */} ( - + ( + + {t("common.display")} + + )} + > - - + + {t("common.cancel")} - + {data ? isSubmitting ? t("common.updating") diff --git a/plane-src/apps/web/core/components/views/modal.tsx b/plane-src/apps/web/core/components/views/modal.tsx index 0d16de1..c8611f6 100644 --- a/plane-src/apps/web/core/components/views/modal.tsx +++ b/plane-src/apps/web/core/components/views/modal.tsx @@ -88,7 +88,12 @@ export const CreateUpdateProjectViewModal = observer(function CreateUpdateProjec }); return ( - + + - + - {truncateText(t(view.i18n_label), 75)} + + {truncateText(t(view.i18n_label), 75)} + + Default workspace view diff --git a/plane-src/apps/web/core/components/workspace/views/form.tsx b/plane-src/apps/web/core/components/workspace/views/form.tsx index 2bbd886..b7a373b 100644 --- a/plane-src/apps/web/core/components/workspace/views/form.tsx +++ b/plane-src/apps/web/core/components/workspace/views/form.tsx @@ -13,7 +13,7 @@ import { Button } from "@plane/propel/button"; import type { IIssueDisplayFilterOptions, IIssueDisplayProperties, IWorkspaceView, IIssueFilters } from "@plane/types"; import { EViewAccess, EIssueLayoutTypes, EIssuesStoreType } from "@plane/types"; import { Input, TextArea } from "@plane/ui"; -import { getComputedDisplayFilters, getComputedDisplayProperties } from "@plane/utils"; +import { cn, getComputedDisplayFilters, getComputedDisplayProperties } from "@plane/utils"; // components import { DisplayFiltersSelection, FiltersDropdown } from "@/components/issues/issue-layouts/filters"; import { WorkspaceLevelWorkItemFiltersHOC } from "@/components/work-item-filters/filters-hoc/workspace-level"; @@ -66,6 +66,7 @@ export const WorkspaceViewForm = observer(function WorkspaceViewForm(props: Prop displayProperties: getValues("display_properties"), kanbanFilters: undefined, }; + const viewPropertyButtonClassName = "nodedc-work-item-property-button !min-h-7 !px-3 !py-0 text-12 font-medium"; const handleCreateUpdateView = async (formData: Partial) => { await handleFormSubmit(formData); @@ -75,8 +76,8 @@ export const WorkspaceViewForm = observer(function WorkspaceViewForm(props: Prop }; return ( - - + + {data ? t("view.update.label") : t("view.create.label")} @@ -100,7 +101,7 @@ export const WorkspaceViewForm = observer(function WorkspaceViewForm(props: Prop ref={ref} hasError={Boolean(errors.name)} placeholder={t("common.title")} - className="w-full text-14" + className="nodedc-modal-input w-full !px-4 !py-3 text-13" /> )} /> @@ -117,13 +118,13 @@ export const WorkspaceViewForm = observer(function WorkspaceViewForm(props: Prop value={value} placeholder={t("common.description")} onChange={onChange} - className="min-h-24 w-full resize-none text-14" + className="nodedc-modal-input min-h-[9.5rem] w-full resize-none !rounded-[1.5rem] !px-4 !py-4 text-13" hasError={Boolean(errors?.description)} /> )} /> - + {/* display filters dropdown */} ( - + ( + + {t("common.display")} + + )} + > - - + + {t("common.cancel")} - + {data ? isSubmitting ? t("common.updating") diff --git a/plane-src/apps/web/core/components/workspace/views/modal.tsx b/plane-src/apps/web/core/components/workspace/views/modal.tsx index 8f9be46..b0b043b 100644 --- a/plane-src/apps/web/core/components/workspace/views/modal.tsx +++ b/plane-src/apps/web/core/components/workspace/views/modal.tsx @@ -104,7 +104,13 @@ export const CreateUpdateWorkspaceViewModal = observer(function CreateUpdateWork if (!workspaceSlug) return null; return ( - + setUpdateViewModal(false)} /> setDeleteViewModal(false)} /> - + - + - {truncateText(view.name, 75)} - {view?.description && {view.description}} + {truncateText(view.name, 75)} + {view?.description ? ( + {view.description} + ) : ( + Custom workspace view + )} diff --git a/plane-src/apps/web/styles/globals.css b/plane-src/apps/web/styles/globals.css index 3f93de6..8c63f70 100644 --- a/plane-src/apps/web/styles/globals.css +++ b/plane-src/apps/web/styles/globals.css @@ -530,6 +530,7 @@ outline: none !important; box-shadow: none !important; border-radius: 999px !important; + height: 2.5rem !important; min-height: 2.5rem; padding-inline: 1.35rem; background: rgba(18, 18, 22, 0.94) !important; @@ -558,6 +559,7 @@ outline: none !important; box-shadow: none !important; border-radius: 999px !important; + height: 2.5rem !important; min-height: 2.5rem; padding-inline: 1.55rem; background: rgb(var(--nodedc-accent-rgb)) !important; @@ -573,6 +575,39 @@ background: color-mix(in srgb, rgb(var(--nodedc-accent-rgb)) 82%, white) !important; } + .nodedc-bottom-dock-secondary-button { + height: 3rem !important; + min-height: 3rem !important; + border: 0 !important; + outline: none !important; + box-shadow: none !important; + border-radius: 1.2rem !important; + background: rgba(255, 255, 255, 0.06) !important; + color: var(--text-color-primary) !important; + padding-inline: 1.35rem !important; + } + + .nodedc-bottom-dock-secondary-button:hover { + background: rgba(255, 255, 255, 0.1) !important; + } + + .nodedc-bottom-dock-primary-button { + height: 3rem !important; + min-height: 3rem !important; + border: 0 !important; + outline: none !important; + box-shadow: none !important; + border-radius: 1.2rem !important; + background: rgb(var(--nodedc-card-active-rgb)) !important; + color: rgb(var(--nodedc-on-card-active-rgb)) !important; + padding-inline: 1.6rem !important; + } + + .nodedc-bottom-dock-primary-button:hover { + background: color-mix(in srgb, rgb(var(--nodedc-card-active-rgb)) 82%, white) !important; + color: rgb(var(--nodedc-on-card-active-rgb)) !important; + } + .nodedc-modal-secondary-button { min-height: 2.75rem; border: 0 !important; @@ -924,6 +959,36 @@ background: rgba(255, 255, 255, 0.08) !important; } + .nodedc-spreadsheet-cell-button { + height: 100% !important; + min-height: 2.75rem !important; + width: 100% !important; + align-items: center !important; + justify-content: flex-start !important; + border: 0 !important; + outline: none !important; + box-shadow: none !important; + border-radius: 0 !important; + background: transparent !important; + color: var(--text-color-primary) !important; + padding-inline: 1rem !important; + font-size: 0.8125rem !important; + line-height: 1rem !important; + transition: background 160ms ease; + } + + .nodedc-spreadsheet-cell-button:hover { + background: rgba(255, 255, 255, 0.035) !important; + } + + .selected-issue-row .nodedc-spreadsheet-cell-button { + background: color-mix(in srgb, rgb(var(--nodedc-accent-rgb)) 8%, transparent) !important; + } + + .selected-issue-row .nodedc-spreadsheet-cell-button:hover { + background: color-mix(in srgb, rgb(var(--nodedc-accent-rgb)) 14%, transparent) !important; + } + .nodedc-calendar-shell { @apply rounded-[1.1rem] border-0 bg-transparent p-1 shadow-none outline-none; } @@ -1304,6 +1369,76 @@ color: rgb(var(--nodedc-on-card-active-rgb)) !important; } + .nodedc-workspace-page-shell { + width: 100%; + max-width: 104rem; + margin: 0 auto; + padding: 1rem 1rem 1.5rem; + } + + @media (min-width: 768px) { + .nodedc-workspace-page-shell { + padding: 1.25rem 1.25rem 1.75rem; + } + } + + .nodedc-workspace-toolbar { + border: 0 !important; + outline: none !important; + border-radius: 1.5rem !important; + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.036) 0%, rgba(255, 255, 255, 0.016) 100%), + rgba(8, 8, 11, 0.76) !important; + box-shadow: + 0 20px 52px rgba(0, 0, 0, 0.22), + inset 0 1px 0 rgba(255, 255, 255, 0.025) !important; + -webkit-backdrop-filter: blur(28px); + backdrop-filter: blur(28px); + } + + .nodedc-workspace-list-row { + border: 0 !important; + outline: none !important; + overflow: visible !important; + isolation: isolate; + border-radius: 1.35rem !important; + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.032) 0%, rgba(255, 255, 255, 0.014) 100%), + rgba(255, 255, 255, 0.026) !important; + box-shadow: + 0 12px 28px rgba(0, 0, 0, 0.14), + inset 0 1px 0 rgba(255, 255, 255, 0.016) !important; + -webkit-backdrop-filter: blur(18px); + backdrop-filter: blur(18px); + transition: + background 160ms ease, + transform 160ms ease, + box-shadow 160ms ease; + } + + .nodedc-workspace-list-row:hover { + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.044) 0%, rgba(255, 255, 255, 0.018) 100%), + rgba(255, 255, 255, 0.036) !important; + box-shadow: + 0 16px 34px rgba(0, 0, 0, 0.18), + inset 0 1px 0 rgba(255, 255, 255, 0.024) !important; + } + + .nodedc-workspace-stat-card { + border: 0 !important; + outline: none !important; + border-radius: 1.3rem !important; + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.028) 0%, rgba(255, 255, 255, 0.01) 100%), + rgba(255, 255, 255, 0.022) !important; + box-shadow: + 0 14px 32px rgba(0, 0, 0, 0.14), + inset 0 1px 0 rgba(255, 255, 255, 0.018) !important; + -webkit-backdrop-filter: blur(18px); + backdrop-filter: blur(18px); + } + .nodedc-external-empty-state { display: flex; width: 100%;
{truncateText(t(view.i18n_label), 75)}
+ {truncateText(t(view.i18n_label), 75)} +
Default workspace view
{truncateText(view.name, 75)}
{view.description}
Custom workspace view