first commit

This commit is contained in:
Sven Wappler
2021-04-17 00:26:33 +02:00
commit 866c63cc63
813 changed files with 100696 additions and 0 deletions

View File

@@ -0,0 +1,183 @@
{namespace solr=WapplerSystems\Meilisearch\ViewHelpers}
{namespace core=TYPO3\CMS\Core\ViewHelpers}
<f:layout name="Backend/WithPageTree"/>
<f:section name="Main">
<div role="tabpanel">
<ul class="nav nav-tabs t3js-tabs" role="tablist" id="tabs-tab" data-store-last-tab="1">
<li role="presentation" class="t3js-tabmenu-item active">
<a href="#synonyms-tab" title="" aria-controls="synonyms-tab" role="tab" data-toggle="tab">
Synonyms
</a>
</li>
<li role="presentation" class="t3js-tabmenu-item ">
<a href="#stopwords-tab" title="" aria-controls="stopwords-tab" role="tab" data-toggle="tab">
Stop Words
</a>
</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="synonyms-tab">
<div class="panel panel-tab">
<div class="panel-body">
<f:render section="Synonyms" arguments="{_all}"/>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="stopwords-tab">
<div class="panel panel-tab">
<div class="panel-body">
<f:render section="StopWords" arguments="{_all}"/>
</div>
</div>
</div>
</div>
</div>
</f:section>
<f:section name="Synonyms">
By defining synonyms you can allow to find documents by words that do not occur in the documents but have the same meaning:<br/>
<b>Note:</b> The word that you want replace with a synonym needs to appear on <b>both</b> sides when you want to find it with the term itself later!<br/>
Example:<br />
<ul>
<li><b>"smartphone" => "smartphone, cellphone, mobile, mobilephone"</b>
<ul>
<li>will match <b>"smartphone, cellphone, mobile, mobilephone"</b></li>
<li>And when "smartphone" were missing on the right side, then you could not find the documents with "smartphone" anymore!</li>
</ul>
</li>
</ul>
<b>Note: The changes do not apply on the fly, you need to reindex all the pages whith occurrences of changed synonyms.</b>
<f:if condition="{synonyms}">
<f:then>
<h3>Manage Synonyms</h3>
<table class="table table-condensed table-hover table-striped">
<thead>
<tr class="t3-row-header">
<th>Base Word</th><th>Synonyms</th>
<th>
<f:link.action action="deleteAllSynonyms" title="Delete all synonyms" class="btn btn-default btn-sm">
<core:icon identifier="actions-edit-delete"/>
</f:link.action>
<f:link.action action="exportSynonyms" title="Export all synonyms" class="btn btn-default btn-sm">
<core:icon identifier="actions-document-export-csv"/>
</f:link.action>
</th>
</tr>
</thead>
<tbody>
<f:for each="{synonyms}" key="baseWord" as="synonymList">
<tr>
<td>{baseWord}</td>
<td>{synonymList}</td>
<td>
<f:link.action action="deleteSynonyms" arguments="{baseWord:'{baseWord}'}" title="Remove Synonym Mapping"><core:icon identifier="actions-edit-delete"/></f:link.action>
</td>
</tr>
</f:for>
</tbody>
</table>
</f:then>
<f:else>
<f:be.infobox state="-1">
No synonyms configured yet.
</f:be.infobox>
</f:else>
</f:if>
<h3>Add Synonyms (lowercase)</h3>
<div class="section">
<f:form action="addSynonyms" id="add-synonyms">
<div class="form-group">
<label for="baseWord">Base Word</label>
<f:form.textfield id="baseWord" name="baseWord" class="form-control" />
<span class="example">f.e. iphone</span>
</div>
<div class="form-group">
<label for="synonyms">Synonyms</label>
<f:form.textfield id="synonyms" name="synonyms" class="form-control" />
<span class="example">comma-separated; f.e. smartphone, cellphone</span>
</div>
<div class="form-group">
<f:form.checkbox id="overrideExistingSingle" name="overrideExisting" value="1" />
<label for="overrideExistingSingle"> Override, if synonym already exists</label>
</div>
<div class="submit">
<f:form.submit value="Add Synonyms" class="btn btn-sm btn-default"/>
</div>
</f:form>
</div>
<h3>Upload Synonym List</h3>
<div class="section">
<f:form action="importSynonymList" id="upload-synonyms" method="post" enctype="multipart/form-data">
<div class="form-group">
<f:form.upload id="synonymFileUpload" name="synonymFileUpload" />
</div>
<div class="form-group">
<f:form.checkbox id="overrideExisting" name="overrideExisting" value="1" />
<label for="overrideExisting"> Override synonym, if synonym already exists</label>
</div>
<div class="form-group">
<f:form.checkbox id="deleteSynonymsBefore" name="deleteSynonymsBefore" value="1" />
<label for="deleteSynonymsBefore"> Replace complete synonym list</label>
</div>
<div class="submit">
<f:form.submit value="Upload file" class="btn btn-sm btn-default"/>
</div>
</f:form>
</div>
</f:section>
<f:section name="StopWords">
<p> Stop words allow you to specify a list of words that will be discarded during indexing.<br/>
Usually they are very small and very common words (such as "the" and "and") that often have <br/>
little bearing on whether a document is a good match or not.<br/>
The format is one word per line.</p>
<h3>Stop Word List (one per line, lowercase)</h3>
<div class="section section-with-header">
<div class="row">
<div class="col-md-12">
<f:if condition="{stopWordsCount} == 0">
<f:be.infobox state="-1">
The stop word list is empty.
</f:be.infobox>
</f:if>
<f:form action="saveStopWords" id="edit-stopwords">
<f:form.textarea name="stopWords" rows="20" cols="50" style="width: auto;" value="{stopWords}"/>
<div class="submit">
<f:form.submit value="Save Stop Word List" class="btn btn-sm btn-default"/>
<f:if condition="{stopWordsCount} > 0">
<f:link.action action="exportStopWords" title="Export StopWords" class="btn btn-default btn-sm">
<core:icon identifier="actions-document-export-csv"/>
</f:link.action>
</f:if>
</div>
</f:form>
</div>
</div>
</div>
<h3>Upload StopWords List</h3>
<div class="section section-with-header">
<f:form action="importStopWordList" id="upload-stopwords" method="post" enctype="multipart/form-data">
<div class="form-group">
<f:form.upload id="stopwordsFileUpload" name="stopwordsFileUpload" />
</div>
<div class="form-group">
<f:form.checkbox id="replaceStopwords" name="replaceStopwords" value="1" checked="1"/>
<label for="replaceStopwords"> Override complete list</label>
</div>
<div class="submit">
<f:form.submit value="Upload file" class="btn btn-sm btn-default"/>
</div>
</f:form>
</div>
</f:section>

