From 7c7c4962f978bab4e315004ad6bea99e6286183b Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Wed, 15 Jan 2020 13:53:51 +0000 Subject: [PATCH] Upgraded `ember-power-*` addons (#1459) no issue - bump deps - adjust usage for breaking changes... - https://github.com/cibernox/ember-power-select/blob/master/CHANGELOG.md#300-beta1 - https://github.com/cibernox/ember-basic-dropdown/blob/master/CHANGELOG.md#200-beta3 - https://github.com/cibernox/ember-power-datepicker/blob/master/CHANGELOG.md#070 - update overridden component and template files to match latest addon code - switch to class syntax w/decorators - adjust for angle bracket syntax --- .../admin/app/components/gh-basic-dropdown.js | 27 +- .../app/components/gh-date-time-picker.js | 3 +- ghost/admin/app/components/gh-token-input.js | 272 +++++++++--------- .../gh-token-input/select-multiple.js | 60 ++-- .../app/components/gh-token-input/select.js | 9 - .../app/components/gh-token-input/trigger.js | 116 ++++---- .../components/gh-date-time-picker.hbs | 28 +- .../templates/components/gh-members-chart.hbs | 30 +- .../components/gh-members-lab-setting.hbs | 18 +- .../app/templates/components/gh-nav-menu.hbs | 12 +- .../components/gh-psm-authors-input.hbs | 16 +- .../components/gh-psm-tags-input.hbs | 22 +- .../templates/components/gh-publishmenu.hbs | 12 +- .../templates/components/gh-search-input.hbs | 21 +- .../templates/components/gh-token-input.hbs | 111 +++---- .../gh-token-input/select-multiple.hbs | 183 ++++-------- .../components/gh-token-input/select.hbs | 103 ------- .../components/gh-token-input/trigger.hbs | 21 +- ...wer-select-vertical-collection-options.hbs | 33 ++- .../components/power-select/trigger.hbs | 15 +- ghost/admin/app/templates/pages-loading.hbs | 118 ++++---- ghost/admin/app/templates/pages.hbs | 110 +++---- ghost/admin/app/templates/posts-loading.hbs | 118 ++++---- ghost/admin/app/templates/posts.hbs | 110 +++---- .../utils/computed-fallback-if-undefined.js | 13 + ghost/admin/package.json | 4 +- ghost/admin/yarn.lock | 103 ++++--- 27 files changed, 807 insertions(+), 881 deletions(-) delete mode 100644 ghost/admin/app/components/gh-token-input/select.js delete mode 100644 ghost/admin/app/templates/components/gh-token-input/select.hbs create mode 100644 ghost/admin/app/utils/computed-fallback-if-undefined.js diff --git a/ghost/admin/app/components/gh-basic-dropdown.js b/ghost/admin/app/components/gh-basic-dropdown.js index 1ebd285f9b..699c5165ef 100644 --- a/ghost/admin/app/components/gh-basic-dropdown.js +++ b/ghost/admin/app/components/gh-basic-dropdown.js @@ -1,19 +1,20 @@ import BasicDropdown from 'ember-basic-dropdown/components/basic-dropdown'; -import layout from 'ember-basic-dropdown/templates/components/basic-dropdown'; +import templateLayout from 'ember-basic-dropdown/templates/components/basic-dropdown'; +import {layout} from '@ember-decorators/component'; import {inject as service} from '@ember/service'; -export default BasicDropdown.extend({ - dropdown: service(), +@layout(templateLayout) +class GhBasicDropdown extends BasicDropdown { + @service dropdown - layout, - - didInsertElement() { - this._super(...arguments); + onInit() { this.dropdown.on('close', this, this.close); - }, - - willDestroyElement() { - this._super(...arguments); - this.dropdown.off('close', this, this.close); } -}); + + willDestroy() { + this.dropdown.off('close', this, this.close); + super.willDestroyElement(...arguments); + } +} + +export default GhBasicDropdown; diff --git a/ghost/admin/app/components/gh-date-time-picker.js b/ghost/admin/app/components/gh-date-time-picker.js index 016c8ed927..8e1f417d05 100644 --- a/ghost/admin/app/components/gh-date-time-picker.js +++ b/ghost/admin/app/components/gh-date-time-picker.js @@ -161,7 +161,8 @@ export default Component.extend({ }), onDateInput: action(function (datepicker, event) { - datepicker.actions.close(); + let skipFocus = true; + datepicker.actions.close(event, skipFocus); this.set('_scratchDate', event.target.value); }), diff --git a/ghost/admin/app/components/gh-token-input.js b/ghost/admin/app/components/gh-token-input.js index e263b31adb..f2b77d9ac3 100644 --- a/ghost/admin/app/components/gh-token-input.js +++ b/ghost/admin/app/components/gh-token-input.js @@ -1,16 +1,17 @@ /* global key */ import Component from '@ember/component'; import Ember from 'ember'; +import fallbackIfUndefined from '../utils/computed-fallback-if-undefined'; import {A, isArray} from '@ember/array'; +import {action, computed, get} from '@ember/object'; import { advanceSelectableOption, defaultMatcher, filterOptions } from 'ember-power-select/utils/group-utils'; -import {computed} from '@ember/object'; -import {get} from '@ember/object'; import {htmlSafe} from '@ember/string'; import {isBlank} from '@ember/utils'; +import {tagName} from '@ember-decorators/component'; import {task} from 'ember-concurrency'; const {Handlebars} = Ember; @@ -18,126 +19,78 @@ const {Handlebars} = Ember; const BACKSPACE = 8; const TAB = 9; -export default Component.extend({ - +@tagName('') +class GhTokenInput extends Component { // public attrs - allowCreation: true, - closeOnSelect: false, - labelField: 'name', - matcher: defaultMatcher, - searchField: 'name', - tagName: '', - triggerComponent: 'gh-token-input/trigger', + @fallbackIfUndefined(true) allowCreation + @fallbackIfUndefined(false) closeOnSelect + @fallbackIfUndefined('name') labelField + @fallbackIfUndefined(defaultMatcher) matcher + @fallbackIfUndefined('name') searchField + @fallbackIfUndefined('gh-token-input/trigger') triggerComponent + @fallbackIfUndefined('power-select-vertical-collection-options') optionsComponent - optionsWithoutSelected: computed('options.[]', 'selected.[]', function () { + @computed('options.[]', 'selected.[]') + get optionsWithoutSelected() { return this.optionsWithoutSelectedTask.perform(); - }), + } - actions: { - handleKeydown(select, event) { - // On backspace with empty text, remove the last token but deviate - // from default behaviour by not updating search to match last token - if (event.keyCode === BACKSPACE && isBlank(event.target.value)) { - let lastSelection = select.selected[select.selected.length - 1]; + // actions ----------------------------------------------------------------- - if (lastSelection) { - this.onchange(select.selected.slice(0, -1), select); - select.actions.search(''); - select.actions.open(event); - } + @action + handleKeydown(select, event) { + // On backspace with empty text, remove the last token but deviate + // from default behaviour by not updating search to match last token + if (event.keyCode === BACKSPACE && isBlank(event.target.value)) { + let lastSelection = select.selected[select.selected.length - 1]; - // prevent default - return false; + if (lastSelection) { + this.onChange(select.selected.slice(0, -1), select); + select.actions.search(''); + select.actions.open(event); } - // Tab should work the same as Enter if there's a highlighted option - if (event.keyCode === TAB && !isBlank(event.target.value) && select.highlighted) { - if (!select.selected || select.selected.indexOf(select.highlighted) === -1) { - select.actions.choose(select.highlighted, event); - return false; - } - } - - // fallback to default - return true; - }, - - onfocus() { - key.setScope('gh-token-input'); - - if (this.onfocus) { - this.onfocus(...arguments); - } - }, - - onblur() { - key.setScope('default'); - - if (this.onblur) { - this.onblur(...arguments); - } - } - }, - - optionsWithoutSelectedTask: task(function* () { - let options = yield this.options; - let selected = yield this.selected; - return options.filter(o => !selected.includes(o)); - }), - - shouldShowCreateOption(term, options) { - if (!this.allowCreation) { + // prevent default return false; } - if (this.showCreateWhen) { - return this.showCreateWhen(term, options); - } else { - return this.hideCreateOptionOnSameTerm(term, options); + // Tab should work the same as Enter if there's a highlighted option + if (event.keyCode === TAB && !isBlank(event.target.value) && select.highlighted) { + if (!select.selected || select.selected.indexOf(select.highlighted) === -1) { + select.actions.choose(select.highlighted, event); + event.preventDefault(); // keep focus in search + return false; + } } - }, - hideCreateOptionOnSameTerm(term, options) { - let searchField = this.searchField; - let existingOption = options.findBy(searchField, term); - return !existingOption; - }, + // fallback to default + return true; + } - addCreateOption(term, options) { - if (this.shouldShowCreateOption(term, options)) { - options.unshift(this.buildSuggestionForTerm(term)); + @action + handleFocus() { + key.setScope('gh-token-input'); + + if (this.onFocus) { + this.onFocus(...arguments); } - }, + } + @action + handleBlur() { + key.setScope('default'); + + if (this.onBlur) { + this.onBlur(...arguments); + } + } + + @action searchAndSuggest(term, select) { return this.searchAndSuggestTask.perform(term, select); - }, - - searchAndSuggestTask: task(function* (term, select) { - let newOptions = (yield this.optionsWithoutSelected).toArray(); - - if (term.length === 0) { - return newOptions; - } - - let searchAction = this.search; - if (searchAction) { - let results = yield searchAction(term, select); - - if (results.toArray) { - results = results.toArray(); - } - - this.addCreateOption(term, results); - return results; - } - - newOptions = this.filter(A(newOptions), term); - this.addCreateOption(term, newOptions); - - return newOptions; - }), + } + @action selectOrCreate(selection, select, keyboardEvent) { // allow tokens to be created with spaces if (keyboardEvent && keyboardEvent.code === 'Space') { @@ -153,40 +106,51 @@ export default Component.extend({ let suggestion = selection.find(option => option.__isSuggestion__); if (suggestion) { - this.oncreate(suggestion.__value__, select); + this.onCreate(suggestion.__value__, select); } else { - this.onchange(selection, select); + this.onChange(selection, select); } // clear select search select.actions.search(''); - }, + } - filter(options, searchText) { - let matcher; - if (this.searchField) { - matcher = (option, text) => this.matcher(get(option, this.searchField), text); - } else { - matcher = (option, text) => this.matcher(option, text); + // tasks ------------------------------------------------------------------- + + @task(function* () { + let options = yield this.options; + let selected = yield this.selected; + return options.filter(o => !selected.includes(o)); + }) + optionsWithoutSelectedTask; + + @task(function* (term, select) { + let newOptions = (yield this.optionsWithoutSelected).toArray(); + + if (term.length === 0) { + return newOptions; } - return filterOptions(options || [], searchText, matcher); - }, - buildSuggestionForTerm(term) { - return { - __isSuggestion__: true, - __value__: term, - text: this.buildSuggestionLabel(term) - }; - }, + let searchAction = this.search; + if (searchAction) { + let results = yield searchAction(term, select); - buildSuggestionLabel(term) { - let buildSuggestion = this.buildSuggestion; - if (buildSuggestion) { - return buildSuggestion(term); + if (results.toArray) { + results = results.toArray(); + } + + this._addCreateOption(term, results); + return results; } - return htmlSafe(`Add "${Handlebars.Utils.escapeExpression(term)}"...`); - }, + + newOptions = this._filter(A(newOptions), term); + this._addCreateOption(term, newOptions); + + return newOptions; + }) + searchAndSuggestTask; + + // internal ---------------------------------------------------------------- // always select the first item in the list that isn't the "Add x" option defaultHighlighted(select) { @@ -200,4 +164,56 @@ export default Component.extend({ return option; } -}); + // private ----------------------------------------------------------------- + + _addCreateOption(term, options) { + if (this._shouldShowCreateOption(term, options)) { + options.unshift(this._buildSuggestionForTerm(term)); + } + } + + _shouldShowCreateOption(term, options) { + if (!this.allowCreation) { + return false; + } + + if (this.showCreateWhen) { + return this.showCreateWhen(term, options); + } else { + return this._hideCreateOptionOnSameTerm(term, options); + } + } + + _buildSuggestionForTerm(term) { + return { + __isSuggestion__: true, + __value__: term, + text: this._buildSuggestionLabel(term) + }; + } + + _hideCreateOptionOnSameTerm(term, options) { + let searchField = this.searchField; + let existingOption = options.findBy(searchField, term); + return !existingOption; + } + + _filter(options, searchText) { + let matcher; + if (this.searchField) { + matcher = (option, text) => this.matcher(get(option, this.searchField), text); + } else { + matcher = (option, text) => this.matcher(option, text); + } + return filterOptions(options || [], searchText, matcher); + } + + _buildSuggestionLabel(term) { + if (this.buildSuggestion) { + return this.buildSuggestion(term); + } + return htmlSafe(`Add "${Handlebars.Utils.escapeExpression(term)}"...`); + } +} + +export default GhTokenInput; diff --git a/ghost/admin/app/components/gh-token-input/select-multiple.js b/ghost/admin/app/components/gh-token-input/select-multiple.js index 0f4577c387..65fb12e673 100644 --- a/ghost/admin/app/components/gh-token-input/select-multiple.js +++ b/ghost/admin/app/components/gh-token-input/select-multiple.js @@ -1,45 +1,51 @@ import $ from 'jquery'; import PowerSelectMultiple from 'ember-power-select/components/power-select-multiple'; +import templateLayout from '../../templates/components/gh-token-input/select-multiple'; +import {action} from '@ember/object'; import {bind} from '@ember/runloop'; +import {layout, tagName} from '@ember-decorators/component'; -const endActions = 'click.ghToken mouseup.ghToken touchend.ghToken'; +// TODO: convert from jQuery to native DOM +const END_ACTIONS = 'click.ghToken mouseup.ghToken touchend.ghToken'; // triggering focus on the search input within ESA's onfocus event breaks the // drag-n-drop functionality in ember-drag-drop so we watch for events that // could be the start of a drag and disable the default focus behaviour until // we get another event signalling the end of a drag -export default PowerSelectMultiple.extend({ - - tagName: 'div', - - _canFocus: true, +export default @tagName('div') @layout(templateLayout) class GhTokenInputSelectMultiple extends PowerSelectMultiple { + _canFocus = true; willDestroyElement() { - this._super(...arguments); + super.willDestroyElement(...arguments); if (this._allowFocusListener) { - $(window).off(endActions, this._allowFocusListener); + $(window).off(END_ACTIONS, this._allowFocusListener); } - }, + } - actions: { - optionMouseDown(event) { - if (event.which === 1 && !event.ctrlKey) { - this._denyFocus(event); - } - }, + // actions - optionTouchStart(event) { + @action + optionMouseDown(event) { + if (event.which === 1 && !event.ctrlKey) { this._denyFocus(event); - }, - - handleFocus() { - if (this._canFocus) { - this._super(...arguments); - } } - }, + } + + @action + optionTouchStart(event) { + this._denyFocus(event); + } + + @action + handleFocus() { + if (this._canFocus) { + super.handleFocus(...arguments); + } + } + + // internal _denyFocus() { if (this._canFocus) { @@ -47,14 +53,14 @@ export default PowerSelectMultiple.extend({ this._allowFocusListener = bind(this, this._allowFocus); - $(window).on(endActions, this._allowFocusListener); + $(window).on(END_ACTIONS, this._allowFocusListener); } - }, + } _allowFocus() { this._canFocus = true; - $(window).off(endActions, this._allowFocusListener); + $(window).off(END_ACTIONS, this._allowFocusListener); this._allowFocusListener = null; } -}); +} diff --git a/ghost/admin/app/components/gh-token-input/select.js b/ghost/admin/app/components/gh-token-input/select.js deleted file mode 100644 index e8eee9335a..0000000000 --- a/ghost/admin/app/components/gh-token-input/select.js +++ /dev/null @@ -1,9 +0,0 @@ -// NOTE: This is only here because we wanted to override the `eventType` attr. -// DO NOT add any functionality here, this will hopefully disappear after an -// upstream PR - -import PowerSelect from 'ember-power-select/components/power-select'; - -export default PowerSelect.extend({ - -}); diff --git a/ghost/admin/app/components/gh-token-input/trigger.js b/ghost/admin/app/components/gh-token-input/trigger.js index 3b1d593aec..215599cdfa 100644 --- a/ghost/admin/app/components/gh-token-input/trigger.js +++ b/ghost/admin/app/components/gh-token-input/trigger.js @@ -1,68 +1,66 @@ import EmberPowerSelectMultipleTrigger from 'ember-power-select/components/power-select-multiple/trigger'; +import {action, get} from '@ember/object'; import {assert} from '@ember/debug'; -import {get} from '@ember/object'; import {isBlank} from '@ember/utils'; -export default EmberPowerSelectMultipleTrigger.extend({ - - actions: { - chooseOption(option) { - this.select.actions.choose(option); - }, - - handleOptionMouseDown(event) { - if (!event.target.closest('[data-selected-index]')) { - let action = this.get('extra.optionMouseDown'); - if (action) { - return action(event); - } +export default class Trigger extends EmberPowerSelectMultipleTrigger { + @action + handleOptionMouseDown(event) { + if (!event.target.closest('[data-selected-index]')) { + let optionMouseDown = this.get('extra.optionMouseDown'); + if (optionMouseDown) { + return optionMouseDown(event); } - }, + } - handleOptionTouchStart(event) { - let action = this.get('extra.optionTouchStart'); - if (action) { - return action(event); - } - }, + return this.chooseOption(event); + } - reorderItems() { - // ember-drag-drop's sortable-objects has two-way bindings and will - // update EPS' selected value directly. We have to create a copy - // after sorting in order to force the onchange action to be triggered - let selectedCopy = this.select.selected.slice(); - this.select.actions.select(selectedCopy); - }, - - // copied directly from EPS, the default behaviour of stopping propagation - // of keydown events prevents our shortcuts from being triggered - onKeydown(e) { - let {onKeydown, select} = this; - if (onKeydown && onKeydown(e) === false) { - e.stopPropagation(); - return false; - } - if (e.keyCode === 8) { - e.stopPropagation(); - if (isBlank(e.target.value)) { - let lastSelection = select.selected[select.selected.length - 1]; - if (lastSelection) { - select.actions.select(this.buildSelection(lastSelection, select), e); - if (typeof lastSelection === 'string') { - select.actions.search(lastSelection); - } else { - let searchField = this.searchField; - assert('`{{power-select-multiple}}` requires a `searchField` when the options are not strings to remove options using backspace', searchField); - select.actions.search(get(lastSelection, searchField)); - } - select.actions.open(e); - } - } - } - // Disable the propagation cancellation so that our shortcuts still work - // } else if (e.keyCode >= 48 && e.keyCode <= 90 || e.keyCode === 32) { // Keys 0-9, a-z or SPACE - // e.stopPropagation(); - // } + @action + handleOptionTouchStart(event) { + let optionTouchStart = this.get('extra.optionTouchStart'); + if (optionTouchStart) { + return optionTouchStart(event); } } -}); + + @action + reorderItems() { + // ember-drag-drop's sortable-objects has two-way bindings and will + // update EPS' selected value directly. We have to create a copy + // after sorting in order to force the onchange action to be triggered + let selectedCopy = this.select.selected.slice(); + this.select.actions.select(selectedCopy); + } + + // copied directly from EPS, the default behaviour of stopping propagation + // of keydown events prevents our shortcuts from being triggered + @action + handleKeydown(e) { + if (this.onKeydown && this.onKeydown(e) === false) { + e.stopPropagation(); + return false; + } + if (e.keyCode === 8) { + e.stopPropagation(); + if (isBlank(e.target.value)) { + let lastSelection = this.select.selected[this.select.selected.length - 1]; + if (lastSelection) { + this.select.actions.select(this.get('buildSelection')(lastSelection, this.select), e); + if (typeof lastSelection === 'string') { + this.select.actions.search(lastSelection); + } else { + let searchField = this.get('searchField'); + assert('`{{power-select-multiple}}` requires a `searchField` when the options are not strings to remove options using backspace', searchField); + this.select.actions.search(get(lastSelection, searchField)); + } + this.select.actions.open(e); + } + } + } + // Disable the propagation cancellation so that our shortcuts still work + // } else if (e.keyCode >= 48 && e.keyCode <= 90 || e.keyCode === 32) { // Keys 0-9, a-z or SPACE + // e.stopPropagation(); + // } + } +} diff --git a/ghost/admin/app/templates/components/gh-date-time-picker.hbs b/ghost/admin/app/templates/components/gh-date-time-picker.hbs index f27d5b5a91..bae379e2f4 100644 --- a/ghost/admin/app/templates/components/gh-date-time-picker.hbs +++ b/ghost/admin/app/templates/components/gh-date-time-picker.hbs @@ -1,12 +1,12 @@
- {{#power-datepicker - selected=this._date - center=this._date - onSelect=(action "setDate" value="date") - renderInPlace=true - disabled=this.disabled as |dp| - }} - {{#dp.trigger tabindex="-1" data-test-date-time-picker-datepicker=true}} + +
{{svg-jar "calendar"}}
- {{/dp.trigger}} - {{#dp.content class="dropdown-menu"}} - {{dp.nav}} - {{dp.days minDate=this._minDate maxDate=this._maxDate weekdayFormat="min"}} - {{/dp.content}} - {{/power-datepicker}} +
+ + + + +
Total members
- {{#power-select - selected=selectedRange - options=availableRange - searchEnabled=false - onchange=(action "changeDateRange") - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-type" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown gh-members-chart-dropdown" - matchTriggerWidth=false - data-test-type-select=true - as |range| - }} - {{range.name}} - {{/power-select}} + + {{range.name}} +
diff --git a/ghost/admin/app/templates/components/gh-members-lab-setting.hbs b/ghost/admin/app/templates/components/gh-members-lab-setting.hbs index 46443e288f..ab5b8c035f 100644 --- a/ghost/admin/app/templates/components/gh-members-lab-setting.hbs +++ b/ghost/admin/app/templates/components/gh-members-lab-setting.hbs @@ -188,15 +188,15 @@ {{#gh-form-group class="gh-labs-mailgun-region"}}
- {{#power-select - options=this.mailgunRegions - selected=this.mailgunRegion - onchange=(action "setBulkEmailRegion") - searchEnabled=false - as |region| - }} - {{region.flag}} {{region.name}} - {{/power-select}} + + {{region.flag}} {{region.name}} +
{{/gh-form-group}} {{#gh-form-group}} diff --git a/ghost/admin/app/templates/components/gh-nav-menu.hbs b/ghost/admin/app/templates/components/gh-nav-menu.hbs index aef7f09ca0..79bef7ac06 100644 --- a/ghost/admin/app/templates/components/gh-nav-menu.hbs +++ b/ghost/admin/app/templates/components/gh-nav-menu.hbs @@ -92,8 +92,8 @@ {{/if}}
- {{#gh-basic-dropdown horizontalPosition="left" verticalPosition="top" calculatePosition=this.userDropdownPosition as |dropdown|}} - {{#dropdown.trigger tagName="div" class="flex items-center outline-0 pointer space-between pa2 pl4 pr3"}} + +
{{#if this.whatsNew.hasNew}}{{/if}} @@ -104,9 +104,9 @@
{{svg-jar "arrow-down" class="w3 mr1 fill-darkgrey"}} - {{/dropdown.trigger}} +
- {{#dropdown.content class="gh-nav-menu-dropdown"}} + - {{/dropdown.content}} - {{/gh-basic-dropdown}} + +
diff --git a/ghost/admin/app/templates/components/gh-psm-authors-input.hbs b/ghost/admin/app/templates/components/gh-psm-authors-input.hbs index d300ad1f80..80bb35a8f6 100644 --- a/ghost/admin/app/templates/components/gh-psm-authors-input.hbs +++ b/ghost/admin/app/templates/components/gh-psm-authors-input.hbs @@ -1,8 +1,8 @@ -{{gh-token-input - options=this.availableAuthors - selected=this.selectedAuthors - onchange=(action "updateAuthors") - allowCreation=false - renderInPlace=true - triggerId=this.triggerId -}} + \ No newline at end of file diff --git a/ghost/admin/app/templates/components/gh-psm-tags-input.hbs b/ghost/admin/app/templates/components/gh-psm-tags-input.hbs index b98c457849..76bf935997 100644 --- a/ghost/admin/app/templates/components/gh-psm-tags-input.hbs +++ b/ghost/admin/app/templates/components/gh-psm-tags-input.hbs @@ -1,12 +1,12 @@ -{{gh-token-input - extra=(hash + diff --git a/ghost/admin/app/templates/components/gh-publishmenu.hbs b/ghost/admin/app/templates/components/gh-publishmenu.hbs index 2cc86bb1e6..a8b34bbda3 100644 --- a/ghost/admin/app/templates/components/gh-publishmenu.hbs +++ b/ghost/admin/app/templates/components/gh-publishmenu.hbs @@ -1,9 +1,9 @@ -{{#basic-dropdown verticalPosition="below" onOpen=(action "open") onClose=(action "close") as |dd|}} - {{#dd.trigger class="gh-btn gh-btn-outline gh-publishmenu-trigger"}} + + {{this.triggerText}} {{svg-jar "arrow-down"}} - {{/dd.trigger}} + - {{#dd.content class="gh-publishmenu-dropdown"}} + {{#if (eq this.displayState "published")}} {{gh-publishmenu-published post=this.post @@ -49,8 +49,8 @@ data-test-publishmenu-save=true /> - {{/dd.content}} -{{/basic-dropdown}} + + {{#if this.showEmailConfirmationModal}} {{highlighted-text name.title select.searchText}} -{{/power-select}} + diff --git a/ghost/admin/app/templates/components/gh-token-input.hbs b/ghost/admin/app/templates/components/gh-token-input.hbs index 04a9a8c040..b0e51d34f2 100644 --- a/ghost/admin/app/templates/components/gh-token-input.hbs +++ b/ghost/admin/app/templates/components/gh-token-input.hbs @@ -1,55 +1,64 @@ -{{#gh-token-input/select-multiple - afterOptionsComponent=this.afterOptionsComponent - allowClear=this.allowClear - ariaDescribedBy=this.ariaDescribedBy - ariaInvalid=this.ariaInvalid - ariaLabel=this.ariaLabel - ariaLabelledBy=this.ariaLabelledBy - beforeOptionsComponent=this.beforeOptionsComponent - class=(concat "gh-token-input " this.class) - closeOnSelect=this.closeOnSelect - defaultHighlighted=this.defaultHighlighted - destination=destination - dir=this.dir - disabled=this.disabled - dropdownClass=this.dropdownClass - extra=this.extra - horizontalPosition=this.horizontalPosition - initiallyOpened=this.initiallyOpened - loadingMessage=this.loadingMessage - matcher=this.matcher - matchTriggerWidth=this.matchTriggerWidth - noMatchesMessage=this.noMatchesMessage - onblur=(action "onblur") - onchange=(action this.selectOrCreate) - onclose=this.onclose - onfocus=(action "onfocus") - oninput=this.oninput - onkeydown=(action "handleKeydown") - onopen=this.onopen - options=this.optionsWithoutSelected - optionsComponent=(or this.optionsComponent "power-select-vertical-collection-options") - placeholder=placeholder - registerAPI=this.registerAPI - renderInPlace=this.renderInPlace - search=(action this.searchAndSuggest) - searchEnabled=this.searchEnabled - searchField=this.searchField - searchMessage=this.searchMessage - searchPlaceholder=this.searchPlaceholder - selected=selected - selectedItemComponent=this.selectedItemComponent - tabindex=this.tabindex - triggerClass=this.triggerClass - triggerComponent=this.triggerComponent - triggerId=this.triggerId - verticalPosition=this.verticalPosition - data-test-token-input=true - as |option term| -}} + {{#if option.__isSuggestion__}} - {{gh-token-input/suggested-option option=option term=term}} + {{else}} {{get option this.labelField}} {{/if}} -{{/gh-token-input/select-multiple}} + \ No newline at end of file diff --git a/ghost/admin/app/templates/components/gh-token-input/select-multiple.hbs b/ghost/admin/app/templates/components/gh-token-input/select-multiple.hbs index e7f0a335d4..bcf6c33d40 100644 --- a/ghost/admin/app/templates/components/gh-token-input/select-multiple.hbs +++ b/ghost/admin/app/templates/components/gh-token-input/select-multiple.hbs @@ -1,125 +1,64 @@ {{!-- - NOTE: changes from ember-power-select: + NOTE: changes from ember-power-select template... - `extra` has our custom drag-tracking actions assigned to it - --}} -{{#if (hasBlock "inverse")}} - {{#gh-token-input/select - afterOptionsComponent=this.afterOptionsComponent - allowClear=this.allowClear - ariaDescribedBy=this.ariaDescribedBy - ariaInvalid=this.ariaInvalid - ariaLabel=this.ariaLabel - ariaLabelledBy=this.ariaLabelledBy - beforeOptionsComponent=this.beforeOptionsComponent - buildSelection=(action "buildSelection") - calculatePosition=this.calculatePosition - class=this.class - closeOnSelect=this.closeOnSelect - defaultHighlighted=this.defaultHighlighted - destination=destination - dir=this.dir - disabled=this.disabled - dropdownClass=this.dropdownClass - extra=(assign this.extra (hash - optionMouseDown=(action "optionMouseDown") - optionTouchStart=(action "optionTouchStart") - )) - horizontalPosition=this.horizontalPosition - initiallyOpened=this.initiallyOpened - loadingMessage=this.loadingMessage - matcher=this.matcher - matchTriggerWidth=this.matchTriggerWidth - noMatchesMessage=this.noMatchesMessage - onblur=this.onblur - onchange=this.onchange - onclose=this.onclose - onfocus=(action "handleFocus") - oninput=this.oninput - onkeydown=(action "handleKeydown") - onopen=(action "handleOpen") - options=options - optionsComponent=this.optionsComponent - groupComponent=this.groupComponent - placeholder=placeholder - registerAPI=(readonly this.registerAPI) - renderInPlace=this.renderInPlace - required=this.required - scrollTo=this.scrollTo - search=search - searchEnabled=this.searchEnabled - searchField=this.searchField - searchMessage=this.searchMessage - searchPlaceholder=this.searchPlaceholder - selected=selected - selectedItemComponent=this.selectedItemComponent - tabindex=this.computedTabIndex - tagName=this.tagName - triggerClass=this.concatenatedTriggerClass - triggerComponent=(component this.triggerComponent tabindex=this.tabindex) - triggerId=this.triggerId - verticalPosition=this.verticalPosition - as |option select|}} +--}} + {{yield option select}} - {{else}} - {{yield to="inverse"}} - {{/gh-token-input/select}} -{{else}} - {{#gh-token-input/select - afterOptionsComponent=this.afterOptionsComponent - allowClear=this.allowClear - ariaDescribedBy=this.ariaDescribedBy - ariaInvalid=this.ariaInvalid - ariaLabel=this.ariaLabel - ariaLabelledBy=this.ariaLabelledBy - beforeOptionsComponent=this.beforeOptionsComponent - buildSelection=(action "buildSelection") - calculatePosition=this.calculatePosition - class=this.class - closeOnSelect=this.closeOnSelect - defaultHighlighted=this.defaultHighlighted - destination=destination - dir=this.dir - disabled=this.disabled - dropdownClass=this.dropdownClass - extra=(assign this.extra (hash - optionMouseDown=(action "optionMouseDown") - optionTouchStart=(action "optionTouchStart") - )) - horizontalPosition=this.horizontalPosition - initiallyOpened=this.initiallyOpened - loadingMessage=this.loadingMessage - matcher=this.matcher - matchTriggerWidth=this.matchTriggerWidth - noMatchesMessage=this.noMatchesMessage - onblur=this.onblur - onchange=this.onchange - onclose=this.onclose - onfocus=(action "handleFocus") - oninput=this.oninput - onkeydown=(action "handleKeydown") - onopen=(action "handleOpen") - options=options - optionsComponent=this.optionsComponent - groupComponent=this.groupComponent - placeholder=placeholder - registerAPI=(readonly this.registerAPI) - renderInPlace=this.renderInPlace - required=this.required - scrollTo=this.scrollTo - search=search - searchEnabled=this.searchEnabled - searchField=this.searchField - searchMessage=this.searchMessage - searchPlaceholder=this.searchPlaceholder - selected=selected - selectedItemComponent=this.selectedItemComponent - tabindex=this.computedTabIndex - tagName=this.tagName - triggerClass=this.concatenatedTriggerClass - triggerComponent=(component this.triggerComponent tabindex=this.tabindex) - triggerId=this.triggerId - verticalPosition=this.verticalPosition - as |option select|}} - {{yield option select}} - {{/gh-token-input/select}} -{{/if}} + \ No newline at end of file diff --git a/ghost/admin/app/templates/components/gh-token-input/select.hbs b/ghost/admin/app/templates/components/gh-token-input/select.hbs deleted file mode 100644 index f805274716..0000000000 --- a/ghost/admin/app/templates/components/gh-token-input/select.hbs +++ /dev/null @@ -1,103 +0,0 @@ -{{!-- - NOTE: the only thing changed here is `eventType="click"` on dropdown.trigger - so it doesn't interfere with the drag-n-drop sorting - - When upgrading ember-power-select ensure the full component template is - copied across here ---}} -{{#basic-dropdown - classNames=(readonly this.classNames) - horizontalPosition=(readonly this.horizontalPosition) - calculatePosition=this.calculatePosition - destination=(readonly destination) - initiallyOpened=(readonly this.initiallyOpened) - matchTriggerWidth=(readonly this.matchTriggerWidth) - onClose=(action "onClose") - onOpen=(action "onOpen") - registerAPI=(action "registerAPI") - renderInPlace=(readonly this.renderInPlace) - verticalPosition=(readonly this.verticalPosition) - disabled=(readonly this.disabled) - as |dropdown|}} - - {{#dropdown.trigger - tagName=(readonly this._triggerTagName) - ariaDescribedBy=(readonly this.ariaDescribedBy) - ariaInvalid=(readonly this.ariaInvalid) - ariaLabel=(readonly this.ariaLabel) - ariaLabelledBy=(readonly this.ariaLabelledBy) - ariaRequired=(readonly this.required) - class=(readonly this.concatenatedTriggerClasses) - id=(readonly this.triggerId) - eventType="click" - onKeyDown=(action "onTriggerKeydown") - onFocus=(action "onTriggerFocus") - onBlur=(action "onTriggerBlur") - tabindex=(readonly this.tabindex)}} - {{#component this.triggerComponent - allowClear=(readonly this.allowClear) - buildSelection=(readonly this.buildSelection) - extra=(readonly this.extra) - listboxId=(readonly this.optionsId) - loadingMessage=(readonly this.loadingMessage) - onFocus=(action "onFocus") - onBlur=(action "onBlur") - onInput=(action "onInput") - placeholder=(readonly placeholder) - placeholderComponent=(readonly this.placeholderComponent) - onKeydown=(action "onKeydown") - searchEnabled=(readonly this.searchEnabled) - searchField=(readonly this.searchField) - select=(readonly this.publicAPI) - selectedItemComponent=(readonly this.selectedItemComponent) - as |opt term|}} - {{yield opt term}} - {{/component}} - {{/dropdown.trigger}} - - {{#dropdown.content _contentTagName=this._contentTagName class=(readonly this.concatenatedDropdownClasses)}} - {{component this.beforeOptionsComponent - extra=(readonly this.extra) - listboxId=(readonly this.optionsId) - onInput=(action "onInput") - onKeydown=(action "onKeydown") - searchEnabled=(readonly this.searchEnabled) - onFocus=(action "onFocus") - onBlur=(action "onBlur") - placeholder=(readonly placeholder) - placeholderComponent=(readonly this.placeholderComponent) - searchPlaceholder=(readonly this.searchPlaceholder) - select=(readonly this.publicAPI)}} - {{#if this.mustShowSearchMessage}} - {{component this.searchMessageComponent - searchMessage=(readonly this.searchMessage) - select=(readonly this.publicAPI) - }} - {{else if this.mustShowNoMessages}} - {{#if (hasBlock "inverse")}} - {{yield to="inverse"}} - {{else if this.noMatchesMessage}} -
    -
  • - {{this.noMatchesMessage}} -
  • -
- {{/if}} - {{else}} - {{#component this.optionsComponent - class="ember-power-select-options" - extra=(readonly this.extra) - groupIndex="" - loadingMessage=(readonly this.loadingMessage) - id=(readonly this.optionsId) - options=(readonly this.publicAPI.results) - optionsComponent=(readonly this.optionsComponent) - groupComponent=(readonly this.groupComponent) - select=(readonly this.publicAPI) - as |option term|}} - {{yield option term}} - {{/component}} - {{/if}} - {{component this.afterOptionsComponent select=(readonly this.publicAPI) extra=(readonly this.extra)}} - {{/dropdown.content}} -{{/basic-dropdown}} diff --git a/ghost/admin/app/templates/components/gh-token-input/trigger.hbs b/ghost/admin/app/templates/components/gh-token-input/trigger.hbs index f710180212..7008d8ac28 100644 --- a/ghost/admin/app/templates/components/gh-token-input/trigger.hbs +++ b/ghost/admin/app/templates/components/gh-token-input/trigger.hbs @@ -39,7 +39,26 @@ {{/each}} {{#if this.searchEnabled}} - + {{/if}} {{/sortable-objects}} diff --git a/ghost/admin/app/templates/components/power-select-vertical-collection-options.hbs b/ghost/admin/app/templates/components/power-select-vertical-collection-options.hbs index a76fb7171b..57cb207dfd 100644 --- a/ghost/admin/app/templates/components/power-select-vertical-collection-options.hbs +++ b/ghost/admin/app/templates/components/power-select-vertical-collection-options.hbs @@ -1,16 +1,19 @@ -{{#if select.loading}} - {{#if this.loadingMessage}} -
  • {{this.loadingMessage}}
  • - {{/if}} -{{/if}} -{{#vertical-collection options minHeight=30 estimateHeight=6 bufferSize=10 as |opt index|}} -
  • - {{yield opt select}} -
  • -{{/vertical-collection}} +
      + {{#if @select.loading}} + {{#if @loadingMessage}} +
    • {{@loadingMessage}}
    • + {{/if}} + {{/if}} + + {{#vertical-collection options minHeight=30 estimateHeight=6 bufferSize=10 as |opt index|}} +
    • + {{yield opt @select}} +
    • + {{/vertical-collection}} +
    \ No newline at end of file diff --git a/ghost/admin/app/templates/components/power-select/trigger.hbs b/ghost/admin/app/templates/components/power-select/trigger.hbs index 6e6cc7c5dc..491c622db4 100644 --- a/ghost/admin/app/templates/components/power-select/trigger.hbs +++ b/ghost/admin/app/templates/components/power-select/trigger.hbs @@ -1,13 +1,14 @@ -{{#if select.selected}} - {{#if this.selectedItemComponent}} - {{component this.selectedItemComponent option=(readonly select.selected) select=(readonly select)}} +{{#if @select.selected}} + {{#if @selectedItemComponent}} + {{component @selectedItemComponent extra=(readonly @extra) option=(readonly @option.selected) select=(readonly @select)}} {{else}} - {{yield select.selected select}} + {{yield @select.selected select}} {{/if}} - {{#if (and this.allowClear (not select.disabled))}} - × + {{#if (and @allowClear (not @select.disabled))}} + × {{/if}} {{else}} - {{component this.placeholderComponent placeholder=placeholder}} + {{component @placeholderComponent placeholder=@placeholder}} {{/if}} +{{!-- this next line is the only difference from original trigger.hbs --}} {{svg-jar "arrow-down-small"}} diff --git a/ghost/admin/app/templates/pages-loading.hbs b/ghost/admin/app/templates/pages-loading.hbs index 0523c46f79..b44a85a7ab 100644 --- a/ghost/admin/app/templates/pages-loading.hbs +++ b/ghost/admin/app/templates/pages-loading.hbs @@ -4,77 +4,77 @@
    {{#unless this.session.user.isContributor}} - {{#power-select - selected=this.selectedType - options=this.availableTypes - searchEnabled=false - onchange=(action (mut k)) - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-type" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - matchTriggerWidth=false - data-test-type-select=true + + {{type.name}} + {{/unless}} {{#unless this.session.user.isAuthorOrContributor}} - {{#power-select - selected=this.selectedAuthor - options=this.availableAuthors - searchField="name" - onchange=(action (mut k)) - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-author" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - searchPlaceholder="Search authors" - matchTriggerWidth=false - data-test-author-select=true + + {{author.name}} + {{/unless}} {{#unless this.session.user.isContributor}} - {{#power-select - selected=this.selectedTag - options=this.availableTags - searchField="name" - onchange=(action (mut k)) - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-tag" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - searchPlaceholder="Search tags" - matchTriggerWidth=false - optionsComponent="power-select-vertical-collection-options" - data-test-tag-select=true + + {{tag.name}} + {{/unless}} - {{#power-select - selected=this.selectedOrder - options=this.availableOrders - searchEnabled=false - onchange=(action (mut k)) - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-sort" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - matchTriggerWidth=false - data-test-order-select=true + + {{order.name}} +
    {{#link-to "editor.new" "page" class="gh-btn gh-btn-green" data-test-new-page-button=true}}New page{{/link-to}} diff --git a/ghost/admin/app/templates/pages.hbs b/ghost/admin/app/templates/pages.hbs index 5e716667a4..5ff685fc12 100644 --- a/ghost/admin/app/templates/pages.hbs +++ b/ghost/admin/app/templates/pages.hbs @@ -4,77 +4,77 @@
    {{#unless this.session.user.isContributor}} - {{#power-select - selected=this.selectedType - options=this.availableTypes - searchEnabled=false - onchange=(action "changeType") - tagName="div" - classNames=this.typeClassNames - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - matchTriggerWidth=false - data-test-type-select=true + {{type.name}} - {{/power-select}} + {{/unless}} {{#unless this.session.user.isAuthorOrContributor}} - {{#power-select - selected=this.selectedAuthor - options=this.availableAuthors - searchField="name" - onchange=(action "changeAuthor") - tagName="div" - classNames=this.authorClassNames - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - searchPlaceholder="Search authors" - matchTriggerWidth=false - data-test-author-select=true + {{author.name}} - {{/power-select}} + {{/unless}} {{#unless this.session.user.isContributor}} - {{#power-select - selected=this.selectedTag - options=this.availableTags - searchField="name" - onchange=(action "changeTag") - tagName="div" - classNames=this.tagClassNames - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - searchPlaceholder="Search tags" - matchTriggerWidth=false - optionsComponent="power-select-vertical-collection-options" - data-test-tag-select=true + {{tag.name}} - {{/power-select}} + {{/unless}} - {{#power-select - selected=this.selectedOrder - options=this.availableOrders - searchEnabled=false - onchange=(action "changeOrder") - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-sort" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - matchTriggerWidth=false - data-test-order-select=true + {{order.name}} - {{/power-select}} +
    {{#link-to "editor.new" "page" class="gh-btn gh-btn-green" data-test-new-page-button=true}}New page{{/link-to}} diff --git a/ghost/admin/app/templates/posts-loading.hbs b/ghost/admin/app/templates/posts-loading.hbs index 81d9a03889..5c772aff93 100644 --- a/ghost/admin/app/templates/posts-loading.hbs +++ b/ghost/admin/app/templates/posts-loading.hbs @@ -4,77 +4,77 @@
    {{#unless this.session.user.isContributor}} - {{#power-select - selected=this.selectedType - options=this.availableTypes - searchEnabled=false - onchange=(action (mut k)) - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-type" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - matchTriggerWidth=false - data-test-type-select=true + + {{type.name}} + {{/unless}} {{#unless this.session.user.isAuthorOrContributor}} - {{#power-select - selected=this.selectedAuthor - options=this.availableAuthors - searchField="name" - onchange=(action (mut k)) - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-author" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - searchPlaceholder="Search authors" - matchTriggerWidth=false - data-test-author-select=true + + {{author.name}} + {{/unless}} {{#unless this.session.user.isContributor}} - {{#power-select - selected=this.selectedTag - options=this.availableTags - searchField="name" - onchange=(action (mut k)) - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-tag" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - searchPlaceholder="Search tags" - matchTriggerWidth=false - optionsComponent="power-select-vertical-collection-options" - data-test-tag-select=true + + {{tag.name}} + {{/unless}} - {{#power-select - selected=this.selectedOrder - options=this.availableOrders - searchEnabled=false - onchange=(action (mut k)) - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-sort" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - matchTriggerWidth=false - data-test-order-select=true + + {{order.name}} +
    {{#link-to "editor.new" "post" class="gh-btn gh-btn-green" data-test-new-post-button=true}}New post{{/link-to}} diff --git a/ghost/admin/app/templates/posts.hbs b/ghost/admin/app/templates/posts.hbs index d82aa078d9..bae7636775 100644 --- a/ghost/admin/app/templates/posts.hbs +++ b/ghost/admin/app/templates/posts.hbs @@ -4,77 +4,77 @@
    {{#unless this.session.user.isContributor}} - {{#power-select - selected=this.selectedType - options=this.availableTypes - searchEnabled=false - onchange=(action "changeType") - tagName="div" - classNames=this.typeClassNames - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - matchTriggerWidth=false - data-test-type-select=true + {{type.name}} - {{/power-select}} + {{/unless}} {{#unless this.session.user.isAuthorOrContributor}} - {{#power-select - selected=this.selectedAuthor - options=this.availableAuthors - searchField="name" - onchange=(action "changeAuthor") - tagName="div" - classNames=this.authorClassNames - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - searchPlaceholder="Search authors" - matchTriggerWidth=false - data-test-author-select=true + {{author.name}} - {{/power-select}} + {{/unless}} {{#unless this.session.user.isContributor}} - {{#power-select - selected=this.selectedTag - options=this.availableTags - searchField="name" - onchange=(action "changeTag") - tagName="div" - classNames=this.tagClassNames - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - searchPlaceholder="Search tags" - matchTriggerWidth=false - optionsComponent="power-select-vertical-collection-options" - data-test-tag-select=true + {{tag.name}} - {{/power-select}} + {{/unless}} - {{#power-select - selected=this.selectedOrder - options=this.availableOrders - searchEnabled=false - onchange=(action "changeOrder") - tagName="div" - classNames="gh-contentfilter-menu gh-contentfilter-sort" - triggerClass="gh-contentfilter-menu-trigger" - dropdownClass="gh-contentfilter-menu-dropdown" - matchTriggerWidth=false - data-test-order-select=true + {{order.name}} - {{/power-select}} +
    {{#link-to "editor.new" "post" class="gh-btn gh-btn-green" data-test-new-post-button=true}}New post{{/link-to}} diff --git a/ghost/admin/app/utils/computed-fallback-if-undefined.js b/ghost/admin/app/utils/computed-fallback-if-undefined.js new file mode 100644 index 0000000000..4ff31dd968 --- /dev/null +++ b/ghost/admin/app/utils/computed-fallback-if-undefined.js @@ -0,0 +1,13 @@ +import {computed} from '@ember/object'; + +export default function computedFallbackIfUndefined(fallback) { + return computed({ + get() { + return fallback; + }, + + set(_, v) { + return v === undefined ? fallback : v; + } + }); +} diff --git a/ghost/admin/package.json b/ghost/admin/package.json index 48d2eb3003..7bafbd3304 100644 --- a/ghost/admin/package.json +++ b/ghost/admin/package.json @@ -85,8 +85,8 @@ "ember-moment": "8.0.0", "ember-one-way-select": "4.0.0", "ember-power-calendar-moment": "0.1.7", - "ember-power-datepicker": "0.6.2", - "ember-power-select": "2.3.5", + "ember-power-datepicker": "0.7.1", + "ember-power-select": "3.0.6", "ember-resolver": "7.0.0", "ember-route-action-helper": "2.0.7", "ember-simple-auth": "2.1.1", diff --git a/ghost/admin/yarn.lock b/ghost/admin/yarn.lock index fc2c6b6cb3..f5a01e7669 100644 --- a/ghost/admin/yarn.lock +++ b/ghost/admin/yarn.lock @@ -941,6 +941,21 @@ ember-cli-typescript "^3.0.0" heimdalljs "^0.3.0" +"@ember-decorators/component@^6.0.0", "@ember-decorators/component@^6.1.0": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@ember-decorators/component/-/component-6.1.1.tgz#b360dc4fa8e576ee1c840879399ef1745fd96e06" + integrity sha512-Cj8tY/c0MC/rsipqsiWLh3YVN72DK92edPYamD/HzvftwzC6oDwawWk8RmStiBnG9PG/vntAt41l3S7HSSA+1Q== + dependencies: + "@ember-decorators/utils" "^6.1.1" + ember-cli-babel "^7.1.3" + +"@ember-decorators/utils@^6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@ember-decorators/utils/-/utils-6.1.1.tgz#6b619814942b4fb3747cfa9f540c9f05283d7c5e" + integrity sha512-0KqnoeoLKb6AyoSU65TRF5T85wmS4uDn06oARddwNPxxf/lt5jQlh41uX3W7V/fWL9tPu8x1L1Vvpc80MN1+YA== + dependencies: + ember-cli-babel "^7.1.3" + "@ember/edition-utils@^1.1.1", "@ember/edition-utils@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@ember/edition-utils/-/edition-utils-1.2.0.tgz#a039f542dc14c8e8299c81cd5abba95e2459cfa6" @@ -979,7 +994,7 @@ ember-cli-babel "^6.16.0" ember-compatibility-helpers "^1.1.1" -"@ember/render-modifiers@1.0.2": +"@ember/render-modifiers@1.0.2", "@ember/render-modifiers@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@ember/render-modifiers/-/render-modifiers-1.0.2.tgz#2e87c48db49d922ce4850d707215caaac60d8444" integrity sha512-6tEnHl5+62NTSAG2mwhGMFPhUrJQjoVqV+slsn+rlTknm2Zik+iwxBQEbwaiQOU1FUYxkS8RWcieovRNMR8inQ== @@ -4949,14 +4964,18 @@ ember-auto-import@1.5.3, ember-auto-import@^1.2.15, ember-auto-import@^1.2.19: walk-sync "^0.3.3" webpack "~4.28" -ember-basic-dropdown@^1.1.0, ember-basic-dropdown@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/ember-basic-dropdown/-/ember-basic-dropdown-1.1.3.tgz#0506045ccc60db4972fc78b963c1324f6415818a" - integrity sha512-zIFk5yzu31L4E5lz3DfXF1IGGMcMAGYssh7hCoemjB7iqkL7Sf1UhUg/yEHcr5aEdfyGc1V3G2s740cRY+VLiQ== +ember-basic-dropdown@^2.0.13, ember-basic-dropdown@^2.0.4: + version "2.0.13" + resolved "https://registry.yarnpkg.com/ember-basic-dropdown/-/ember-basic-dropdown-2.0.13.tgz#f081496a9e50f855ad58e614fe96a4abb06cb254" + integrity sha512-FaUIFjuy/Qg/5r+cev/IRiUabsztVNpMbk7YypsHXYrty8xkfpRNIrRB2DWfzRR0LcpjDiSevyAPvze+S70Xhw== dependencies: - ember-cli-babel "^7.2.0" - ember-cli-htmlbars "^3.0.1" - ember-maybe-in-element "^0.2.0" + "@ember-decorators/component" "^6.1.0" + "@ember/render-modifiers" "^1.0.2" + ember-cli-babel "^7.11.0" + ember-cli-htmlbars "^4.0.8" + ember-element-helper "^0.2.0" + ember-maybe-in-element "^0.4.0" + ember-truth-helpers "2.1.0" ember-cli-app-version@3.2.0: version "3.2.0" @@ -4971,7 +4990,7 @@ ember-cli-babel-plugin-helpers@^1.0.0, ember-cli-babel-plugin-helpers@^1.1.0: resolved "https://registry.yarnpkg.com/ember-cli-babel-plugin-helpers/-/ember-cli-babel-plugin-helpers-1.1.0.tgz#de3baedd093163b6c2461f95964888c1676325ac" integrity sha512-Zr4my8Xn+CzO0gIuFNXji0eTRml5AxZUTDQz/wsNJ5AJAtyFWCY4QtKdoELNNbiCVGt1lq5yLiwTm4scGKu6xA== -ember-cli-babel@7.13.2, ember-cli-babel@^7.1.0, ember-cli-babel@^7.1.2, ember-cli-babel@^7.1.3, ember-cli-babel@^7.10.0, ember-cli-babel@^7.11.0, ember-cli-babel@^7.11.1, ember-cli-babel@^7.12.0, ember-cli-babel@^7.13.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.2.0, ember-cli-babel@^7.5.0, ember-cli-babel@^7.7.3, ember-cli-babel@^7.8.0: +ember-cli-babel@7.13.2, ember-cli-babel@^7.1.0, ember-cli-babel@^7.1.2, ember-cli-babel@^7.1.3, ember-cli-babel@^7.10.0, ember-cli-babel@^7.11.0, ember-cli-babel@^7.11.1, ember-cli-babel@^7.12.0, ember-cli-babel@^7.13.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.5.0, ember-cli-babel@^7.7.3, ember-cli-babel@^7.8.0: version "7.13.2" resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.13.2.tgz#6b6f4d508cc3bb300c5711d3d02c59ba80f0f686" integrity sha512-VH2tMXaRFkbQEyVJnxUtAyta5bAKjtcLwJ4lStW/iRk/NIlNFNJh1uOd7uL9H9Vm0f4/xR7Mc0Q7ND9ezKOo+A== @@ -5128,7 +5147,7 @@ ember-cli-htmlbars-inline-precompile@^2.1.0: heimdalljs-logger "^0.1.9" silent-error "^1.1.0" -ember-cli-htmlbars@4.2.1: +ember-cli-htmlbars@4.2.1, ember-cli-htmlbars@^4.0.8: version "4.2.1" resolved "https://registry.yarnpkg.com/ember-cli-htmlbars/-/ember-cli-htmlbars-4.2.1.tgz#c74c5deba6025c8e80d84289a88901073e1ca1f7" integrity sha512-jZ9LYO4R6ieYC5Bcei4RWbK2/SY0LDQ5cUIyt9YQpN/VU7A9G+es9w7FJYfHtDD+TxvaXDKMuXAeBwOz+mZKPA== @@ -5507,7 +5526,7 @@ ember-composable-helpers@3.0.3: ember-cli-babel "^7.1.0" resolve "^1.10.0" -ember-concurrency@1.1.4, "ember-concurrency@^0.8.27 || ^0.9.0 || ^0.10.0 || ^1.0.0": +ember-concurrency@1.1.4, "ember-concurrency@^0.8.27 || ^0.9.0 || ^0.10.0 || ^1.0.0 || ^1.1.0", ember-concurrency@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/ember-concurrency/-/ember-concurrency-1.1.4.tgz#ee8eb773e4b426d0d720410e33d1082f3218ac66" integrity sha512-wA5TBTtuEsWnpDXsaC4UIfr0eLyw/mGxAor7eRp4i4uWKPGL3Tf0BWu2Zl19vuX5eCucdsXlpdhjcdd/tR7WKQ== @@ -5556,6 +5575,13 @@ ember-drag-drop@0.4.8: dependencies: ember-cli-babel "^6.6.0" +ember-element-helper@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ember-element-helper/-/ember-element-helper-0.2.0.tgz#eacdf4d8507d6708812623206e24ad37bad487e7" + integrity sha512-/WV0PNLyxDvLX/YETb/8KICFTr719OYqFWXqV5XUkh9YhhBGDU/mr1OtlQaWOlsx+sHm42HD2UAICecqex8ziw== + dependencies: + ember-cli-babel "^6.16.0" + ember-exam@4.0.9: version "4.0.9" resolved "https://registry.yarnpkg.com/ember-exam/-/ember-exam-4.0.9.tgz#a3a9a85647654549490e73365adb9f64ce9c285f" @@ -5706,10 +5732,10 @@ ember-maybe-import-regenerator@^0.1.6: ember-cli-babel "^6.0.0-beta.4" regenerator-runtime "^0.9.5" -ember-maybe-in-element@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/ember-maybe-in-element/-/ember-maybe-in-element-0.2.0.tgz#9ac51cbbd9d83d6230ad996c11e33f0eca3032e0" - integrity sha512-R5e6N8yDbfNbA/3lMZsFs2KEzv/jt80TsATiKMCqdqKuSG82KrD25cRdU5VkaE8dTQbziyBeuJs90bBiqOnakQ== +ember-maybe-in-element@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/ember-maybe-in-element/-/ember-maybe-in-element-0.4.0.tgz#fe1994c60ee64527d2b2f3b4479ebf8806928bd8" + integrity sha512-ADQ9jewz46Y2MWiTAKrheIukHiU6p0QHn3xqz1BBDDOmubW1WdAjSrvtkEWsJQ08DyxIn3RdMuNDzAUo6HN6qw== dependencies: ember-cli-babel "^7.1.0" @@ -5762,36 +5788,41 @@ ember-power-calendar-moment@0.1.7: ember-cli-babel "^7.7.3" ember-cli-moment-shim "^3.7.1" -ember-power-calendar@^0.13.3: - version "0.13.3" - resolved "https://registry.yarnpkg.com/ember-power-calendar/-/ember-power-calendar-0.13.3.tgz#daff0f668ffbe65fd59c479aa5569e58c59daafd" - integrity sha512-xgXEHke4yzjZ9VUkQ/Cgd5c/lAUtl8chQilKDx7FMV+1z7/uLi9hxG56e1NHHbwEI9KBUPtO+pimuPqbZ3DzEg== +ember-power-calendar@^0.14.1: + version "0.14.5" + resolved "https://registry.yarnpkg.com/ember-power-calendar/-/ember-power-calendar-0.14.5.tgz#6d3ed1cafcbcb3c945ab70bbcebeb875059030bf" + integrity sha512-SbFp8mLpoqxiGphIidZR+q4Za7aqJhMAkuw0piU/qBksC/OtQZDL0i5V1bti4yD90aI2I6IlOuHFyod9LQ7Gkg== dependencies: + "@ember-decorators/component" "^6.0.0" ember-assign-helper "^0.2.0" - ember-cli-babel "^7.2.0" + ember-cli-babel "^7.7.3" ember-cli-element-closest-polyfill "^0.0.1" - ember-cli-htmlbars "^3.0.1" - ember-concurrency "^0.8.27 || ^0.9.0 || ^0.10.0 || ^1.0.0" + ember-cli-htmlbars "^3.1.0" + ember-concurrency "^0.8.27 || ^0.9.0 || ^0.10.0 || ^1.0.0 || ^1.1.0" + ember-element-helper "^0.2.0" + ember-truth-helpers "^2.1.0" -ember-power-datepicker@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/ember-power-datepicker/-/ember-power-datepicker-0.6.2.tgz#5fd2da3b3871787fee825ac51cdc6d5bf7148607" - integrity sha512-pE6ntPAQUlQRbymQyLzxrufmQUEwBMUTZ+BMYnihWjIAJWPMaqXagBwhVnfZ65N/KSXF3IylFuLitgsri4lUHg== +ember-power-datepicker@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ember-power-datepicker/-/ember-power-datepicker-0.7.1.tgz#64c2b3a5bde860aea0101e7a0d9317b00930a1d2" + integrity sha512-vewFUXagd2kFRMV7KAE4ir9iO2IieTHdi6tS1SENyF6s1Vajece0M4ytHxSolixoFCWwblzyDugRFG3nOEN4fg== dependencies: - ember-basic-dropdown "^1.1.2" + "@ember-decorators/component" "^6.0.0" + ember-basic-dropdown "^2.0.4" ember-cli-babel "^7.8.0" ember-cli-htmlbars "^3.1.0" - ember-power-calendar "^0.13.3" + ember-power-calendar "^0.14.1" -ember-power-select@2.3.5: - version "2.3.5" - resolved "https://registry.yarnpkg.com/ember-power-select/-/ember-power-select-2.3.5.tgz#c702d5cf5b2c6c2fd422f0a8253e982cecbdd048" - integrity sha512-75QJklWSthm9gedcbpKC0ZALaQXEfKlIRRy5pb87GsXcykFn0rBgxlnGsITWO+IX9u2V0oojQPorIa/ZYKVd3Q== +ember-power-select@3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/ember-power-select/-/ember-power-select-3.0.6.tgz#97dcbaf04e6afd9bd4c75cbb150c3a8d5fe50fec" + integrity sha512-osS+fbwfaxPo5RCCKDOWzJfaNc+toMmg3MMGmLz3h73Uqd3burRSUBo3DAkEHyYVHCy+oMas4+eZtRcjUrLWjg== dependencies: - ember-basic-dropdown "^1.1.0" - ember-cli-babel "^7.7.3" - ember-cli-htmlbars "^3.0.1" - ember-concurrency "^0.8.27 || ^0.9.0 || ^0.10.0 || ^1.0.0" + "@ember-decorators/component" "^6.1.0" + ember-basic-dropdown "^2.0.13" + ember-cli-babel "^7.11.0" + ember-cli-htmlbars "^3.1.0" + ember-concurrency "^1.0.0" ember-text-measurer "^0.5.0" ember-truth-helpers "^2.1.0"