From 65aa6361a6a81696adea11ce4baae647852e4ba6 Mon Sep 17 00:00:00 2001 From: JB Date: Sat, 25 Jul 2026 21:18:11 -0400 Subject: [PATCH] Add ISAC registry search controls --- docs/DESIGN_SYSTEM.md | 14 ++++++++ src/app.css | 4 +-- src/lib/components/RegistryPagination.svelte | 35 ++++++++++++++++++-- src/lib/server/pagination.ts | 9 +++++ src/routes/isac/attributes/+page.server.ts | 22 ++++++++---- src/routes/isac/attributes/+page.svelte | 2 +- src/routes/isac/brands/+page.server.ts | 20 +++++++---- src/routes/isac/brands/+page.svelte | 2 +- src/routes/isac/gear/+page.server.ts | 22 +++++++----- src/routes/isac/gear/+page.svelte | 2 +- src/routes/isac/protocols/+page.server.ts | 11 ++++-- src/routes/isac/protocols/+page.svelte | 2 +- src/routes/isac/roles/+page.server.ts | 18 ++++++---- src/routes/isac/roles/+page.svelte | 2 +- src/routes/isac/skillchips/+page.server.ts | 22 +++++++----- src/routes/isac/skillchips/+page.svelte | 2 +- src/routes/isac/talents/+page.server.ts | 26 ++++++++++----- src/routes/isac/talents/+page.svelte | 2 +- src/routes/isac/users/+page.svelte | 4 +-- src/routes/isac/weapons/+page.server.ts | 14 ++++++-- src/routes/isac/weapons/+page.svelte | 2 +- 21 files changed, 172 insertions(+), 65 deletions(-) diff --git a/docs/DESIGN_SYSTEM.md b/docs/DESIGN_SYSTEM.md index 80e46d9..7e183bb 100644 --- a/docs/DESIGN_SYSTEM.md +++ b/docs/DESIGN_SYSTEM.md @@ -633,6 +633,20 @@ never silently describe only the visible page. On narrow screens, retain previous, next, current page, and page-size controls before optional page numbers. +Registries with a meaningful name, title, or agent-identity column place the +shared server-side search inside this pagination rail. Submission resets the +page number while preserving the selected KPI filter and row-count preset; +page navigation preserves the query. Provide an explicit clear action whenever +a query is active. Search applies to the complete filtered registry before +pagination, including visible pending proposals, and never only to the current +page. Specialized oversight and history searches may remain in their richer +filter consoles when they search evidence beyond a single identity column. + +At intermediate widths the search spans the pagination rail above its range +and navigation controls. At mobile widths all groups stack, the input retains a +usable width, and search, clear, previous, and next remain explicit keyboard +and touch targets. + ### Registry metric filters The KPI row above an ISAC registry is an operational filter surface, not passive diff --git a/src/app.css b/src/app.css index 867a234..1d0d732 100644 --- a/src/app.css +++ b/src/app.css @@ -123,9 +123,9 @@ .game-icon{display:block;width:24px;height:24px;object-fit:contain}.weapon-editor{border-top-color:#d07a2c}.weapon-identity-grid{display:grid;grid-template-columns:1.6fr repeat(5,minmax(0,1fr));gap:8px}.weapon-fixed-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px}.damage-type-picker{min-width:0;margin:0;padding:0;border:0}.damage-type-picker legend{color:#858b8d;font-size:8px;font-weight:bold;letter-spacing:1px}.damage-type-picker>div{height:32px;display:grid;grid-template-columns:repeat(3,1fr);margin-top:5px;border:1px solid #363b3c;background:#0d0f10}.damage-type-picker label{min-width:0;border-left:1px solid #303536;cursor:pointer}.damage-type-picker label:first-child{border-left:0}.damage-type-picker input{position:absolute;opacity:0;pointer-events:none}.damage-type-picker span{height:100%;display:flex;align-items:center;justify-content:center;gap:3px;color:#737a7c}.damage-type-picker .game-icon{width:17px;height:17px;opacity:.62}.damage-type-picker b{overflow:hidden;font-size:5px;letter-spacing:.25px;text-overflow:ellipsis}.damage-type-picker label:hover span{background:#171b1c;color:#ecebe5}.damage-type-picker label:active span{transform:translateY(1px);filter:brightness(.88)}.damage-type-picker input:checked+span{background:#211a0e;color:#f6a821;box-shadow:inset 0 -2px #f6a821}.damage-type-picker input:checked+span .game-icon{opacity:1}.damage-type-picker input:focus-visible+span{outline:2px solid #f6a821;outline-offset:2px}.exotic-toggle>span{min-height:32px;margin-top:5px;padding:0 9px;display:flex;align-items:center;gap:7px;border:1px solid #363b3c;background:#0d0f10;color:#d3d5d1;font-size:8px}.exotic-toggle input{width:auto;margin:0;accent-color:#f6a821}.weapon-tier-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:9px}.weapon-tier-card{min-width:0;margin:0;padding:7px;border:1px solid #3b4142;background:#101314}.weapon-tier-card legend{padding:0 7px;color:#f6a821;font-size:8px;font-weight:900;letter-spacing:1.2px}.weapon-range-row{display:grid;grid-template-columns:65px 1fr 1fr;gap:5px;align-items:end;padding:5px;border-top:1px solid #282e2f}.weapon-range-row:first-of-type{border-top:0}.weapon-range-row>strong{align-self:center;display:flex;align-items:center;gap:4px;color:#d7d9d5;font-size:9px}.weapon-range-row>strong .game-icon{width:20px;height:20px}.weapon-range-row>strong small{display:block;color:#596164;font-size:5px;letter-spacing:.5px}.weapon-range-row label{color:#737a7c;font-size:6px;letter-spacing:.7px}.weapon-range-row input{margin-top:3px;padding:7px;font-size:8px}.weapon-talent-pools{display:grid;grid-template-columns:1fr 1fr;gap:9px}.compact-selection{grid-template-columns:repeat(2,minmax(0,1fr));max-height:210px;overflow:auto}.weapon-base-bonuses,.weapon-augment-effects{display:grid;gap:5px;margin-top:7px}.base-bonus-row,.augment-effect{display:grid;grid-template-columns:35px minmax(180px,1fr) 130px 30px;gap:6px;align-items:center;padding:5px;border:1px solid #303536;background:#101314}.base-bonus-row>strong,.augment-effect>strong{height:100%;display:grid;place-items:center;background:#171b1c;color:#f6a821;font-size:8px}.base-bonus-row .field,.augment-effect .field{margin:0}.base-bonus-row button,.augment-effect button{height:30px;border:1px solid #563734;background:#1d1212;color:#da746c;cursor:pointer}.base-bonus-row button:disabled{opacity:.3;cursor:not-allowed}.augment-effect:not(:has(>button)){grid-template-columns:35px minmax(180px,1fr) 130px}.augment-sequence{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:5px;margin-top:7px}.augment-sequence>div{min-height:42px;display:grid;place-items:center;padding:5px;border:1px solid #303536;background:#0d1011}.augment-sequence b{color:#f6a821;font-size:8px}.augment-sequence span{color:#727a7c;font-size:7px}.augment-sequence .exotic-step{border-color:#875d25;background:#211a0e}.weapon-row{min-width:1180px;grid-template-columns:1.3fr .7fr 1.2fr .6fr .6fr .5fr .5fr .3fr}.weapon-row>span small{color:#596164}.weapon-damage-label{display:flex!important;align-items:center;gap:4px}.weapon-damage-label .game-icon{width:16px;height:16px}.weapon-dashboard-table{margin-top:10px} .assignment-picker{border:1px solid #303536;background:#0d1011}.assignment-selected{display:grid;grid-template-columns:70px 1fr;min-height:45px;border-bottom:1px solid #303536}.assignment-summary{display:grid;place-items:center;background:#15191a}.assignment-summary span{color:#687073;font-size:6px;letter-spacing:1px}.assignment-summary b{color:#f6a821;font-size:14px}.assignment-chips{display:flex;align-items:center;gap:5px;overflow:auto;padding:6px}.assignment-chips>button{flex:0 0 auto;display:flex;align-items:center;gap:7px;padding:6px 8px;border:1px solid #6b5128;background:#211a0e;color:#e2cda7;font-size:7px;cursor:pointer}.assignment-chips>button:hover{border-color:#f6a821;color:#f6a821}.assignment-chips>button:active{transform:translateY(1px)}.assignment-chips small{color:#596164;font-size:7px}.assignment-search{display:block;padding:7px 8px;color:#70787a;font-size:6px;letter-spacing:1px}.assignment-search input{height:32px;margin-top:5px;padding:0 9px;font-size:9px}.assignment-results-head{height:27px;display:flex;align-items:center;justify-content:space-between;padding:0 9px;border-top:1px solid #262b2c;border-bottom:1px solid #262b2c;color:#687073;font-size:6px;letter-spacing:1px}.assignment-results-head b{color:#8a672b}.assignment-results{max-height:210px;overflow:auto}.assignment-results>button{width:100%;min-height:34px;display:flex;align-items:center;justify-content:space-between;padding:6px 9px;border:0;border-top:1px solid #24292a;background:#111415;color:#a4aaac;text-align:left;font-size:8px;cursor:pointer}.assignment-results>button:first-child{border-top:0}.assignment-results>button:hover,.assignment-results>button:focus-visible{background:#171b1c;color:#fff;box-shadow:inset 2px 0 #f6a821}.assignment-results>button.selected{background:#211a0e;color:#f6a821;box-shadow:inset 2px 0 #f6a821}.assignment-results>button b{font-size:6px;letter-spacing:.7px}.assignment-results>button:active{transform:translateY(1px);filter:brightness(.88)}.assignment-results>p{margin:0;padding:25px;text-align:center;color:#596164;font-size:7px;letter-spacing:1px} .assignment-picker.compact{position:relative;z-index:1;display:grid;grid-template-columns:minmax(120px,.85fr) minmax(135px,1fr);min-width:0}.assignment-picker.compact:focus-within,.assignment-picker.compact.open{z-index:20;border-color:#8a672b}.assignment-picker.compact .assignment-selected{grid-template-columns:42px minmax(0,1fr);min-width:0;min-height:40px;border-right:1px solid var(--shd-border);border-bottom:0}.assignment-picker.compact .assignment-summary span{font-size:5px}.assignment-picker.compact .assignment-summary b{font-size:10px}.assignment-picker.compact .assignment-chips{min-width:0;padding:4px}.assignment-picker.compact .assignment-chips>button{max-width:100%;padding:5px 6px}.assignment-picker.compact .assignment-chips>button span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.assignment-picker.compact .assignment-search{display:grid;align-content:center;padding:4px}.assignment-picker.compact .assignment-search>span{display:none}.assignment-picker.compact .assignment-search input{height:32px;margin:0}.assignment-picker.compact .assignment-results-head,.assignment-picker.compact .assignment-results{display:none;position:absolute;left:-1px;right:-1px;background:#0d1011}.assignment-picker.compact.open .assignment-results-head{top:100%;display:flex;border:1px solid #8a672b;border-bottom-color:var(--shd-border)}.assignment-picker.compact.open .assignment-results{top:calc(100% + 27px);display:block;border:1px solid #8a672b;border-top:0;box-shadow:0 12px 24px #000b}.assignment-picker.compact .assignment-results>button{min-height:38px}@media(max-width:600px){.assignment-picker.compact{grid-template-columns:1fr}.assignment-picker.compact .assignment-selected{border-right:0;border-bottom:1px solid var(--shd-border)}} -.registry-pagination{width:100%;height:auto;min-height:48px;margin:8px 0 0;padding:7px 9px;display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:12px;border:1px solid #303536;border-bottom:0;background:#0f1213}.pagination-range{display:flex;align-items:center;gap:6px;color:#697174;font-size:7px;letter-spacing:.8px}.pagination-range b{color:#d7d9d5;font-size:9px}.pagination-pages{display:flex;align-items:center;justify-content:center;gap:4px}.pagination-pages a,.pagination-sizes a{min-width:30px;height:30px;display:grid;place-items:center;border:1px solid #343a3b;background:#111415;color:#8c9395;font-size:7px;font-weight:900;letter-spacing:.5px;cursor:pointer}.pagination-pages a:first-child,.pagination-pages a:last-child{min-width:58px;padding:0 8px}.pagination-pages a:hover,.pagination-pages a:focus-visible,.pagination-sizes a:hover,.pagination-sizes a:focus-visible{border-color:#8a672b;color:#f6a821}.pagination-pages a.active,.pagination-sizes a.active{border-color:#f6a821;background:#211a0e;color:#f6a821}.pagination-pages a:active,.pagination-sizes a:active{transform:translateY(1px);filter:brightness(.88)}.pagination-pages a.disabled{opacity:.35;pointer-events:none}.pagination-gap{color:#555d5f;font-size:8px}.pagination-sizes{display:flex;align-items:center;gap:4px}.pagination-sizes>span{margin-right:3px;color:#697174;font-size:7px;letter-spacing:1px}.pagination-sizes a{min-width:34px}.registry-pagination a:focus-visible{outline:2px solid #f6a821;outline-offset:2px} +.registry-pagination{width:100%;height:auto;min-height:48px;margin:8px 0 0;padding:7px 9px;display:grid;grid-template-columns:minmax(190px,260px) auto 1fr auto;align-items:center;gap:12px;border:1px solid #303536;border-bottom:0;background:#0f1213}.registry-pagination:not(:has(.pagination-search)){grid-template-columns:auto 1fr auto}.pagination-search{min-width:0;display:grid;grid-template-columns:minmax(100px,1fr) auto auto;align-items:center;gap:4px}.pagination-search input[type=search]{min-width:0;height:30px;margin:0;padding:0 8px;font-size:7px}.pagination-search button,.pagination-search>a{height:30px;display:grid;place-items:center;margin:0;padding:0 9px;border:1px solid #3b4142;background:#111415;color:#8c9395;font-size:6px;font-weight:900;letter-spacing:.6px;cursor:pointer}.pagination-search button:hover,.pagination-search button:focus-visible,.pagination-search>a:hover,.pagination-search>a:focus-visible{border-color:#8a672b;color:var(--shd-orange)}.pagination-search button:active,.pagination-search>a:active{transform:translateY(1px);filter:brightness(.88)}.pagination-range{display:flex;align-items:center;gap:6px;color:#697174;font-size:7px;letter-spacing:.8px}.pagination-range b{color:#d7d9d5;font-size:9px}.pagination-pages{display:flex;align-items:center;justify-content:center;gap:4px}.pagination-pages a,.pagination-sizes a{min-width:30px;height:30px;display:grid;place-items:center;border:1px solid #343a3b;background:#111415;color:#8c9395;font-size:7px;font-weight:900;letter-spacing:.5px;cursor:pointer}.pagination-pages a:first-child,.pagination-pages a:last-child{min-width:58px;padding:0 8px}.pagination-pages a:hover,.pagination-pages a:focus-visible,.pagination-sizes a:hover,.pagination-sizes a:focus-visible{border-color:#8a672b;color:#f6a821}.pagination-pages a.active,.pagination-sizes a.active{border-color:#f6a821;background:#211a0e;color:#f6a821}.pagination-pages a:active,.pagination-sizes a:active{transform:translateY(1px);filter:brightness(.88)}.pagination-pages a.disabled{opacity:.35;pointer-events:none}.pagination-gap{color:#555d5f;font-size:8px}.pagination-sizes{display:flex;align-items:center;gap:4px}.pagination-sizes>span{margin-right:3px;color:#697174;font-size:7px;letter-spacing:1px}.pagination-sizes a{min-width:34px}.registry-pagination a:focus-visible{outline:2px solid #f6a821;outline-offset:2px} .registry-pagination+.dashboard-table{margin-top:0} -@media(max-width:900px){.registry-pagination{grid-template-columns:1fr}.pagination-range,.pagination-pages,.pagination-sizes{justify-content:center}}@media(max-width:560px){.pagination-pages a:not(:first-child):not(:last-child):not(.active),.pagination-gap{display:none}.pagination-sizes>span{display:none}} +@media(max-width:1100px){.registry-pagination,.registry-pagination:not(:has(.pagination-search)){grid-template-columns:1fr 1fr}.pagination-search{grid-column:1/3}.pagination-pages{justify-content:flex-end}}@media(max-width:650px){.registry-pagination,.registry-pagination:not(:has(.pagination-search)){grid-template-columns:1fr}.pagination-search{grid-column:auto}.pagination-range,.pagination-pages,.pagination-sizes{justify-content:center}}@media(max-width:560px){.pagination-search{grid-template-columns:minmax(0,1fr) auto}.pagination-search>a{grid-column:1/3}.pagination-pages a:not(:first-child):not(:last-child):not(.active),.pagination-gap{display:none}.pagination-sizes>span{display:none}} @media(max-width:1200px){.weapon-identity-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.weapon-fixed-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.weapon-tier-grid{grid-template-columns:1fr}.weapon-talent-pools{grid-template-columns:1fr}}@media(max-width:700px){.weapon-identity-grid,.weapon-fixed-grid{grid-template-columns:1fr 1fr}.compact-selection{grid-template-columns:1fr}.base-bonus-row,.augment-effect,.augment-effect:not(:has(>button)){grid-template-columns:30px 1fr}.base-bonus-row .field:nth-of-type(2),.augment-effect .field:nth-of-type(2){grid-column:2}.base-bonus-row>button,.augment-effect>button{grid-column:2}.augment-sequence{grid-template-columns:1fr 1fr}}@media(max-width:480px){.weapon-identity-grid,.weapon-fixed-grid{grid-template-columns:1fr}.weapon-range-row{grid-template-columns:45px 1fr 1fr}} .weapon-tier-card.unavailable{position:relative;opacity:.42;border-color:#292d2e}.weapon-tier-card.unavailable .weapon-range-row{filter:grayscale(1)}.tier-unavailable{margin:0;padding:7px;border-bottom:1px solid #282e2f;background:#0d1011;color:#7b8284;font-size:6px;font-weight:900;letter-spacing:.8px;text-align:center}.core-range-row>strong{gap:7px}.core-icon-stack{display:flex;align-items:center}.core-icon-stack .game-icon{width:17px;height:17px;margin-left:-7px}.core-icon-stack .game-icon:first-child{margin-left:0}.weapon-archive-action{min-height:40px;padding:0 13px}.weapon-archive-action>b{font-size:9px;transform:rotate(90deg)} .legal-table-wrap{overflow-x:auto;margin:18px 0}.legal-table{width:100%;min-width:720px;border-collapse:collapse;border:1px solid var(--shd-border);background:#0b0e0f}.legal-table th,.legal-table td{padding:12px 14px;border:1px solid var(--shd-border);text-align:left;vertical-align:top}.legal-table th{color:var(--shd-orange);background:#111516;font-size:7px;letter-spacing:1px}.legal-table td{color:#a1a7a8;font:12px/1.55 Georgia,serif}.legal-table code,.legal-document code{color:#d9dedf;font:11px Consolas,monospace}.cookie-notice{position:fixed;z-index:1000;right:24px;bottom:24px;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:22px;width:min(620px,calc(100vw - 48px));padding:18px 20px;border:1px solid var(--shd-orange);background:rgba(10,13,14,.98);box-shadow:0 14px 48px #000c,4px 0 0 var(--shd-orange)}.cookie-notice .eyebrow{margin:0 0 8px}.cookie-notice div>p:not(.eyebrow){margin:0;color:var(--shd-text-muted);font:12px/1.5 Georgia,serif}.cookie-notice a{display:inline-block;margin-top:10px;color:var(--shd-orange);font-size:7px;font-weight:900;letter-spacing:1px}.cookie-notice button{min-width:84px}@media(max-width:600px){.cookie-notice{right:12px;bottom:12px;grid-template-columns:1fr;width:calc(100vw - 24px)}.cookie-notice button{width:100%}} diff --git a/src/lib/components/RegistryPagination.svelte b/src/lib/components/RegistryPagination.svelte index 6f3b8f8..833f5e5 100644 --- a/src/lib/components/RegistryPagination.svelte +++ b/src/lib/components/RegistryPagination.svelte @@ -1,12 +1,33 @@