From 29243f11854f6913b18c587830331c78542c5232 Mon Sep 17 00:00:00 2001 From: Jason Gessner Date: Tue, 24 Feb 2026 23:26:08 -0600 Subject: [PATCH 1/3] Add skeleton of V3 search UI. --- .../views/Search/search_new.html.twig | 243 ++++++++++++++++++ .../Controller/SearchNewController.php | 21 ++ src/AppBundle/Resources/config/routing.yml | 5 + web/js/topnav.js | 4 + 4 files changed, 273 insertions(+) create mode 100644 app/Resources/views/Search/search_new.html.twig create mode 100755 src/AppBundle/Controller/SearchNewController.php diff --git a/app/Resources/views/Search/search_new.html.twig b/app/Resources/views/Search/search_new.html.twig new file mode 100644 index 00000000..042e5709 --- /dev/null +++ b/app/Resources/views/Search/search_new.html.twig @@ -0,0 +1,243 @@ +{% extends '/layout.html.twig' %} + +{% block title %}New Card Search{% endblock %} + +{% block body %} +{% include '/Scripts/api.html.twig' %} + +
+ +
+ +
+
+

New Search!

+

Use the new Search Syntax from api.netrunnerdb.com (the V3 API).

+

TODO: Add Syntax here

+
+
+ +
+
+
+ + + + + +
+
+ +
+ +
+ +
+ +
+
+ +
+ + + + + + + + + + + + + + + + + +
+
+
+
+ + +{% endblock %} diff --git a/src/AppBundle/Controller/SearchNewController.php b/src/AppBundle/Controller/SearchNewController.php new file mode 100755 index 00000000..767a8749 --- /dev/null +++ b/src/AppBundle/Controller/SearchNewController.php @@ -0,0 +1,21 @@ +render('/search/search_new.html.twig', [ + 'pagetitle' => "Card Search (new)", + 'pagedescription' => "New Card Search", + 'query' => $request->query->get('q') ?: '' + ]); + } +} diff --git a/src/AppBundle/Resources/config/routing.yml b/src/AppBundle/Resources/config/routing.yml index 3658eb19..354b12f5 100755 --- a/src/AppBundle/Resources/config/routing.yml +++ b/src/AppBundle/Resources/config/routing.yml @@ -834,6 +834,11 @@ cards_find: defaults: _controller: AppBundle:Search:find +cards_find_v3: + path: /search_new/ + defaults: + _controller: AppBundle:SearchNew:get + cards_processSearchForm: path: /process/ defaults: diff --git a/web/js/topnav.js b/web/js/topnav.js index e287b762..e1020db3 100644 --- a/web/js/topnav.js +++ b/web/js/topnav.js @@ -62,6 +62,10 @@ Promise.all([NRDB.data.promise, NRDB.ui.promise]).then(function() { $('#top_nav_card_search').keypress(function(event) { var keycode = (event.keyCode ? event.keyCode : event.which); if(keycode == '13'){ + if (NRDB.user?.data?.use_new_search) { + let f = document.getElementById('top_nav_card_search_form'); + f.action = Routing.generate('cards_find_v3', {}, true); + } $('#top_nav_card_search_form').submit(); } }); From c4be6e27749610d25177c29bdaf5f6fd7bbfaa4b Mon Sep 17 00:00:00 2001 From: Jason Gessner Date: Wed, 25 Feb 2026 23:08:32 -0600 Subject: [PATCH 2/3] Add text only and full views (with some jank still). --- .../views/Search/search_new.html.twig | 96 ++++++++++++++++++- 1 file changed, 92 insertions(+), 4 deletions(-) diff --git a/app/Resources/views/Search/search_new.html.twig b/app/Resources/views/Search/search_new.html.twig index 042e5709..a58af78d 100644 --- a/app/Resources/views/Search/search_new.html.twig +++ b/app/Resources/views/Search/search_new.html.twig @@ -46,8 +46,6 @@ - - @@ -70,6 +68,8 @@ + +
@@ -84,6 +84,8 @@ $('#view_type').on('change', function(e) { const e = $(`#card_results_${o.value}`); if (e.length && !o.selected) { e.hide(); + } else if (o.selected && o.value == 'text') { + $('[id^="card_results_text_row_"]').hide(); } else if (o.value == 'images') { $('[id^="card_results_images_row_"]').hide(); } @@ -94,6 +96,8 @@ $('#view_type').on('change', function(e) { const e = $(`#card_results_${o.value}`); if (e.length && o.selected) { e.show(); + } else if (o.selected && o.value == 'text') { + $('[id^="card_results_text_row_"]').show(); } else if (o.selected && o.value == 'images') { $('[id^="card_results_images_row_"]').show(); } @@ -111,6 +115,10 @@ $('#q').on("keyup", function(e) { let lastSearchQuery = null; +function textOnlyCard(card) { + return ''; +} + async function doSearch() { let q = $('#q'); console.log(`q is ${q.val()}`); @@ -131,6 +139,11 @@ async function doSearch() { // Hide and reset containers. $('#card_results_table').hide(); $('#card_results_table_body').empty(); + $('#card_results_full').hide(); + $('#card_results_full').empty(); + $('#card_results_full').append('
'); + $('[id^="card_results_text_row_"]').hide(); + $('[id^="card_results_text_row_"]').remove(); $('[id^="card_results_images_row_"]').hide(); $('[id^="card_results_images_row_"]').remove(); @@ -138,12 +151,13 @@ async function doSearch() { $('#loading_row').append(loading_icon); // Load api data - const [searchResults, cardSets, cardCycles, cardTypes] = await Promise.all( + const [searchResults, cardSets, cardCycles, cardTypes, factions] = await Promise.all( [ fetchJson(`{{ v3_api_url }}/api/v3/public/cards?include=printings&filter[search]=${encodeURIComponent(q.val())}`), fetchJson(`{{ v3_api_url }}/api/v3/public/card_sets`), fetchJson(`{{ v3_api_url }}/api/v3/public/card_cycles`), fetchJson(`{{ v3_api_url }}/api/v3/public/card_types`), + fetchJson(`{{ v3_api_url }}/api/v3/public/factions`), ]); let cardCycleMap = new Map(); cardCycles.data.forEach((cc) => { @@ -157,6 +171,10 @@ async function doSearch() { cardTypes.data.forEach((t) => { cardTypeMap.set(t.id, t); }) + let factionMap = new Map(); + factions.data.forEach((f) => { + factionMap.set(f.id, f); + }) let printings = searchResults.included?.filter(i => i.type == 'printings'); let printingsMap = new Map(); if (printings) { @@ -166,6 +184,9 @@ async function doSearch() { } let rowNum = 0; + let textOnlyRowNum = 0; + let textOnlyCardNum = 0; + let textOnlyCardsPerRow = 3; let imagesRowNum = 0; let imagesCardNum = 0; let imagesPerRow = 4; @@ -210,6 +231,20 @@ async function doSearch() { `; $('#card_results_table_body').append(rowContents); + // Text view + // Insert a new row every imagesPerColumn + if (textOnlyCardNum % textOnlyCardsPerRow == 0) { + textOnlyRowNum++; + $('#list').append(``); + } + textOnlyCardNum++; + + $(`#card_results_text_row_${textOnlyRowNum}`).append(` +
+

${card.attributes.title}

+
+ `); + // Image view // Insert a new row every imagesPerColumn if (imagesCardNum % imagesPerRow == 0) { @@ -223,6 +258,57 @@ async function doSearch() { ${card.attributes.title} `); + + // Full view + let illustrators = ''; + printingsMap.get(card.attributes.latest_printing_id).attributes.illustrator_names.forEach((illustrator) => { + const search = Routing.generate('cards_find', {type:'find', 'view':'images', 'q':`i:"${illustrator}"`}); + + illustrators += `${illustrator} • `; + }); + + // ${illustratorMap.get(card.attributes.illustrator_id).attributes.name} • + $('#card_results_full_contents').append(` +
+
+
+ +
+
+ ${cardTypeMap.get(card.attributes.card_type_id).attributes.name} + • Cost: ${card.attributes.cost} • Trash: ${card.attributes.trash_cost} • Influence: ${card.attributes.influence_cost} +
+
+

${card.attributes.text}

+
+
+ ${printingsMap.get(card.attributes.latest_printing_id).attributes.flavor} +
+
+ + ${factionMap.get(card.attributes.faction_id).attributes.name} • + ${illustrators} + + ${cardSetMap.get(card.attributes.card_set_ids[0]).attributes.name} ${printingsMap.get(card.attributes.latest_printing_id).attributes.position} + +
+
+
+
+
+ `); + $('#card_results_full_contents').append(` +
+
+ ${card.attributes.title} +
+
+ `); + }); // Remove the loading indicator @@ -231,8 +317,10 @@ async function doSearch() { // Show the proper display. if ($('#view_type').val() == 'table') { $('#card_results_table').show(); + } else if ($('#view_type').val() == 'text') { + $('[id^="card_results_text_row_"]').show(); } else if ($('#view_type').val() == 'images') { - $('#card_results_images').show(); + $('[id^="card_results_images_row_"]').show(); } else { } From d79512139cb03002f4d211ac1d75de5ba9670012 Mon Sep 17 00:00:00 2001 From: Jason Gessner Date: Wed, 25 Feb 2026 23:09:17 -0600 Subject: [PATCH 3/3] Remove debugging --- app/Resources/views/Search/search_new.html.twig | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/Resources/views/Search/search_new.html.twig b/app/Resources/views/Search/search_new.html.twig index a58af78d..115ab863 100644 --- a/app/Resources/views/Search/search_new.html.twig +++ b/app/Resources/views/Search/search_new.html.twig @@ -121,11 +121,9 @@ function textOnlyCard(card) { async function doSearch() { let q = $('#q'); - console.log(`q is ${q.val()}`); // Avoid duplicate API calls. if (lastSearchQuery == q.val()) { - console.log('Skipping duplicate search.'); return; } @@ -267,7 +265,6 @@ async function doSearch() { illustrators += `${illustrator} • `; }); - // ${illustratorMap.get(card.attributes.illustrator_id).attributes.name} • $('#card_results_full_contents').append(`