closes https://github.com/TryGhost/Team/issues/3077
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 27c2916</samp>
This pull request refactors the modal-post-history component from a
classic Ember component to a glimmer component, using the latest APIs
and syntax. This improves the code quality and aligns with the Octane
edition of Ember. The changes affect the
`ghost/admin/app/components/modal-post-history.js` and
`ghost/admin/app/components/modal-post-history.hbs` files.
refs https://github.com/TryGhost/Team/issues/3034
- adds new integration page for Pintura in Admin
- allows site owners to enable/disable the image editor integration
- allows self-hosters to upload the files for enabling Pintura image
editor
---------
Co-authored-by: Sodbileg Gansukh <sodbileg.gansukh@gmail.com>
Rather than displaying changes inside cards, we want to show a complete
replacement of the card. The current html diffing library is not capable of
supporting this so we have to use the approach here. First we find all cards
with changes in them, and then pull out the changes into two duplicated version
of the card, once for removals and one for additions.
refs https://github.com/TryGhost/Team/issues/3041
- Added a 10k search limit in Admin reserouce search. The limit prevents the search component from crashing when there are way too many resources to fetch.
- The default ordering is preserved for the fetched resources.
refs TryGhost/Team#3052
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 7173288</samp>
This pull request adds new components and settings for the announcement
bar feature, which allows the user to customize the content, background,
and visibility of a banner that appears on the site.
refs https://github.com/TryGhost/Team/issues/3034
- while fetching the image from source for editing in the image editor, it throws cors error when the image is returned from cache instead of ghost server
- the cached image response causes cors to trip over if admin url is different from frontend url for site as it doesn't has the right header
- adds a dynamic `v=...` query param while fetching image in editor to bypass cache and fetch image from server directly
Because we're using the old style components we need to make this a computed
property for changes to it to cause a rerender. We also add a latest property
to the first revision so that it can be rendered differently
The Lexical editor isn't passed the editor state it's passed the _initial_
editor state, which means that subsequent renders will not use an updated
state. To work around this we store a reference to the editor api and manually
set the state ourselves when the selected revision is changed.
refs https://github.com/TryGhost/Team/issues/3034
- adds new alpha feature flag for image editing in Admin
- allows new config for Pintura files that enable the image editing in
Admin
- adds new ember component for triggering image editing for post feature
images
---------
Co-authored-by: Sodbileg Gansukh <sodbileg.gansukh@gmail.com>
When we request all members, what happens is that the amount of data is
so great that Ghost is completely overwhelmed - database connections
are hanging open, spanners are thrown in the works, half the team are
staying up half the night!
no issue
- the members stats service was being used for the total member count
when checking member limits for publishing but the stats service is not
always correct which could result in publishing being blocked
unexpectedly
- switched to using the total count from a `/members/` query which
should always be correct/match other counts within the UI
We want the diff to be based on what the editor looks like, so we render two
hidden koenig instances and diff the html output, as opposed to using lexical
to render the "frontend" HTML. We also have some weirdness with the last
revision being the same content as the current state of the post. We can look
to fix that at the storage or API level in future
no issue
- post_revisions will now be included in any request to the /posts
endpoint
- updated admin models to include post_revisions
- post revisions can now be accessed in the modal-portal-history via
this.post.post_revisions
refs TryGhost/Team#3008
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 2a60623</samp>
This pull request adds a new experimental feature for displaying an
announcement bar at the top of the site. It introduces a new component
template and class for the announcement bar, a new feature flag and its
UI controls, and some CSS adjustments for the editor input and the
announcement bar.
no issue
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at 2839ca2</samp>
This pull request adds a feature to show the HTML diff of the post
content changes in the post history modal. It uses the `node-htmldiff`
module to generate the diff and updates the `modal-post-history`
component and its template and style files.
---------
Co-authored-by: Fabien "egg" O'Carroll <fabien@allou.is>
refs TryGhost/Team#3008
---
<!-- Leave the line below if you'd like GitHub Copilot to generate a
summary from your commit -->
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at f785fd8</samp>
This change adds a new component `koenig-lexical-editor-input` that
renders a React component using the `@tryghost/koenig-lexical` package,
which provides a new editor for Ghost that supports rich text and
markdown editing. The component can be used to edit HTML content using
the Lexical editor, and syncs the HTML content with the `html` argument
and the `onChangeHtml` callback. The component also handles dynamic
import, loading, error, and dark mode scenarios.
no issue
- added modal-post-history component and wired it up to the
lexical-editor
### <samp>🤖 Generated by Copilot at b726dd5</samp>
> _`Post history` is the key to the past_
> _Unveil the changes in a modal so vast_
> _But beware of the doom that lurks in the edits_
> _The lexical-editor is a portal to the abyss_
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.
refs https://github.com/TryGhost/Team/issues/2677
- This extends the bulk editing UI to pages.
- New endpoints for editing pages in bulk
- Support for type in bulk edit UI
- Fixed empty messages for lists
- Minor bugfixes (e.g. save button when adding tags became red because
task didn't return true)
---
This pull request adds support for bulk editing and deleting of pages in
the admin UI and the API. It refactors the context menu component and
the list templates to handle different types of content (posts or pages)
dynamically. It also updates the selection list utility and the no posts
box component to work with the new feature. It modifies the `posts.js`
and `pages.js` API files and the corresponding input and output
serializers and routes.
refs https://github.com/TryGhost/Team/issues/2677
When opening a context menu close to the border of the window, the menu went outside the window. This PR updates the position mirror horizontally or vertically if the menu would go outside the window.
refs https://github.com/TryGhost/Team/issues/2677
- When shift clicking on the first item, it no longer will select from top to that item. It will now just select that item.
- Updates event listeners to use mousedown to prevent text selection glitch
refs https://github.com/TryGhost/Team/issues/2677
The dependency caused errors in Safari, probably due to incompatible JS features that need to be polyfilled. Removed it for now and replaced it with a simple method instead.
refs https://github.com/TryGhost/Team/issues/2677
When doing CMD+TAB, then CMD+TAB+shift, the CMD key got released but both the keyup and blur events weren't called (also focus not).
To fix this, on the next click we'll check the meta, shift and ctrl keys so we can restore the situation.
refs https://github.com/TryGhost/Team/issues/2677
Fixed a bug that the current selection is deselected when clicking inside a modal when performing a context menu action.
Refactored the context menu component and its usage in the posts list to
improve the user experience and code quality. Introduced a `state`
property and a `setState` method to the `gh-context-menu` component to
handle different scenarios. Used the `gh-context-menu` component in the
`posts-list/context-menu` component to simplify the modal and loading
logic. Added a `#frozen` property and methods to the `selection-list`
utility to prevent the selection of posts from changing while the
context menu is active.
---------
Co-authored-by: Simon Backx <simon@ghost.org>
no issue
- there was an errant space after the `wss:` protocol used when building the websockets URL for multiplayer that caused errors when trying to connect
refs https://github.com/TryGhost/Team/issues/2677
When deselecting all items, and then using shift, it still tries to shift between the previous selection. This fixes that issue.
no issue
Rough prototype only, current limitations:
- **No persistence**. Docs are in-memory only, YJS state will be lost on server restart although it could be re-populated by clients if they reconnect without closing their local doc (needs testing/investigation)
- **No tie-in with saved lexical state**. Lexical state is updated in the post model via normal API requests from Admin which can mean the multiplayer doc and the saved lexical state become out of sync but there's no detection/indication of that state at present. Will also trigger the "someone else is editing" errors because multiplayer doesn't yet override the default post update collision detection
- **New posts don't start in multiplayer**. New posts don't have an ID and so can't have a respective YJS doc, after initial save we don't transition to multiplayer because the React component in Ember doesn't re-render on prop changes yet
- **No tests**. Experimental code just to get something working and help answer questions for what's next
Changes:
- added `lexicalMultiplayer` labs flag
- updated `<KoenigLexicalEditor>` to pass through the required `<KoenigComposer>` props for multiplayer when enabled
- added `lexical-multiplayer` service
- `init()` called during boot, used to set up the `enable()` and `disable()` methods so the flag can be toggled without restarts
- when enabled it adds `upgrade` request handling to the base Ghost server
- returns 404 if the URL doesn't match `/ghost/api/admin/posts/multiplayer/*`
- returns 401 if a valid session cookie is not present
- if everything is good, hands off to code in `y-websocket.js` that handles YJS doc creation, awareness, keepalive, etc
- uses doc names in the format `${post.id}/${docId}` where `docId` is `main` for the primary document and a GUID for any sub-documents like captions and nested editors in cards
- updated `SettingsBREADService` to check if the `labs` setting is changed, and enables/disables the `lexical-multiplayer` service as needed so the websockets server can be started and shutdown when toggling without requiring a restart
refs https://github.com/TryGhost/Team/issues/2677
- Use post access level by default when doing single selection
- Use default access level from settings when selecting multiple posts
fixes https://github.com/TryGhost/Team/issues/2924
This change adds a new bulk edit action for posts to update their
visibility. It also implements a modal to change the post access level
for multiple posts at once using this new API.
It also fixes a pattern that was used when modifying the Ember models in
memory. They previously were marked as dirty, this is fixed now. So when
going to the editor after modifying posts, you won't get a confirmation
dialog any longer.
fixes https://github.com/TryGhost/Team/issues/2938
- Multi selection is disabled for contributors and authors (no actions available)
- Delete action is only available for admins and owners
fixes https://github.com/TryGhost/Team/issues/2983
When navigating, the posts selection will get cleared. This also fixes a bug with CMD+a that had an old event listener that was not cleared correctly, breakign CMD+A after navigation.
fixes https://github.com/TryGhost/Team/issues/2939
When using CMD+F, the multiple selection list still thinks CMD is pressed because the keyup event is not fired. This is fixed by clearing the pressed keys when the window is blurred.
These posts make no sense to be featured, so we are removing the option
from the context menu when there is only a single email-only post under
selection.
We still allow featuring these posts in the PSM and when they are
part of a larger selection, but fixing all places for this is out of
scope atm.
refs https://github.com/TryGhost/Team/issues/2680
- Includes a new helper that is able to count HTML characters
- Prevent saving portal settings when maximum length is exceeded
Refs https://github.com/TryGhost/Team/issues/2878
- The free-only version of Portal will show the signup terms just above the signup button, whereas the non-free Portal version will show the signup terms above the plan selection
- The signup terms settings have been moved to the "Signup options" section
fixes https://github.com/TryGhost/Team/issues/2919
This pull request implements a new feature that allows bulk editing of
posts by a filter. It adds a new `bulkEdit` endpoint to the posts API
and new `PostsService` methods to handle the bulk actions.
The posts list component is duplicated, so we can keep working in a
copied version without affecting the old version without a flag. It
temporarily adds a star icon to indicate featured posts in the posts
list.
refs https://github.com/TryGhost/Team/issues/2680
When selecting a portion of text in KoenigBasicHtmlInput (caption input
for images, newsletter footer text input, new signup notice), and then
pasting a link, some funky things happen:
- Part of the text disappears
- The wrong part of the text is linked
The cause of this is that `KoenigBasicHtmlInput` deletes the selected
text range when pasting, even when pasting a link. so moving that part
below the code that detected a valid link, fixes the issue.
This also adds an option to not close an old style modal when pressing
the enter key (e.g. pressing enter when entering a link causes the modal
to close).
refs https://github.com/TryGhost/Team/issues/2936
We want to make sure that downloads complete in a reasonable number of
time, and the simplest way to do that is to cap the size of the file.
refs https://github.com/TryGhost/Team/issues/2935
This allows us to track the state with a loading spinner and a
success/error message on completion. This is expecially important for
larger sites where the download can take a long time, and users are
unsure if something is happening.
The existing approach didn't expose when the download was complete.
By fetching the file upfront and downloading from a blob we can better
estimate when the download is complete because we load the file in
memory, and then download from there.
The promise resolves after the file is in memory, so the delay between
the promise resolving and the file actually being downloaded is a lot
shorter, and based on the size of the file.
refs https://github.com/TryGhost/Team/issues/2906
Adds a way to select posts using CMD, shift and CMD+A. And adds a placeholder context menu.
Behind the making it rain feature flag.
closesTryGhost/Team#2859
- when removing all selected labels/newsletters, the UI would uncheck
the Specific People checkbox and hide the label/newsletter selection
- this change forces the Specific People checkbox to be checked even if
no labels/newsletters are selected
- test enhanced to cover this specific edge case
fixes https://github.com/TryGhost/Team/issues/2678
- Includes a new filename for the export (post-analytics instead of posts)
Co-authored-by: Fabien 'egg' O'Carroll <fabien@allou.is>
Co-authored-by: Sanne de Vries <sannedv@protonmail.com>
refs https://github.com/TryGhost/Team/issues/2830
- Colors stay in the same order
- Auto color changes faster because direct usage of preset colors and no longer uses ordered colors
refs https://github.com/TryGhost/Team/issues/2846
In order to render the preview correctly and use the new design settings
we need to expose them to the template. Unfortuantely we've had to
duplicate all of the code from the backend here, long term we should try
and pull the newsletter email rendering into a component that can be
shared between the server & client.
refs https://github.com/TryGhost/Team/issues/2830
Only update the order of the colors on mouseleave (+ after the animation). This also includes some minor changes to the CSS files to remove glitches in the animation. I temporarily removed the border of the colors because they keep taking up space when the colors are hidden. Ideally we want to move those borders to :before or :after, that will also be better for the animation.
closes https://github.com/TryGhost/Team/issues/2851
We had two separate flags to manage the Mentions beta, one for showing
UI and other for sending emails. This change combines them both under
the single `webmentions` flag that was previously only used to show the
UI.
no issue
- Renovate merged in a breaking change to ember-cli-code-coverage which
broke our coverage reporting for the admin app
- This commit fixes the issue by pinning the version of
ember-cli-code-coverage to the last working version and telling renovate
to ignore it in the future
- It also adds html coverage reporting to make it easier to run locally
and see your coverage before pushing
refs https://github.com/TryGhost/Team/issues/2619
- the footer text "Sent a broken link? You can update it" of the newsletter clicks was breaking in certain browser width
- this fixes it by adding extra media queries to the already existing solution of hiding the normal text in small screen
refs https://github.com/TryGhost/Team/issues/2634
Added suport for type "file" which refers to basically any non-specific
file type for use on the file card.
Bypasses validation when a file gets uploaded.
Refs https://github.com/TryGhost/Team/issues/2801
- It was not possible to click latest post links in Outlook due to <a>
tag wrapping around a table
- The post meta data wouldn't display properly when centered in Outlook
---------
Co-authored-by: Simon Backx <simon@ghost.org>
- closes https://github.com/TryGhost/Team/issues/2786
- when trying to deselect all recipients, the UI would pass null as the filter to publish-options
- publish-options would then fallback to the default options, which is all recipients, and then the UI wouldn't update which made things even weirder
- we want to fallback to the default recipients when the recipientFilter is undefined (e.g. hasn't been set at all), but not when it is explicitly set to null (e.g. when the user has deselected all recipients)
- Moves Milestone emails from public beta to GA✨ Moved Milestone emails to GA
- Moves Milestone emails from public beta to GA✨ Moved Milestone emails to GA
- Moves Milestone emails from public beta to GA✨ Moved Milestone emails to GA
- Moves Milestone emails from public beta to GA✨ Moved Milestone emails to GA
- Moves Milestone emails from public beta to GA✨ Moved Milestone emails to GA
- Moves Milestone emails from public beta to GA✨ Moved Milestone emails to GA
- Moves Milestone emails from public beta to GA✨ Moved Milestone emails to GA
- Moves Milestone emails from public beta to GA✨ Moved Milestone emails to GA
- Moves Milestone emails from public beta to GA
closes https://github.com/TryGhost/Team/issues/2483
- the button is toggled depending on `stripeConnectIntegrationToken` which is a calculated value
- however, this calculated value isn't reset when Stripe is disconnected right away without closing the modal
- the reset action was already available and it's now passed to `StripeSettingsForm`, so that it can be called when Stripe is disconnected
refs https://github.com/TryGhost/Team/issues/2713
- currently, it's not clear enough that if the theme activation was successful
- highlighting "successful" makes it easier to know the main action was successful even though there are errors to fix
refs TryGhost/Team#2401
- Previously, if you opened a new post using the plus button on the sidebar while on a different post's analytics page, the breadcrumbs would point back to Analytics instead of the Posts list view. Going back to Analytics brought you back to the analytics page for the post you just created, which wasn't populating since it likely hadn't been published yet.
- This commit fixes the issue by setting fromAnalytics = false if transitioning to a new Post, even if the previous route was the analytics page.
refs
https://www.notion.so/ghost/Marketing-Milestone-email-campaigns-1d2c9dee3cfa4029863edb16092ad5c4?pvs=4
- Added email template for milestones with using a configuration file
for different member milestone values, as we're sending different
content for each one
- Implement sending the email to users who have
`milestone-notifications` enabled, currently still behind a flag
Co-authored-by: Peter Zimon <peter.zimon@gmail.com>