add SelectOrInput widget to support custom analyzer
This commit is contained in:
parent
f981c27e00
commit
8e5576db94
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,51 @@
|
||||||
|
import type Mithril from 'mithril';
|
||||||
|
import AdminPage, { CommonSettingsItemOptions } from 'flarum/admin/components/AdminPage';
|
||||||
|
import SelectOrInput from "../../common/Components/SelectOrInput";
|
||||||
|
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 };
|
||||||
|
checkboxDescription: string;
|
||||||
|
default: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SelectOrInputSettingComponentOptions extends SelectOrInputSettingComponentOptionsWithoutType {
|
||||||
|
type: 'select-or-input';
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstLoadCompletedSet: Set<string> = new Set();
|
||||||
|
|
||||||
|
export default function (this: AdminPage, _entry: CommonSettingsItemOptions) {
|
||||||
|
// do this cast because function signature is restricted
|
||||||
|
const entry = _entry as SelectOrInputSettingComponentOptionsWithoutType;
|
||||||
|
const [inputId, helpTextId] = [generateElementId(), generateElementId()];
|
||||||
|
const { setting, help, label, ...componentAttrs } = entry;
|
||||||
|
const { default: defaultValue, options, checkboxDescription, ...otherAttrs } = componentAttrs;
|
||||||
|
const value = this.setting(setting)();
|
||||||
|
let settingElement: Mithril.Children;
|
||||||
|
|
||||||
|
const firstLoadCompleted = firstLoadCompletedSet.has(entry.setting);
|
||||||
|
|
||||||
|
settingElement = (
|
||||||
|
<SelectOrInput
|
||||||
|
id={inputId}
|
||||||
|
aria-describedby={helpTextId}
|
||||||
|
value={(!firstLoadCompleted && !value) ? defaultValue : value}
|
||||||
|
options={options}
|
||||||
|
onchange={this.settings[setting]}
|
||||||
|
checkboxDescription={checkboxDescription}
|
||||||
|
{...otherAttrs}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!firstLoadCompleted) firstLoadCompletedSet.add(entry.setting);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="Form-group">
|
||||||
|
{label && <label for={inputId}>{label}</label>}
|
||||||
|
<div id={helpTextId} className="helpText">{help}</div>
|
||||||
|
{settingElement}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import app from 'flarum/admin/app';
|
import app from 'flarum/admin/app';
|
||||||
|
import extendCustomSettingComponents from './extendCustomSettingComponents';
|
||||||
|
|
||||||
app.initializers.add('blomstra-search', () => {
|
app.initializers.add('blomstra-search', () => {
|
||||||
|
extendCustomSettingComponents();
|
||||||
|
|
||||||
const languages = new Map();
|
const languages = new Map();
|
||||||
[
|
[
|
||||||
'arabic',
|
'arabic',
|
||||||
|
|
@ -69,8 +72,9 @@ app.initializers.add('blomstra-search', () => {
|
||||||
setting: 'blomstra-search.analyzer-language',
|
setting: 'blomstra-search.analyzer-language',
|
||||||
label: app.translator.trans('blomstra-search.admin.analyzer.label'),
|
label: app.translator.trans('blomstra-search.admin.analyzer.label'),
|
||||||
help: app.translator.trans('blomstra-search.admin.analyzer.help'),
|
help: app.translator.trans('blomstra-search.admin.analyzer.help'),
|
||||||
type: 'select',
|
type: 'select-or-input',
|
||||||
options: Object.fromEntries(languages.entries()),
|
options: Object.fromEntries(languages.entries()),
|
||||||
|
checkboxDescription: app.translator.trans('blomstra-search.admin.analyzer.custom'),
|
||||||
default: 'english',
|
default: 'english',
|
||||||
})
|
})
|
||||||
.registerSetting({
|
.registerSetting({
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
import Mithril from 'mithril';
|
||||||
|
import classList from 'flarum/common/utils/classList';
|
||||||
|
import Component, { ComponentAttrs } from 'flarum/common/Component';
|
||||||
|
import Select from 'flarum/common/components/Select';
|
||||||
|
import Checkbox, { ICheckboxAttrs } from 'flarum/common/components/Checkbox';
|
||||||
|
|
||||||
|
type visibility = 'visible' | 'hidden';
|
||||||
|
|
||||||
|
interface ISelectAttrs extends ComponentAttrs {
|
||||||
|
options: { [k: string]: Mithril.Children };
|
||||||
|
onchange: (value: string) => void;
|
||||||
|
value?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
wrapperAttrs?: ComponentAttrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ISubSelectAttrs extends ComponentAttrs {
|
||||||
|
wrapperAttrs?: ComponentAttrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ISelectOrInputAttrs<
|
||||||
|
SelectAttrs extends ISubSelectAttrs = ISubSelectAttrs
|
||||||
|
> extends ComponentAttrs {
|
||||||
|
onchange: (value: string) => void;
|
||||||
|
options: { [k: string]: Mithril.Children };
|
||||||
|
value?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
checkboxDescription?: string;
|
||||||
|
selectAttrs?: SelectAttrs;
|
||||||
|
rawTextInputAttrs?: ComponentAttrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class SelectOrInput<CustomAttrs extends ISelectOrInputAttrs> extends Component<CustomAttrs> {
|
||||||
|
private onCheckboxChange(checked: boolean, component: Checkbox) {
|
||||||
|
this.attrs.value = checked ? '' : undefined;
|
||||||
|
this.attrs.onchange(this.attrs.value!);
|
||||||
|
m.redraw();
|
||||||
|
}
|
||||||
|
private onSelectChange(value: string) {
|
||||||
|
this.attrs.value = value;
|
||||||
|
this.attrs.onchange(value);
|
||||||
|
}
|
||||||
|
private onInputChange(event: Event) {
|
||||||
|
const value = (event.target as HTMLInputElement).value;
|
||||||
|
this.attrs.value = value;
|
||||||
|
this.attrs.onchange(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
view(vnode: Mithril.Vnode<CustomAttrs, this>) {
|
||||||
|
const {
|
||||||
|
class: _class,
|
||||||
|
className,
|
||||||
|
onchange,
|
||||||
|
options,
|
||||||
|
value: _value,
|
||||||
|
disabled,
|
||||||
|
selectAttrs,
|
||||||
|
rawTextInputAttrs,
|
||||||
|
...domAttrs
|
||||||
|
} = this.attrs;
|
||||||
|
|
||||||
|
var useinput: boolean; var value: string;
|
||||||
|
const selectOptionValues = Object.keys(options);
|
||||||
|
|
||||||
|
if (typeof _value === 'undefined') {
|
||||||
|
value = selectOptionValues[0];
|
||||||
|
this.attrs.value = value;
|
||||||
|
useinput = false;
|
||||||
|
} else {
|
||||||
|
value = _value;
|
||||||
|
useinput = !(selectOptionValues.indexOf(value!) > -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const {
|
||||||
|
class: inputClass,
|
||||||
|
className: inputClassName,
|
||||||
|
...otherInputAttrs
|
||||||
|
} = rawTextInputAttrs ?? {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classList('SelectOrInput', className, _class)}
|
||||||
|
{...domAttrs}
|
||||||
|
>
|
||||||
|
{this.attrs.checkboxDescription ?? ''}
|
||||||
|
<div style='display: inline-block;'>
|
||||||
|
<Checkbox
|
||||||
|
state={useinput}
|
||||||
|
onchange={this.onCheckboxChange.bind(this)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style='display: inline-block;'>
|
||||||
|
{!useinput
|
||||||
|
? <Select
|
||||||
|
options={options}
|
||||||
|
onchange={this.onSelectChange.bind(this)}
|
||||||
|
disabled={disabled}
|
||||||
|
value={value}
|
||||||
|
{...selectAttrs}
|
||||||
|
/>
|
||||||
|
: <input
|
||||||
|
className={classList('FormControl', inputClassName, inputClass)}
|
||||||
|
type='text'
|
||||||
|
onchange={this.onInputChange.bind(this)}
|
||||||
|
disabled={disabled}
|
||||||
|
value={value}
|
||||||
|
{...otherInputAttrs}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,6 +9,7 @@ blomstra-search:
|
||||||
help: |
|
help: |
|
||||||
The analyzer makes search understand stop words and undertakes language
|
The analyzer makes search understand stop words and undertakes language
|
||||||
specific improvements for indexing.
|
specific improvements for indexing.
|
||||||
|
custom: Use custom analyzer
|
||||||
search-discussion-subjects: Search inside discussion titles
|
search-discussion-subjects: Search inside discussion titles
|
||||||
search-post-bodies: Search inside comments
|
search-post-bodies: Search inside comments
|
||||||
match-sentences: Match search term against full sentence
|
match-sentences: Match search term against full sentence
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue