0
Fork 0
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:
Kevin Ansfield 2021-07-12 14:03:37 +01:00
parent dc9c812d9c
commit 3dc4126397
3 changed files with 57 additions and 88 deletions

View file

@ -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>

View file

@ -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>`);
} }

View file

@ -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;
}
});
}