Remove not allowed cursor from Contributors and BranchSelector

Adds also HoverPopover tooltips, with some hints
This commit is contained in:
Sebastian Martinez
2023-11-17 10:19:57 +01:00
parent 709450cbac
commit b331f446ee
10 changed files with 111 additions and 69 deletions
+5 -1
View File
@@ -16,6 +16,7 @@
export let autofocus: boolean = false;
export let disabled: boolean = false;
export let notAllowed: boolean = true;
export let styleFontFamily: string | undefined = undefined;
export let stylePadding: string | undefined = undefined;
@@ -40,9 +41,11 @@
}
button:disabled {
cursor: not-allowed;
color: var(--color-foreground-disabled);
}
button:disabled.not-allowed {
cursor: not-allowed;
}
.small {
height: var(--button-tiny-height);
@@ -214,6 +217,7 @@
on:mouseout
on:mouseover
class:disabled
class:not-allowed={notAllowed}
class:small={size === "small"}
class:regular={size === "regular"}
class:large={size === "large"}
+1 -1
View File
@@ -27,7 +27,7 @@
box-shadow: var(--elevation-low);
position: relative;
right: 1rem;
z-index: 1;
z-index: 10;
}
</style>
-1
View File
@@ -138,7 +138,6 @@
const preElement = node.parentElement as HTMLElement;
const copyButton = document.createElement("radicle-clipboard");
copyButton.setAttribute("text", node.textContent || "");
copyButton.setAttribute("small", "");
preElement.prepend(copyButton);
const className = Array.from(node.classList).find(name =>
+56 -28
View File
@@ -11,6 +11,7 @@
import IconSmall from "@app/components/IconSmall.svelte";
import Link from "@app/components/Link.svelte";
import Button from "@app/components/Button.svelte";
import HoverPopover from "@app/components/HoverPopover.svelte";
export let branches: Array<{ name: string; route: Route }>;
export let node: BaseUrl;
@@ -35,39 +36,66 @@
}
</style>
<div class="branch" title="Current branch">
<div class="branch">
{#if selectedBranch}
<Popover
popoverPadding="0"
popoverPositionTop="2.5rem"
popoverBorderRadius="var(--border-radius-small)">
<Button
variant="outline"
let:expanded
let:toggle
on:click={toggle}
slot="toggle"
styleBorderRadius="var(--border-radius-tiny) 0 0 var(--border-radius-tiny)"
title="Change branch"
disabled={hideDropdown}>
<IconSmall name="branch" />
<div class="identifier">{selectedBranch}</div>
<IconSmall name={expanded ? "chevron-up" : "chevron-down"} />
</Button>
{#if hideDropdown}
<HoverPopover popoverPositionLeft="0" popoverPositionTop="0.5rem">
<Button
ariaLabel="canonical-branch"
variant="outline"
styleBorderRadius="var(--border-radius-tiny) 0 0 var(--border-radius-tiny)"
slot="toggle"
disabled
notAllowed={false}>
<IconSmall name="branch" />
<div class="identifier">{project.defaultBranch}</div>
</Button>
<div
class="txt-small"
style:padding="0.5rem 0.5rem 0.5rem 0.75rem"
slot="popover">
<div style:margin-bottom="1rem">
You are currently browsing the canonical branch.
</div>
<div>If you want to browse a specific branch,</div>
<div>you need to select the desired remote first.</div>
</div>
</HoverPopover>
{:else}
<Popover
popoverPadding="0"
popoverPositionTop="2.5rem"
popoverBorderRadius="var(--border-radius-small)">
<Button
variant="outline"
let:expanded
let:toggle
on:click={toggle}
slot="toggle"
styleBorderRadius="var(--border-radius-tiny) 0 0 var(--border-radius-tiny)"
title="Change branch"
disabled={hideDropdown}>
<IconSmall name="branch" />
<div class="identifier">{selectedBranch}</div>
<IconSmall
name={hideDropdown && expanded ? "chevron-up" : "chevron-down"} />
</Button>
<DropdownList slot="popover" items={branches}>
<svelte:fragment slot="item" let:item>
<Link route={item.route} on:afterNavigate={() => closeFocused()}>
<DropdownListItem selected={item.name === selectedBranch}>
<div class="identifier">{item.name}</div>
</DropdownListItem>
</Link>
</svelte:fragment>
</DropdownList>
</Popover>
<DropdownList slot="popover" items={branches}>
<svelte:fragment slot="item" let:item>
<Link route={item.route} on:afterNavigate={() => closeFocused()}>
<DropdownListItem selected={item.name === selectedBranch}>
<div class="identifier">{item.name}</div>
</DropdownListItem>
</Link>
</svelte:fragment>
</DropdownList>
</Popover>
{/if}
{/if}
<Button
title="Current HEAD"
variant={selectedBranch ? "gray" : "outline"}
styleBorderRadius={selectedBranch
? "0 var(--border-radius-tiny) var(--border-radius-tiny) 0"
+16 -6
View File
@@ -11,6 +11,7 @@
import Link from "@app/components/Link.svelte";
import Button from "@app/components/Button.svelte";
import Radio from "@app/components/Radio.svelte";
import HoverPopover from "@app/components/HoverPopover.svelte";
export let node: BaseUrl;
export let branches: Array<{ name: string; route: Route }>;
@@ -100,11 +101,20 @@
</Link>
</Radio>
<Button disabled variant="outline">
<IconSmall name="user" />
<div>
{tree.stats.contributors}
{pluralize("contributor", tree.stats.contributors)}
<HoverPopover popoverPositionLeft="0" popoverPositionTop="0.5rem">
<Button disabled notAllowed={false} variant="outline" slot="toggle">
<IconSmall name="user" />
<div>
{tree.stats.contributors}
{pluralize("contributor", tree.stats.contributors)}
</div>
</Button>
<div
class="txt-small"
style:padding="0.5rem 0.5rem 0.5rem 0.75rem"
slot="popover">
<div style:margin-bottom="1rem">Coming soon.</div>
<div>Listing all contributors is not yet implemented.</div>
</div>
</Button>
</HoverPopover>
</div>
+21 -15
View File
@@ -49,8 +49,9 @@ test("navigate to project", async ({ page }) => {
// Project menu shows default selected branch and commit and contributor counts.
{
await expect(page.getByTitle("Current branch")).toContainText(
`main ${aliceMainHead.substring(0, 7)}`,
await expect(page.getByLabel("canonical-branch")).toBeVisible();
await expect(page.getByTitle("Current HEAD")).toHaveText(
aliceMainHead.substring(0, 7),
);
await expectCounts({ commits: 6, contributors: 1 }, page);
}
@@ -79,7 +80,7 @@ test("show source tree at specific revision", async ({ page }) => {
})
.click();
await expect(page.getByTitle("Current branch")).toContainText("335dd6d");
await expect(page.getByTitle("Current HEAD")).toContainText("335dd6d");
await expect(page.locator(".source-tree")).toHaveText("bin src");
await expectCounts({ commits: 2, contributors: 1 }, page);
});
@@ -294,8 +295,9 @@ test("peer and branch switching", async ({ page }) => {
// Default `main` branch.
{
await expect(page.getByTitle("Current branch")).toContainText(
`main ${aliceMainHead.substring(0, 7)}`,
await expect(page.getByTitle("Change branch")).toHaveText("main");
await expect(page.getByTitle("Current HEAD")).toHaveText(
aliceMainHead.substring(0, 7),
);
await expectCounts({ commits: 6, contributors: 1 }, page);
}
@@ -305,9 +307,10 @@ test("peer and branch switching", async ({ page }) => {
await page.getByTitle("Change branch").click();
await page.getByText("feature/branch").click();
await expect(page.getByTitle("Current branch")).toContainText(
"feature/branch 1aded56",
);
await expect(
page.getByRole("button", { name: "feature/branch" }),
).toBeVisible();
await expect(page.getByTitle("Current HEAD")).toHaveText("1aded56");
await expectCounts({ commits: 9, contributors: 1 }, page);
}
@@ -316,9 +319,10 @@ test("peer and branch switching", async ({ page }) => {
await page.getByTitle("Change branch").click();
await page.getByText("orphaned-branch").click();
await expect(page.getByTitle("Current branch")).toContainText(
"orphaned-branch af3641c",
);
await expect(
page.getByRole("button", { name: "orphaned-branch" }),
).toBeVisible();
await expect(page.getByTitle("Current HEAD")).toHaveText("af3641c");
await expectCounts({ commits: 1, contributors: 1 }, page);
await expect(page.getByText("No files at this revision")).toBeVisible();
@@ -332,8 +336,9 @@ test("peer and branch switching", async ({ page }) => {
await expect(page.getByTitle("Change peer")).not.toContainText("alice");
await expect(page.getByTitle("Change peer")).not.toContainText("bob");
await expect(page.getByTitle("Current branch")).toContainText(
`main ${aliceMainHead.substring(0, 7)}`,
await expect(page.getByLabel("canonical-branch")).toBeVisible();
await expect(page.getByTitle("Current HEAD")).toHaveText(
aliceMainHead.substring(0, 7),
);
await expect(page.getByText("Git test repository")).toBeVisible();
}
@@ -347,8 +352,9 @@ test("peer and branch switching", async ({ page }) => {
// Default `main` branch.
{
await expect(page.getByTitle("Current branch")).toContainText(
`main ${bobHead.substring(0, 7)}`,
await expect(page.getByLabel("canonical-branch")).toBeVisible();
await expect(page.getByTitle("Current HEAD")).toHaveText(
bobHead.substring(0, 7),
);
await expectCounts({ commits: 7, contributors: 2 }, page);
await expect(
-2
View File
@@ -52,7 +52,6 @@ test("add and remove assignees", async ({ page, authenticatedPeer }) => {
await expect(
page.getByRole("button", { name: "save assignees" }),
).toBeHidden();
await page.reload();
await expect(
page.getByRole("button", { name: "avatar did:key:z6MktU…1xB22S" }),
).toBeVisible();
@@ -71,7 +70,6 @@ test("add and remove assignees", async ({ page, authenticatedPeer }) => {
await expect(
page.getByRole("button", { name: "save assignees" }),
).toBeHidden();
await page.reload();
await expect(
page.getByRole("button", { name: "avatar did:key:z6Mkkf…XVsVz5" }),
).toBeVisible();
+1 -1
View File
@@ -114,7 +114,7 @@ test("navigation to source tree at specific revision", async ({ page }) => {
await expect(page).toHaveURL(
`${sourceBrowsingUrl}/tree/0801aceeab500033f8d608778218657bd626ef73/deep/directory/hierarchy/is/entirely/possible/in/git/repositories/.gitkeep`,
);
await expect(page.getByTitle("Current branch")).toContainText("0801ace");
await expect(page.getByTitle("Current HEAD")).toContainText("0801ace");
await expect(page.locator(".source-tree >> text=.gitkeep")).toBeVisible();
await expect(
page.locator(
+11 -8
View File
@@ -38,18 +38,18 @@ test("peer and branch switching", async ({ page }) => {
await page.getByTitle("Change branch").click();
await page.getByText("feature/branch").click();
await expect(page.getByTitle("Current branch")).toContainText(
"feature/branch 1aded56",
);
await expect(
page.getByRole("button", { name: "feature/branch" }),
).toBeVisible();
await expect(page.getByText("Thursday, November 17, 2022")).toBeVisible();
await expect(page.locator(".history .teaser")).toHaveCount(9);
await page.getByTitle("Change branch").click();
await page.getByText("orphaned-branch").click();
await expect(page.getByTitle("Current branch")).toContainText(
"orphaned-branch af3641c",
);
await expect(
page.getByRole("button", { name: "orphaned-branch" }),
).toBeVisible();
await expect(page.getByText("Thursday, November 17, 2022")).toBeVisible();
await expect(page.locator(".list")).toHaveCount(1);
}
@@ -146,7 +146,9 @@ test("pushing changes while viewing history", async ({ page, peerManager }) => {
await page.reload();
await expect(page).toHaveURL(`${alice.uiUrl()}/${rid}/history`);
await expect(page.getByRole("link", { name: "2 commits" })).toBeVisible();
await expect(page.getByTitle("Current branch")).toContainText("main 516fa74");
await expect(page.getByLabel("canonical-branch")).toHaveText("main");
await expect(page.getByTitle("Current HEAD")).toHaveText("516fa74");
await page.getByText("alice-project").click();
await expect(page).toHaveURL(`${alice.uiUrl()}/${rid}`);
@@ -171,5 +173,6 @@ test("pushing changes while viewing history", async ({ page, peerManager }) => {
await expect(page.getByRole("link", { name: "3 commits" })).toHaveText(
"3 commits",
);
await expect(page.getByTitle("Current branch")).toContainText("main bb9089a");
await expect(page.getByLabel("canonical-branch")).toHaveText("main");
await expect(page.getByTitle("Current HEAD")).toHaveText("bb9089a");
});
-6
View File
@@ -58,7 +58,6 @@ export async function expectThreadCommentingToWork(page: Page) {
await page.getByPlaceholder("Leave your comment").fill("This is a comment");
await page.getByRole("button", { name: "Comment" }).click();
await expect(page.getByLabel("extended-textarea")).toBeHidden();
await page.reload();
await expect(page.getByText("This is a comment")).toBeVisible();
await page.getByRole("button", { name: "edit comment" }).first().click();
@@ -67,14 +66,12 @@ export async function expectThreadCommentingToWork(page: Page) {
.fill("This is an edited comment");
await page.getByRole("button", { name: "Save" }).click();
await expect(page.getByLabel("extended-textarea")).toBeHidden();
await page.reload();
await expect(page.getByText("This is an edited comment")).toBeVisible();
await page.getByRole("button", { name: "Reply to comment" }).click();
await page.getByPlaceholder("Reply to comment").fill("This is a reply");
await page.getByRole("button", { name: "Comment", exact: true }).click();
await expect(page.getByLabel("extended-textarea")).toBeHidden();
await page.reload();
await expect(page.getByText("This is a reply")).toBeVisible();
await page.getByRole("button", { name: "edit comment" }).nth(1).click();
@@ -83,7 +80,6 @@ export async function expectThreadCommentingToWork(page: Page) {
.fill("This is an edited reply");
await page.getByRole("button", { name: "Save" }).click();
await expect(page.getByLabel("extended-textarea")).toBeHidden();
await page.reload();
await expect(page.getByText("This is an edited reply")).toBeVisible();
}
@@ -108,7 +104,6 @@ export async function expectLabelEditingToWork(page: Page) {
await page.keyboard.press("Enter");
await page.getByRole("button", { name: "save labels" }).click();
await expect(page.getByRole("button", { name: "save labels" })).toBeHidden();
await page.reload();
await expect(page.getByRole("button", { name: "bug" })).toBeVisible();
await expect(
page.getByRole("button", { name: "documentation" }),
@@ -122,7 +117,6 @@ export async function expectLabelEditingToWork(page: Page) {
.click();
await page.getByRole("button", { name: "save labels" }).click();
await expect(page.getByRole("button", { name: "save labels" })).toBeHidden();
await page.reload();
await expect(page.getByRole("button", { name: "bug" })).toBeVisible();
}