no issue
- fixes problem when the nav menu would be shown on an error404 route when the user is not logged in
- adds failing test that passes with this change
no issue
- if the session is "authenticated" but is invalid, the initial load of the app would fail. It could be replicated by:
1. Authenticating in a running ghost instance
2. Stopping ghost
3. Deleting the database
4. Re-starting ghost
5. Closing the browser
6. Re-opening the browser and visiting http://localhost:2368/ghost
- this fix stores the `transition` object for the duration of the initial load so that `sessionInvalidated` method can trigger actions before the transition has finished
no issue
- always ensure we load a full settings object so that we don't risk saving a partial settings object back to the server
- should fix the issues reported in Slack of disappearing private settings over time
no issue
- Check for title, user_name and user_email in the top level of config.
- If they exist, return them as part of the setup check, so that the setup screen can be prepopulated
closes#4556
- when <kbd>CMD-S</kbd> is used, if the focused element is an input, trigger it's `focusout` handler then schedule the save action to happen after any actions resulting from the trigger
- split out read CSV function into utility and add tests
- update API response to follow JSONAPI more closely
- update the UI to match the new API response
Update for synchronous feature service
Add client-side handling of server-side errors when adding subscribers
- display server-provided error message when we get a server error
- fix the ajax util's `getRequestErrorMessage` method so that it works correctly with Ember's `InvalidError` object instead of the previous request object that it was receiving (*TODO:* this really needs looking at properly so we aren't losing details and Ember Data can do it's stuff)
Styling updates
- proper icon for ascending/descending
- change hover colour to green for "Import CSV" button
Delete subscriber button with confirm modal
- display delete button when hovering over a subscriber row (WARN: really ugly button, styles definitely want looking at)
- show confirm modal when clicking the delete button
- delete subscriber, remove from table, and update total on confirm
Form:
- add confirm, location & referrer hidden fields
- add script to populate location & referrer
- add helper for creating the email field
- pass through input class and placeholder for email from top level form helper
- rename subscribe_form template & helper as it sounds more natural
- handle success and error cases differently
- improve error message display
- ensure useful data is passed back so that we can show nice messages
- check for honeypot value being filled out
- refactor error handler to set an error and always still render
Initial Subscribers screen
- set up mocked api endpoints
- basic subscribers screen with data loading, infinite scroll
"Add Subscriber" screen
- uses modal to display a new subscriber form
- validates subscriber e-mail address
- moves pagination from route into controller to use filtered/sorted CPs on top of a live-query so that new subscribers are added to the list and the total can be properly managed
TODO:
- there is currently a pretty serious performance issue where the whole table is re-rendered when the live-query is updated. `ember-light-table` doesn't allow for live-binding and has no options to easily manipulate it's rows using an external interface - it's possible to move the page loading into the component so we only render new rows but that leaves it difficult to react to new subscribers being added through the UI. I believe the number of components used within the table is also adding to the performance problems.
- most likely solution is to drop `ember-light-table` in favour of rendering the table directly - glimmer should do a good job of fast updates even though the underlying array will be completely swapped out
"Import subscribers" screen
- uses modal to display an import subscribers CSV file upload form
- displays upload progress
- displays import stats and reloads subscribers table once import has completed
- adds `gh-file-uploader` component (NB. pared down copy of `gh-image-uploader`, ripe for some refactoring)
- fixes subscribers acceptance test failing because fixtures did not have the labs flag enabled
Unfortunately this doesn't have 100% test coverage as we're limited in how we can simulate file uploads 😞
Fix performance issues with subscribers table
- moves the table definition from the component up to the controller
- switches back to manually manipulating table rows instead of using a live-query
This is a quick-fix in that it allows us to continue using the `ember-light-table` component but it does mean that we lose some flexibility that the live-query gave us. For now it's not much of an issue and it allows us to defer deeper performance/flexibility work until we have a concrete need and requirements.
Hook up Export CSV button
- use a hidden iFrame to trigger the browser to hit the CSV export endpoint and download the file
Re-order subscribers table by clicking column headers
- displays currently sorted column and sort direction
- clicking a column header re-fetches the data from the server with the appropriate query params
Fix scroll triggers for infinite pagination + icon change
- adds a debounce as well as the throttle so that we always get a final scroll trigger once scrolling has stopped
- changes the subscribers icon from the temporary team icon to the mail icon
refs #6640
- add `NotFoundError` to ajax service and test against that when catching errors in `gh-profile-image`
- don't use `passthrough` in Mirage for gravatar requests to avoid network calls during testing
- add additional tests for `gh-profile-image` and put the debounced gravatar test back in place
Closes#5882
* If a gravatar image is available, remove the default image behind it
* If gravatar image is not available, keep or replace the default image
closes#6534
- new input fields in general settings incl. validation
- facebook and twitter as new models in settings.js
- adds values for facebook and twitter to default-settings.js
- adds blog helpers for facebook and twittter
- rather than saving the whole URL, the Twitter username incl. '@' will be extracted from URL and saved in the settings. The User will still input the full URL. After saving the blog setting, the stored Twitter username will be parsed again as the full URL and available in the input field. A custom transform is used for this.
- adding meta fields to be rendered in {{ghost_head}}:
- '<meta property="article:publisher" content="https://www.facebook.com/page" />' and
- '<meta name="twitter:site" content="@user"/>'
- adds facebook and twitter to unit test for structured data
- adds unit test for general settings
- adds acceptance test for new input fields in general settings
- adds a custom transform for twitter model to save only the username to the server
- adds unit test for transform
no issue
- ~10x speedup in processing time taken on each keypress when there are many images/image upload components in the editor
- edit DOM in memory before changing it in the page to avoid double-render
- keep upload components around and re-assign them on re-render, adding or removing an image will still re-generate everything
- adds a throttle to the preview rendering so that renders don't get queued up
- fixes occasional bug where uploading an image didn't update the markdown correctly due to a timing issue
closes#6584
- Frontend Changes:
- adds 'Apps' to Navigation Menu
- adds 'Slack' as nested page to Apps
- adds `apps.css`
- adds `slack-integration` model and uses `slack-settings` custom transform to parse JSON file
- adds validation for `slack` model
- adds fixtures and `slack/test` API endpoint to Mirage
- adds acceptance tests for `apps-test` and `slack-test`
- adds unit tests for `slack-settings` and `slack-integration`
- Backend Changes:
- adds API endpoint `slack/test` to send Test Notification
- adds default-values for slack model
- sends payload to slack:
- text: the url of the blogpost / test message
- icon_url: url to ghost logo
- username: Ghost
- adds `slack/index.js` to send webhook to slack if
- a new post is published (if slack webhook url is saved in settings)
- user clicks on 'Send Test Notification' in UI
- adds `slack.init()` to `server.index.js` to add event listener
- adds unit test for `slack/index`
supersedes #6773
- update `feature` service and `gh-feature-flag` component to work synchronously rather than async
- use the application route's `afterModel` hook so that settings are loaded before first load
- override `session` service's `authenticate` method to load the settings after successful authentication before any other routes are processed
no issue
- updates the `TrailingHistory` locationType so that trailing slashes aren't added to the end of URLs with parameters but instead matches how the server-side redirects to trailing-slash URLs
- before: `/subscribers?order=created_at/`
- after: `/subscribers/?order=created_at`
no issue
- moves the `NavItem` object from the navigation controller to an explicit `NavigationItem` model file
- adds a custom transform `navigation-settings` that transforms the navigation settings JSON string to/from an array of `NavigationItem` objects
- simplifies the `settings/navigation` controller as it no longer has to export it's own internal model and handle serialization and deserialization
This pattern should also help simplify the apps/slack integration code if implemented there.
no issue
- ensure that each validator instance gets it's own `errors` and `hasValidated` objects
- updates some uses of `ValidationEngine` that were relying on side-effects of the unintended reference sharing
- fixes issue with add subscriber modal displaying an error state after opening if it previously had errors when closing
no issue
- returns the promise/result from `loadNextPage` so that it's return value can be utilised in closure actions
- sets the `isLoading` property in `loadFirstPage` to match `loadNextPage` behaviour
- reset the `isLoading` property even if the request fails
- adds a `didReceivePaginationMeta` hook so that consumers of the mixin can use the metadata values without having to rely on observers
- eg. pulling the `total` into a separate property that can be manipulated when items are added/removed but still reset to the sever's total value the next time a page is loaded
- renames the `pagination-route` mixin to simply `pagination` as it's not tied to routes and works equally well in other objects that need to paginate an API resource
no issue
- moves existing mirage config into the `testConfig()` function to retain full mocks during testing
- configure mirage to passthrough all requests when in development mode
no issue
- replace deprecated `normalizeHash` with `normalize` in post serializer
- ensure we check for both `post` and `posts` properties as it will vary depending on the expected response type