Allow to show recently submitted pages, and create them from the page

This commit is contained in:
Jan Böhmer 2026-05-14 17:27:10 +02:00
parent e33c13ecfa
commit 91a6a26746
4 changed files with 58 additions and 3 deletions

View file

@ -28,6 +28,7 @@ use App\Entity\Parts\Part;
use App\Exceptions\OAuthReconnectRequiredException; use App\Exceptions\OAuthReconnectRequiredException;
use App\Form\InfoProviderSystem\FromURLFormType; use App\Form\InfoProviderSystem\FromURLFormType;
use App\Form\InfoProviderSystem\PartSearchType; use App\Form\InfoProviderSystem\PartSearchType;
use App\Services\InfoProviderSystem\SubmittedPageStorage;
use App\Services\InfoProviderSystem\ExistingPartFinder; use App\Services\InfoProviderSystem\ExistingPartFinder;
use App\Services\InfoProviderSystem\CreateFromUrlHelper; use App\Services\InfoProviderSystem\CreateFromUrlHelper;
use App\Services\InfoProviderSystem\PartInfoRetriever; use App\Services\InfoProviderSystem\PartInfoRetriever;
@ -62,7 +63,8 @@ class InfoProviderController extends AbstractController
private readonly PartInfoRetriever $infoRetriever, private readonly PartInfoRetriever $infoRetriever,
private readonly ExistingPartFinder $existingPartFinder, private readonly ExistingPartFinder $existingPartFinder,
private readonly SettingsManagerInterface $settingsManager, private readonly SettingsManagerInterface $settingsManager,
private readonly SettingsFormFactoryInterface $settingsFormFactory private readonly SettingsFormFactoryInterface $settingsFormFactory,
private readonly SubmittedPageStorage $browserHtmlStorage,
) )
{ {
@ -221,7 +223,7 @@ class InfoProviderController extends AbstractController
} }
#[Route('/from_url', name: 'info_providers_from_url')] #[Route('/from_url', name: 'info_providers_from_url')]
public function fromURL(Request $request, GenericWebProvider $provider, CreateFromUrlHelper $fromUrlHelper): Response public function fromURL(Request $request, CreateFromUrlHelper $fromUrlHelper): Response
{ {
$this->denyAccessUnlessGranted('@info_providers.create_parts'); $this->denyAccessUnlessGranted('@info_providers.create_parts');
@ -242,6 +244,12 @@ class InfoProviderController extends AbstractController
$no_cache = $form->get('no_cache')->getData(); $no_cache = $form->get('no_cache')->getData();
$skip_delegation = $form->get('skip_delegation')->getData(); $skip_delegation = $form->get('skip_delegation')->getData();
$submittedPageToken = $request->request->get('submitted_page_token', null);
if ($submittedPageToken !== null && $submittedPageToken !== '') {
$url = $this->browserHtmlStorage->retrieve($submittedPageToken)->url;
}
try { try {
//It's okay if we use the cached results here, as its just for convenience //It's okay if we use the cached results here, as its just for convenience
$searchResult = $this->infoRetriever->searchByKeyword( $searchResult = $this->infoRetriever->searchByKeyword(
@ -249,6 +257,7 @@ class InfoProviderController extends AbstractController
providers: [$method], providers: [$method],
options: [ options: [
InfoProviderInterface::OPTION_SKIP_DELEGATION => $skip_delegation, InfoProviderInterface::OPTION_SKIP_DELEGATION => $skip_delegation,
InfoProviderInterface::OPTION_SUBMITTED_PAGE_TOKEN => $submittedPageToken,
] ]
); );
@ -262,6 +271,7 @@ class InfoProviderController extends AbstractController
'providerId' => $searchResult->provider_id, 'providerId' => $searchResult->provider_id,
'no_cache' => $no_cache ? 1 : null, 'no_cache' => $no_cache ? 1 : null,
'skip_delegation' => $skip_delegation ? 1 : null, 'skip_delegation' => $skip_delegation ? 1 : null,
'submitted_page_token' => $submittedPageToken ?: null,
]); ]);
} }
} catch (ExceptionInterface $e) { } catch (ExceptionInterface $e) {
@ -272,6 +282,7 @@ class InfoProviderController extends AbstractController
return $this->render('info_providers/from_url/from_url.html.twig', [ return $this->render('info_providers/from_url/from_url.html.twig', [
'form' => $form, 'form' => $form,
'partDetail' => $partDetail, 'partDetail' => $partDetail,
'recentBrowserPages' => $this->browserHtmlStorage->getRecentPages(),
]); ]);
} }

View file

@ -63,7 +63,7 @@ class SubmittedPageStorage
$session->get(self::SESSION_KEY, []), $session->get(self::SESSION_KEY, []),
static fn(string $u): bool => $u !== $page->token, static fn(string $u): bool => $u !== $page->token,
)); ));
array_unshift($tokens, $page->url); array_unshift($tokens, $page->token);
$session->set(self::SESSION_KEY, array_slice($tokens, 0, self::MAX_RECENT)); $session->set(self::SESSION_KEY, array_slice($tokens, 0, self::MAX_RECENT));
return $page->token; return $page->token;

View file

@ -33,5 +33,31 @@
</div> </div>
{{ form_row(form.submit) }} {{ form_row(form.submit) }}
{% if recentBrowserPages is not empty %}
<hr class="{{ offset_label }} mt-4">
<div class="row mb-1">
<label class="col-form-label {{ col_label }}">
{% trans %}browser_plugin.recent_pages.title{% endtrans %}
</label>
<div class="{{ col_input }}">
<p class="text-muted small mb-2">{% trans %}browser_plugin.recent_pages.help{% endtrans %}</p>
<div class="list-group list-group-numbered">
{% for page in recentBrowserPages %}
<button type="submit" name="submitted_page_token" value="{{ page.token }}" formnovalidate
class="list-group-item d-flex justify-content-between align-items-start text-start">
<div class="ms-2 me-auto">
<div class="fw-bold">{{ page.title }}</div>
<small class="text-muted">{{ page.url }}</small>
</div>
<span class="badge text-bg-primary rounded-pill">{{ page.submittedAt|format_time("short") }}</span>
</button>
{% endfor %}
</div>
</div>
</div>
{% endif %}
{{ form_end(form) }} {{ form_end(form) }}
{% endblock %} {% endblock %}

View file

@ -13607,5 +13607,23 @@ Buerklin-API Authentication server:
<target>Host URL</target> <target>Host URL</target>
</segment> </segment>
</unit> </unit>
<unit id="mL.rY_F" name="browser_plugin.session_expired">
<segment state="translated">
<source>browser_plugin.session_expired</source>
<target>The browser plugin session has expired. Please submit the page from your browser extension again.</target>
</segment>
</unit>
<unit id="kuDv.So" name="browser_plugin.recent_pages.title">
<segment state="translated">
<source>browser_plugin.recent_pages.title</source>
<target>Recent browser submissions</target>
</segment>
</unit>
<unit id="AjNj8wk" name="browser_plugin.recent_pages.help">
<segment state="translated">
<source>browser_plugin.recent_pages.help</source>
<target>Pages recently submitted from your browser extension. Click to create a part using the captured HTML.</target>
</segment>
</unit>
</file> </file>
</xliff> </xliff>