0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-24 23:48:13 -05:00

Added delete button with confirmation to snippets in card menus

no issue

- show a delete icon when a snippet is hovered in plus/slash menus
- show a confirmation dialog when the delete icon is clicked
- keep menus open whilst displaying the delete confirmation dialog
This commit is contained in:
Kevin Ansfield 2020-10-26 17:09:09 +00:00
parent cddd977536
commit 1bd4b5cda7
14 changed files with 140 additions and 10 deletions

View file

@ -32,5 +32,6 @@
@wordCountDidChange={{action this.onWordCountChange}}
@snippets={{@snippets}}
@saveSnippet={{@saveSnippet}}
@deleteSnippet={{@deleteSnippet}}
/>
</div>

View file

@ -8,8 +8,11 @@
{{svg-jar "arrow-down-small"}}
</span>
</GhDropdownButton>
<GhDropdown @name="members-label-menu" @tagName="div"
@classNames="dropdown-menu dropdown-triangle-top-right dropdown-action">
<GhDropdown
@name="members-label-menu"
@tagName="div"
@classNames="dropdown-menu dropdown-triangle-top-right dropdown-action"
>
<ul class="dropdown-content">
{{#each @availableLabels as |label|}}
<li class="{{if (eq @selectedLabel.name label.name) "selected"}}">

View file

@ -0,0 +1,20 @@
<header class="modal-header">
<h1>Are you sure?</h1>
</header>
<a class="close" href="" role="button" title="Close" {{action "closeModal"}}>{{svg-jar "close"}}<span class="hidden">Close</span></a>
<div class="modal-body">
<p>
Deleting snippet "{{this.snippet.name}}" will make it unavailable to all staff users.
</p>
</div>
<div class="modal-footer">
<button {{action "closeModal"}} class="gh-btn"><span>Cancel</span></button>
<GhTaskButton
@buttonText="Delete Snippet"
@successText="Deleted"
@task={{this.deleteSnippet}}
@taskArgs={{this.snippet}}
@class="gh-btn gh-btn-red gh-btn-icon" />
</div>

View file

@ -0,0 +1,27 @@
import ModalComponent from 'ghost-admin/components/modal-base';
import {alias} from '@ember/object/computed';
import {inject as service} from '@ember/service';
import {task} from 'ember-concurrency';
export default ModalComponent.extend({
router: service(),
notifications: service(),
snippet: alias('model'),
actions: {
confirm() {
this.deleteSnippet.perform();
}
},
deleteSnippet: task(function* (snippet) {
try {
yield this.confirm(snippet);
} catch (error) {
this.notifications.showAPIError(error, {key: 'snippet.delete.failed'});
} finally {
this.send('closeModal');
}
}).drop()
});

View file

@ -102,6 +102,7 @@ export default Controller.extend({
showReAuthenticateModal: false,
showEmailPreviewModal: false,
showUpgradeModal: false,
showDeleteSnippetModal: false,
hostLimitError: null,
// koenig related properties
wordcount: null,
@ -310,6 +311,14 @@ export default Controller.extend({
snippetRecord.rollbackAttributes();
throw error;
});
},
toggleDeleteSnippetModal(snippet) {
this.set('snippetToDelete', snippet);
},
deleteSnippet(snippet) {
return snippet.destroyRecord();
}
},

View file

@ -804,6 +804,40 @@
color: var(--darkgrey);
}
.kg-cardmenu-card-hover .kg-cardmenu-action-icon {
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity ease-in-out 0.15s;
padding: 4px;
margin-top: -2px;
margin-bottom: -2px;
margin-right: 4px;
border-radius: 3px;
}
.kg-cardmenu-card-hover:hover .kg-cardmenu-action-icon {
opacity: 1.0;
}
.kg-cardmenu-card-hover .kg-cardmenu-action-icon:hover {
background: var(--whitegrey-d1);
}
.kg-cardmenu-card-hover .kg-cardmenu-action-icon svg {
margin: 0;
height: 1em;
}
.kg-cardmenu-card-hover .kg-cardmenu-action-icon svg path {
fill: var(--midgrey);
}
.kg-cardmenu-card-hover .kg-cardmenu-action-icon:hover svg path {
fill: var(--darkgrey);
}
/* Padded container housing title + editor canvas, scrollable content */
.gh-koenig-editor-pane {
padding: 11vw 92px;

View file

@ -83,6 +83,7 @@
@onWordCountChange={{action "updateWordCount"}}
@snippets={{this.snippets}}
@saveSnippet={{action "saveSnippet"}}
@deleteSnippet={{action "toggleDeleteSnippetModal"}}
/>
<div class="absolute flex items-center br3 bg-white {{if editor.headerClass "right-4 bottom-4" "right-6 bottom-6"}}">
@ -134,6 +135,16 @@
/>
{{/if}}
{{#if this.snippetToDelete}}
<GhFullscreenModal
@modal="delete-snippet"
@model={{this.snippetToDelete}}
@confirm={{action "deleteSnippet"}}
@close={{action "toggleDeleteSnippetModal"}}
@modifier="action wide"
/>
{{/if}}
<LiquidWormhole>
<GhPostSettingsMenu
@post={{this.post}}

View file

@ -51,6 +51,7 @@
@editor={{this.editor}}
@editorRange={{this.selectedRange}}
@snippets={{this.snippets}}
@deleteSnippet={{this.deleteSnippet}}
@replaceWithCardSection={{action "replaceWithCardSection"}}
@replaceWithPost={{action "replaceWithPost"}}
/>
@ -60,6 +61,7 @@
@editor={{this.editor}}
@editorRange={{this.selectedRange}}
@snippets={{this.snippets}}
@deleteSnippet={{this.deleteSnippet}}
@replaceWithCardSection={{action "replaceWithCardSection"}}
@replaceWithPost={{action "replaceWithPost"}}
/>

View file

@ -6,9 +6,17 @@
</div>
{{#each section.items as |item|}}
{{#if (or (not item.developerExperiment) (enable-developer-experiments))}}
<div class="{{if (eq item @selectedItem) "kg-cardmenu-card-selected"}} {{kg-style "cardmenu-card"}}" {{on "click" (fn @itemClicked item)}} data-kg="cardmenu-card" role="menuitem">
<div
class="{{if (eq item @selectedItem) "kg-cardmenu-card-selected"}} {{kg-style "cardmenu-card"}}"
data-kg="cardmenu-card"
role="menuitem"
{{on "click" (fn @itemClicked item)}}
>
<div class="{{kg-style "cardmenu-icon"}} {{item.iconClass}}" aria-hidden="true">{{svg-jar item.icon class="w7 h7"}}</div>
<div class="{{kg-style "cardmenu-label"}}">{{item.label}}</div>
{{#if item.deleteClicked}}
<span class="kg-cardmenu-action-icon" {{on "click" item.deleteClicked}}>{{svg-jar "trash"}}</span>
{{/if}}
</div>
{{/if}}
{{/each}}

View file

@ -9,6 +9,9 @@
{{svg-jar "koenig/search"}}
<input type="text" placeholder="Search for a card..." class="gh-input koenig-cardmenu-search-input">
</div> --}}
<KoenigMenuContent @itemSections={{this.itemSections}} @itemClicked={{action "itemClicked"}} />
<KoenigMenuContent
@itemSections={{this.itemSections}}
@itemClicked={{action "itemClicked"}}
/>
</div>
{{/if}}

View file

@ -53,7 +53,12 @@ export default Component.extend({
label: snippet.name,
icon: snippetIcon(snippet),
type: 'snippet',
matches: [snippet.name.toLowerCase()]
matches: [snippet.name.toLowerCase()],
deleteClicked: (event) => {
event.preventDefault();
event.stopImmediatePropagation();
this.deleteSnippet(snippet);
}
});
});
@ -236,7 +241,9 @@ export default Component.extend({
},
_handleWindowMousedown(event) {
if (!event.target.closest(`#${this.elementId}`)) {
if (
!event.target.closest(`#${this.elementId}, .fullscreen-modal`)
) {
this._hideMenu();
}
},

View file

@ -72,7 +72,12 @@ export default class KoenigSlashMenuComponent extends Component {
label: snippet.name,
icon: snippetIcon(snippet),
type: 'snippet',
matches: [snippet.name.toLowerCase()]
matches: [snippet.name.toLowerCase()],
deleteClicked: (event) => {
event.preventDefault();
event.stopImmediatePropagation();
this.args.deleteSnippet(snippet);
}
});
});
@ -303,7 +308,7 @@ export default class KoenigSlashMenuComponent extends Component {
_handleWindowMousedown(event) {
// clicks outside the menu should always close
if (!event.target.closest(`#${this.containerElement.id}`)) {
if (!event.target.closest(`#${this.containerElement.id}, .fullscreen-modal`)) {
this._hideMenu();
// clicks on the menu but not on a button should be ignored so that the

View file

@ -21,7 +21,7 @@ export function kgStyle([style], options) {
break;
case 'cardmenu-label':
cssClass = 'f-7 tracked-1 fw4 ma0 ml4';
cssClass = 'f-7 tracked-1 fw4 ma0 ml4 flex-grow-1';
break;
// Container cards