Skip to content
This repository has been archived by the owner on Dec 26, 2023. It is now read-only.

Commit

Permalink
feat(ui): clickable widgets (#597)
Browse files Browse the repository at this point in the history
  • Loading branch information
leg100 committed Sep 12, 2023
1 parent 3596ad9 commit 518452e
Show file tree
Hide file tree
Showing 16 changed files with 61 additions and 36 deletions.
14 changes: 10 additions & 4 deletions internal/http/html/static/css/output.css
Original file line number Diff line number Diff line change
Expand Up @@ -936,10 +936,6 @@ th, td {
width: 100%;
}

.w-20 {
width: 5rem;
}

.max-w-2xl {
max-width: 42rem;
}
Expand Down Expand Up @@ -1361,6 +1357,11 @@ th, td {
--tw-shadow: var(--tw-shadow-colored);
}

.blur {
--tw-blur: blur(8px);
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}

.even\:bg-gray-100:nth-child(even) {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
Expand All @@ -1376,6 +1377,11 @@ th, td {
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
}

.hover\:bg-gray-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
}

.hover\:text-blue-800:hover {
--tw-text-opacity: 1;
color: rgb(30 64 175 / var(--tw-text-opacity));
Expand Down
45 changes: 32 additions & 13 deletions internal/http/html/static/js/main.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
// https://daverupert.com/2017/11/happier-html5-forms/
window.addEventListener('load', (e) => {
// https://daverupert.com/2017/11/happier-html5-forms/
const inputs = document.querySelectorAll("input, select, textarea");
inputs.forEach(input => {
input.addEventListener(
"invalid",
event => {
input.classList.add("error");
},
false
);
input.addEventListener("blur", function() {
input.checkValidity();
});
const inputs = document.querySelectorAll("input, select, textarea");
inputs.forEach(input => {
input.addEventListener(
"invalid",
event => {
input.classList.add("error");
},
false
);
input.addEventListener("blur", function() {
input.checkValidity();
});
});
});

// https://css-tricks.com/block-links-the-search-for-a-perfect-solution/#method-4-sprinkle-javascript-on-the-second-method
document.addEventListener('alpine:init', () => {
Alpine.data('block_link', (block, link) => ({
init() {
block.classList.add("cursor-pointer", "hover:bg-gray-100");
block.addEventListener("click", (e) => {
isTextSelected = window.getSelection().toString();
if (!isTextSelected) {
location = link;
}
});
links = block.querySelectorAll("a");
links.forEach(link => {
link.addEventListener("click", (e) => e.stopPropagation());
});
}
}))
})
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
{{ end }}

{{ define "content-list-item" }}
<div class="widget">
<div class="widget" x-data="block_link($el, '{{ modulePath .ID }}')">
<div>
<a href="{{ modulePath .ID }}">{{ .Name }}</a>
<span>{{ durationRound .CreatedAt }} ago</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
{{ range .Items }}
<div class="widget">
<div>
<span>{{ .Name }}</span>
<span>{{ .String }}</span>
<span>{{ durationRound .CreatedAt }} ago</span>
</div>
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
{{ end }}

{{ define "content-list-item" }}
<div class="widget">
<div class="widget" x-data="block_link($el, '{{ organizationPath .Name }}')">
<div>
<a href="{{ organizationPath .Name }}">{{ .Name }}</a>
</div>
Expand Down
2 changes: 1 addition & 1 deletion internal/http/html/static/templates/content/team_list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
{{ define "content" }}
<div id="content-list">
{{ range .Teams }}
<div id="item-team-{{ .Name }}" class="widget">
<div id="item-team-{{ .Name }}" class="widget" x-data="block_link($el, '{{ teamPath .ID }}')">
<div>
<a href="{{ teamPath .ID }}">{{ .Name }}</a>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,10 @@

<div id="content-list">
{{ range .Items }}
<div class="widget">
{{ $path := (printf "%s?vcs_provider_id=%s" (setupConnectionRepoWorkspacePath $.Workspace.ID) .ID) }}
<div class="widget" x-data="block_link($el, '{{ $path }}')" id="{{ .ID }}">
<div>
<span class="font-semibold">
<a href="{{ setupConnectionRepoWorkspacePath $.Workspace.ID }}?vcs_provider_id={{ .ID }}">
{{ .String }}
</a>
</span>
<span class="font-semibold">{{ .String }}</span>
<span>{{ durationRound .CreatedAt }} ago</span>
</div>
<div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{{ define "copyable_content" }}
<div class="flex gap-1 items-center" x-data="{ open: false }">
<span x-ref="content" class="font-mono break-all text-gray-500 text-xs">{{ . }}</span>
<img id="clipboard-icon" class="cursor-pointer" @click="navigator.clipboard.writeText($refs.content.innerHTML); open = true; setTimeout(() => open = false, 1000)" src="{{ addHash "/static/images/clipboard_copy.svg" }}">
<a @click="navigator.clipboard.writeText($refs.content.innerHTML); open = true; setTimeout(() => open = false, 1000)">
<img id="clipboard-icon" src="{{ addHash "/static/images/clipboard_copy.svg" }}">
</a>
<div class="relative">
<span class="bg-black text-white p-1 text-xs font-bold absolute" x-cloak x-show="open" x-transition>copied!</span>
</div>
Expand Down
2 changes: 1 addition & 1 deletion internal/http/html/static/templates/partials/run_item.tmpl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{{ define "run-item" }}
<div sse-swap="run-item-{{ .ID }}">
<div id="{{ .ID }}" class="widget">
<div x-data="block_link($el, '{{ runPath .ID }}')" id="{{ .ID }}" class="widget">
<div>
{{ template "run-status" . }}
{{ if .PlanOnly }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{ define "variable-set-item" }}
<div class="widget" id="item-variable-set-{{ .Name }}">
<div class="widget" id="item-variable-set-{{ .Name }}" x-data="block_link($el, '{{ editVariableSetPath .ID }}')">
<span id="name">
<a href="{{ editVariableSetPath .ID }}">{{ .Name }}</a>
</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{ define "workspace-item" }}
<div class="widget" id="item-workspace-{{ .Name }}">
<div x-data="block_link($el, '{{ workspacePath .ID }}')" class="widget" id="item-workspace-{{ .Name }}">
<div>
<a class="text-lg" href="{{ workspacePath .ID }}">{{ .Name }}</a>
{{ with .LatestRun }}
Expand Down
2 changes: 1 addition & 1 deletion internal/integration/connect_repo_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func TestConnectRepoE2E(t *testing.T) {
chromedp.Navigate(organizationURL(daemon.Hostname(), org.Name)),
screenshot(t),
// go to vcs providers
chromedp.Click("#vcs_providers > a"),
chromedp.Click("#vcs_providers > a", chromedp.ByQuery),
screenshot(t),
// click delete button for one and only vcs provider
chromedp.Click(`//button[text()='delete']`),
Expand Down
4 changes: 2 additions & 2 deletions internal/integration/organization_ui_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ func TestIntegration_OrganizationUI(t *testing.T) {
// go to the list of organizations
chromedp.Navigate("https://" + daemon.Hostname() + "/app/organizations"),
// should be 100 orgs listed on page one
chromedp.Nodes(`//*[@class='widget']`, &pageOneWidgets, chromedp.NodeVisible),
chromedp.Nodes(`.widget`, &pageOneWidgets, chromedp.NodeVisible),
// go to page two
chromedp.Click(`#next-page-link`, chromedp.ByQuery),
// should be one org listed
chromedp.Nodes(`//*[@class='widget']`, &pageTwoWidgets, chromedp.NodeVisible),
chromedp.Nodes(`.widget`, &pageTwoWidgets, chromedp.NodeVisible),
})
assert.Equal(t, 100, len(pageOneWidgets))
assert.Equal(t, 1, len(pageTwoWidgets))
Expand Down
2 changes: 1 addition & 1 deletion internal/integration/ui_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ func connectWorkspaceTasks(t *testing.T, hostname, org, name, provider string) c
chromedp.Click(`//button[@id='list-workspace-vcs-providers-button']`),
screenshot(t, "workspace_vcs_providers_list"),
// select provider
chromedp.Click(fmt.Sprintf(`//a[normalize-space(text())='%s']`, provider)),
chromedp.Click(`div.widget`, chromedp.ByQuery),
screenshot(t, "workspace_vcs_repo_list"),
// connect to first repo in list (there should only be one)
chromedp.Click(`//div[@id='content-list']//button[text()='connect']`),
Expand Down
2 changes: 1 addition & 1 deletion internal/integration/workspace_ui_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestIntegration_WorkspaceUI(t *testing.T) {
chromedp.Focus(`input[type="search"]`, chromedp.NodeVisible, chromedp.ByQuery),
input.InsertText("workspace-1"),
chromedp.Submit(`input[type="search"]`, chromedp.ByQuery),
chromedp.WaitVisible(`//*[@class="widget"]`, chromedp.AtLeast(2)),
chromedp.WaitVisible(`div.widget`, chromedp.AtLeast(2)),
// and workspace-2 should not be visible
chromedp.WaitNotPresent(`//*[@id="item-workspace-workspace-2"]`),
// clear search term
Expand Down
1 change: 1 addition & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module.exports = {
"./internal/http/html/static/templates/**/*.tmpl",
"./internal/http/html/static/templates/layout.tmpl",
"./internal/http/html/static/images/*.svg",
"./internal/http/html/static/js/main.js",
],
theme: {
extend: {},
Expand Down

0 comments on commit 518452e

Please sign in to comment.