mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-03-11 02:12:21 -05:00
Wired lexical snippets to Ghost (#16647)
refs TryGhost/Team#2904 <!-- Leave the line below if you'd like GitHub Copilot to generate a summary from your commit --> <!-- copilot:summary --> ### <samp>🤖 Generated by Copilot at 2ba5e2a</samp> This pull request adds the lexical editor feature to the Ghost admin app, which allows users to create and edit snippets in a natural language format. It modifies the `snippet` model, adapter, and controller, and the `lexical-editor` template and component to support the new feature.
This commit is contained in:
parent
deb613fcf9
commit
2236d2ef24
6 changed files with 54 additions and 11 deletions
20
ghost/admin/app/adapters/snippet.js
Normal file
20
ghost/admin/app/adapters/snippet.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
import ApplicationAdapter from 'ghost-admin/adapters/application';
|
||||
|
||||
export default class Snippet extends ApplicationAdapter {
|
||||
buildURL() {
|
||||
const url = super.buildURL(...arguments);
|
||||
|
||||
try {
|
||||
const parsedUrl = new URL(url);
|
||||
if (!parsedUrl.searchParams.get('formats')) {
|
||||
parsedUrl.searchParams.set('formats', 'mobiledoc,lexical');
|
||||
return parsedUrl.href;
|
||||
}
|
||||
} catch (e) {
|
||||
// noop, just use the original url
|
||||
console.error('Couldn\'t parse URL', e); // eslint-disable-line
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
}
|
|
@ -7,10 +7,15 @@ export default class UpdateSnippetModal extends Component {
|
|||
|
||||
@task({drop: true})
|
||||
*updateSnippetTask() {
|
||||
const {snippet, updatedProperties: {mobiledoc}} = this.args.data;
|
||||
const {snippet, updatedProperties: {mobiledoc, lexical}} = this.args.data;
|
||||
|
||||
try {
|
||||
snippet.mobiledoc = mobiledoc;
|
||||
if (mobiledoc) {
|
||||
snippet.mobiledoc = mobiledoc;
|
||||
}
|
||||
if (lexical) {
|
||||
snippet.lexical = lexical;
|
||||
}
|
||||
|
||||
yield snippet.save();
|
||||
|
||||
|
|
|
@ -172,7 +172,8 @@ export default class EditorController extends Controller {
|
|||
get snippets() {
|
||||
return this._snippets
|
||||
.reject(snippet => snippet.get('isNew'))
|
||||
.sort((a, b) => a.name.localeCompare(b.name));
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.filterBy('lexical', null);
|
||||
}
|
||||
|
||||
@computed('session.user.{isAdmin,isEditor}')
|
||||
|
|
|
@ -170,9 +170,15 @@ export default class LexicalEditorController extends Controller {
|
|||
|
||||
@computed('_snippets.@each.{name,isNew}')
|
||||
get snippets() {
|
||||
return this._snippets
|
||||
const snippets = this._snippets
|
||||
.reject(snippet => snippet.get('isNew'))
|
||||
.sort((a, b) => a.name.localeCompare(b.name));
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.filter(item => item.lexical !== null);
|
||||
return snippets.map((item) => {
|
||||
item.value = item.lexical;
|
||||
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
@computed('session.user.{isAdmin,isEditor}')
|
||||
|
@ -343,7 +349,8 @@ export default class LexicalEditorController extends Controller {
|
|||
|
||||
@action
|
||||
saveSnippet(snippet) {
|
||||
let snippetRecord = this.store.createRecord('snippet', snippet);
|
||||
const snippetData = {name: snippet.name, lexical: snippet.value, mobiledoc: '{}'};
|
||||
let snippetRecord = this.store.createRecord('snippet', snippetData);
|
||||
return snippetRecord.save().then(() => {
|
||||
this.notifications.closeAlerts('snippet.save');
|
||||
this.notifications.showNotification(
|
||||
|
@ -363,6 +370,18 @@ export default class LexicalEditorController extends Controller {
|
|||
});
|
||||
}
|
||||
|
||||
@action
|
||||
async createSnippet(data) {
|
||||
const snippetNameLC = data.name.trim().toLowerCase();
|
||||
const existingSnippet = this.snippets.find(snippet => snippet.name.toLowerCase() === snippetNameLC);
|
||||
|
||||
if (existingSnippet) {
|
||||
await this.confirmUpdateSnippet(existingSnippet, {lexical: data.value, mobiledoc: '{}'});
|
||||
} else {
|
||||
await this.saveSnippet(data);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
async confirmUpdateSnippet(snippet, updatedProperties = {}) {
|
||||
await this.modals.open(UpdateSnippetModal, {
|
||||
|
|
|
@ -6,6 +6,7 @@ export default Model.extend(ValidationEngine, {
|
|||
|
||||
name: attr('string'),
|
||||
mobiledoc: attr('json-string'),
|
||||
lexical: attr('json-string'),
|
||||
createdAtUTC: attr('moment-utc'),
|
||||
updatedAtUTC: attr('moment-utc')
|
||||
});
|
||||
|
|
|
@ -81,10 +81,6 @@
|
|||
@scrollOffsetBottomSelector=".gh-mobile-nav-bar"
|
||||
@onEditorCreated={{this.setKoenigEditor}}
|
||||
@onWordCountChange={{this.updateWordCount}}
|
||||
@snippets={{this.snippets}}
|
||||
@saveSnippet={{if this.canManageSnippets this.saveSnippet}}
|
||||
@updateSnippet={{if this.canManageSnippets this.confirmUpdateSnippet}}
|
||||
@deleteSnippet={{if this.canManageSnippets this.confirmDeleteSnippet}}
|
||||
@featureImage={{this.post.featureImage}}
|
||||
@featureImageAlt={{this.post.featureImageAlt}}
|
||||
@featureImageCaption={{this.post.featureImageCaption}}
|
||||
|
@ -95,7 +91,8 @@
|
|||
@cardOptions={{hash
|
||||
post=this.post
|
||||
snippets=this.snippets
|
||||
deleteSnippet=this.confirmDeleteSnippet
|
||||
deleteSnippet=(if this.canManageSnippets this.confirmDeleteSnippet)
|
||||
createSnippet=(if this.canManageSnippets this.createSnippet)
|
||||
}}
|
||||
@postType={{this.post.displayName}}
|
||||
/>
|
||||
|
|
Loading…
Add table
Reference in a new issue