Commit Graph

172 Commits

Author SHA1 Message Date
Sag
e740cef863
Fixed regex to ignore AbortError in Sentry (#20639)
fixes https://linear.app/tryghost/issue/SLO-175
2024-07-22 07:55:37 +00:00
Kevin Ansfield
8ea1dfb957
🐛 Fixed listing pages in Admin (#20633)
closes https://github.com/TryGhost/Ghost/issues/20632

- Revert " Improved performance loading the posts list in admin (#20618)"
2024-07-20 20:49:21 +00:00
Sag
c5bb2e5dc7
🐛 Fixed member subscription details in Admin (#20619)
fixes https://linear.app/tryghost/issue/ONC-189

- commit 4084a3d introduced a regression that caused member subscription
details to not be rendered for active/canceled subscriptions
- with this fix, the rendering logic in Admin for member subscription
details has been fully moved to a helper and is now covered by
additional unit tests
2024-07-18 12:14:38 +02:00
Steve Larson
cd17b94e9c
Improved performance loading the posts list in admin (#20618)
ref https://github.com/TryGhost/Ghost/pull/20503
- undid the reversion for the performance improvements
- built upon new tests for the posts list functionality in admin,
including right click actions

This was originally reverted because the changes to improve loading
response times broke right click (bulk) actions in the posts list. This
was not caught because it turned out we had near-zero test coverage of
that part of the codebase. Test coverage has been expanded for the posts
list, and while not comprehensive, is a much better place for us to be
in.
2024-07-17 16:55:47 -05:00
Fabien 'egg' O'Carroll
a4107b8202
🐛 Fixed incorrect member subscription details in Admin (#20476)
fixes https://linear.app/tryghost/issue/ENG-642

- When a subscription is in the `canceled` state the corresponding
Member has no access to the Ghost site. The only time a Member will
continue to have access if their subscription is due to cancel at the
period end is if it is still in an active state, which is one of
`active` `trialing` `unpaid` or `past_due`
- When a subscription is canceled immediately (i.e. before the end of
the current billing period), we now render "Ended" without a date,
because we don't store the cancellation date in the subscription object.
We previously used "Ended {current_period_end}" which would sometimes
lead to dates in the future
- Bonus: refactored code and added unit tests

---------

Co-authored-by: Sag <guptazy@gmail.com>
2024-07-02 13:58:20 +00:00
Daniel Lockyer
f250898a3b Optimized stats aggregation code for Admin dashboard
fix https://linear.app/tryghost/issue/SLO-168/rangeerror-maximum-call-stack-size-exceeded

- this code takes the API output and reduces it down to collect together
  stats per date
- the current code is recursive, and we've seen errors with the
  recursion hitting a `RangeError: Maximum call stack size exceeded`
  error
- as well as that, we're doing a lot of array concat'ing and cloning,
  which burns memory and CPU time
- instead, we can just use `.reduce`
- the new implementation is much faster than the existing one (1ms vs
  85ms) and uses no recursion, so those errors should go away
- I've also verified that the output is the same between the two
  functions
2024-06-26 15:46:39 +02:00
Daniel Lockyer
43bb83f7bb Extracted stats aggregation function to util
ref https://linear.app/tryghost/issue/SLO-168/rangeerror-maximum-call-stack-size-exceeded

- this extracts a function to a util so we can unit test it
- this function is about to be optimized but having unit tests allows us
  to make the change with confidence
2024-06-26 15:46:39 +02:00
Daniel Lockyer
019f417c7d Moved error exclusion to correct place
- adding it to ignoreErrors is better than beforeSend because it's built
  for this purpose and we've just looking at the error message
2024-06-26 12:43:55 +02:00
Daniel Lockyer
5f5293cf6d Excluded errors caused by browser power-saving settings
fix https://linear.app/tryghost/issue/SLO-164/error-aborterror-the-play-request-was-interrupted-because-video-only

- in the case that the browser has power-saving settings enabled, we get
  an error in Sentry
- this error does not affect the user experience, so it should be safe
  to ignore
- this adds an exclusion to Sentry to ignore these errors
2024-06-26 11:49:42 +02:00
Sag
66f7911d24
Ignored posthog-js and ember-concurrency cancellation errors in Sentry (#20383)
fixes https://linear.app/tryghost/issue/SLO-126
fixes https://linear.app/tryghost/issue/SLO-141
fixes https://linear.app/tryghost/issue/SLO-150

- during a session, posthog-js' rrweb extension can start throwing a lot
of errors. These errors do not affect the application
- similarly, ember-concurrency's task cancellation errors do not affect
the application. Task in ember-concurrency are expected to be canceled.
However, if they're cast to a Promise, they show up as unhandled Promise
rejections as Promises do not have a concept of cancellation
2024-06-13 10:38:46 +00:00
Nick Moreton
7c407af642
Added Posthog event sending to trackEvent function (#19716)
refs PA-37

As we add Posthog to the stack we want to send the existing events we
track to it, as well as opening up the method to teams to use in their
initiatives.

---------

Co-authored-by: Chris Raible <chris@ghost.org>
2024-02-20 14:32:56 -08:00
Chris Raible
f49b5ab78d
Added reusable isPosthogLoaded function (#19722)
no issue

- We were checking if Posthog was loaded in a few separate places using
the same logic — this PR consolidates that logic into a simple utility
function so we can ensure consistency and change this logic more easily
if we need to in the future
2024-02-20 14:08:35 -08:00
Chris Raible
fbeecd58e6
Fixed issue with calling Posthog functions before it is loaded (#19721)
refs PA-36

- Since Posthog is loaded outside of the main Admin app bundle, we need
to check to make sure it exists before calling it. This way it will only
run on Pro and not locally or on self-hosted instances
- Previously we were checking that `window.posthog` existed, but there
are some cases where `window.posthog` may exist, but the `posthog`
object is not fully loaded yet.
- This change fixes this by checking for `window.posthog.__loaded`
instead, which is set to `true` once the `posthog` object is fully
loaded — at this point, we should be able to call whatever functions we
need to on `window.posthog`
2024-02-20 13:57:42 -08:00
Chris Raible
7dafefbfa7
Added PostHog identify calls in admin using hashed email address of user (#19685)
refs PA-24

- Added PostHog identify() calls using the user's hashed email address
when a user is logged into admin
- Added PostHog reset() calls to reset PostHog's distinct_id when a user
logs out of admin
- These events will only be sent in Admin running on Ghost(Pro), and won't impact self-hosted instances.
2024-02-13 13:23:03 -08:00
Chris Raible
59076d1bca
Reverted "Fixed PostHog toolbar in admin (#19675)" (#19680)
This reverts commit c32ee3ca40.

- I found another way to fix this, making this change unnecessary
2024-02-08 16:58:46 -08:00
Chris Raible
c32ee3ca40
Fixed PostHog toolbar in admin (#19675)
refs PA-32

- The PostHog toolbar relies on a value that is passed via a hash in the
URL to launch successfully
- Admin overwrites the hash (since it uses hash based routing) before
the toolbar has a chance to read the value
- This change checks for the hash and if it exists, it launches the
toolbar using the hash value
2024-02-08 13:40:03 -08:00
Simon Backx
1f2857e0e4
Reduced amount of member count queries when opening the editor (#19474)
no issue

When we open the editor, we fire 4 requests to fetch member counts. This
commit fixes this by replacing those calls with the members count cache
service.
2024-01-13 19:13:49 +01:00
Chris Raible
a97e2b823e
Added error handling to Sentry's beforeSend (#19109)
refs TryGhost/Product#4175

- Added error handling to Sentry's beforeSend function in both Admin and
Core, so if there is any error in beforeSend, we will still send the
unmodified event to Sentry
- This is in response to an incident yesterday wherein the beforeSend
function threw an error due to an unexpected missing value in the
exception. The event sent to Sentry was the error in the beforeSend
function, and the original error never reached Sentry.
- If the original event had reached Sentry, even if unmodified by the
logic in beforeSend, we could have been alerted to the issue sooner and
more easily identified all affected sites.
- Also added defensive logic to protect for certain values in the
exception passed to beforeSend not existing and added unit tests for the
beforeSend function in admin and core
2023-11-23 02:46:50 +00:00
Susheel Thapa
2e5fdffe32
Fixed typos (#18648)
Co-authored-by: Daniel Lockyer <daniellockyer@fastmail.com>
2023-10-31 15:21:44 +00:00
Kevin Ansfield
fa0b1c607b
Deleted all Admin code relating to the old editor (#18580)
no issue

- removed labs flag
- removed main editor component and all associated components
- switched usage of `<KoenigBasicHtmlInput>` and `<KoenigBasicHtmlTextarea>` over to use plain `textarea`, the only uses were in settings modals that have been replaced in AdminX
- cleaned up unused editor CSS
2023-10-12 13:17:39 +01:00
Daniel Lockyer
3e42d4b1be Implemented cachebuster for Admin-X Settings and Koenig-Lexical files
fixes https://github.com/TryGhost/DevOps/issues/86

- this will now hash the files and append a cachebuster, so we never
  serve stale files again
2023-10-06 10:41:37 +02:00
Daniel Lockyer
639be25f1d Updated Koenig-Lexical bundling
refs https://github.com/TryGhost/DevOps/issues/83

- this will now continue use the dev server assets if we tell it to,
  or copy the dependency package files to the built folder otherwise
- removes `editor` from config API because it's no longer needed
- removes dependency on `editor.url` in tests, as this no longer exists
- edits dev script to pass dev server URL as env var
- adds `@tryghost/koenig-lexical` dependency to Admin
2023-10-04 12:50:21 +02:00
Daniel Lockyer
6e46e8b5ba
Refactored loading of Koenig-Lexical package (#18392)
refs https://ghost.slack.com/archives/C02G9E68C/p1695901801049219?thread_ts=1695035790.122589&cid=C02G9E68C

- DRY up all the fetching of Koenig-Lexical so we only do it from one place
- this will help when we switch to loading Koenig-Lexical from local assets

Co-authored-by: Jono Mingard <reason.koan@gmail.com>
2023-09-28 17:43:12 +02:00
Daniel Lockyer
f705dda314 Updated Admin-X bundling process
refs https://github.com/TryGhost/DevOps/issues/80

- as part of moving Admin-X-Setting towards GA, we want to change it from
  loading the settings externally via a CDN, to bundling it in with
  Admin
- the bulk of the changes here are removing the config in Ghost, setting
  up the copy to the Admin assets dir, and loading the new path in Admin
- several other changes have come along the way as I've cleaned up
  unneeded code
2023-09-19 11:31:55 +02:00
Sag
6c481b74a9
Added an upper limit to Tips & Donations suggested amount (#17695)
refs https://github.com/TryGhost/Product/issues/3695

- also updated the "minimumAmountPerCurrency" helper to return a
standard price (not in cents), to keep the code more readable
2023-08-11 13:09:42 +00:00
Sag
ea75ca6188
Updated minimum price validation in Tiers, to support more currencies (#17661)
no issue

- Stripe imposes different minimum charges based on the currency used,
see
https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts
- Our validation uses double that limit, to take into account
conversions to the main currency in use in the Stripe account
2023-08-09 15:44:01 +00:00
Sag
99a9dea988
Added a validation for a minimum suggested amount for Tips & Donations (#17653)
closes https://github.com/TryGhost/Product/issues/3695

- Stripe has minimum charge amounts per currency, see
https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts
- We double these limits in our validation, to take into account
currency conversions to the main currency used on the Stripe account. If
the publishers enters a suggested amount below the limit, they will see
an error in Admin
- 0 is permitted as default value and corresponds to "no suggested
amount"
2023-08-09 16:36:29 +02:00
Ronald Langeveld
42a1630740
🐛 Fixed email only to post rescheduling. (#17538)
refs https://github.com/TryGhost/Product/issues/3657

- When reverting a post to a draft, the meta, `email_only` remained
true.
- This fix switches `email_only` back to false when the `revertToDraftTask` is executed.
2023-07-31 13:32:58 +02:00
Daniel Lockyer
532a7cf6e3 Fixed loading assets from CDN URL
refs https://ghost.slack.com/archives/C027S85FS/p1690202522054729

- this is another set of places where we load assets slightly
  differently
- this should fix user profile images when using assets from a CDN
2023-07-24 16:12:29 +02:00
Michael Barrett
184c6ae951
Retain newsletter subscriptions on suppression (#17373)
refs https://github.com/TryGhost/Product/issues/2610
2023-07-24 10:47:57 +01:00
Nick Moreton
14ce57fa2b
Added trackEvent util for sending events to Plausible (#16824) 2023-05-18 14:32:50 +01:00
Simon Backx
854f616f70
Added bulk edit pages API and admin UI (#16633)
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.
2023-04-14 12:16:15 +02:00
Simon Backx
062a716fbc Added clear selection when right clicking non selected item
refs https://github.com/TryGhost/Team/issues/2677
2023-04-14 11:12:30 +02:00
Simon Backx
cce324724a Updated shift post selection to use first shift position
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
2023-04-14 10:19:40 +02:00
Fabien 'egg' O'Carroll
27976381f8
Updated GhContextMenu to handle freezing the SelectionList (#16624)
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>
2023-04-13 15:04:06 +02:00
Simon Backx
e3105bdde4 Improved shift selection when deselecting items
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.
2023-04-13 10:22:09 +02:00
Simon Backx
8bdd23e1cc Improved bulk delete and unpublish modals copy
refs https://github.com/TryGhost/Team/issues/2677
2023-04-12 15:53:17 +02:00
Simon Backx
66b353ed97
Added bulk destroy posts api (#16587)
fixes https://github.com/TryGhost/Team/issues/2921

Adds the bulk destroy API for posts, and implemented it in the admin UI.
2023-04-11 16:37:42 +02:00
Simon Backx
1ce4e4c522 Updated post context menu to take permissions into account
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
2023-04-11 16:33:39 +02:00
Simon Backx
f4d75388fd
Added post bulk edit api (#16576)
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.
2023-04-07 11:48:14 +02:00
Simon Backx
8c046740f0 Added support for selecting posts
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.
2023-04-05 18:00:08 +02:00
Chris Raible
2a876ac7a8
🐛 Fixed UI bug when choosing email recipients (#16481)
- 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)
2023-03-24 15:25:35 +05:30
Simon Backx
832610fd2a
🐛 Fixed retrying failed emails when rescheduling them (#16383)
fixes https://github.com/TryGhost/Team/issues/2560

When an email fails, and you reschedule the post, the error dialog was
shown (from the previous try). The retry button on that page allowed you
to retry sending the email immediately, which could be very confusing.

- The email error dialog is no longer shown for scheduled emails
- The email status is no longer polled for scheduled emails
- Retrying an email is not possible via the API if the post status is
not published or sent
- Added some extra snapshot tests
- When retrying an email, we immediately update the email status to
'pending' to have a better API response (instead of still returning
failed).
- Disabled email sending retrying in development (otherwise very hard to
test failed emails if it takes 10 mins before it gives up automatic
retrying)
2023-03-09 12:32:22 +01:00
Kevin Ansfield
923a9a1cd6
🐛 Fixed default email recipients always being "everyone" rather than matching post visibility (#16247)
refs https://github.com/TryGhost/Ghost/issues/16125

The previous fix for incorrect recipient details being shown when
re-sending a failed email introduced another bug that prevented the
"Match post visibility" default recipients setting from working.

- the server always sets `post.emailSegment` to `'all'` for new posts so
the publish flow recipient filter logic that checked for
`post.emailSegment` being present always defaulted to `'all'` rather
than falling back to the selected default recipients setting
- when a post has been published but the email failed it will have its
`newsletter` value set so we can use that as a check for using the
`post.emailSegment` value in place of the default recipients setting
2023-02-08 11:41:48 +00:00
Fabien 'egg' O'Carroll
c11e79765e
🐛 Fixed newsletter resending showing incorrect recipient data
closes https://github.com/TryGhost/Ghost/issues/16125

We weren't taking into account any existing email segment set on the
post. This is usually not an issue because during the publishing flow
the post.emailSegment and the selectedRecipientFilter are kept in sync,
but it becomes and issue when the email fails to send and is later
retried - we now have an inconsistency between the two values.
2023-01-30 16:44:57 +07:00
Simon Backx
b615c9f7d2
Added post scheduling Playwright test and loosened time restrictions (#15960)
refs https://github.com/TryGhost/Team/issues/2371

- Adds a test that schedules a post 5 seconds in the future and waits
for it to be published
- Reduced the time restrictions for scheduling: 
    - The minimum time in the frontend is now 5 seconds in the future (came
from 5 minutes in the future)
    - The time picker now suggests 10 minutes in the future instead of the
minimum scheduling time (came from 5 minutes)
    - In the backend, a post will be allowed to be scheduled if it is at
least 2 minutes in the past (came from 2 minutes in the future)
    - The scheduler will publish a post if it is at least 5 minutes in the
past, and maximum 5 minutes in the future (came from 2 minutes)
2022-12-07 17:29:36 +01:00
Kevin Ansfield
b68686fe9c Fixed 403 newsletters request for contributors when opening editor
closes https://github.com/TryGhost/Team/issues/2242

Contributors don't have permission to fetch `/newsletters/` but the publish flow was sending a request every time a contributor opened a post in the editor creating noise in event logs and in the developer console.

- disabled the newsletters fetch when the logged in user is a contributor
- contributors can't publish so the "missing" data has no effect on the publish flow as it's not used
2022-12-06 11:18:29 +00:00
Kevin Ansfield
9bdb25d184
Fixed hosting management screen not loading after sign-in process (#15763)
refs https://github.com/TryGhost/Team/issues/2110

- dynamically defined properties on the config service did not have
autotracking set up properly if they were accessed in any way before the
property was defined, this caused problems in a number of areas because
we have both "unauthed" and "authed" sets of config and when not logged
in we had parts of the app checking for authed config properties that
don't exist until after sign-in and subsequent config re-fetch
- renamed `config` service to `configManager` and updated to only
contain methods for fetching config data
- added a `config` instance initializer that sets up a `TrackedObject`
instance with some custom properties/methods and registers it on
`config:main`
- uses application instance initializer rather than a standard
initializer because standard initializers are only called once when
setting up the test suite so we'd end up with config leaking across
tests
- added an `@inject` decorator that when used takes the property name
and injects whatever is registered at `${propertyName}:main`, this
allows us to use dependency injection for any object rather than just
services or controllers
- using `application.inject()` in the initializer was initially used but
that only works for objects that extend from `EmberObject`, the
injections weren't available in native-class glimmer components so this
decorator keeps the injection syntax consistent
  - swapped all `@service config` uses to `@inject config`
2022-11-03 11:14:36 +00:00
Kevin Ansfield
7b443d4b63 Removed need for .get() with config service
no issue

The `config` service has been a source of confusion when writing with modern Ember patterns because it's use of the deprecated `ProxyMixin` forced all property access/setting to go via `.get()` and `.set()` whereas the rest of the system has mostly (there are a few other uses of ProxyObjects remaining) eliminated the use of the non-native get/set methods.

- removed use of `ProxyMixin` in the `config` service by grabbing the API response after fetching and using `Object.defineProperty()` to add native getters/setters that pass through to a tracked object holding the API response data. Ember's autotracking automatically works across the native getters/setters so we can then use the service as if it was any other native object
- updated all code to use `config.{attrName}` directly for getting/setting instead of `.get()` and `.set()`
- removed unnecessary async around `config.availableTimezones` which wasn't making any async calls
2022-10-07 16:14:57 +01:00
Kevin Ansfield
060d791a63 Removed need for .get() with settings service
no issue

The `settings` service has been a source of confusion when writing with modern Ember patterns because it's use of the deprecated `ProxyMixin` forced all property access/setting to go via `.get()` and `.set()` whereas the rest of the system has mostly (there are a few other uses of ProxyObjects remaining) eliminated the use of the non-native get/set methods.

- removed use of `ProxyMixin` in the `settings` service by grabbing the attributes off the setting model after fetching and using `Object.defineProperty()` to add native getters/setters that pass through to the model's getters/setters. Ember's autotracking automatically works across the native getters/setters so we can then use the service as if it was any other native object
- updated all code to use `settings.{attrName}` directly for getting/setting instead of `.get()` and `.set()`
- removed use of observer in the `customViews` service because it was being set up before the native properties had been added on the settings service meaning autotracking wasn't able to set up properly
2022-10-07 16:14:57 +01:00