diff --git a/resources/js/components/fieldtypes/bard/BardButtonsSettingFieldtype.vue b/resources/js/components/fieldtypes/bard/BardButtonsSettingFieldtype.vue index 79b19e852c3..53ccdacb996 100644 --- a/resources/js/components/fieldtypes/bard/BardButtonsSettingFieldtype.vue +++ b/resources/js/components/fieldtypes/bard/BardButtonsSettingFieldtype.vue @@ -58,7 +58,28 @@ export default { methods: { initButtons() { - let available = addButtonHtml(availableButtons()); + // Get all default buttons first + let available = availableButtons(); + + // Add custom buttons from a project or addon + this.$bard.buttonCallbacks.map(callback => { + // Since the developer uses the same callback to add buttons to the field itself, and for the + // button configurator, we need to make the button conditional when on the Bard fieldtype, + // but not here. Here we want to just show them all, so the user is able to toggle it. + const buttonFn = (button) => button; + + let returned = callback(available, buttonFn); + + // No return value means they intend to manipulate the + // buttons object manually. Just continue on. + if (!returned) return; + + available = available.concat( + Array.isArray(returned) ? returned : [returned] + ); + }) + + available = addButtonHtml(available); let buttons = available.map(button => { button.enabled = this.data.includes(button.name); diff --git a/resources/js/components/fieldtypes/bard/BardFieldtype.vue b/resources/js/components/fieldtypes/bard/BardFieldtype.vue index 929855eef47..0c4020af13f 100644 --- a/resources/js/components/fieldtypes/bard/BardFieldtype.vue +++ b/resources/js/components/fieldtypes/bard/BardFieldtype.vue @@ -396,23 +396,31 @@ export default { // Get the configured buttons and swap them with corresponding objects let buttons = selectedButtons.map(button => { - return _.findWhere(availableButtons(), { name: button.toLowerCase() }) - || button; + return _.findWhere(availableButtons(), { name: button.toLowerCase() }) || button; }); // Let addons add, remove, or control the position of buttons. this.$bard.buttonCallbacks.forEach(callback => { - let returned = callback(buttons); + // Since the developer uses the same callback to add buttons to the field itself, and for the + // button configurator, we need to make the button conditional when on the Bard fieldtype + // but not in the button configurator. So here we'll filter it out if it's not selected. + const buttonFn = (button) => selectedButtons.includes(button.name) ? button : null; - // No return value means they intend to manipulate the - // buttons object manually. Just continue on. - if (! returned) return; + const addedButtons = callback(buttons, buttonFn); + + // No return value means either they literally returned nothing, with the intention + // of manipulating the buttons object manually. Or, they used the button() and + // the button was not configured in the field so it was stripped out. + if (! addedButtons) return; buttons = buttons.concat( - Array.isArray(returned) ? returned : [returned] + Array.isArray(addedButtons) ? addedButtons : [addedButtons] ); }); + // Remove any nulls. This could happen if a developer-added button was not specified in this field's buttons array. + buttons = buttons.filter(button => !!button); + // Remove any non-objects. This would happen if you configure a button name that doesn't exist. buttons = buttons.filter(button => typeof button != 'string');