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

Issue #3495112 by phenaproxima, chrisfromredfin, iamdroid: Export a coherent...

Issue #3495112 by phenaproxima, chrisfromredfin, iamdroid: Export a coherent set of information about a particular Project Browser instance in drupalSettings
parent 3caebcc4
No related branches found
No related tags found
1 merge request!650Create a drpalSettings.projectBrowser structure with consistent instance...
Pipeline #407494 passed
......@@ -38,7 +38,7 @@ function project_browser_help(string $route_name, RouteMatchInterface $route_mat
function project_browser_theme(): array {
return [
'project_browser_main_app' => [
'variables' => [],
'render element' => 'element',
],
];
}
......@@ -59,3 +59,13 @@ function project_browser_project_browser_source_info_alter(array &$definitions):
];
}
}
/**
* Preprocess function for the project_browser_main_app theme hook.
*
* @param array $variables
* The variables to pass to the template.
*/
function template_preprocess_project_browser_main_app(array &$variables): void {
$variables['id'] = $variables['element']['#id'];
}
......@@ -3,6 +3,7 @@
namespace Drupal\project_browser\Element;
use Drupal\Component\Utility\DeprecationHelper;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Extension\ModuleHandlerInterface;
......@@ -31,6 +32,7 @@ final class ProjectBrowser implements ElementInterface, ContainerFactoryPluginIn
private readonly ?InstallReadiness $installReadiness,
private readonly ModuleHandlerInterface $moduleHandler,
private readonly ConfigFactoryInterface $configFactory,
private readonly UuidInterface $uuid,
) {}
/**
......@@ -60,6 +62,7 @@ final class ProjectBrowser implements ElementInterface, ContainerFactoryPluginIn
$install_readiness,
$container->get(ModuleHandlerInterface::class),
$container->get(ConfigFactoryInterface::class),
$container->get(UuidInterface::class),
);
}
......@@ -94,8 +97,10 @@ final class ProjectBrowser implements ElementInterface, ContainerFactoryPluginIn
*/
public function attachProjectBrowserSettings(array $element): array {
assert($element['#source'] instanceof ProjectBrowserSourceInterface);
$element['#id'] ??= $this->uuid->generate();
$element['#attached']['drupalSettings']['project_browser'] = $this->getDrupalSettings(
$element['#source'],
$element['#id'],
$element['#max_selections'] ?? $this->configFactory->get('project_browser.admin_settings')->get('max_selections') ?? NULL,
);
return $element;
......@@ -106,6 +111,8 @@ final class ProjectBrowser implements ElementInterface, ContainerFactoryPluginIn
*
* @param \Drupal\project_browser\Plugin\ProjectBrowserSourceInterface $source
* The source plugin to query for projects.
* @param string $instance_id
* An identifier for the project browser application instance.
* @param int|null $max_selections
* (optional) The maximum number of project to install at once, or NULL for
* no limit. Defaults to NULL.
......@@ -113,7 +120,7 @@ final class ProjectBrowser implements ElementInterface, ContainerFactoryPluginIn
* @return array
* An array of Drupal settings.
*/
private function getDrupalSettings(ProjectBrowserSourceInterface $source, ?int $max_selections = NULL): array {
private function getDrupalSettings(ProjectBrowserSourceInterface $source, string $instance_id, ?int $max_selections = NULL): array {
if (is_int($max_selections) && $max_selections <= 0) {
throw new \InvalidArgumentException('$max_selections must be a positive integer or NULL.');
}
......@@ -139,6 +146,12 @@ final class ProjectBrowser implements ElementInterface, ContainerFactoryPluginIn
'package_manager' => $package_manager,
'filters' => (object) $source->getFilterDefinitions(),
'max_selections' => $max_selections,
'instances' => [
$instance_id => [
'source' => $source->getPluginId(),
'filters' => (object) $source->getFilterDefinitions(),
],
],
];
}
......
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.
<script>
import ProjectBrowser from './ProjectBrowser.svelte';
// eslint-disable-next-line import/prefer-default-export
export let id;
// Removes initial loader if it exists.
const initialLoader = document.getElementById('initial-loader');
if (initialLoader) {
......@@ -8,4 +11,4 @@
}
</script>
<ProjectBrowser />
<ProjectBrowser {id} />
......@@ -31,9 +31,12 @@
} from './constants';
// cspell:ignore tabwise
const { Drupal } = window;
const { Drupal, drupalSettings } = window;
const { announce } = Drupal;
export let id;
const settings = drupalSettings.project_browser.instances[id];
let data;
let rows = [];
let sources = [];
......@@ -286,6 +289,7 @@
on:selectCategory={onSelectCategory}
{searchText}
{refreshLiveRegion}
filterDefinitions={settings.filters}
/>
<div class="pb-layout__header">
......
<script>
import { filters } from '../stores';
export let name;
export let definition;
const { name, on_label: onLabel, off_label: offLabel } = definition;
export let changeHandler;
export let type;
export let onLabel;
export let offLabel;
</script>
<div class="filter-group__filter-options form-item">
......
......@@ -13,7 +13,7 @@
searchString,
sortCriteria,
} from '../stores';
import { FULL_MODULE_PATH, DARK_COLOR_SCHEME, FILTERS } from '../constants';
import { FULL_MODULE_PATH, DARK_COLOR_SCHEME } from '../constants';
const { Drupal } = window;
const dispatch = createEventDispatcher();
......@@ -39,6 +39,8 @@
let sortText = sortMatch.text;
let filterComponent;
export let filterDefinitions;
export async function onSearch(event) {
const state = stateContext.getState();
const detail = {
......@@ -74,7 +76,7 @@
if (event) {
const filterName = event.target.name;
if (FILTERS[filterName]._type === 'boolean') {
if (filterDefinitions[filterName]._type === 'boolean') {
$filters[filterName] = event.target.value === 'true';
} else {
$filters[filterName] = event.target.value;
......@@ -116,8 +118,6 @@
document.getElementById('pb-text').focus();
}
const filterDefinitions = Object.entries(FILTERS);
/**
* Resets the filters to the initial values provided by the source.
*
......@@ -127,7 +127,7 @@
*/
const resetFilters = (clear) => {
$filters = {};
filterDefinitions.forEach(([name, definition]) => {
Object.entries(filterDefinitions).forEach(([name, definition]) => {
let value;
if (clear) {
if (definition._type === 'boolean') {
......@@ -205,16 +205,14 @@
</button>
</div>
</div>
{#if filterDefinitions.length !== 0}
{#if Object.keys(filterDefinitions).length !== 0}
<div class="search__form-filters-container">
<div class="search__form-filters">
{#each filterDefinitions as [filterType, filter]}
{#each Object.entries(filterDefinitions) as [filterType, filter]}
{#if filter._type === 'boolean'}
<BooleanFilter
name={filter.name}
definition={filter}
type={filterType}
onLabel={filter.on_label}
offLabel={filter.off_label}
changeHandler={onAdvancedFilter}
/>
{:else if filter._type === 'multiple_choice'}
......
import App from './App.svelte';
const element = document.querySelector('[data-project-browser-instance-id]');
const app = new App({
// The #project-browser markup is returned by the project_browser.browse Drupal route.
target: document.querySelector('#project-browser'),
props: {},
target: element,
props: {
id: element.getAttribute('data-project-browser-instance-id'),
},
});
export default app;
......@@ -11,4 +11,4 @@
&nbsp;
</div>
</div>
<div id="project-browser"></div>
<div data-project-browser-instance-id="{{ id }}" id="project-browser"></div>
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