Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion js/dist/admin.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion js/dist/admin.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion js/dist/forum.js.map

Large diffs are not rendered by default.

92 changes: 92 additions & 0 deletions js/src/admin/ConfigToComponents/buildSelectOrInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import type Mithril from 'mithril';
import Stream from 'flarum/common/utils/Stream';
import classList from 'flarum/common/utils/classList';
import withAttr from 'flarum/common/utils/withAttr';
import AdminPage, { CommonSettingsItemOptions } from 'flarum/admin/components/AdminPage';
import Select from 'flarum/common/components/Select';
import generateElementId from 'flarum/admin/utils/generateElementId';

// forgive me, but this interface is just what its name implies
interface SelectOrInputSettingComponentOptionsWithoutType extends CommonSettingsItemOptions {
options: { [value: string]: Mithril.Children };
inputDescription: string;
default: string;
}

export interface SelectOrInputSettingComponentOptions extends SelectOrInputSettingComponentOptionsWithoutType {
type: 'select-or-input';
}

interface StreamWithUpstream<T> extends Stream<T> {
upstreams?: Array<Stream<unknown>>;
}

function mergeSelectOrInput(
selectStream: Stream<string>, inputStream: Stream<string>,
changed: Array<Stream<unknown>>
) {
return inputStream() || selectStream();
}

export default function (this: AdminPage, _entry: CommonSettingsItemOptions) {
// do this cast because function signature is restricted
const entry = _entry as SelectOrInputSettingComponentOptionsWithoutType;
const [selectId, inputId, helpTextId] = [generateElementId(), generateElementId(), generateElementId()];
const { setting, help, label, ...componentAttrs } = entry;
const { default: defaultValue, options, inputDescription, className, ...otherAttrs } = componentAttrs;

let settingStream = this.settings[setting] as StreamWithUpstream<string>;

if (!settingStream.upstreams) {
let value = settingStream() || defaultValue;
let selectStream = Stream();
let inputStream = Stream();
let upstreams = [selectStream, inputStream]
settingStream = Stream.combine(mergeSelectOrInput, upstreams);
settingStream.upstreams = upstreams;
let useSelect = Object.keys(options).indexOf(value) > -1;
if (useSelect) {
selectStream(value);
inputStream('');
} else {
selectStream(defaultValue);
inputStream(value);
}
this.settings[setting] = settingStream;
}

let [selectStream, inputStream] = settingStream.upstreams!;

let selectElement = (
<Select
className={className}
id={selectId}
aria-describedby={helpTextId}
value={selectStream()}
options={options}
onchange={selectStream}
{...otherAttrs}
/>
);

let inputElement = (
<input
className={classList('FormControl', className)}
id={inputId}
type='text'
onchange={withAttr('value', inputStream)}
value={inputStream()}
{...otherAttrs}
/>
);

return (
<div className="Form-group">
{label && <label for={selectId}>{label}</label>}
<div id={helpTextId} className="helpText">{help}</div>
{selectElement}
{inputDescription && <label style={{'padding-top': '10px'}} for={inputId}>{inputDescription}</label>}
{inputElement}
</div>
);
}
9 changes: 9 additions & 0 deletions js/src/admin/extendCustomSettingComponents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { extend } from 'flarum/common/extend';
import AdminPage, { CommonSettingsItemOptions } from 'flarum/admin/components/AdminPage';
import buildSelectOrInput from './ConfigToComponents/buildSelectOrInput';

export default function() {
extend(AdminPage.prototype, 'customSettingComponents', function (items) {
items.add('select-or-input', buildSelectOrInput.bind(this));
})
}
6 changes: 5 additions & 1 deletion js/src/admin/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import app from 'flarum/admin/app';
import extendCustomSettingComponents from './extendCustomSettingComponents';

app.initializers.add('blomstra-search', () => {
extendCustomSettingComponents();

const languages = new Map();
[
'arabic',
Expand Down Expand Up @@ -69,8 +72,9 @@ app.initializers.add('blomstra-search', () => {
setting: 'blomstra-search.analyzer-language',
label: app.translator.trans('blomstra-search.admin.analyzer.label'),
help: app.translator.trans('blomstra-search.admin.analyzer.help'),
type: 'select',
type: 'select-or-input',
options: Object.fromEntries(languages.entries()),
inputDescription: app.translator.trans('blomstra-search.admin.analyzer.custom'),
default: 'english',
})
.registerSetting({
Expand Down
1 change: 1 addition & 0 deletions resources/locale/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ blomstra-search:
help: |
The analyzer makes search understand stop words and undertakes language
specific improvements for indexing.
custom: Use custom analyzer
search-discussion-subjects: Search inside discussion titles
search-post-bodies: Search inside comments
match-sentences: Match search term against full sentence
Expand Down