Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ember.js] admin UI rewrite #2271

Closed
59 of 61 tasks
ErisDS opened this issue Feb 26, 2014 · 26 comments
Closed
59 of 61 tasks

[Ember.js] admin UI rewrite #2271

ErisDS opened this issue Feb 26, 2014 · 26 comments
Labels
affects:admin Anything relating to Ghost Admin

Comments

@ErisDS
Copy link
Member

ErisDS commented Feb 26, 2014

Code: https://github.com/TryGhost/Ghost/tree/master/core/client

The following is an outline of the admin UI as it stands, and all the pieces that need to be rebuilt in Ember.js

Build tools:

  • Add relevant parts of EAK into ghost grunt tasks
  • ES6 modules!

Current routes:

All routes (except signin, signout, forgotten, reset and signup) are protected through login => when logged out redirect to signin (applies to all remaining routes)

Current features:

General

Posts list

Editor

Notes on future behaviour:

  • Editor should stay as is for now, we will rewrite this in a future project.
  • Offline capabilities are very much desired in future, but not as part of the rewrite
    • Create new post in offline-mode => regularly push local draft into localstorage (new status: "localdraft", addtional to "draft" + "published")?
    • Have the full collection of posts available offline?
    • Or should a user be able to opt-in for a selected post for offline editing?

Settings

Settings General #2421

Settings Apps #2423

Debug #2847

  • Upload file (import)
  • Download file (export)
  • Reset button
  • Should all have API endpoints, but may need changes
  • Notifications

Login

  • Email + password + login button
  • Authentication is done with server call managed via a cookie. Session is stored in the DB. Note Need a new approach for auth (oauth?)
  • oAuth [Ember.js] Authentication with OAuth #2759

Forgotten password #2843

  • Forgotten password screen
    • Enter email address + submit
  • Reset password screen
    • Enter new password + submit
  • Currently done with server call Note Need new API route for reseting + sending email => redirect signin

API endpoints:

For development we will write a stupid express server that mocks the current API endpoint and static responses for all requests, @sebgie will lead this

Additionally needed API endpoints:

  • authentication
  • de-authentication
  • password recovery
  • image uploads?

Restful API endpoints:

Documentation available on the wiki: https://github.com/TryGhost/Ghost/wiki/%5BWIP%5D-API-Documentation

Ember specific discussions

Settings User #2422 (moved to multi-user)

  • Misc inputs
  • Upload image modal [Ember.js] Upload Modal #2547
  • Save
  • Change password
  • Client side validation needed (currently incomplete) - rules defined in core/server/data/schema.js
@ErisDS ErisDS added this to the Ember.js milestone Feb 26, 2014
@ErisDS ErisDS added the epic label Feb 26, 2014
@hswolff
Copy link
Contributor

hswolff commented Feb 26, 2014

dibs :P

@halfdan
Copy link
Contributor

halfdan commented Feb 26, 2014

Ignore @hswolff :D
Dibs!

@ErisDS ErisDS added the client label Feb 26, 2014
@manuelmitasch
Copy link

Should we start a separate issue on discussing the model layer or are we already sold on "very thin to begin - later investigate more complex options"?

The suggestion by @rjackson was to use a custom Ghost.Model with find and save methods using ic-ajax.

Once the rewrite is finished we can still use more advanced libraries such as Ember Data, Ember Model, Orbit.js, and friends.

@stefanpenner
Copy link

Tooling:

just a heads-up, ember-cli work is progressing nicely. It aims to replace EAK especially the plethora of brittle and slow grunt tasks. It aims to be compatible, but will dramatical improve developer ergonomics.

As the project improves, I will try to keep your ember project in sync.

Persistence:

I would also encourage using ember-data directly, rather the shimming it in later. It is easy to use ember-data as a model + ajax layer without touching some of the more complex features (relationships and such) this will resemble your use of Ghost.Model but will instead benefit from a community of maintainers and best practices.

If you all have further questions feel free to reach out to me, I can likely spare small bursts of time.

@jackfrancis
Copy link

For Your Consideration (in terms of approach and perhaps, what not do do), something I whipped up as a response to Ember Data roadblocks (mostly due to backend factors: our API was not as Rails-y as the Ember team prefers, a slightly different approach to route paths, etc.; paginated result sets were especially a challenge for us to solve with ember-data at that time).

https://github.com/askcom/quarry-webui/blob/master/app/quarry-data.js

And example of a model object that extends the 'Quarry' data persistence layer namespace (for lack of a better term):

https://github.com/askcom/quarry-webui/blob/master/app/models/asset_model.js

I borrowed ideas from Discourse (at the time their codebase was not ember-data-enabled, not sure about now), especially the ajax function here:

https://github.com/askcom/quarry-webui/blob/master/app/quarry-data.js#L363

(that code block suggests @ErisDS's remark about "thin wrapper around ajax calls".

This is not the most elegant solution, and the .reopenClass() pattern is weird to the uninitiated, but this type of approach can work.

I agree with @stefanpenner that adoption of ember-data will yield the most long-term benefit, caveats about keeping very up-to-date with the ember-data community as it approaches 1.0 (and breaking changes are inevitably introduced). We chose to roll our own (this was 18 months ago so more defensible then) and wanted to share that this is a possible option.

@stefanpenner
Copy link

i'll gladly work with someone on the minimal ember-data usage, that basically exposes the raw ajax requests on a per model basis (via per model adapter) but still benefits from much of the internals and most importantly if problems arise a community is present.

@manuelmitasch
Copy link

@stefanpenner What do you think ghost would benefit from Ember Data other than an identity map? AFAIK the data structures for the ghost admin currently is always one API endpoint per route. Of course, this does not mean the models could not be structured differently. I have stopped using ED approx. 1 year ago as I could not get rid of some nasty bugs. This was before the jj-abrams reboot, so things might be a lot better now.

Are there any good examples where ember-data is used to additionally enable offline-capability? I think we would at least need to write our own adapter that integrates offline-storage as well.

In my view it mainly adds unnecessary complexity and payload. I believe if we use ED from the beginning we would have more work in case we would like to use orbit.js or something similar. What do you think about that?

@stefanpenner
Copy link

@manuelmitasch a lot has changed in a year, even ember a year ago was dramatically less mature.

  1. consistent patterns and api (like the rest of ember)
  2. a ever improving project (independent of ghost's efforts)
  3. ever growing community + knowledge base

Given the following:

// models/post.js
export default DS.Model.extend({
  firstName: DS.attr('string')
});

Assuming your API is a bit non-standard, per model adapters are you best-friend.

// adapter/post.js
export default DS.RestAdapter.extend({
  find: function(store, type, id) {
    return /* ajax call for find, which returns
                 a promise that fulfills with the data */
  },
  // implement functionality as needed (if it is non-standard)
});

see: https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/adapter.js#L111 for the rest of the Adapter API

In addition to the above, using ember data will provide you with.

  • an state aware object model
  • identity map
  • good in-flight merge resolution (not just last-write)
  • solutions for lessons you have yet to learn.

Now if you decide to add offline support, you have a clear and concise place to put that functionality (the adapter). If you (or someone else) releases such an adapter it would be of interest to others in the community, which intern could mean more contributions and a better adapter.

Given the possibility of a later migration (to something like orbit), I would prefer my usage of persistence to be consistent across the board.

That being said, given the architectural choices of ember-data and orbit.js, I wouldn't rule out orbit.js working as a super-charged adapter layer for ember-data.

@jackfrancis
Copy link

@stefanpenner Those are great, simple examples of the kind of customization that was not (obviously) accessible to the ember-data newbie when we rolled our custom adapter code in late 2012. Additionally, we built the core of our main app in late 2011, and as such had to endure a plethora of breaking changes and refactors during the maturation and lead-up to 1.0. This experience frightened us away from doing that all over again with ember-data in a pre-1.0 state (of course this remains the case).

However, based on two years of working with Ember, my faith in the core team’s architectural decision making is pretty high (this despite tons of little frustruations during this journey!), and so I’m much more likely now to +1 investing in ember-data from here on out.

@rwjblue
Copy link
Contributor

rwjblue commented Feb 26, 2014

I agree with @stefanpenner. We can almost certainly customize Ember Data to our needs (and I know there are a few contributors to that project in this thread to unblock us on any issues).

Ember Data gets us off the ground with a good base with many features that we would likely not have implemented ourselves.

@stefanpenner
Copy link

@jackfrancis although my time is limited, I would like to provide any help I can, especially at the start of this project. feel free to ping me on irc #iamstef

@ErisDS
Copy link
Member Author

ErisDS commented Feb 27, 2014

So it seems there are strong feelings that we should use Ember Data? It was my impression that this was a pretty heavy component that we might not even need.

@stefanpenner I see the benefits you've laid out, are there any drawbacks we should be aware of?

I was very keen to start light touch and build heavier duty stuff in when it became apparent we needed it, but I'm not familiar enough with all the options just yet so am very much open to suggestion.


In terms of an approach to getting the rewrite done, it has been proposed that we use a 'dumb' API that returns static responses.

I think we should also turn authentication off completely to start with, and focus on building it back in once we have some of the core content/editor/settings screens in place?

This should be relatively easy if we're going to build this at /ghost/ember/ for the time being as we can just add it to the list of noAuthRequired routes.

@jackfrancis
Copy link

For static API responses (I take that to mean mocks), I've had good success with the jquery-mockjax library.

https://github.com/appendto/jquery-mockjax

ErisDS added a commit to ErisDS/Ghost that referenced this issue Feb 27, 2014
issue TryGhost#2271

- should allow development of new admin UI whilst still having access to the old ui
@stefanpenner
Copy link

@ErisDS extra abstraction === learning cost, some advanced features (some aspects of relationships) may not be fully fleshed out.

Ultimately it is up to you guys but I feel strongly the simple use-cases is easily accomplished with ember-data, with an upside of good separation of concerns. As more complexity arises it provides a foundation to build on.

@Globegitter
Copy link

@ErisDS If the API doesn't return the response that ED expects there is definitely some extra work involved and it does add some weight to the total code size, but as Stefan pointed out customization has gotten much better over time. I have been using ED since rev. 0.12 myself and a few months after it got in the beta phase I started to see it as more mature and feel comfortable using it in production (which I am doing). Some nice things that I have gotten to like while using it: Caching, how it just handles the loading the same resource multiple times, automatic loading of the right model based on the route and compared to using it the first time it now much more has the feeling of 'it just works'.
Edit: Oh an not forget the ability to use ember-extension can sometimes come in really handy.

On a completely different note: Depending on what work there needs to be done I would love to help out on the project itself. Let me know if and how I could get involved some more.

@manuelmitasch
Copy link

I'm okay with using Ember Data. It's obviously an amazing piece of software.
So it seems the suggested way is a per model adapter that could use a custom ic-ajax call.
@ErisDS what are your feelings about it after this discussion?

@manuelmitasch
Copy link

One thing that we did not really discuss is the folder structure. In EAK we have an app folder where all the app relevant files go. On the same level there is also a config and test folder. I believe for acceptance tests the existing Casper.js tests could be used. Although, I like the idea to compare an Ember app to a iOS/Android app and would prefer to have qunit tests that are placed inside the client folder.

What are the feelings about the folder structure inside the app folder? They can be organised by type (all controllers into controllers folder, ...) or in PODs (eg. route, controller, template for editor in one folder). By type is well established, in PODs seems nicer for big apps, but has the drawback that it is not always clear where to put files that do not strictly belong into a specific POD. I think as the admin interface is not very big we can stick with the by type structure.

@hswolff
Copy link
Contributor

hswolff commented Feb 27, 2014

By type works for me. When I implemented the EAK folder structure I didn't commit all the empty files with .gitkeep as those aren't necessary to be in the repo. I figured once we had controllers, routes, etc we'd add them into their appropriate type folders.

Also we have a test specific folder at the moment, it'd be nice to centralize all the ember tests there.

@rwjblue
Copy link
Contributor

rwjblue commented Feb 27, 2014

I personally like the pods structure, but the EAK resolver falls back to lookup by type after attempting to lookup via POD. So it is easy to mix and match as makes sense. For example, things that are global to the application (like models and reusable components) can just be stored in their respective folders by type.

Either structure works well though.

@ebryn
Copy link
Contributor

ebryn commented Mar 2, 2014

I expressed my opinion on what the Ghost team should do re: data/model layer during our hangout call today. Here's a direct link to that part of the call: http://www.youtube.com/watch?v=GsN1diIdT0o&feature=share&t=1h15m19s

TL;DR: KISS (keep it simple stupid)

  1. Start with $.ajax
  2. Build up a tiny model class on top of that to get some things for free (like the default model hook behavior with dynamic segments)
  3. When you feel the need, look into data libraries like Ember Model and Ember Data.

@sebgie
Copy link
Contributor

sebgie commented Mar 7, 2014

I have opened some issues for API responses ( #2347, #2348, #2349, #2350) yesterday and I think that the ember implementation could already use the new API responses.

After doing some research and a short discussion with @ErisDS we think that @jackfrancis suggestion of using a mocking library to simulate the API responses is a better solution than my initial idea of building an API server. jquery-mockjax seems like a good solution if everyone is happy with it? I can do the setup for the mocks and fill in the initial API responses, if someone points me to where they should go :-).

@jackfrancis
Copy link

Happy to help with any mocking tasks. I recommend creating a thin wrapper around mockjax to make the actual mock invocations a bit easier to digest. For example, with something like this:

var MockApi = Ember.Namespace.create({
    ajaxStub: function (path, http_verb, http_data, http_response) {
        return $.mockjax({
            url: 'http://myapi.example.com' + path,
            type: http_verb,
            data: http_data,
            dataType: 'json',
            responseText: http_response
        });
    }
});

You can do lots of these:

MockApi.ajaxStub('/ghost/api/v0.1/posts/1*', 'GET', null, MockApi.post_response);

As opposed to the more tedious:

$.mockjax({
    url: 'http://myapi.example.com/ghost/api/v0.1/posts/1*',
    type: 'GET',
    data: null,
    dataType: 'json',
    responseText: MockApi.post_response
});

(Assuming that MockApi.post_response is a literal object that reflects an API json response payload.)

I had trouble getting url strings to match without the wildcard suffix, but always hoped that was my own misunderstanding. (To explain the asterisk in both examples above.)

@manuelmitasch
Copy link

@sebgie I agree that a 'client-side' mock should be enough for the development at the moment. We are already using ic-ajax which has the possibility to define fixtures per URL. Thus, I see no need to integrate mockjax as we already have the functionality.

See file: https://github.com/ErisDS/Ghost/blob/ember-with-proto/core/client/fixtures/init.js

@manuelmitasch
Copy link

As a followup on @sebgie 's API response issues I have opened an issue to discuss a possible standard/spec/media-type for the JSON REST API.

@ErisDS ErisDS changed the title [Ember.js] [Discussion] admin UI rewrite [Ember.js] admin UI rewrite Apr 15, 2014
@ErisDS
Copy link
Member Author

ErisDS commented Jun 17, 2014

A quick look at the list in this issue shows just how much of the Ember admin is complete. Still a lot of things are in a not-quite-finished state, where they mostly work but some of the finer points are missing.

There are 5 main areas of concern:

1. Validations

Covered by #2856 and #2976

We need a foundation on which to build validations for all aspects of the app. Updating posts and signin/signup are incomplete due to a lack of validations. Settings/General will also need this to be completed. @darvelo is working on this, but opinions and ideas are very welcome.

Required by: #3036, #2893, #2850 as well as #2856 and #2976

2. Mobile Support

Foundation issue: #2333 + #2957

We need a foundation on which to build a solid mobile offering. This is going to be time consuming, so in the short term we need to at least re-implement the 'mobile interactions' that we had in the old admin - #403 serves as a list of differences / special things we served to mobile devices.

Additionally, we need to not regress on the editor, and ensure that we can still serve codemirrorMobile to touch screen devices.

3. Keyboard Shortcuts

Foundation issue: #2752

Yet another missing foundation, we need the tools to add various kinds of Keyboard shortcuts. #2752 will be considered closed once the handful of shortcuts outlined in #2752 (comment) are implemented.

Required by #2988 and #2984, there will be many more of these #1463 acts as an epic for the whole process.

4. Wiring in Ember Data

Issues: #2951, #2846

So far, only the posts actually use ember data. We need to wire up the rest of the admin to also use it. There are two issues so far and more to come.

5. Tests

Covered by: #2989, #2990

At the moment we're flying blind with the ember admin, never knowing if a change we are making is breaking some other feature elsewhere. Step one is to get the old casper.js test suite running against the ember admin, leaving any tests that won't run due to incompleteness commented out with an issue marker where possible. Step two is to get a new suite of unit tests up and running against the most sensitive parts of the app (managing posts).

@ErisDS
Copy link
Member Author

ErisDS commented Jun 18, 2014

Additionally, here is a shortlist of the last big pieces of functionality left to complete in Ember. Essentially this is the same list as the one at the top, but with all the stuff we've completed removed so it's easier to see:

@ErisDS ErisDS modified the milestones: 0.5 Multi-user, 0.4 Ember.js Jun 18, 2014
@ErisDS ErisDS modified the milestones: 0.5 Multi-user, 0.4 Ember.js Jul 1, 2014
@ErisDS ErisDS closed this as completed Jul 1, 2014
tigefa4u pushed a commit to tigefa4u/Ghost that referenced this issue Aug 3, 2022
No issue

- Changed the Member details page to be more scalable and flexible, depending on whether creators are using subscriptions, emails, and stats.

* Hidden email stats on member detail page when subscriptions are off
* Hid subscription box on member details page when Stripe is not connected
* Updated copy and layout of member details page
* Updated old activity feed styles on member page
* Fixed padding issue for empty activity feed
* Fixed current and new activity feed
* Added Last seen to member details page behind feature flag
* Updated lint todo file
* Fixed spacing issue in member details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects:admin Anything relating to Ghost Admin
Projects
None yet
Development

No branches or pull requests

10 participants