UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: CTA создания проекта и полировка project-menu и cover-header
This commit is contained in:
parent
b7b0388dc1
commit
49c32fccf1
|
|
@ -96,6 +96,7 @@ const ProjectsToolbarMenu = observer(function ProjectsToolbarMenu() {
|
||||||
const pathname = usePathname();
|
const pathname = usePathname();
|
||||||
const { workspaceSlug } = useParams();
|
const { workspaceSlug } = useParams();
|
||||||
const { joinedProjectIds } = useProject();
|
const { joinedProjectIds } = useProject();
|
||||||
|
const { toggleCreateProjectModal } = useCommandPalette();
|
||||||
|
|
||||||
const handleCopyText = (projectId: string) =>
|
const handleCopyText = (projectId: string) =>
|
||||||
copyUrlToClipboard(`${workspaceSlug}/projects/${projectId}/issues`).then(() => {
|
copyUrlToClipboard(`${workspaceSlug}/projects/${projectId}/issues`).then(() => {
|
||||||
|
|
@ -139,6 +140,18 @@ const ProjectsToolbarMenu = observer(function ProjectsToolbarMenu() {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mt-2 border-t border-white/8 px-1 pt-2">
|
||||||
|
<Menu.Item>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="nodedc-toolbar-primary nodedc-toolbar-primary-wide flex w-full items-center justify-center gap-2 text-13 font-medium"
|
||||||
|
onClick={() => toggleCreateProjectModal(true)}
|
||||||
|
>
|
||||||
|
<PlusIcon className="size-4" />
|
||||||
|
<span>{t("create_project")}</span>
|
||||||
|
</button>
|
||||||
|
</Menu.Item>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Menu.Items>
|
</Menu.Items>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,8 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) {
|
||||||
<div className="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" />
|
<div className="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" />
|
||||||
<CoverImage src={coverImage} alt="Project cover image" className="h-44 w-full rounded-md" />
|
<CoverImage src={coverImage} alt="Project cover image" className="h-44 w-full rounded-md" />
|
||||||
<div className="absolute bottom-4 z-5 flex w-full items-end justify-between gap-3 px-4">
|
<div className="absolute bottom-4 z-5 flex w-full items-end justify-between gap-3 px-4">
|
||||||
<div className="flex flex-grow gap-3 truncate">
|
<div className="flex min-w-0 flex-grow gap-3 truncate">
|
||||||
|
<div className="flex min-w-0 flex-1 items-center gap-3 rounded-[1.2rem] bg-white/10 px-2.5 py-2.5 backdrop-blur-2xl">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="logo_props"
|
name="logo_props"
|
||||||
|
|
@ -208,7 +209,7 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) {
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
handleToggle={(val: boolean) => setIsOpen(val)}
|
handleToggle={(val: boolean) => setIsOpen(val)}
|
||||||
className="flex items-center justify-center"
|
className="flex items-center justify-center"
|
||||||
buttonClassName="flex h-[52px] w-[52px] flex-shrink-0 items-center justify-center rounded-lg bg-white/10"
|
buttonClassName="flex h-[52px] w-[52px] flex-shrink-0 items-center justify-center rounded-lg bg-white/[0.06]"
|
||||||
label={<Logo logo={value} size={28} />}
|
label={<Logo logo={value} size={28} />}
|
||||||
// TODO: fix types
|
// TODO: fix types
|
||||||
onChange={(val: any) => {
|
onChange={(val: any) => {
|
||||||
|
|
@ -245,6 +246,7 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) {
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div className="flex flex-shrink-0 justify-center">
|
<div className="flex flex-shrink-0 justify-center">
|
||||||
<div>
|
<div>
|
||||||
<Controller
|
<Controller
|
||||||
|
|
@ -397,7 +399,7 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
menuButtonWrapperClassName="nodedc-settings-select !h-12 font-medium"
|
menuButtonWrapperClassName="nodedc-settings-select !h-12 min-w-[12.75rem] px-4 font-medium"
|
||||||
disabled={!isAdmin}
|
disabled={!isAdmin}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -392,13 +392,12 @@ export const SidebarProjectsListItem = observer(function SidebarProjectsListItem
|
||||||
</button>
|
</button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
<>
|
|
||||||
<ControlLink href={defaultTabUrl} className="flex flex-grow truncate" onClick={handleItemClick}>
|
|
||||||
{isAccordionMode ? (
|
{isAccordionMode ? (
|
||||||
<Disclosure.Button
|
<div className="flex w-full items-center gap-1">
|
||||||
as="button"
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={cn("flex w-full flex-grow items-center gap-1.5 text-left select-none", {})}
|
className="flex min-w-0 flex-1 items-center gap-3 text-left select-none"
|
||||||
|
onClick={() => setIsProjectListOpen(!isProjectListOpen)}
|
||||||
aria-label={
|
aria-label={
|
||||||
isProjectListOpen
|
isProjectListOpen
|
||||||
? t("aria_labels.projects_sidebar.close_project_menu")
|
? t("aria_labels.projects_sidebar.close_project_menu")
|
||||||
|
|
@ -409,18 +408,50 @@ export const SidebarProjectsListItem = observer(function SidebarProjectsListItem
|
||||||
<WorkItemsIcon className="size-4 text-tertiary" />
|
<WorkItemsIcon className="size-4 text-tertiary" />
|
||||||
</div>
|
</div>
|
||||||
<p className="truncate text-13 font-medium text-secondary">{project.name}</p>
|
<p className="truncate text-13 font-medium text-secondary">{project.name}</p>
|
||||||
</Disclosure.Button>
|
<span className="ml-auto grid size-7 flex-shrink-0 place-items-center rounded-full text-placeholder transition-colors group-hover/project-item:bg-layer-transparent-hover">
|
||||||
|
<ChevronRightIcon
|
||||||
|
className={cn("size-4 transition-transform", {
|
||||||
|
"rotate-90": isProjectListOpen,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
{!renderInToolbarMenu && (
|
||||||
|
<ActionDropdown
|
||||||
|
button={
|
||||||
|
<span className="grid place-items-center">
|
||||||
|
<MoreHorizontal className="h-3.5 w-3.5 text-placeholder" />
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
className={cn(
|
||||||
|
"pointer-events-none flex-shrink-0 opacity-0 group-hover/project-item:pointer-events-auto group-hover/project-item:opacity-100",
|
||||||
|
{
|
||||||
|
"pointer-events-auto opacity-100": isMenuActive,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
buttonClassName={cn(
|
||||||
|
"grid size-7 place-items-center rounded-full text-placeholder transition-colors hover:bg-layer-transparent-hover",
|
||||||
|
{
|
||||||
|
"bg-layer-transparent-hover": isMenuActive,
|
||||||
|
}
|
||||||
|
)}
|
||||||
|
placement="bottom-start"
|
||||||
|
onOpenChange={setIsMenuActive}
|
||||||
|
items={projectActionMenuItems}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
<>
|
||||||
|
<ControlLink href={defaultTabUrl} className="flex flex-grow truncate" onClick={handleItemClick}>
|
||||||
<div className="flex w-full flex-grow items-center gap-3 text-left select-none">
|
<div className="flex w-full flex-grow items-center gap-3 text-left select-none">
|
||||||
<div className="grid size-8 flex-shrink-0 place-items-center rounded-full border border-white/8 bg-white/[0.04]">
|
<div className="grid size-8 flex-shrink-0 place-items-center rounded-full border border-white/8 bg-white/[0.04]">
|
||||||
<WorkItemsIcon className="size-4 text-tertiary" />
|
<WorkItemsIcon className="size-4 text-tertiary" />
|
||||||
</div>
|
</div>
|
||||||
<p className="truncate text-13 font-medium text-secondary">{project.name}</p>
|
<p className="truncate text-13 font-medium text-secondary">{project.name}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</ControlLink>
|
</ControlLink>
|
||||||
<div className="flex items-center gap-1">
|
<div className="flex items-center gap-1">
|
||||||
{!renderInToolbarMenu && (
|
|
||||||
<ActionDropdown
|
<ActionDropdown
|
||||||
button={
|
button={
|
||||||
<span className="grid place-items-center">
|
<span className="grid place-items-center">
|
||||||
|
|
@ -444,28 +475,9 @@ export const SidebarProjectsListItem = observer(function SidebarProjectsListItem
|
||||||
onOpenChange={setIsMenuActive}
|
onOpenChange={setIsMenuActive}
|
||||||
items={projectActionMenuItems}
|
items={projectActionMenuItems}
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
{isAccordionMode && (
|
|
||||||
<IconButton
|
|
||||||
variant="ghost"
|
|
||||||
size="sm"
|
|
||||||
icon={ChevronRightIcon}
|
|
||||||
onClick={() => setIsProjectListOpen(!isProjectListOpen)}
|
|
||||||
className={cn("hidden text-placeholder group-hover/project-item:inline-flex", {
|
|
||||||
"inline-flex": isMenuActive,
|
|
||||||
})}
|
|
||||||
iconClassName={cn("transition-transform", {
|
|
||||||
"rotate-90": isProjectListOpen,
|
|
||||||
})}
|
|
||||||
aria-label={t(
|
|
||||||
isProjectListOpen
|
|
||||||
? "aria_labels.projects_sidebar.close_project_menu"
|
|
||||||
: "aria_labels.projects_sidebar.open_project_menu"
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{isAccordionMode && (
|
{isAccordionMode && (
|
||||||
<Transition
|
<Transition
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue