@bongos/core 1.20.67 → 1.20.69
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bongos-core.json +19 -19
- package/docs/copy-inventory.md +61 -52
- package/docs/copy-registry.json +258 -166
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-inventory.json +3 -1
- package/docs/page-readings.json +82 -72
- package/modules/public-landing/public/account-private.states.json +1 -1
- package/modules/public-landing/public/account.html +143 -26
- package/modules/public-landing/public/account.probes.json +30 -0
- package/modules/public-landing/public/account.states.json +7 -5
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/src/module-api.js +1 -1
- package/tests/hub_account_page.mjs +235 -12
|
@@ -2791,5 +2791,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2791
2791
|
landed since 1.20.65 with no explicit bump. run 36854308972. (task 1002620)
|
|
2792
2792
|
1.20.67 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2793
2793
|
landed since 1.20.66 with no explicit bump. run 36860726629. (task 1002620)
|
|
2794
|
+
1.20.68 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2795
|
+
landed since 1.20.67 with no explicit bump. run 36871565601. (task 1002620)
|
|
2796
|
+
1.20.69 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2797
|
+
landed since 1.20.68 with no explicit bump. run 36873353617. (task 1002620)
|
|
2794
2798
|
---------------------------------------------------------------------------
|
|
2795
2799
|
```
|
package/docs/page-inventory.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"pages": 40,
|
|
14
14
|
"surfaces": 3,
|
|
15
15
|
"with_states": 33,
|
|
16
|
-
"states":
|
|
16
|
+
"states": 204
|
|
17
17
|
},
|
|
18
18
|
"surfaces": [
|
|
19
19
|
{
|
|
@@ -1137,6 +1137,8 @@
|
|
|
1137
1137
|
"states": [
|
|
1138
1138
|
"out",
|
|
1139
1139
|
"in",
|
|
1140
|
+
"in-projects-band",
|
|
1141
|
+
"in-profile-band",
|
|
1140
1142
|
"in-privacy",
|
|
1141
1143
|
"in-private"
|
|
1142
1144
|
]
|
package/docs/page-readings.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"adr": "0341 D3",
|
|
6
6
|
"reread": "node scripts/gds/page-reader.js --stale",
|
|
7
7
|
"how": ["Generated by node scripts/gds/page-reader.js (BV2.TW04, task 1004315; ADR 0341 D3). Do not hand-edit.","One entry per page of docs/page-inventory.json. Lines are in page order: the default state first, and a line only another state shows sits where that state shows it, with its state named.","placement: placed = a docs/copy-registry.json row renders it (file, line, string_id); shared = shell text every page of the surface carries (top bar, sidebar, footer), with its row when the registry has one; unplaced = the registry cannot place it (a rewrite becomes an engineer task, ADR 0341 D4).","text keeps {…} where the registry row has a hole, or where a value the page read from its API was filled in. A string that is only such data is counted under omitted.data, not listed.","reading_hash is over the non-shared lines (key, section, text); files_hash is over the page's inventory files. --check compares files_hash only and never opens a browser.","Rendered through the hall-preview harness (hall) and the ui-design kit stub (landing, status), at 1280x800 with the clock pinned, so a reading is the fixture world's page."],
|
|
8
|
-
"counts": {"pages":40,"lines":
|
|
8
|
+
"counts": {"pages":40,"lines":4016,"placed":1431,"shared":245,"unplaced":2340,"omitted_data":2233},
|
|
9
9
|
"pages": [
|
|
10
10
|
{
|
|
11
11
|
"id": "builders:atlas",
|
|
@@ -3447,80 +3447,90 @@
|
|
|
3447
3447
|
"id": "landing:account",
|
|
3448
3448
|
"surface": "landing",
|
|
3449
3449
|
"title": "{{productName}} — Your account",
|
|
3450
|
-
"states_read": ["out","in","in-privacy","in-private"],
|
|
3451
|
-
"files_hash": "
|
|
3452
|
-
"reading_hash": "
|
|
3453
|
-
"counts": {"lines":
|
|
3454
|
-
"omitted": {"data":
|
|
3450
|
+
"states_read": ["out","in","in-projects-band","in-profile-band","in-privacy","in-private"],
|
|
3451
|
+
"files_hash": "de5fcf1e4b00fef2",
|
|
3452
|
+
"reading_hash": "09a23355300dacb4",
|
|
3453
|
+
"counts": {"lines":77,"placed":41,"shared":10,"unplaced":26},
|
|
3454
|
+
"omitted": {"data":3},
|
|
3455
3455
|
"notes": [],
|
|
3456
3456
|
"lines": [
|
|
3457
3457
|
{"key":"L0001","section":"top bar","text":"Projects","placement":"shared"},
|
|
3458
|
-
{"key":"L0002","section":"top
|
|
3459
|
-
{"key":"L0003","section":"
|
|
3460
|
-
{"key":"L0004","section":"
|
|
3461
|
-
{"key":"L0005","section":"
|
|
3462
|
-
{"key":"L0006","section":"
|
|
3463
|
-
{"key":"L0007","section":"
|
|
3464
|
-
{"key":"L0008","section":"
|
|
3465
|
-
{"key":"L0009","section":"
|
|
3466
|
-
{"key":"L0010","section":"
|
|
3467
|
-
{"key":"L0011","section":"
|
|
3468
|
-
{"key":"L0012","section":"
|
|
3469
|
-
{"key":"L0013","section":"
|
|
3470
|
-
{"key":"L0014","section":"your
|
|
3471
|
-
{"key":"L0015","section":"your
|
|
3472
|
-
{"key":"L0016","section":"your profile","text":"
|
|
3473
|
-
{"key":"L0017","section":"your profile","text":"
|
|
3474
|
-
{"key":"L0018","section":"your profile","text":"
|
|
3475
|
-
{"key":"L0019","section":"your profile","text":"
|
|
3476
|
-
{"key":"L0020","section":"your profile","text":"
|
|
3477
|
-
{"key":"L0021","section":"your profile","text":"
|
|
3478
|
-
{"key":"L0022","section":"your profile","text":"
|
|
3479
|
-
{"key":"L0023","section":"your profile","text":"
|
|
3480
|
-
{"key":"L0024","section":"your profile","text":"
|
|
3481
|
-
{"key":"L0025","section":"your
|
|
3482
|
-
{"key":"L0026","section":"your
|
|
3483
|
-
{"key":"L0027","section":"your
|
|
3484
|
-
{"key":"L0028","section":"your
|
|
3485
|
-
{"key":"L0029","section":"your
|
|
3486
|
-
{"key":"L0030","section":"your
|
|
3487
|
-
{"key":"L0031","section":"
|
|
3488
|
-
{"key":"L0032","section":"
|
|
3489
|
-
{"key":"L0033","section":"
|
|
3490
|
-
{"key":"L0034","section":"
|
|
3491
|
-
{"key":"L0035","section":"
|
|
3492
|
-
{"key":"L0036","section":"
|
|
3493
|
-
{"key":"L0037","section":"
|
|
3494
|
-
{"key":"L0038","section":"
|
|
3495
|
-
{"key":"L0039","section":"
|
|
3496
|
-
{"key":"L0040","section":"who can find you","text":"
|
|
3497
|
-
{"key":"L0041","section":"who can find you","text":"
|
|
3498
|
-
{"key":"L0042","section":"who can find you","text":"
|
|
3499
|
-
{"key":"L0043","section":"who can find you","text":"
|
|
3500
|
-
{"key":"L0044","section":"who can find you","text":"
|
|
3501
|
-
{"key":"L0045","section":"who can find you","text":"
|
|
3502
|
-
{"key":"L0046","section":"who can find you","text":"
|
|
3503
|
-
{"key":"L0047","section":"who can find you","text":"
|
|
3504
|
-
{"key":"L0048","section":"who can find you","text":"
|
|
3505
|
-
{"key":"L0049","section":"
|
|
3506
|
-
{"key":"L0050","section":"
|
|
3507
|
-
{"key":"L0051","section":"
|
|
3508
|
-
{"key":"L0052","section":"
|
|
3509
|
-
{"key":"L0053","section":"
|
|
3510
|
-
{"key":"L0054","section":"
|
|
3511
|
-
{"key":"L0055","section":"
|
|
3512
|
-
{"key":"L0056","section":"
|
|
3513
|
-
{"key":"L0057","section":"
|
|
3514
|
-
{"key":"L0058","section":"your record","text":"
|
|
3515
|
-
{"key":"L0059","section":"
|
|
3516
|
-
{"key":"L0060","section":"
|
|
3517
|
-
{"key":"L0061","section":"
|
|
3518
|
-
{"key":"L0062","section":"
|
|
3519
|
-
{"key":"L0063","section":"
|
|
3520
|
-
{"key":"L0064","section":"
|
|
3521
|
-
{"key":"L0065","section":"
|
|
3522
|
-
{"key":"L0066","section":"your
|
|
3523
|
-
{"key":"L0067","section":"your
|
|
3458
|
+
{"key":"L0002","section":"page top","text":"My projects","placement":"placed","file":"modules/public-landing/public/account.html","line":125,"string_id":"4a167ef6e515","state":"in-profile-band"},
|
|
3459
|
+
{"key":"L0003","section":"page top","text":"Account","placement":"unplaced","state":"in-profile-band"},
|
|
3460
|
+
{"key":"L0004","section":"page top","text":"Sign out","placement":"placed","file":"modules/public-landing/public/account.html","line":128,"string_id":"f9af2d90ce5b","state":"in-profile-band"},
|
|
3461
|
+
{"key":"L0005","section":"page top","text":"Sky","placement":"unplaced","state":"in-projects-band"},
|
|
3462
|
+
{"key":"L0006","section":"page top","text":"the sky of every project","placement":"placed","file":"modules/public-landing/public/account.html","line":114,"string_id":"8fa12f730019","state":"in-projects-band"},
|
|
3463
|
+
{"key":"L0007","section":"page top","text":"Table","placement":"unplaced","state":"in-projects-band"},
|
|
3464
|
+
{"key":"L0008","section":"page top","text":"the same projects as rows","placement":"placed","file":"modules/public-landing/public/account.html","line":115,"string_id":"21453b3ba5c3","state":"in-projects-band"},
|
|
3465
|
+
{"key":"L0009","section":"page top","text":"Your projects","placement":"placed","file":"modules/public-landing/public/account.html","line":116,"string_id":"4e25e6872321","state":"in-projects-band"},
|
|
3466
|
+
{"key":"L0010","section":"page top","text":"the ones you own or build on","placement":"placed","file":"modules/public-landing/public/account.html","line":116,"string_id":"4d88dcfcb8e8","state":"in-projects-band"},
|
|
3467
|
+
{"key":"L0011","section":"page top","text":"New project","placement":"placed","file":"modules/public-landing/public/account.html","line":117,"string_id":"0a81a82d10c4","state":"in-projects-band"},
|
|
3468
|
+
{"key":"L0012","section":"page top","text":"five questions and a home","placement":"placed","file":"modules/public-landing/public/account.html","line":117,"string_id":"94a3462373d2","state":"in-projects-band"},
|
|
3469
|
+
{"key":"L0013","section":"top bar","text":"Sign in","placement":"shared","file":"modules/public-landing/public/account.html","line":107,"string_id":"ad80586f802a"},
|
|
3470
|
+
{"key":"L0014","section":"your account","text":"your account","placement":"placed","file":"modules/public-landing/public/account.html","line":134,"string_id":"402563eecd10"},
|
|
3471
|
+
{"key":"L0015","section":"your account","text":"Who you are across every project on {{productName}}, and who can find you. It is one account, so you change these once, here — each project’s own settings stay in that project’s hall.","placement":"placed","file":"modules/public-landing/public/account.html","line":135,"string_id":"53d4f098a176"},
|
|
3472
|
+
{"key":"L0016","section":"your profile","text":"your profile","placement":"placed","file":"modules/public-landing/public/account.html","line":158,"string_id":"751054b62c88","state":"in"},
|
|
3473
|
+
{"key":"L0017","section":"your profile","text":"Shown wherever your profile appears on {{productName}}. Each project’s hall keeps its own display name — change that one in the hall’s settings.","placement":"placed","file":"modules/public-landing/public/account.html","line":159,"string_id":"25f031d4c292","state":"in"},
|
|
3474
|
+
{"key":"L0018","section":"your profile","text":"Display name","placement":"placed","file":"modules/public-landing/public/account.html","line":161,"string_id":"97509672c5cc","state":"in"},
|
|
3475
|
+
{"key":"L0019","section":"your profile","text":"Your name","placement":"placed","file":"modules/public-landing/public/account.html","line":162,"string_id":"5f8ce59e698a","attr":"placeholder","state":"in"},
|
|
3476
|
+
{"key":"L0020","section":"your profile","text":"Bio","placement":"unplaced","state":"in"},
|
|
3477
|
+
{"key":"L0021","section":"your profile","text":"What you build, and what you would like to build next.","placement":"placed","file":"modules/public-landing/public/account.html","line":164,"string_id":"d0160e86c2bf","attr":"placeholder","state":"in"},
|
|
3478
|
+
{"key":"L0022","section":"your profile","text":"0 of 280 characters","placement":"placed","file":"modules/public-landing/public/account.html","line":165,"string_id":"98c8eeb65e17","state":"in-private"},
|
|
3479
|
+
{"key":"L0023","section":"your profile","text":"81 of 280 characters","placement":"unplaced","state":"in"},
|
|
3480
|
+
{"key":"L0024","section":"your profile","text":"Website","placement":"unplaced","state":"in"},
|
|
3481
|
+
{"key":"L0025","section":"your profile","text":"https://","placement":"unplaced","attr":"placeholder","state":"in"},
|
|
3482
|
+
{"key":"L0026","section":"your profile","text":"X","placement":"unplaced","state":"in"},
|
|
3483
|
+
{"key":"L0027","section":"your profile","text":"https://x.com/…","placement":"unplaced","attr":"placeholder","state":"in"},
|
|
3484
|
+
{"key":"L0028","section":"your profile","text":"LinkedIn","placement":"unplaced","state":"in"},
|
|
3485
|
+
{"key":"L0029","section":"your profile","text":"https://linkedin.com/in/…","placement":"unplaced","attr":"placeholder","state":"in"},
|
|
3486
|
+
{"key":"L0030","section":"your profile","text":"Discord","placement":"unplaced","state":"in"},
|
|
3487
|
+
{"key":"L0031","section":"your profile","text":"https://discord.gg/…","placement":"unplaced","attr":"placeholder","state":"in"},
|
|
3488
|
+
{"key":"L0032","section":"your profile","text":"Your bio is plain text, shown exactly as you write it. Links start with https://, and an X, LinkedIn or Discord link has to point at that site.","placement":"placed","file":"modules/public-landing/public/account.html","line":176,"string_id":"4f9e0fffcd3c","state":"in"},
|
|
3489
|
+
{"key":"L0033","section":"your profile","text":"save profile","placement":"placed","file":"modules/public-landing/public/account.html","line":177,"string_id":"56787ad7373b","state":"in"},
|
|
3490
|
+
{"key":"L0034","section":"your handle","text":"your handle","placement":"placed","file":"modules/public-landing/public/account.html","line":186,"string_id":"c56498c0d064","state":"in"},
|
|
3491
|
+
{"key":"L0035","section":"your handle","text":"The short name people find you by, the same in every project.","placement":"placed","file":"modules/public-landing/public/account.html","line":187,"string_id":"53dccf3e2ad9","state":"in"},
|
|
3492
|
+
{"key":"L0036","section":"your handle","text":"Handle","placement":"unplaced","state":"in"},
|
|
3493
|
+
{"key":"L0037","section":"your handle","text":"your-handle","placement":"unplaced","attr":"placeholder","state":"in"},
|
|
3494
|
+
{"key":"L0038","section":"your handle","text":"Lowercase letters, numbers and hyphens, up to 39. You can change it once a week, and your old handle keeps leading to you until you change it again.","placement":"placed","file":"modules/public-landing/public/account.html","line":191,"string_id":"5ceffa7b9d7e","state":"in"},
|
|
3495
|
+
{"key":"L0039","section":"your handle","text":"change handle","placement":"placed","file":"modules/public-landing/public/account.html","line":192,"string_id":"0a22c9a537b4","state":"in"},
|
|
3496
|
+
{"key":"L0040","section":"who can find you","text":"who can find you","placement":"placed","file":"modules/public-landing/public/account.html","line":203,"string_id":"7322eee6b8b4","state":"in"},
|
|
3497
|
+
{"key":"L0041","section":"who can find you","text":"Your profile page can be public or private, and recruiters are let in separately — so a private profile can still be reachable for work, and a public one can stay out of recruiting entirely.","placement":"placed","file":"modules/public-landing/public/account.html","line":204,"string_id":"38f40fb26117","state":"in"},
|
|
3498
|
+
{"key":"L0042","section":"who can find you","text":"Your profile page","placement":"placed","file":"modules/public-landing/public/account.html","line":207,"string_id":"2df3e63e4761","state":"in"},
|
|
3499
|
+
{"key":"L0043","section":"who can find you","text":"Public","placement":"unplaced","state":"in"},
|
|
3500
|
+
{"key":"L0044","section":"who can find you","text":"Anyone can open your profile page and find you by name.","placement":"placed","file":"modules/public-landing/public/account.html","line":209,"string_id":"2620b4583b20","state":"in"},
|
|
3501
|
+
{"key":"L0045","section":"who can find you","text":"Private","placement":"unplaced","state":"in"},
|
|
3502
|
+
{"key":"L0046","section":"who can find you","text":"Private hides the page from everyone — including you: it answers “not found” to every visitor, and you read your own record here instead.","placement":"placed","file":"modules/public-landing/public/account.html","line":210,"string_id":"082156998085","state":"in"},
|
|
3503
|
+
{"key":"L0047","section":"who can find you","text":"Recruiters","placement":"unplaced","state":"in"},
|
|
3504
|
+
{"key":"L0048","section":"who can find you","text":"Can find me","placement":"placed","file":"modules/public-landing/public/account.html","line":216,"string_id":"50d493f08964","state":"in"},
|
|
3505
|
+
{"key":"L0049","section":"who can find you","text":"Recruiters looking for builders can find you.","placement":"placed","file":"modules/public-landing/public/account.html","line":216,"string_id":"604f5274ae98","state":"in"},
|
|
3506
|
+
{"key":"L0050","section":"who can find you","text":"Can’t find me","placement":"placed","file":"modules/public-landing/public/account.html","line":217,"string_id":"48d721eb2ed7","state":"in"},
|
|
3507
|
+
{"key":"L0051","section":"who can find you","text":"You stay out of the recruiting directory and a recruiter’s look-up.","placement":"placed","file":"modules/public-landing/public/account.html","line":217,"string_id":"af2177106d7c","state":"in"},
|
|
3508
|
+
{"key":"L0052","section":"who can find you","text":"Because your cross-project record is hidden, they will see your name and your picture, and nothing else. This is the one thing a recruiter can see while your profile page is {…}. Turning this off removes you from both recruiting surfaces — the recruiting directory, and a recruiter’s look-up of one {…} — straight away.","placement":"unplaced","state":"in-private"},
|
|
3509
|
+
{"key":"L0053","section":"who can find you","text":"They will see your name, your picture, your roles, and whether you have been {…} in the last 30 days — never your {…}, works shipped, karma, or the projects you build on. This is the one thing a recruiter can see while your profile page is {…}. Turning this off removes you from both recruiting surfaces — the recruiting directory, and a recruiter’s look-up of one {…} — straight away.","placement":"unplaced","state":"in-privacy"},
|
|
3510
|
+
{"key":"L0054","section":"who can find you","text":"They will see your name, your picture, your roles, and whether you have been {…} in the last 30 days — never your {…}, works shipped, karma, or the projects you build on. Turning this off removes you from both recruiting surfaces — the recruiting directory, and a recruiter’s look-up of one {…} — straight away.","placement":"unplaced","state":"in"},
|
|
3511
|
+
{"key":"L0055","section":"who can find you","text":"· For now this follows your profile page setting.","placement":"unplaced","state":"in"},
|
|
3512
|
+
{"key":"L0056","section":"who can find you","text":"Your profile page setting applies now — private already answers “not found” everywhere your profile is read. Recruiter discoverability applies now too — switching it off removes you from both recruiting surfaces immediately, and back on puts you there again.","placement":"placed","file":"modules/public-landing/public/account.html","line":221,"string_id":"e0d6e4196161","state":"in"},
|
|
3513
|
+
{"key":"L0057","section":"who can find you","text":"save","placement":"unplaced","state":"in"},
|
|
3514
|
+
{"key":"L0058","section":"your record","text":"your record","placement":"placed","file":"modules/public-landing/public/account.html","line":232,"string_id":"b494287ce724","state":"in"},
|
|
3515
|
+
{"key":"L0059","section":"your record","text":"Your track record across every project you build on. Hiding it takes effect immediately everywhere — your profile, the recruiting directory, and a recruiter’s look-up of one builder.","placement":"placed","file":"modules/public-landing/public/account.html","line":233,"string_id":"f18600e9cff1","state":"in"},
|
|
3516
|
+
{"key":"L0060","section":"your record","text":"No cross-project activity reported yet. Your profile is not published yet; it publishes after your next sign-in.","placement":"unplaced","state":"in-private"},
|
|
3517
|
+
{"key":"L0061","section":"your record","text":"Your record: 3 projects · 1000 {…} · 19 works shipped · 10 karma.","placement":"unplaced","state":"in"},
|
|
3518
|
+
{"key":"L0062","section":"your record","text":"Show my cross-project record","placement":"placed","file":"modules/public-landing/public/account.html","line":237,"string_id":"19ba62ca1ce4","state":"in"},
|
|
3519
|
+
{"key":"L0063","section":"your record","text":"Show it","placement":"placed","file":"modules/public-landing/public/account.html","line":239,"string_id":"960b894c0ea1","state":"in"},
|
|
3520
|
+
{"key":"L0064","section":"your record","text":"Your numbers appear on your profile and in the directories.","placement":"placed","file":"modules/public-landing/public/account.html","line":239,"string_id":"b93f267cf549","state":"in"},
|
|
3521
|
+
{"key":"L0065","section":"your record","text":"Hide it","placement":"placed","file":"modules/public-landing/public/account.html","line":240,"string_id":"ccd4861996eb","state":"in"},
|
|
3522
|
+
{"key":"L0066","section":"your record","text":"Your numbers leave your profile and the directories. You always see them here.","placement":"placed","file":"modules/public-landing/public/account.html","line":240,"string_id":"312b422976f8","state":"in"},
|
|
3523
|
+
{"key":"L0067","section":"your record","text":"save","placement":"unplaced","state":"in"},
|
|
3524
|
+
{"key":"L0068","section":"footer","text":"A non-profit, capture-resistant commons.","placement":"shared","file":"modules/public-landing/public/account.html","line":250,"string_id":"afe83bbbd0d4","state":"in","occurrences":2},
|
|
3525
|
+
{"key":"L0069","section":"footer","text":"Built by agents, on Cloud Bongos.","placement":"shared","file":"modules/public-landing/public/account.html","line":250,"string_id":"bd315dd71ea7","state":"in","occurrences":2},
|
|
3526
|
+
{"key":"L0070","section":"footer","text":"Open source","placement":"shared","file":"modules/public-landing/public/account.html","line":250,"string_id":"d6314ddcc1d0","state":"in","occurrences":2},
|
|
3527
|
+
{"key":"L0071","section":"footer","text":"AGPL-3.0","placement":"shared","state":"in","occurrences":2},
|
|
3528
|
+
{"key":"L0072","section":"navigation","text":"Privacy","placement":"shared","state":"in","occurrences":2},
|
|
3529
|
+
{"key":"L0073","section":"navigation","text":"Terms","placement":"shared","state":"in","occurrences":2},
|
|
3530
|
+
{"key":"L0074","section":"navigation","text":"Contact","placement":"shared","state":"in","occurrences":2},
|
|
3531
|
+
{"key":"L0075","section":"navigation","text":"Builders' hall","placement":"shared","file":"modules/public-landing/public/account.html","line":250,"string_id":"90a128c97eae","state":"in","occurrences":2},
|
|
3532
|
+
{"key":"L0076","section":"your account","text":"Sign in with GitHub to change your handle, your bio and links, and who can find you.","placement":"placed","file":"modules/public-landing/public/account.html","line":140,"string_id":"57efe272685a"},
|
|
3533
|
+
{"key":"L0077","section":"your account","text":"Sign in with GitHub","placement":"placed","file":"modules/public-landing/public/account.html","line":143,"string_id":"df38941b25a6"}
|
|
3524
3534
|
]
|
|
3525
3535
|
},
|
|
3526
3536
|
{
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"stub": { "fixtures": { "me__cross-project": "me-cross-project-private" } },
|
|
6
6
|
"modes": ["dark"],
|
|
7
7
|
"modeQuery": false,
|
|
8
|
-
"ignoreRequests": ["/api/(gds|bongos)/me/cross-project$"],
|
|
8
|
+
"ignoreRequests": ["/api/(gds|bongos)/me$", "/api/(gds|bongos)/me/cross-project$"],
|
|
9
9
|
"ignoreConsole": ["/api/(gds|bongos)/me/cross-project", "\\b401\\b", "Unauthorized"],
|
|
10
10
|
"ignoreControls": [".vh"],
|
|
11
11
|
"states": {
|
|
@@ -24,14 +24,16 @@
|
|
|
24
24
|
/* The account page's own layout, in the hub's manage-view voice (a lowercase
|
|
25
25
|
light heading, hairline sections with the title left and the controls right,
|
|
26
26
|
hairline fields, the choice cells with the dot). No :root block — the pack's
|
|
27
|
-
injected theme owns the tokens; everything below reads them.
|
|
27
|
+
injected theme owns the tokens; everything below reads them. The bar and
|
|
28
|
+
the bands are cosmos.css's own rules, not restyled here. */
|
|
29
|
+
/* the skip link un-hides itself on focus, reversing everything .vh sets (the hub's rule) */
|
|
30
|
+
.skip:focus{position:fixed;top:8px;left:8px;z-index:100;width:auto;height:auto;margin:0;overflow:visible;clip-path:none;white-space:normal;
|
|
31
|
+
font-size:14px;font-weight:800;text-decoration:none;color:var(--ink);background:var(--bg-card);
|
|
32
|
+
border:2px solid var(--ctl-line);border-radius:12px;padding:10px 16px;}
|
|
28
33
|
.acct{position:relative;z-index:1;max-width:1060px;margin:0 auto;padding:clamp(6px,1.5vw,18px) clamp(16px,4vw,40px) 56px;}
|
|
29
34
|
.acct h1{font-family:var(--font-display);font-weight:300;font-size:clamp(28px,3.4vw,44px);letter-spacing:-.035em;line-height:1.04;text-transform:lowercase;color:var(--ink);margin:18px 0 0;}
|
|
30
35
|
.acct .lede{margin:8px 0 18px;max-width:62ch;font-size:15.5px;line-height:1.55;color:var(--ink-soft);}
|
|
31
36
|
.acct .loading{font-size:15px;color:var(--ink-soft);}
|
|
32
|
-
.aWho{display:flex;flex-wrap:wrap;align-items:center;gap:4px 14px;margin:0 0 26px;font-size:14px;color:var(--ink-soft);}
|
|
33
|
-
.aWho b{font-weight:500;color:var(--ink);overflow-wrap:anywhere;}
|
|
34
|
-
.aWho a{display:inline-flex;align-items:center;min-height:24px;color:var(--ink);text-decoration:underline;}
|
|
35
37
|
.aDoor{border-top:1px solid var(--rule);padding:30px 0 10px;max-width:62ch;}
|
|
36
38
|
.aDoor p{margin:0 0 18px;font-size:15.5px;line-height:1.55;color:var(--ink-soft);}
|
|
37
39
|
.aDoor .gh{width:18px;height:18px;fill:currentColor;}
|
|
@@ -70,12 +72,6 @@
|
|
|
70
72
|
.aSec>h2,.aSec>.aSide,.aSec>.aBody{grid-column:1;grid-row:auto;}
|
|
71
73
|
.aSec>.aSide{max-width:none;}
|
|
72
74
|
}
|
|
73
|
-
@media (max-width:420px){
|
|
74
|
-
.top{padding:16px;}
|
|
75
|
-
.top .mark{font-size:19px;}
|
|
76
|
-
.top-right{gap:8px;}
|
|
77
|
-
.top .btn-space{padding:7px 12px;}
|
|
78
|
-
}
|
|
79
75
|
@media (max-width:560px){
|
|
80
76
|
.aLinks{grid-template-columns:1fr;}
|
|
81
77
|
.aBand [role="radiogroup"]{grid-template-columns:1fr;}
|
|
@@ -85,14 +81,55 @@
|
|
|
85
81
|
</style>
|
|
86
82
|
</head>
|
|
87
83
|
<body>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
84
|
+
<!-- THE BAR and its two bands are the hub's own (projects.html, task 1004455):
|
|
85
|
+
same markup, same cosmos.css rules, so /projects → /account keeps the chrome.
|
|
86
|
+
No map search (it only filters the map), and the band links name /projects
|
|
87
|
+
in full because this page has no views of its own. -->
|
|
88
|
+
<a class="skip vh" href="#acct">Skip to content</a>
|
|
89
|
+
<header class="shell bar">
|
|
90
|
+
<div class="barLeft">
|
|
91
|
+
<a class="barMark" id="barMark" href="/">
|
|
92
|
+
<svg viewBox="0 0 26 20" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.4"
|
|
93
|
+
stroke-linecap="round" stroke-linejoin="round">
|
|
94
|
+
<ellipse cx="8.4" cy="5.6" rx="6.6" ry="2.9"/>
|
|
95
|
+
<path d="M1.8 5.6v6.6a6.6 2.9 0 0 0 13.2 0V5.6"/>
|
|
96
|
+
<ellipse cx="19.6" cy="8.4" rx="4.7" ry="2.1"/>
|
|
97
|
+
<path d="M14.9 8.4v4.6a4.7 2.1 0 0 0 9.4 0V8.4"/>
|
|
98
|
+
</svg>
|
|
99
|
+
<span>{{productName}}</span>
|
|
100
|
+
</a>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="barRight">
|
|
103
|
+
<button class="trig" type="button" id="projTrig" data-menu="projects" aria-expanded="false" aria-controls="menuProjects">Projects<svg class="cv" viewBox="0 0 20 20" aria-hidden="true"><path d="m5.6 8 4.4 4.4L14.4 8"/></svg></button>
|
|
104
|
+
<!-- the identity chip IS the profile trigger; paintBar fills it from GET /me.
|
|
105
|
+
Signed out it stays hidden and the sign-in door takes its slot. -->
|
|
106
|
+
<button class="trig who" type="button" id="who" data-menu="profile" aria-expanded="false" aria-controls="menuProfile" hidden><img id="whoImg" alt="" hidden><span class="whoName" id="whoLogin"></span><svg class="cv" viewBox="0 0 20 20" aria-hidden="true"><path d="m5.6 8 4.4 4.4L14.4 8"/></svg></button>
|
|
107
|
+
<a class="signinDoor" id="signinTop" hidden href="/api/bongos/auth/web/start?return=/account">Sign in</a>
|
|
93
108
|
</div>
|
|
94
109
|
</header>
|
|
95
110
|
|
|
111
|
+
<div class="menuBand" id="menuProjects" data-menu="projects" hidden>
|
|
112
|
+
<div class="bandIn">
|
|
113
|
+
<ul class="bandRow">
|
|
114
|
+
<li class="bandCell"><a class="bandT" href="/projects?view=map">Sky</a><span class="bandC">the sky of every project</span></li>
|
|
115
|
+
<li class="bandCell"><a class="bandT" href="/projects?view=map&sub=table">Table</a><span class="bandC">the same projects as rows</span></li>
|
|
116
|
+
<li class="bandCell" id="mineCell"><a class="bandT" href="/projects?view=mine">Your projects</a><span class="bandC">the ones you own or build on</span></li>
|
|
117
|
+
<li class="bandCell"><a class="bandT" href="/projects?view=new">New project</a><span class="bandC">five questions and a home</span></li>
|
|
118
|
+
</ul>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
<div class="menuBand" id="menuProfile" data-menu="profile" hidden>
|
|
122
|
+
<div class="bandIn bandProfile">
|
|
123
|
+
<p class="bandWho" id="bandWho"><img id="bandWhoImg" alt="" hidden><span class="whoName" id="bandWhoLogin"></span></p>
|
|
124
|
+
<ul class="bandRow">
|
|
125
|
+
<li class="bandCell"><a class="bandT" href="/projects?view=mine">My projects</a></li>
|
|
126
|
+
<li class="bandCell"><a class="bandT" href="/account" aria-current="page">Account</a></li>
|
|
127
|
+
<!-- the honest hover target; the delegated click upgrades it to the POST -->
|
|
128
|
+
<li class="bandCell"><a class="bandT signout" href="/api/bongos/auth/logout">Sign out</a></li>
|
|
129
|
+
</ul>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
|
|
96
133
|
<main class="acct" id="acct">
|
|
97
134
|
<h1>your account</h1>
|
|
98
135
|
<p class="lede">Who you are across every project on {{productName}}, and who can find you. It is one account, so you change these once, here — each project’s own settings stay in that project’s hall.</p>
|
|
@@ -108,10 +145,6 @@
|
|
|
108
145
|
</a>
|
|
109
146
|
</section>
|
|
110
147
|
|
|
111
|
-
<!-- who is signed in, and the way out: in the page rather than the bar, so
|
|
112
|
-
the bar keeps the footer doors' two pills and fits a phone on one line -->
|
|
113
|
-
<p class="aWho" id="aWho" hidden><span>Signed in as <b id="whoName"></b></span><a href="/api/bongos/auth/logout" id="signOut">sign out</a></p>
|
|
114
|
-
|
|
115
148
|
<p class="loading" id="loading">Reading your account…</p>
|
|
116
149
|
<div class="alert" id="pageAlert" role="alert"></div>
|
|
117
150
|
|
|
@@ -214,7 +247,7 @@
|
|
|
214
247
|
</div>
|
|
215
248
|
</main>
|
|
216
249
|
|
|
217
|
-
<footer class="foot"><!--apex-only:start--><span>A non-profit, capture-resistant commons. </span><!--apex-only:end-->Built by agents, on Cloud Bongos. <a href="https://www.npmjs.com/package/@bongos/core" target="_blank" rel="noopener">Open source</a> (<a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank" rel="noopener">AGPL-3.0</a>).<nav class="footNav" aria-label="Site"><a href="/privacy">Privacy</a><a href="/terms">Terms</a><a href="/contact">Contact</a></nav></footer>
|
|
250
|
+
<footer class="foot"><!--apex-only:start--><span>A non-profit, capture-resistant commons. </span><!--apex-only:end-->Built by agents, on Cloud Bongos. <a href="https://www.npmjs.com/package/@bongos/core" target="_blank" rel="noopener">Open source</a> (<a href="https://www.gnu.org/licenses/agpl-3.0.html" target="_blank" rel="noopener">AGPL-3.0</a>).<nav class="footNav" aria-label="Site"><a href="/privacy">Privacy</a><a href="/terms">Terms</a><a href="/contact">Contact</a><a data-link-hall href="{{buildersOrigin}}">Builders' hall</a></nav></footer>
|
|
218
251
|
|
|
219
252
|
<script>
|
|
220
253
|
(function () {
|
|
@@ -265,7 +298,7 @@
|
|
|
265
298
|
function showDoor() {
|
|
266
299
|
$('loading').hidden = true;
|
|
267
300
|
$('acctBody').hidden = true;
|
|
268
|
-
|
|
301
|
+
paintBar(null);
|
|
269
302
|
$('door').hidden = false;
|
|
270
303
|
}
|
|
271
304
|
function showAlert(text) {
|
|
@@ -283,8 +316,6 @@
|
|
|
283
316
|
$('loading').hidden = true;
|
|
284
317
|
$('door').hidden = true;
|
|
285
318
|
$('acctBody').hidden = false;
|
|
286
|
-
$('whoName').textContent = acct.handle || acct.display_name || 'your account';
|
|
287
|
-
$('aWho').hidden = false;
|
|
288
319
|
}, function () { showAlert('Couldn’t reach the server — check your connection and refresh.'); });
|
|
289
320
|
}
|
|
290
321
|
|
|
@@ -492,8 +523,86 @@
|
|
|
492
523
|
: 'Cross-project record shown on your public profile.');
|
|
493
524
|
});
|
|
494
525
|
|
|
495
|
-
// ----
|
|
496
|
-
|
|
526
|
+
// ---- the bar: who is signed in, from the hub's own identity read. Signed
|
|
527
|
+
// out there is no chip and no Your-projects item; the sign-in door takes the slot ----
|
|
528
|
+
function paintBar(me) {
|
|
529
|
+
var login = me ? (me.github_login || 'signed in') : '';
|
|
530
|
+
var avatar = me && me.avatar_url;
|
|
531
|
+
$('who').hidden = !me;
|
|
532
|
+
$('signinTop').hidden = !!me;
|
|
533
|
+
$('mineCell').hidden = !me;
|
|
534
|
+
[['whoImg', 'whoLogin'], ['bandWhoImg', 'bandWhoLogin']].forEach(function (ids) {
|
|
535
|
+
$(ids[0]).hidden = !avatar;
|
|
536
|
+
if (avatar) $(ids[0]).src = avatar;
|
|
537
|
+
$(ids[1]).textContent = login;
|
|
538
|
+
});
|
|
539
|
+
if (me) $('who').setAttribute('aria-label', 'Account, ' + login);
|
|
540
|
+
else closeMenus();
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// ---- the bands: the hub's disclosure (projects.html "THE BANDS") without
|
|
544
|
+
// the map search. Escape closes and returns focus to the trigger, a click
|
|
545
|
+
// outside closes, the arrows walk the items, opening one closes the other ----
|
|
546
|
+
function openBand() { return document.querySelector('.menuBand:not([hidden])'); }
|
|
547
|
+
function closeMenus() {
|
|
548
|
+
var open = openBand();
|
|
549
|
+
if (!open) return;
|
|
550
|
+
var trig = document.querySelector('.trig[aria-expanded="true"]');
|
|
551
|
+
var inside = open.contains(document.activeElement);
|
|
552
|
+
open.hidden = true;
|
|
553
|
+
if (trig) trig.setAttribute('aria-expanded', 'false');
|
|
554
|
+
if (inside && trig) trig.focus();
|
|
555
|
+
}
|
|
556
|
+
function openMenu(trig, byKeyboard) {
|
|
557
|
+
closeMenus();
|
|
558
|
+
trig.setAttribute('aria-expanded', 'true');
|
|
559
|
+
var band = $(trig.getAttribute('aria-controls'));
|
|
560
|
+
band.hidden = false;
|
|
561
|
+
// Enter/Space on the trigger lands on the first item; a pointer stays put
|
|
562
|
+
if (byKeyboard) { var first = band.querySelector('.bandCell:not([hidden]) a'); if (first) first.focus(); }
|
|
563
|
+
}
|
|
564
|
+
document.querySelectorAll('.trig').forEach(function (t) {
|
|
565
|
+
t.addEventListener('click', function (ev) {
|
|
566
|
+
if (t.getAttribute('aria-expanded') === 'true') closeMenus();
|
|
567
|
+
else openMenu(t, ev.detail === 0);
|
|
568
|
+
});
|
|
569
|
+
});
|
|
570
|
+
document.addEventListener('click', function (ev) {
|
|
571
|
+
if (!openBand()) return;
|
|
572
|
+
if (ev.target.closest && (ev.target.closest('.menuBand') || ev.target.closest('.trig'))) return;
|
|
573
|
+
closeMenus();
|
|
574
|
+
});
|
|
575
|
+
document.addEventListener('keydown', function (ev) {
|
|
576
|
+
var open = openBand();
|
|
577
|
+
if (!open) return;
|
|
578
|
+
if (ev.key === 'Escape') { closeMenus(); return; }
|
|
579
|
+
if (ev.key !== 'ArrowDown' && ev.key !== 'ArrowUp') return;
|
|
580
|
+
var items = Array.prototype.filter.call(open.querySelectorAll('a'), function (a) { return !a.closest('[hidden]'); });
|
|
581
|
+
if (!items.length) return;
|
|
582
|
+
var at = items.indexOf(document.activeElement);
|
|
583
|
+
ev.preventDefault();
|
|
584
|
+
items[(at + (ev.key === 'ArrowDown' ? 1 : items.length - 1) + items.length) % items.length].focus();
|
|
585
|
+
});
|
|
586
|
+
document.querySelectorAll('.menuBand').forEach(function (b) {
|
|
587
|
+
b.addEventListener('click', function (ev) {
|
|
588
|
+
if (ev.target.closest && ev.target.closest('a')) closeMenus();
|
|
589
|
+
});
|
|
590
|
+
// Tab out of the band closes it; a null relatedTarget is the window losing
|
|
591
|
+
// focus or a click on nothing, which the document click covers
|
|
592
|
+
b.addEventListener('focusout', function (ev) {
|
|
593
|
+
var to = ev.relatedTarget;
|
|
594
|
+
if (!to || b.contains(to) || (to.closest && to.closest('.trig'))) return;
|
|
595
|
+
closeMenus();
|
|
596
|
+
});
|
|
597
|
+
});
|
|
598
|
+
|
|
599
|
+
// ---- sign out: the hub's own logout (projects.html doLogout), delegated on
|
|
600
|
+
// the profile band's plain anchor ----
|
|
601
|
+
$('menuProfile').addEventListener('click', function (ev) {
|
|
602
|
+
if (!ev.target.closest) return;
|
|
603
|
+
// Account is this page: a reload would only throw away what was typed
|
|
604
|
+
if (ev.target.closest('[aria-current="page"]')) { ev.preventDefault(); return; }
|
|
605
|
+
if (!ev.target.closest('a.signout')) return;
|
|
497
606
|
ev.preventDefault();
|
|
498
607
|
var finish = function () {
|
|
499
608
|
var apex = location.hostname.split('.').slice(-2).join('.');
|
|
@@ -506,7 +615,15 @@
|
|
|
506
615
|
fetch(API + '/auth/logout', { method: 'POST', credentials: 'same-origin' }).then(finish, finish);
|
|
507
616
|
});
|
|
508
617
|
|
|
509
|
-
|
|
618
|
+
var whoRead = request('GET', '/me').then(function (res) {
|
|
619
|
+
var d = res.ok && res.data;
|
|
620
|
+
paintBar(d ? (d.builder || d.me || d) : null);
|
|
621
|
+
}, function () { paintBar(null); });
|
|
622
|
+
// The identity read failing is not a sign-out. If the account itself was
|
|
623
|
+
// read, the chip names it from that answer, so the way out is never lost.
|
|
624
|
+
load().then(function () { return whoRead; }).then(function () {
|
|
625
|
+
if (acct && $('who').hidden) paintBar({ github_login: acct.handle || acct.display_name });
|
|
626
|
+
});
|
|
510
627
|
})();
|
|
511
628
|
</script>
|
|
512
629
|
</body>
|
|
@@ -30,6 +30,36 @@
|
|
|
30
30
|
{ "name": "hiding the record saves hide_stats alone", "continue": true,
|
|
31
31
|
"steps": [["click", "#aRecord .aOpt:nth-child(2)"], ["click", "#recordSave"], ["wait", 400]],
|
|
32
32
|
"expect": { "text": [["#recordMsg", "Cross-project record hidden — removed from your profile and directories immediately."]], "checked": "input[name=record][value=hide]" } },
|
|
33
|
+
{ "name": "the hub's bar: the chip names the person, both bands closed, the page starts under the bar (task 1004455)", "auth": true, "width": 1440,
|
|
34
|
+
"steps": [["wait", 400]],
|
|
35
|
+
"expect": { "expanded": false, "top": [["#acct", 64]], "visible": ["#projTrig", "#who"], "hidden": ["#signinTop", "#menuProjects", "#menuProfile"], "text": [["#whoLogin", "builder"]], "count": [["#mapQ", 0]] } },
|
|
36
|
+
{ "name": "Enter opens Projects and lands on the first item; the band overlays and the page does not move", "continue": true,
|
|
37
|
+
"steps": [["focus", "#projTrig"], ["press", "Enter"], ["wait", 150]],
|
|
38
|
+
"expect": { "open": "#menuProjects", "activeText": "Sky", "top": [["#acct", 64]], "href": [["#menuProjects .bandCell:first-child a", "/projects?view=map"]] } },
|
|
39
|
+
{ "name": "ArrowDown walks to Table", "continue": true,
|
|
40
|
+
"steps": [["press", "ArrowDown"]],
|
|
41
|
+
"expect": { "activeText": "Table" } },
|
|
42
|
+
{ "name": "ArrowUp wraps to the last item", "continue": true,
|
|
43
|
+
"steps": [["press", "ArrowUp"], ["press", "ArrowUp"]],
|
|
44
|
+
"expect": { "activeText": "New project" } },
|
|
45
|
+
{ "name": "Escape closes and returns focus to the trigger", "continue": true,
|
|
46
|
+
"steps": [["press", "Escape"], ["wait", 100]],
|
|
47
|
+
"expect": { "closed": "#menuProjects", "activeId": "projTrig", "expanded": false } },
|
|
48
|
+
{ "name": "opening the profile band closes the Projects band; Account is the current place", "continue": true,
|
|
49
|
+
"steps": [["click", "#projTrig"], ["wait", 120], ["click", "#who"], ["wait", 120]],
|
|
50
|
+
"expect": { "open": "#menuProfile", "closed": "#menuProjects", "expandedIds": ["who"], "text": [["#bandWhoLogin", "builder"], ["#menuProfile [aria-current=\"page\"]", "Account"]], "count": [["#bandWho img", 1], ["[aria-current=\"page\"]", 1]], "href": [["#menuProfile a.signout", "/api/bongos/auth/logout"], ["#menuProfile .bandCell:first-child a", "/projects?view=mine"]] } },
|
|
51
|
+
{ "name": "a click outside closes", "continue": true,
|
|
52
|
+
"steps": [["clickAt", 700, 600], ["wait", 120]],
|
|
53
|
+
"expect": { "closed": "#menuProfile", "expanded": false } },
|
|
54
|
+
{ "name": "Tab out of the band closes it", "continue": true,
|
|
55
|
+
"steps": [["click", "#projTrig"], ["wait", 120], ["focus", "#menuProjects .bandCell:last-child a"], ["press", "Tab"], ["wait", 120]],
|
|
56
|
+
"expect": { "closed": "#menuProjects" } },
|
|
57
|
+
{ "name": "signed out: no chip, the sign-in door in its slot, returning to /account", "auth": false, "width": 1440,
|
|
58
|
+
"steps": [["wait", 300]],
|
|
59
|
+
"expect": { "hidden": ["#who"], "visible": ["#signinTop", "#projTrig"], "href": [["#signinTop", "/api/bongos/auth/web/start?return=/account"]] } },
|
|
60
|
+
{ "name": "signed out the Projects band is Sky / Table / New project (no Your projects)", "continue": true,
|
|
61
|
+
"steps": [["click", "#projTrig"], ["wait", 120]],
|
|
62
|
+
"expect": { "open": "#menuProjects", "count": [["#menuProjects .bandCell:not([hidden])", 3]], "hidden": ["#mineCell"] } },
|
|
33
63
|
{ "name": "phone width: the bar stays one line and nothing scrolls sideways", "auth": true, "width": 320,
|
|
34
64
|
"steps": [["wait", 400]],
|
|
35
65
|
"expect": { "noOverflow": true, "visible": ["#acctBody"] } }
|