Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ui): clickable widgets #597

Merged
merged 2 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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