refactor: cloak elements that need alpine loaded

This commit is contained in:
Robert Perce 2026-04-08 09:27:14 -05:00
parent 7b70a10463
commit 231eee3e10
7 changed files with 16 additions and 17 deletions

View file

@ -4,7 +4,6 @@ import { login, verifyCreateUser, todate } from './util';
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
await login(page); await login(page);
await verifyCreateUser(page, { names: ['Test Testerson'] }); await verifyCreateUser(page, { names: ['Test Testerson'] });
await expect(page.locator('#alpine-loaded')).not.toHaveAttribute('x-cloak');
}); });
test('manual-freshen date is editable', async ({ page }) => { test('manual-freshen date is editable', async ({ page }) => {
@ -19,19 +18,21 @@ test('last-contact date on display resolves journal mentions and manual-freshen'
const entryBox = page.getByPlaceholder(/new entry/i); const entryBox = page.getByPlaceholder(/new entry/i);
await entryDate.fill("2025-05-05"); await entryDate.fill("2025-05-05");
await entryBox.fill("[[Test Testerson]]"); await entryBox.fill("[[Test Testerson]]");
let load = page.waitForResponse('/journal_entry');
await page.getByRole('button', { name: /add entry/i }).click(); await page.getByRole('button', { name: /add entry/i }).click();
await load;
await page.reload(); await page.reload();
await expect(page.locator('#fields')).toContainText("freshened2025-05-05"); await expect(page.locator('#fields')).toContainText("freshened2025-05-05");
}); });
test.skip("groups wrap nicely", async ({ page }) => { test.skip("groups wrap nicely", async ({ page }) => {
await page.getByRole('link', { name: /edit/i }).click(); await page.getByRole('link', { name: /edit/i }).click();
await expect(page.locator('#alpine-loaded')).not.toHaveAttribute('x-cloak');
const groupBox = page.getByPlaceholder(/group name/i); const groupBox = page.getByPlaceholder(/group name/i);
await groupBox.fill('this is a long group name'); await groupBox.fill('this is a long group name');
await page.getByRole('button', { name: /save/i }).click(); await page.getByRole('button', { name: /save/i }).click();
await expect(page.locator('#alpine-loaded')).not.toHaveAttribute('x-cloak');
// TODO: this drives to the right location but i can't figure out how to assert // TODO: this drives to the right location but i can't figure out how to assert
// that the text is all on one line. Manual inspection looks good at time of writing. // that the text is all on one line. Manual inspection looks good at time of writing.
@ -39,7 +40,6 @@ test.skip("groups wrap nicely", async ({ page }) => {
test('allow marking as inactive', async ({ page }) => { test('allow marking as inactive', async ({ page }) => {
await page.getByRole('link', { name: /edit/i }).click(); await page.getByRole('link', { name: /edit/i }).click();
await expect(page.locator('#alpine-loaded')).not.toHaveAttribute('x-cloak');
await page.getByLabel('status').selectOption('Inactive'); await page.getByLabel('status').selectOption('Inactive');
await page.getByRole('button', { name: /save/i }).click(); await page.getByRole('button', { name: /save/i }).click();
@ -55,6 +55,7 @@ test('allow exempting from stale', async ({ page }) => {
await page.getByLabel('status').selectOption('Cannot go stale'); await page.getByLabel('status').selectOption('Cannot go stale');
await page.getByRole('button', { name: /save/i }).click(); await page.getByRole('button', { name: /save/i }).click();
await page.waitForURL(/contact\/\d+$/);
await page.goto('/'); await page.goto('/');
await expect(page.locator('#freshness')).not.toContainText('Test Testersonnever'); await expect(page.locator('#freshness')).not.toContainText('Test Testersonnever');
}); });

View file

@ -16,9 +16,7 @@ type UserFields = {
}; };
export const verifyCreateUser = async (page: Page, fields: UserFields) => { export const verifyCreateUser = async (page: Page, fields: UserFields) => {
await page.getByRole('button', { name: /add contact/i }).click(); await page.getByRole('button', { name: /add contact/i }).click();
await page.waitForResponse('/contact/new'); await page.waitForURL(/contact\/\d+\/edit$/);
await expect(page.locator('#alpine-loaded')).not.toHaveAttribute('x-cloak');
const { names, ...simple } = fields; const { names, ...simple } = fields;
for (const name of (names ?? [])) { for (const name of (names ?? [])) {
@ -31,6 +29,6 @@ export const verifyCreateUser = async (page: Page, fields: UserFields) => {
} }
await page.getByRole('button', { name: /save/i }).click(); await page.getByRole('button', { name: /save/i }).click();
await page.waitForResponse(/\/contact\/\d+/); await page.waitForURL(/contact\/\d+$/);
}; };

View file

@ -98,9 +98,9 @@ mod get {
h1 { "Mascarpone" } h1 { "Mascarpone" }
form hx-post=(post_url) hx-target-error="#error" x-data="{ user: '', pass: '' }" { form hx-post=(post_url) hx-target-error="#error" x-data="{ user: '', pass: '' }" {
label for="username" { "Username" } label for="username" { "Username" }
input name="username" #username autofocus x-model="user"; input name="username" #username autofocus x-model="user" x-cloak;
label for="password" { "Password" } label for="password" { "Password" }
input name="password" #password type="password" x-model="pass"; input name="password" #password type="password" x-model="pass" x-cloak;
input type="submit" value="login" x-bind:disabled="!(user.length && pass.length)"; input type="submit" value="login" x-bind:disabled="!(user.length && pass.length)";
#error {} #error {}

View file

@ -64,14 +64,13 @@ mod get {
fn scroll_to(id: DbId) -> String { fn scroll_to(id: DbId) -> String {
format!( format!(
"\ "\
const top = document\ const top=document\
.getElementById('nav-link-{}')\ .getElementById('nav-link-{}')\
?.getBoundingClientRect()\ ?.getBoundingClientRect()\
?.top;\ ?.top;\
console.log({{ top }});\ top&&document\
top && document\
.getElementById('contacts-sidebar')\ .getElementById('contacts-sidebar')\
.scrollTo({{top: top+window.innerHeight/2,left:0,behavior:'instant'}});", .scrollTo({{top:top+window.innerHeight/2,left:0,behavior:'instant'}});",
id id
) )
} }
@ -264,7 +263,7 @@ mod get {
div #error; div #error;
} }
#fields x-data=(json!({ "status": contact.status() })) x-init=(scroll_to(contact_id)) { #fields x-data=(json!({ "status": contact.status() })) x-init=(scroll_to(contact_id)) x-cloak {
label { @if contact.names.len() > 1 { "names" } @else { "name" }} label { @if contact.names.len() > 1 { "names" } @else { "name" }}
div #names x-data=(format!("{{ names: {:?}, new_name: '' }}", &contact.names)) { div #names x-data=(format!("{{ names: {:?}, new_name: '' }}", &contact.names)) {
template x-for="(name, idx) in names" { template x-for="(name, idx) in names" {

View file

@ -129,7 +129,7 @@ pub async fn journal_section(
are now, or leave everything blank to default to 'today'. Entries will be are now, or leave everything blank to default to 'today'. Entries will be
added to the top of the list regardless of date; refresh the page to re-sort." added to the top of the list regardless of date; refresh the page to re-sort."
} }
form hx-post="/journal_entry" hx-target="next .entries" hx-target-error="#journal-error" hx-swap="afterbegin" hx-on::after-request="if(event.detail.successful) this.reset()" { form hx-post="/journal_entry" hx-target="next .entries" hx-target-error="#journal-error" hx-swap="afterbegin" hx-on::after-request="if(event.detail.successful) this.reset()" x-cloak {
input name="date" placeholder=(Zoned::now().date().to_string()); input name="date" placeholder=(Zoned::now().date().to_string());
textarea name="value" placeholder="New entry..." autofocus {} textarea name="value" placeholder="New entry..." autofocus {}
input type="submit" value="Add Entry"; input type="submit" value="Add Entry";

View file

@ -151,7 +151,6 @@ impl Layout {
(content) (content)
} }
} }
template #alpine-loaded x-cloak {}
} }
} }
} }

View file

@ -106,3 +106,5 @@ a, a:visited {
color: var(--link-color); color: var(--link-color);
text-decoration: underline dotted; text-decoration: underline dotted;
} }
[x-cloak] { display: none !important; }