Public: anyone can read this; the crew can change it.

An app's members and custom domains speak the home page's language #9914

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/9855-an-app-s-members-and-custom-domains-spea → main 2 commits fork

  • Merged. scout/9855-an-app-s-members-and-custom-domains-spea was merged into main as 8c351e7.

Review

Sign in to review this change.
3 files changed +35 −29
src/web/pages/settings.ts +16 −29
@@ -902,8 +902,9 @@ function appMembersView(
902902 access: AppAccess,
903903 named: readonly string[],
904904 ): Html {
905 return card(
906 html`<form method="post" action="${base}/settings/app/members">
905 return html`<section class="settings-block" id="members">
906 <h2>${icon("users")} Who may enter</h2>
907 <form method="post" action="${base}/settings/app/members">
907908 <div class="field">
908909 <label for="f-members">People</label>
909910 <textarea
@@ -924,12 +925,8 @@ ${named.join("\n")}</textarea
924925 </p>
925926 </div>
926927 <div class="form-actions">${btn("Save people", { variant: "primary" })}</div>
927 </form>`,
928 {
929 head: html`${icon("users")}
930 <h2>Who may enter</h2>`,
931 },
932 );
928 </form>
929 </section>`;
933930 }
934931
935932 function appDomainsView(
@@ -970,14 +967,13 @@ function appDomainsView(
970967 </div>
971968 </li>`,
972969 );
973 return card(
974 html`<div class="card-body">
975 <p class="muted small">
970 return html`<section class="settings-block" id="domains">
971 <h2>${icon("globe")} Domains</h2>
972 <p class="muted small mb">
976973 Serve the app at a name of your own —
977974 <span class="mono">app.example.com</span>, or an apex. Add it, publish
978975 the two records it shows, and press Check now.
979976 </p>
980 </div>
981977 ${when(
982978 rows.length > 0,
983979 () =>
@@ -986,19 +982,15 @@ function appDomainsView(
986982 </ul>`,
987983 )}
988984 ${domains === undefined
989 ? html`<div class="card-body">
990 <p class="muted small">
985 ? html`<p class="muted small">
991986 Nothing is serving apps on this forge, so a domain would have
992987 nowhere to point.
988 </p>`
989 : html`<p class="muted small mb">
990 The forge serves the app there as soon as the record is
991 verified. The app itself learns its new address at its next
992 deploy.
993993 </p>
994 </div>`
995 : html`<div class="card-body">
996 <p class="muted small">
997 The forge serves the app there as soon as the record is
998 verified. The app itself learns its new address at its next
999 deploy.
1000 </p>
1001 </div>
1002994 <form
1003995 class="edit-row"
1004996 method="post"
@@ -1015,13 +1007,8 @@ function appDomainsView(
10151007 required
10161008 />
10171009 ${btn("Add", { variant: "primary", size: "sm", icon: "plus" })}
1018 </form>`}`,
1019 {
1020 head: html`${icon("globe")}
1021 <h2>Domains</h2>`,
1022 pad: false,
1023 },
1024 );
1010 </form>`}
1011 </section>`;
10251012 }
10261013
10271014 /** The records as a person copies them into a zone: type, name, value. */
test/app-members.test.ts +3
@@ -433,6 +433,9 @@ describe("a private app names the people who may enter it", () => {
433433 })
434434 ).text();
435435 expect(page).toContain("Who may enter");
436 const members = page.slice(page.indexOf('id="members"'), page.indexOf("</section>", page.indexOf('id="members"')));
437 expect(members).toContain('action="/alice/game/settings/app/members"');
438 expect(members).not.toContain('class="card');
436439 expect(page).toContain("are named under Who may enter (carol)");
437440 // The form saves the whole list.
438441 const saved = await fetch(
test/settings-app-domains.test.ts +16
@@ -160,3 +160,19 @@ test("a writer who is not an admin is refused, as is a stranger who cannot read
160160 expect(hidden.status).toBe(404);
161161 expect(rows()).toEqual([]);
162162 });
163
164 test("the domains section is headings over rows, not a card, and says what to publish", async () => {
165 await post("founder", DOMAINS, { host: HOST });
166 const page = await (
167 await fetch(`${servers.url}/acme/shop/settings/app`, { headers: { cookie: `${cookies["founder"]}; forge_mode=dev` } })
168 ).text();
169 const start = page.indexOf('id="domains"');
170 expect(start).toBeGreaterThan(0);
171 const section = page.slice(start, page.indexOf("</section>", start));
172 expect(section).not.toContain('class="card');
173 expect(section).toContain("waiting for DNS");
174 expect(section).toContain(PROOF);
175 expect(section).toContain(`${DOMAINS}/${HOST}/check`);
176 expect(section).toContain(encodeURIComponent(`${DOMAINS}/${HOST}/delete`));
177 await post("founder", `${DOMAINS}/${HOST}/delete`);
178 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs