window.$events.listen('entity-select-confirm', this.handleConfirmedSelection.bind(this));
}
- show(callback, searchText = '') {
+ /**
+ * Show the selector popup.
+ * @param {Function} callback
+ * @param {String} searchText
+ * @param {EntitySelectorSearchOptions} searchOptions
+ */
+ show(callback, searchText = '', searchOptions = {}) {
this.callback = callback;
+ this.getSelector().configureSearchOptions(searchOptions);
this.getPopup().show();
if (searchText) {
import {onChildEvent} from '../services/dom';
import {Component} from './component';
+/**
+ * @typedef EntitySelectorSearchOptions
+ * @property entityTypes string
+ * @property entityPermission string
+ * @property searchEndpoint string
+ */
+
/**
* Entity Selector
*/
setup() {
this.elem = this.$el;
- this.entityTypes = this.$opts.entityTypes || 'page,book,chapter';
- this.entityPermission = this.$opts.entityPermission || 'view';
- this.searchEndpoint = this.$opts.searchEndpoint || '/search/entity-selector';
this.input = this.$refs.input;
this.searchInput = this.$refs.search;
this.loading = this.$refs.loading;
this.resultsContainer = this.$refs.results;
+ this.searchOptions = {
+ entityTypes: this.$opts.entityTypes || 'page,book,chapter',
+ entityPermission: this.$opts.entityPermission || 'view',
+ searchEndpoint: this.$opts.searchEndpoint || '',
+ };
+
this.search = '';
this.lastClick = 0;
this.setupListeners();
this.showLoading();
- this.initialLoad();
+
+ if (this.searchOptions.searchEndpoint) {
+ this.initialLoad();
+ }
+ }
+
+ /**
+ * @param {EntitySelectorSearchOptions} options
+ */
+ configureSearchOptions(options) {
+ Object.assign(this.searchOptions, options);
+ this.reset();
}
setupListeners() {
}
initialLoad() {
+ if (!this.searchOptions.searchEndpoint) {
+ throw new Error('Search endpoint not set for entity-selector load');
+ }
+
window.$http.get(this.searchUrl()).then(resp => {
this.resultsContainer.innerHTML = resp.data;
this.hideLoading();
}
searchUrl() {
- return `${this.searchEndpoint}?types=${encodeURIComponent(this.entityTypes)}&permission=${encodeURIComponent(this.entityPermission)}`;
+ const query = `types=${encodeURIComponent(this.searchOptions.entityTypes)}&permission=${encodeURIComponent(this.searchOptions.entityPermission)}`;
+ return `${this.searchOptions.searchEndpoint}?${query}`;
}
searchEntities(searchTerm) {
+ if (!this.searchOptions.searchEndpoint) {
+ throw new Error('Search endpoint not set for entity-selector load');
+ }
+
this.input.value = '';
const url = `${this.searchUrl()}&term=${encodeURIComponent(searchTerm)}`;
window.$http.get(url).then(resp => {
this.defaultDisplay = this.$refs.defaultDisplay;
this.buttonSep = this.$refs.buttonSeperator;
+ this.selectorEndpoint = this.$opts.selectorEndpoint;
+
this.value = this.input.value;
this.setupListeners();
}
const selectorPopup = window.$components.first('entity-selector-popup');
selectorPopup.show(entity => {
this.setValue(entity.id, entity.name);
+ }, '', {
+ searchEndpoint: this.selectorEndpoint,
+ entityTypes: 'page',
+ entityPermission: 'view',
});
}
const selectedText = selectionText || entity.name;
const newText = `[${selectedText}](${entity.link})`;
this.#replaceSelection(newText, newText.length, selectionRange);
- }, selectionText);
+ }, selectionText, {
+ searchEndpoint: '/search/entity-selector',
+ entityTypes: 'page,book,chapter,bookshelf',
+ entityPermission: 'view',
+ });
}
// Show draw.io if enabled and handle save.
text: entity.name,
title: entity.name,
});
- }, selectionText);
+ }, selectionText, {
+ searchEndpoint: '/search/entity-selector',
+ entityTypes: 'page,book,chapter,bookshelf',
+ entityPermission: 'view',
+ });
}
if (meta.filetype === 'image') {
editor.selection.collapse(false);
editor.focus();
- }, selectionText);
+ }, selectionText, {
+ searchEndpoint: '/search/entity-selector',
+ entityTypes: 'page,book,chapter,bookshelf',
+ entityPermission: 'view',
+ });
});
}
'name' => 'default_template_id',
'placeholder' => trans('entities.books_default_template_select'),
'value' => $book->default_template_id ?? null,
+ 'selectorEndpoint' => '/search/entity-selector-templates',
])
</div>
</div>
<button type="submit" class="button">{{ trans('entities.books_save') }}</button>
</div>
-@include('entities.selector-popup', ['entityTypes' => 'page', 'selectorEndpoint' => '/search/entity-selector-templates'])
+@include('entities.selector-popup')
@include('form.editor-translations')
\ No newline at end of file
<button type="submit" class="button">{{ trans('entities.chapters_save') }}</button>
</div>
-@include('entities.selector-popup', ['entityTypes' => 'page', 'selectorEndpoint' => '/search/entity-selector-templates'])
+@include('entities.selector-popup')
@include('form.editor-translations')
\ No newline at end of file
<div class="popup-title">{{ trans('entities.entity_select') }}</div>
<button refs="popup@hide" type="button" class="popup-header-close">@icon('close')</button>
</div>
- @include('entities.selector', ['name' => 'entity-selector'])
+ @include('entities.selector', ['name' => 'entity-selector', 'selectorEndpoint' => ''])
<div class="popup-footer">
<button refs="entity-selector-popup@select" type="button" disabled class="button">{{ trans('common.select') }}</button>
</div>
{{--Depends on entity selector popup--}}
-<div component="page-picker">
+<div component="page-picker"
+ option:page-picker:selector-endpoint="{{ $selectorEndpoint }}">
<div class="input-base overflow-hidden height-auto">
<span @if($value) hidden @endif refs="page-picker@default-display" class="text-muted italic">{{ $placeholder }}</span>
<a @if(!$value) hidden @endif href="{{ url('/link/' . $value) }}" target="_blank" rel="noopener" class="text-page" refs="page-picker@display">#{{$value}}, {{$value ? \BookStack\Entities\Models\Page::query()->visible()->find($value)->name ?? '' : '' }}</a>
@section('card')
<h1 id="customization" class="list-heading">{{ trans('settings.app_customization') }}</h1>
<form action="{{ url("/settings/customization") }}" method="POST" enctype="multipart/form-data">
- {!! csrf_field() !!}
+ {{ csrf_field() }}
<input type="hidden" name="section" value="customization">
<div class="setting-list">
</select>
<div refs="setting-homepage-control@page-picker-container" style="display: none;" class="mt-m">
- @include('form.page-picker', ['name' => 'setting-app-homepage', 'placeholder' => trans('settings.app_homepage_select'), 'value' => setting('app-homepage')])
+ @include('form.page-picker', [
+ 'name' => 'setting-app-homepage',
+ 'placeholder' => trans('settings.app_homepage_select'),
+ 'value' => setting('app-homepage'),
+ 'selectorEndpoint' => '/search/entity-selector',
+ ])
</div>
</div>
</div>
@endsection
@section('after-content')
- @include('entities.selector-popup', ['entityTypes' => 'page'])
+ @include('entities.selector-popup')
@endsection
<button type="submit" class="button">{{ trans('entities.shelves_save') }}</button>
</div>
-@include('entities.selector-popup', ['entityTypes' => 'page', 'selectorEndpoint' => '/search/entity-selector-templates'])
+@include('entities.selector-popup')
@include('form.editor-translations')
\ No newline at end of file