View File

@@ -0,0 +1,72 @@
{namespace solr=WapplerSystems\Meilisearch\ViewHelpers}
<f:layout name="Backend/WithPageTree"/>
<f:section name="Main">
<f:be.pageRenderer includeRequireJsModules="{0:'TYPO3/CMS/Solr/FormModal'}"/>
<div class="row">
<div class="col-xs-12">
<h1>{f:translate(key: 'solr.backend.index_administration.label', default: 'Index Administration')}</h1>
<p class="lead"><f:translate key="solr.backend.index_administration.description" /></p>
</div>
</div>
<h3>Reload Core Configuration</h3>
<div class="row">
<div class="col-xs-3">
<f:form action="reloadIndexConfiguration">
<f:form.submit value="Reload Configuration" class="btn btn-sm btn-default" />
</f:form>
</div>
<div class="col-xs-9 action-description">
<p>
A core in Solr is what holds your index. When changing core/index configuration
such as synonyms, stop words, or protected words you need to reload the core
to make the changes become active. To reload configuration you can either restart
the whole Solr server or simply reload a specific core.
Here you can reload the site's cores/indexes.
</p>
</div>
</div>
<h3>Empty Index</h3>
<div class="row">
<div class="col-xs-3">
<f:form action="emptyIndex" method="POST">
<f:form.submit class="btn btn-sm btn-default btn-danger t3js-modal-formsubmit-trigger"
data="{title: 'Please confirm', content: 'Are you sure you want to clear the index? All Solr documents will be removed.', severity: 'warning'}"
value="Empty Index"/>
</f:form>
</div>
<div class="col-xs-9 action-description">
<p>
This will simply empty the site's index. When doing so it will take
care of
only deleting the currently selected site's documents even if
you index multiple sites into one index.
</p>
</div>
</div>
<h3>
<f:translate key="solr.backend.index_queue_module.button.clear_index_queue"/>
</h3>
<div class="row">
<div class="col-xs-3">
<f:form action="clearIndexQueue" method="POST">
<f:form.submit class="btn btn-sm btn-default btn-danger t3js-modal-formsubmit-trigger"
data="{title: 'Please confirm', content: 'Are you sure you want to clear the Index Queue?', severity: 'warning'}"
value="{f:translate(key:'solr.backend.index_queue_module.button.clear_index_queue')}"/>
</f:form>
</div>
<div class="col-xs-9 action-description">
<p>
This will empty the Index Queue. It will take care of only deleting
the currently selected site's Index Queue entries.
You will have to re-initialize the Index Queue afterwards.
</p>
</div>
</div>
</f:section>

View File

@@ -0,0 +1,154 @@
{namespace solr=WapplerSystems\Meilisearch\ViewHelpers}
<f:layout name="Backend/WithPageTree"/>
<f:section name="Main">
<f:be.pageRenderer includeCssFiles="{0: '{f:uri.resource(path:\'StyleSheets/Backend/IndexQueueModule.css\')}'}" includeRequireJsModules="{0:'TYPO3/CMS/Solr/FormModal'}"/>
<h1>Index Queue</h1>
<p class="lead"><f:translate key="solr.backend.index_queue_module.description" /></p>
<hr class="section-divider" />
<f:if condition="{indexqueue_statistics.totalCount} > 0">
<div class="row section-with-header">
<div class="col-md-12">
<h2>
<f:translate key="solr.backend.index_queue_module.header_status"/>
</h2>
<div class="row">
<div class="col-md-12">
<div class="progress">
<f:if condition="{indexqueue_statistics.successCount} > 0">
<div class="progress-bar progress-bar-success"
style="width: {indexqueue_statistics.successPercentage}%"
title="{f:translate(key:'solr.backend.index_queue_module.status.indexed')}: {indexqueue_statistics.successCount}/{indexqueue_statistics.totalCount} ({indexqueue_statistics.successPercentage}%)">
<f:translate key="solr.backend.index_queue_module.status.indexed"/>
</div>
</f:if>
<f:if condition="{indexqueue_statistics.pendingCount} > 0">
<div class="progress-bar progress-bar-warning"
style="width: {indexqueue_statistics.pendingPercentage}%"
title="{f:translate(key:'solr.backend.index_queue_module.status.pending')}: {indexqueue_statistics.pendingCount}/{indexqueue_statistics.totalCount} ({indexqueue_statistics.pendingPercentage}%)">
<f:translate key="solr.backend.index_queue_module.status.pending"/>
</div>
</f:if>
<f:if condition="{indexqueue_statistics.failedCount} > 0">
<div class="progress-bar progress-bar-danger"
style="width: {indexqueue_statistics.failedPercentage}%"
title="{f:translate(key:'solr.backend.index_queue_module.status.errors')}: {indexqueue_statistics.failedCount}/{indexqueue_statistics.totalCount} ({indexqueue_statistics.failedPercentage}%)">
<f:translate key="solr.backend.index_queue_module.status.errors"/>
</div>
</f:if>
</div>
<f:form action="doIndexingRun" method="POST">
<f:form.submit class="btn btn-sm btn-default"
value="{f:translate(key:'solr.backend.index_queue_module.index_now')}"/>
</f:form>
</div>
</div>
<hr />
<f:if condition="{indexqueue_errors}">
<div class="row">
<div class="col-md-12">
<h2>
<f:translate key="solr.backend.index_queue_module.errors.headline"/>
</h2>
<table class="table table-condensed table-hover table-striped">
<tr>
<th>
<f:translate key="solr.backend.index_queue_module.errors.id"/>
</th>
<th>
<f:translate key="solr.backend.index_queue_module.errors.item_type"/>
</th>
<th>
<f:translate key="solr.backend.index_queue_module.errors.item_uid"/>
</th>
<th></th>
</tr>
<f:for each="{indexqueue_errors}" as="item">
<tr>
<td>{item.uid}</td>
<td>{item.item_type}</td>
<td>{item.item_uid}</td>
<td>
<f:link.action action="showError" arguments="{indexQueueItemId: item.uid}">
<f:translate key="solr.backend.index_queue_module.errors.show_button"/>
</f:link.action>
</td>
</tr>
</f:for>
</table>
<f:form action="resetLogErrors" method="POST">
<f:form.submit class="btn btn-sm btn-default"
value="{f:translate(key:'solr.backend.index_queue_module.errors.reset_button')}"/>
</f:form>
</div>
</div>
</f:if>
</div>
</div>
</f:if>
<hr class="section-divider" />
<div class="row section-with-header">
<div class="col-md-12">
<h2>
<f:translate key="solr.backend.index_queue_module.header_init" />
</h2>
<f:form name="editform" action="initializeIndexQueue">
<div class="t3js-formengine-palette-field index-queue-init-form">
<f:format.raw>{indexQueueInitializationSelector}</f:format.raw>
</div>
<f:form.submit name="initializeIndexQueue" value="Queue Selected Content for Indexing" class="btn btn-sm btn-default"/>
<solr:backend.button.helpButton title="Index Queue Initialization" description="{f:translate(key:'solr.backend.index_queue_module.help')}" />
</f:form>
</div>
</div>
<f:comment><!-- Show this button only if module indexadministration is allowed for be user/group --></f:comment>
<solr:backend.security.ifHasAccessToModule extension="Solr" main="searchbackend" sub="indexadministration">
<f:then>
<hr class="section-divider" />
<div class="row section-with-header">
<div class="col-md-3">
<f:form addQueryString="1"
additionalParams="{route: '/searchbackend/SolrIndexadministration/', tx_meilisearch_searchbackend_solrindexadministration:{controller: 'Backend\\Search\\IndexAdministrationModule', action: 'clearIndexQueue', id: '{pageUID}', fromQueue: 'true'}}">
<f:form.submit class="btn btn-sm btn-default btn-danger t3js-modal-formsubmit-trigger"
data="{title: 'Please confirm', content: 'Are you sure you want to clear the Index Queue?', severity: 'warning'}"
value="{f:translate(key:'solr.backend.index_queue_module.button.clear_index_queue')}"/>
</f:form>
</div>
<div class="col-md-9 action-description">
<h3>
<f:translate key="solr.backend.index_queue_module.button.clear_index_queue"/>
</h3>
<p>
This will empty the Index Queue. It will take care of only deleting
the currently selected site's Index Queue entries.
You will have to re-initialize the Index Queue afterwards.
</p>
</div>
</div>
</f:then>
</solr:backend.security.ifHasAccessToModule>
</f:section>

View File

@@ -0,0 +1,13 @@
<html
xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
data-namespace-typo3-fluid="true">
<f:if condition="{indexQueueItem.errors}">
<h1><f:translate key="solr.backend.index_queue_module.error_details"/> (uid: <code>{indexQueueItem.indexQueueUid}</code>, type: <code>{indexQueueItem.type}</code>):</h1>
<pre class="alert alert-danger">{indexQueueItem.errors}</pre>
<f:link.action class="btn btn-default">
{core:icon(identifier:'actions-view-go-back')} <f:translate key="solr.backend.index_queue_module.back"/>
</f:link.action>
</f:if>
</html>

View File

@@ -0,0 +1,8 @@
{namespace solr=WapplerSystems\Meilisearch\ViewHelpers}
<f:layout name="Backend/WithPageTree"/>
<f:section name="Main">
<f:for each="{documents}" as="document">
<f:render partial="Backend/ApacheSolr/SingleDocument" arguments="{document: document, documentType: documentType, documentsCount: '{f:count(subject: documents)}'}"/>
</f:for>
</f:section>

View File

@@ -0,0 +1,334 @@
{namespace solr=WapplerSystems\Meilisearch\ViewHelpers}
<f:layout name="Backend/WithPageTree"/>
<f:section name="Main">
<div role="tabpanel">
<ul class="nav nav-tabs t3js-tabs" role="tablist" id="tabs-tab" data-store-last-tab="1">
<li role="presentation" class="t3js-tabmenu-item active">
<a href="#connections-tab" title="" aria-controls="tab-1" role="tab" data-toggle="tab">
Connections
</a>
</li>
<li role="presentation" class="t3js-tabmenu-item ">
<a href="#statistics-tab" title="" aria-controls="tab-3" role="tab" data-toggle="tab">
Statistics
</a>
</li>
<li role="presentation" class="t3js-tabmenu-item ">
<a href="#index_fields-tab" title="" aria-controls="tab-2" role="tab" data-toggle="tab">
Index Fields
</a>
</li>
<li role="presentation" class="t3js-tabmenu-item">
<a href="#index_inspector-tab" title="" aria-controls="tab-2" role="tab" data-toggle="tab">
Index Documents
</a>
</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="connections-tab">
<div class="panel panel-tab">
<div class="panel-body">
<f:render section="ConnectionInfos" arguments="{_all}"/>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="statistics-tab">
<div class="panel panel-tab">
<div class="panel-body">
<f:render section="Statistics" arguments="{_all}"/>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="index_fields-tab">
<div class="panel panel-tab">
<div class="panel-body">
<f:render section="IndexFields" arguments="{_all}"/>
</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="index_inspector-tab">
<div class="panel panel-tab">
<div class="panel-body">
<f:render section="IndexInspector" arguments="{_all}"/>
</div>
</div>
</div>
</div>
</div>
</f:section>
<f:comment><!-- Sections --></f:comment>
<f:section name="ConnectionInfos">
<h2>Site: {site.label}</h2>
<f:if condition="{connectedHosts}">
<f:be.infobox title="Following Apache Solr servers have been contacted:" state="0">
<ul>
<f:for each="{connectedHosts}" as="connectedHost">
<li>{connectedHost}</li>
</f:for>
</ul>
</f:be.infobox>
</f:if>
<f:if condition="{missingHosts}">
<f:be.infobox title="Unable to contact following Apache Solr servers:" state="2">
<ul>
<f:for each="{missingHosts}" as="missingHost">
<li>{missingHost}</li>
</f:for>
</ul>
</f:be.infobox>
</f:if>
<f:if condition="{invalidPaths}">
<f:be.infobox title="Following paths are not valid:" state="1">
<ul>
<f:for each="{invalidPaths}" as="invalidPath">
<li>{invalidPath}</li>
</f:for>
</ul>
<p>Path should not contain the characters "*, ?, <, >, |, :, or #"!</p>
</f:be.infobox>
</f:if>
<hr class="double" />
Used domain: {site.domain}
<hr class="double" />
API key: {apiKey}
<hr class="double" />
No solr server running? You can use <strong><a href="http://www.hosted-solr.com/" target="_blank">hosted-solr.com</a></strong> to setup a solr core with just a few clicks.
</f:section>
<f:section name="Statistics">
<!-- TODO add buttons to select time frame [last 24h] [last 30 days] [all] -->
<f:be.pageRenderer
includeJsFiles="{
0: '{f:uri.resource(path:\'JavaScript/SearchStatistics.js\')}'
}"
/>
<div class="row">
<div class="col-md-12">
<script type="application/javascript">
var queryLabels = <f:format.raw>{queriesChartLabels}</f:format.raw>;
var queryData = {queriesChartData};
</script>
<canvas id="queriesOverTime"></canvas>
</div>
</div>
<f:if condition="{top_search_phrases}">
<div class="row">
<div class="col-md-12">
<h2>
<f:translate key="solr.backend.search_statistics_module.top_search_phrases"/>
</h2>
<ul>
<f:for each="{top_search_phrases}" as="phrase">
<li>
{phrase.keywords} ({phrase.count})
</li>
</f:for>
</ul>
</div>
</div>
<hr class="section-divider" />
</f:if>
<f:if condition="{top_search_phrases_without_hits}">
<div class="row section-with-header">
<div class="col-md-12">
<h2>
<f:translate key="solr.backend.search_statistics_module.top_search_phrases_without_hits"/>
</h2>
<ul>
<f:for each="{top_search_phrases_without_hits}" as="phrase">
<li>
{phrase.keywords} ({phrase.count})
</li>
</f:for>
</ul>
</div>
</div>
<hr class="section-divider" />
</f:if>
<div class="row section-with-header">
<div class="col-md-12">
<h2>
<f:translate key="solr.backend.search_statistics_module.search_phrases_header"/>
</h2>
<f:if condition="{search_phrases_statistics}">
<f:then>
<table class="table table-condensed table-hover table-striped">
<thead>
<tr class="t3-row-header">
<th class="nowrap">&nbsp;</th>
<th>
<f:translate key="solr.backend.search_statistics_module.item_phrase"/>
</th>
<th>
<f:translate key="solr.backend.search_statistics_module.item_count"/>
</th>
<th>
<f:translate key="solr.backend.search_statistics_module.results"/>
</th>
<th>
<f:translate key="solr.backend.search_statistics_module.percentage"/>
</th>
</tr>
</thead>
<tbody>
<f:for each="{search_phrases_statistics}" as="item" iteration="i">
<tr>
<td class="nowrap"><strong>{i.cycle}.</strong></td>
<td>{item.keywords}</td>
<td>{item.count}</td>
<td>{item.hits -> f:format.number(decimals: 1)}</td>
<td>{item.percent -> f:format.number(decimals: 1)}%</td>
</tr>
</f:for>
</tbody>
</table>
</f:then>
<f:else>
<f:be.infobox state="2">
<f:translate key="solr.backend.search_statistics_module.no_records_found"/>
</f:be.infobox>
</f:else>
</f:if>
</div>
</div>
</f:section>
<f:section name="IndexFields">
<div class="panel-group" id="index-fields_accordion">
<f:for each="{indexFieldsInfoByCorePaths}" as="indexFieldsInfoForCore" iteration="iterator">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<f:if condition="{indexFieldsInfoForCore.coreMetrics.numberOfDocuments}">
<f:then>
<a data-toggle="collapse" data-parent="#index-fields_accordion" href="#collapse-core{iterator.index}">{indexFieldsInfoForCore.corePath}</a>
</f:then>
<f:else>
<a>{indexFieldsInfoForCore.corePath} is empty!</a>
</f:else>
</f:if>
</h4>
</div>
<div id="collapse-core{iterator.index}" class="panel-collapse collapse {f:if(condition: '{iterator.isFirst}', then: 'in')}">
<div class="panel-body">
<f:render partial="Backend/ApacheSolr/FieldTypesForSingleCore" arguments="{indexFieldsInfoForCore: indexFieldsInfoForCore}"/>
</div>
</div>
</div>
</f:for>
</div>
</f:section>
<f:section name="IndexInspector">
<div class="panel-group" id="index-inspector_accordion">
<f:for each="{indexInspectorDocumentsByLanguageAndType}" as="indexInspectorDocumentsByType" key="language" iteration="currentCore">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<a href="#panel-group3document-core-{currentCore.index}" data-toggle="collapse">{indexInspectorDocumentsByType.core.corepath}</a>
<a href="#panel-group3document-core-{currentCore.index}" title="Collapse table" class="pull-right" data-toggle="collapse">
<core:icon identifier="actions-view-list-expand" size="small"/><f:comment><!-- @todo: make Icon toggable between actions-view-list-collapse/actions-view-list-expand --></f:comment>
</a>
</h3>
</div>
<div id="panel-group3document-core-{currentCore.index}" class="panel-collapse collapse {f:if(condition: '{iterator.isFirst}', then: 'in')}">
<div class="panel-body">
<f:for each="{indexInspectorDocumentsByType.documents}" as="documents" key="documentType">
<f:if condition="{documents}"> <f:comment><!-- Don't show emty panel groups if array with documents is empty. --></f:comment>
<f:render section="PanelGroupForDocumentType" arguments="{_all}"/>
</f:if>
</f:for>
</div>
</div>
</div>
</f:for>
</div>
<f:section name="PanelGroupForDocumentType">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
<a href="#panel-group4document-type-{currentCore.index}-{documentType}" data-toggle="collapse">Type: {documentType} ({f:count(subject: documents)})</a>
<a href="#panel-group4document-type-{currentCore.index}-{documentType}" title="Collapse table" class="pull-right" data-toggle="collapse">
<core:icon identifier="actions-view-list-expand" size="small"/><f:comment><!-- @todo: make Icon toggable between actions-view-list-collapse/actions-view-list-expand --></f:comment>
</a>
</h3>
</div>
<div id="panel-group4document-type-{currentCore.index}-{documentType}" class="panel-collapse collapse {f:if(condition: '{f:count(subject: documentsByType)} < 2', then: 'in', else: '')}">
<div class="panel-body">
<div class="panel-group">
<table class="table table-striped table-condensed">
<tr>
<th>Id</th>
<th>Title</th>
<th>Url</th>
<th>Created</th>
<th>Indexed</th>
<th>Actions</th>
</tr>
<f:for each="{documents}" as="document">
<tr>
<td>{document.uid}</td>
<td><f:format.crop maxCharacters="20">{document.title}</f:format.crop></td>
<td><f:format.crop maxCharacters="40">{document.url}</f:format.crop></td>
<td><f:format.date format="d.m.Y H:i:s">{document.created}</f:format.date></td>
<td><f:format.date format="d.m.Y H:i:s">{document.indexed}</f:format.date></td>
<td>
<span class="btn btn-default">
<f:link.action action="documentsDetails" arguments="{uid: document.uid, type: document.type, languageUid: language, pageId: pageId}" title="Show details">
<core:icon identifier="actions-document-view" />
</f:link.action>
</span>
<f:comment>
<!-- The additionalPrams M:'...' can be removed whe TYPO3 8 support will be dropped. -->
</f:comment>
<solr:backend.security.ifHasAccessToModule extension="Solr" main="searchbackend" sub="indexqueue">
<span class="btn btn-default">
<f:link.action action="requeueDocument" arguments="{uid: document.uid, type: document.type}"
controller="Backend\Search\IndexQueueModule"
pluginName="searchbackend_SolrIndexqueue"
additionalParams="{M:'searchbackend_SolrIndexqueue',route: 'searchbackend_SolrIndexqueue'}" title="ReQueue for all languages">
<core:icon identifier="actions-refresh" />
</f:link.action>
</span>
</solr:backend.security.ifHasAccessToModule>
</td>
</tr>
</f:for>
</table>
</div>
</div>
</div>
</div>
</f:section>
</f:section>