mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-24 23:48:13 -05:00
Dropped use of @classic decorator in <GhTokenInput>
no issue - updated component to be a glimmer component and use full "Octane" syntax
This commit is contained in:
parent
dc9c812d9c
commit
3dc4126397
3 changed files with 57 additions and 88 deletions
|
@ -10,7 +10,7 @@
|
||||||
@beforeOptionsComponent={{@beforeOptionsComponent}}
|
@beforeOptionsComponent={{@beforeOptionsComponent}}
|
||||||
@buildSelection={{@buildSelection}}
|
@buildSelection={{@buildSelection}}
|
||||||
@calculatePosition={{@calculatePosition}}
|
@calculatePosition={{@calculatePosition}}
|
||||||
@closeOnSelect={{this.closeOnSelect}}
|
@closeOnSelect={{or @closeOnSelect false}}
|
||||||
@defaultHighlighted={{this.defaultHighlighted}}
|
@defaultHighlighted={{this.defaultHighlighted}}
|
||||||
@destination={{@destination}}
|
@destination={{@destination}}
|
||||||
@disabled={{@disabled}}
|
@disabled={{@disabled}}
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
@onKeydown={{this.handleKeydown}}
|
@onKeydown={{this.handleKeydown}}
|
||||||
@onOpen={{@onOpen}}
|
@onOpen={{@onOpen}}
|
||||||
@options={{this.optionsWithoutSelected}}
|
@options={{this.optionsWithoutSelected}}
|
||||||
@optionsComponent={{this.optionsComponent}}
|
@optionsComponent={{or @optionsComponent "power-select-vertical-collection-options"}}
|
||||||
@placeholder={{@placeholder}}
|
@placeholder={{@placeholder}}
|
||||||
@placeholderComponent={{@placeholderComponent}}
|
@placeholderComponent={{@placeholderComponent}}
|
||||||
@preventScroll={{@preventScroll}}
|
@preventScroll={{@preventScroll}}
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
@eventType={{@eventType}}
|
@eventType={{@eventType}}
|
||||||
@title={{@title}}
|
@title={{@title}}
|
||||||
@triggerClass={{@triggerClass}}
|
@triggerClass={{@triggerClass}}
|
||||||
@triggerComponent={{this.triggerComponent}}
|
@triggerComponent={{or @triggerComponent "gh-token-input/trigger"}}
|
||||||
@triggerId={{@triggerId}}
|
@triggerId={{@triggerId}}
|
||||||
@verticalPosition={{@verticalPosition}}
|
@verticalPosition={{@verticalPosition}}
|
||||||
@tabindex={{@tabindex}}
|
@tabindex={{@tabindex}}
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
{{#if (has-block)}}
|
{{#if (has-block)}}
|
||||||
{{yield option}}
|
{{yield option}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{get option this.labelField}}
|
{{get option (or @labelField "name")}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</GhTokenInput::SelectMultiple>
|
</GhTokenInput::SelectMultiple>
|
|
@ -1,10 +1,8 @@
|
||||||
/* global key */
|
/* global key */
|
||||||
import Component from '@ember/component';
|
import Component from '@glimmer/component';
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
import classic from 'ember-classic-decorator';
|
|
||||||
import fallbackIfUndefined from '../utils/computed-fallback-if-undefined';
|
|
||||||
import {A, isArray} from '@ember/array';
|
import {A, isArray} from '@ember/array';
|
||||||
import {action, computed, get} from '@ember/object';
|
import {action, get} from '@ember/object';
|
||||||
import {
|
import {
|
||||||
advanceSelectableOption,
|
advanceSelectableOption,
|
||||||
defaultMatcher,
|
defaultMatcher,
|
||||||
|
@ -12,7 +10,6 @@ import {
|
||||||
} from 'ember-power-select/utils/group-utils';
|
} from 'ember-power-select/utils/group-utils';
|
||||||
import {htmlSafe} from '@ember/template';
|
import {htmlSafe} from '@ember/template';
|
||||||
import {isBlank} from '@ember/utils';
|
import {isBlank} from '@ember/utils';
|
||||||
import {tagName} from '@ember-decorators/component';
|
|
||||||
import {task} from 'ember-concurrency-decorators';
|
import {task} from 'ember-concurrency-decorators';
|
||||||
|
|
||||||
const {Handlebars} = Ember;
|
const {Handlebars} = Ember;
|
||||||
|
@ -20,21 +17,46 @@ const {Handlebars} = Ember;
|
||||||
const BACKSPACE = 8;
|
const BACKSPACE = 8;
|
||||||
const TAB = 9;
|
const TAB = 9;
|
||||||
|
|
||||||
@classic
|
|
||||||
@tagName('')
|
|
||||||
class GhTokenInput extends Component {
|
class GhTokenInput extends Component {
|
||||||
// public attrs
|
get matcher() {
|
||||||
@fallbackIfUndefined(true) allowCreation
|
return this.args.matcher || defaultMatcher;
|
||||||
@fallbackIfUndefined(false) closeOnSelect
|
}
|
||||||
@fallbackIfUndefined('name') labelField
|
|
||||||
@fallbackIfUndefined(defaultMatcher) matcher
|
get searchField() {
|
||||||
@fallbackIfUndefined('name') searchField
|
return this.args.searchField === undefined ? 'name' : this.args.searchField;
|
||||||
@fallbackIfUndefined('gh-token-input/trigger') triggerComponent
|
}
|
||||||
@fallbackIfUndefined('power-select-vertical-collection-options') optionsComponent
|
|
||||||
|
|
||||||
@computed('options.[]', 'selected.[]')
|
|
||||||
get optionsWithoutSelected() {
|
get optionsWithoutSelected() {
|
||||||
return this.optionsWithoutSelectedTask.perform();
|
let options = this.args.options;
|
||||||
|
let selected = this.args.selected;
|
||||||
|
|
||||||
|
let optionsWithoutSelected = [];
|
||||||
|
|
||||||
|
function filterSelectedOptions(opts, result) {
|
||||||
|
opts.forEach((o) => {
|
||||||
|
if (o.options) {
|
||||||
|
const withoutSelected = [];
|
||||||
|
filterSelectedOptions(o.options, withoutSelected);
|
||||||
|
|
||||||
|
if (withoutSelected.length > 0) {
|
||||||
|
result.push({
|
||||||
|
groupName: o.groupName,
|
||||||
|
options: withoutSelected
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!selected.includes(o)) {
|
||||||
|
result.push(o);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
filterSelectedOptions(options, optionsWithoutSelected);
|
||||||
|
|
||||||
|
return optionsWithoutSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
// actions -----------------------------------------------------------------
|
// actions -----------------------------------------------------------------
|
||||||
|
@ -47,7 +69,7 @@ class GhTokenInput extends Component {
|
||||||
let lastSelection = select.selected[select.selected.length - 1];
|
let lastSelection = select.selected[select.selected.length - 1];
|
||||||
|
|
||||||
if (lastSelection) {
|
if (lastSelection) {
|
||||||
this.onChange(select.selected.slice(0, -1), select);
|
this.args.onChange(select.selected.slice(0, -1), select);
|
||||||
select.actions.search('');
|
select.actions.search('');
|
||||||
select.actions.open(event);
|
select.actions.open(event);
|
||||||
}
|
}
|
||||||
|
@ -83,19 +105,13 @@ class GhTokenInput extends Component {
|
||||||
@action
|
@action
|
||||||
handleFocus() {
|
handleFocus() {
|
||||||
key.setScope('gh-token-input');
|
key.setScope('gh-token-input');
|
||||||
|
this.args.onFocus?.(...arguments);
|
||||||
if (this.onFocus) {
|
|
||||||
this.onFocus(...arguments);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
handleBlur() {
|
handleBlur() {
|
||||||
key.setScope('default');
|
key.setScope('default');
|
||||||
|
this.args.onBlur?.(...arguments);
|
||||||
if (this.onBlur) {
|
|
||||||
this.onBlur(...arguments);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -119,9 +135,9 @@ class GhTokenInput extends Component {
|
||||||
let suggestion = selection.find(option => option.__isSuggestion__);
|
let suggestion = selection.find(option => option.__isSuggestion__);
|
||||||
|
|
||||||
if (suggestion) {
|
if (suggestion) {
|
||||||
this.onCreate(suggestion.__value__, select);
|
this.args.onCreate(suggestion.__value__, select);
|
||||||
} else {
|
} else {
|
||||||
this.onChange(selection, select);
|
this.args.onChange(selection, select);
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear select search
|
// clear select search
|
||||||
|
@ -130,49 +146,15 @@ class GhTokenInput extends Component {
|
||||||
|
|
||||||
// tasks -------------------------------------------------------------------
|
// tasks -------------------------------------------------------------------
|
||||||
|
|
||||||
@task
|
|
||||||
*optionsWithoutSelectedTask() {
|
|
||||||
let options = yield this.options;
|
|
||||||
let selected = yield this.selected;
|
|
||||||
|
|
||||||
let optionsWithoutSelected = [];
|
|
||||||
|
|
||||||
function filterSelectedOptions(opts, result) {
|
|
||||||
opts.forEach((o) => {
|
|
||||||
if (o.options) {
|
|
||||||
const withoutSelected = [];
|
|
||||||
filterSelectedOptions(o.options, withoutSelected);
|
|
||||||
|
|
||||||
if (withoutSelected.length > 0) {
|
|
||||||
result.push({
|
|
||||||
groupName: o.groupName,
|
|
||||||
options: withoutSelected
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!selected.includes(o)) {
|
|
||||||
result.push(o);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
filterSelectedOptions(options, optionsWithoutSelected);
|
|
||||||
|
|
||||||
return optionsWithoutSelected;
|
|
||||||
}
|
|
||||||
|
|
||||||
@task
|
@task
|
||||||
*searchAndSuggestTask(term, select) {
|
*searchAndSuggestTask(term, select) {
|
||||||
let newOptions = (yield this.optionsWithoutSelected).toArray();
|
let newOptions = this.optionsWithoutSelected.toArray();
|
||||||
|
|
||||||
if (term.length === 0) {
|
if (term.length === 0) {
|
||||||
return newOptions;
|
return newOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
let searchAction = this.search;
|
let searchAction = this.args.search;
|
||||||
if (searchAction) {
|
if (searchAction) {
|
||||||
let results = yield searchAction(term, select);
|
let results = yield searchAction(term, select);
|
||||||
|
|
||||||
|
@ -193,6 +175,7 @@ class GhTokenInput extends Component {
|
||||||
// internal ----------------------------------------------------------------
|
// internal ----------------------------------------------------------------
|
||||||
|
|
||||||
// always select the first item in the list that isn't the "Add x" option
|
// always select the first item in the list that isn't the "Add x" option
|
||||||
|
@action
|
||||||
defaultHighlighted(select) {
|
defaultHighlighted(select) {
|
||||||
let {results} = select;
|
let {results} = select;
|
||||||
let option = advanceSelectableOption(results, undefined, 1);
|
let option = advanceSelectableOption(results, undefined, 1);
|
||||||
|
@ -213,12 +196,12 @@ class GhTokenInput extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_shouldShowCreateOption(term, options) {
|
_shouldShowCreateOption(term, options) {
|
||||||
if (!this.allowCreation) {
|
if (this.args.allowCreation === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.showCreateWhen) {
|
if (this.args.showCreateWhen) {
|
||||||
return this.showCreateWhen(term, options);
|
return this.args.showCreateWhen(term, options);
|
||||||
} else {
|
} else {
|
||||||
return this._hideCreateOptionOnSameTerm(term, options);
|
return this._hideCreateOptionOnSameTerm(term, options);
|
||||||
}
|
}
|
||||||
|
@ -233,8 +216,7 @@ class GhTokenInput extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_hideCreateOptionOnSameTerm(term, options) {
|
_hideCreateOptionOnSameTerm(term, options) {
|
||||||
let searchField = this.searchField;
|
let existingOption = options.findBy(this.searchField, term);
|
||||||
let existingOption = options.findBy(searchField, term);
|
|
||||||
return !existingOption;
|
return !existingOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,8 +231,8 @@ class GhTokenInput extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildSuggestionLabel(term) {
|
_buildSuggestionLabel(term) {
|
||||||
if (this.buildSuggestion) {
|
if (this.args.buildSuggestion) {
|
||||||
return this.buildSuggestion(term);
|
return this.args.buildSuggestion(term);
|
||||||
}
|
}
|
||||||
return htmlSafe(`Add <strong>"${Handlebars.Utils.escapeExpression(term)}"...</strong>`);
|
return htmlSafe(`Add <strong>"${Handlebars.Utils.escapeExpression(term)}"...</strong>`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
import {computed} from '@ember/object';
|
|
||||||
|
|
||||||
export default function computedFallbackIfUndefined(fallback) {
|
|
||||||
return computed({
|
|
||||||
get() {
|
|
||||||
return fallback;
|
|
||||||
},
|
|
||||||
|
|
||||||
set(_, v) {
|
|
||||||
return v === undefined ? fallback : v;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue