Skip to content
Snippets Groups Projects
Commit 791496ca authored by Adam G-H's avatar Adam G-H Committed by Chris Wells
Browse files

Issue #3455917 by phenaproxima, vbouchet, tim.plunkett, chrisfromredfin: The...

Issue #3455917 by phenaproxima, vbouchet, tim.plunkett, chrisfromredfin: The project detail page should take a project ID, not a machine name
parent 095be78a
No related branches found
No related tags found
1 merge request!525Identify projects by UUID to the backend
Pipeline #208831 passed with warnings
......@@ -19,11 +19,11 @@ project_browser.api_project_get_all:
#options:
# no_cache: 'TRUE'
project_browser.browse:
path: '/admin/modules/browse/{module_name}'
path: '/admin/modules/browse/{id}'
defaults:
_controller: '\Drupal\project_browser\Controller\BrowserController::browse'
_title: 'Browse projects'
module_name: ''
id: null
requirements:
_permission: 'administer modules'
project_browser.settings:
......
......@@ -63,18 +63,18 @@ class BrowserController extends ControllerBase {
* rendered. For example, 'https//drupal-site/admin/modules/browse/ctools'
* will display the details for ctools.
*
* @param string $module_name
* Module for which the detailed page is built.
* @param string|null $id
* The project ID, if any.
*
* @return array
* A render array.
*/
public function browse($module_name) {
public function browse(?string $id = NULL) {
$request = $this->requestStack->getCurrentRequest();
$current_sources = $this->enabledSource->getCurrentSources();
$ui_install_enabled = (bool) $this->config('project_browser.admin_settings')->get('allow_ui_install') && (bool) $this->installReadiness;
if (!empty($current_sources['drupalorg_mockapi']) && !$module_name) {
if (array_key_exists('drupalorg_mockapi', $current_sources) && empty($id)) {
$this->messenger()
->addStatus($this->t('Project Browser is currently a prototype, and the projects listed may not be up to date with Drupal.org. For the most updated list of projects, visit <a href=":url">:url</a>', [':url' => 'https://www.drupal.org/project/project_module']))
->addStatus($this->t('Your feedback and input are welcome at <a href=":url">:url</a>', [':url' => 'https://www.drupal.org/project/issues/project_browser']));
......
......@@ -45,11 +45,30 @@ class ProjectBrowserEndpointController extends ControllerBase {
* Typically a project listing.
*/
public function getAllProjects(Request $request) {
$id = $request->query->get('id');
if ($id) {
return new JsonResponse($this->enabledSource->getStoredProject($id));
}
$current_sources = $this->enabledSource->getCurrentSources();
if (!$current_sources) {
return new JsonResponse([], Response::HTTP_ACCEPTED);
}
$query = $this->buildQuery($request);
return new JsonResponse($this->enabledSource->getProjects($query));
}
/**
* Builds the query based on the current request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The request.
*
* @return array
* See \Drupal\project_browser\EnabledSourceHandler::getProjects().
*/
private function buildQuery(Request $request): array {
// Validate and build query.
$query = [
'page' => (int) $request->query->get('page', 0),
......@@ -101,7 +120,7 @@ class ProjectBrowserEndpointController extends ControllerBase {
$query['tabwise_categories'] = $tabwise_categories;
}
return new JsonResponse($this->enabledSource->getProjects($query));
return $query;
}
/**
......
......@@ -119,8 +119,13 @@ class EnabledSourceHandler implements LoggerAwareInterface, EventSubscriberInter
// name, which are unlikely to change. This isn't security-sensitive,
// so SHA1 is okay for this purpose.
$project->id = sha1($source_id . $project->packageName . $project->machineName);
// Remember the ID of the source plugin that exposed this project,
// since that information might be needed by the front-end.
$project->source = $source_id;
$this->keyValue->setIfNotExists($project->id, $project);
// Add activation data to the project.
// Add activation data to the project. This is volatile and should not
// be changed.
$this->getActivationData($project);
}
// Store each source's results for this query as a set of arguments to
......@@ -189,10 +194,10 @@ class EnabledSourceHandler implements LoggerAwareInterface, EventSubscriberInter
}
/**
* Looks up a previously stored project by its UUID.
* Looks up a previously stored project by its ID.
*
* @param string $uuid
* The project UUID. See ::getProjects() for where this is set.
* @param string $id
* The project ID. See ::getProjects() for where this is set.
*
* @return \Drupal\project_browser\ProjectBrowser\Project
* The project object, with activation status and commands added.
......@@ -200,8 +205,8 @@ class EnabledSourceHandler implements LoggerAwareInterface, EventSubscriberInter
* @throws \RuntimeException
* Thrown if the project is not found in the non-volatile data store.
*/
public function getStoredProject(string $uuid): Project {
$project = $this->keyValue->get($uuid) ?? throw new \RuntimeException("Project '$uuid' was not found in non-volatile storage.");
public function getStoredProject(string $id): Project {
$project = $this->keyValue->get($id) ?? throw new \RuntimeException("Project '$id' was not found in non-volatile storage.");
$this->getActivationData($project);
return $project;
}
......
......@@ -17,15 +17,30 @@ class Project implements \JsonSerializable {
/**
* A persistent ID for this project in non-volatile storage.
*
* This property is internal and should be ignored by source plugins.
*
* @var string
*
* @see \Drupal\project_browser\EnabledSourceHandler::getProjects()
*/
public string $id;
/**
* The ID of the source plugin which exposed this project.
*
* This property is internal and should be ignored by source plugins.
*
* @var string
*
* @see \Drupal\project_browser\EnabledSourceHandler::getProjects()
*/
public string $source;
/**
* The status of this project in the current site.
*
* This property is internal and should be ignored by source plugins.
*
* @var \Drupal\project_browser\ActivationStatus
*/
public ActivationStatus $status;
......@@ -33,6 +48,8 @@ class Project implements \JsonSerializable {
/**
* The instructions, if any, to activate this project.
*
* This property is internal and should be ignored by source plugins.
*
* @var string|\Drupal\Core\Url|null
*
* @see \Drupal\project_browser\ActivatorInterface::getInstructions()
......@@ -187,6 +204,7 @@ class Project implements \JsonSerializable {
'selector_id' => $this->getSelectorId(),
'commands' => $commands,
'id' => $this->id,
'source' => $this->source,
];
}
......
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
......@@ -8,7 +8,7 @@
const matches = window.location.pathname.match(
/\/admin\/modules\/browse\/([^/]+)/,
);
const moduleName = matches ? matches[1] : null;
const projectId = matches ? matches[1] : null;
let loading = true;
let data;
......@@ -18,20 +18,11 @@
loading = true;
const res = await fetch(url);
if (res.ok) {
data = await res.json();
Object.entries(data).forEach((item) => {
const [source, result] = item;
if (result.totalResults !== 0) {
$activeTab = source;
[project] = result.list;
projectExists = true;
}
});
project = await res.json();
$activeTab = project.source;
projectExists = true;
}
loading = false;
if (!projectExists) {
$searchString = moduleName;
}
return project;
}
......@@ -42,10 +33,10 @@
}
</script>
{#if !moduleName}
{#if !projectId}
<ProjectBrowser />
{:else}
{#await load(`${ORIGIN_URL}/drupal-org-proxy/project?machine_name=${moduleName}`)}
{#await load(`${ORIGIN_URL}/drupal-org-proxy/project?id=${projectId}`)}
{#if loading}
<Loading />
{/if}
......
......@@ -33,7 +33,7 @@
<a
id="{project.project_machine_name}_title"
class="pb-project__link"
href="{ORIGIN_URL}/admin/modules/browse/{project.project_machine_name}"
href="{ORIGIN_URL}/admin/modules/browse/{project.id}"
rel="noreferrer">{project.title}</a
>
</h3>
......
......@@ -590,7 +590,8 @@ class ProjectBrowserUiTest extends WebDriverTestBase {
$this->svelteInitHelper('text', 'Helvetica');
$page->clickLink('Helvetica');
$this->assertTrue($assert_session->waitForText('By Hel Vetica'));
$assert_session->addressEquals('admin/modules/browse/helvetica');
// cspell:disable-next-line
$assert_session->addressEquals('/admin/modules/browse/' . sha1('drupalorg_mockapidrupal/helveticahelvetica'));
$page->clickLink('Back to Browsing');
$assert_session->addressEquals('admin/modules/browse');
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment