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

Parameterize entities views. Global filters? Custom routes? #636

Closed
armellarcier opened this issue Aug 31, 2015 · 17 comments
Closed

Parameterize entities views. Global filters? Custom routes? #636

armellarcier opened this issue Aug 31, 2015 · 17 comments
Labels

Comments

@armellarcier
Copy link
Contributor

I have an apps entity which is the base model of my application.
Every other entity is linked to it. e.g. categories have an appId that reference an app.
I can nest categories inside other categories if they have the same appId.
I need to be able to edit an app's categories, thus displaying only categories with the same appId in my listView and in reference fields. For reference fields that means having a permanent filter with the selected appId.
Basically, when I select an app, I should modify every linked entities views accordingly so the data gets filtered right away.
I could have a custom route : categories/app/{appId}/list
I don't know if I'm making myself clear enough but the main ID is to parameterize every view according to the admin's state.
I need directions on how to do that...
Can anybody help please?

@armellarcier armellarcier changed the title Parameterize entities views Parameterize entities views. Global filters? Aug 31, 2015
@armellarcier armellarcier changed the title Parameterize entities views. Global filters? Parameterize entities views. Global filters? Custom routes? Aug 31, 2015
@TimoSolo
Copy link

TimoSolo commented Sep 1, 2015

I asked a similar question in #627

you could try set a global variable when you access an app and then use that ID in all your other url functions. eg:

var users = nga.entity('app')
                        .url(function(entity, view, id, element) {
                            window.app_id = id;
                            return 'app/' + ( id ? id+"/" : "" )
                        });
var categories = nga.entity('categories')
                        .url(function(entity, view, id, element) {
                            var app_id = window.app_id || 0
                            return 'categories/app/'+app_id+'/list'
                        });

(the parameters might be different - I think i was using the master branch)

@fzaninotto
Copy link
Member

Is permanentFilters() the solution to your need?

http://marmelab.com/blog/2015/08/26/ng-admin-0-8.html#permanent-filters

@armellarcier
Copy link
Contributor Author

Yes but it should look like
permanentFilters({ appId: app.id }); but I can't change it according to navigation can I?

@fzaninotto
Copy link
Member

You could if permanentFilters accepted a function and not only an object... Which is a deprecated feature (refs https://github.com/marmelab/admin-config/blob/master/lib/Queries/ReadQueries.js#L202-L205). But can you at least test that it works, in which case I'd de-deprecate it?

@armellarcier
Copy link
Contributor Author

Is it possible to access $stateParams in that function? to get the current ID?
Or the entry?

@armellarcier
Copy link
Contributor Author

@fzaninotto Hi! So I tried the permanentFilters function but as its only argument is the search query, it is no good indeed.
The main problem here is that fields have no access to filter parameters, queries or anything actually (not even the raw references json objects sent by the api on refresh). So that I'm left with two options :

  • Either store a global variable that will be updated by the fields directives, used in a fullRequestInterceptor to add dynamic filters and cleared when the view changes (I don't know how to achieve that last part BTW), which is real nasty
  • Or modify ng-admin and admin-config to expose some useful objects...
    A third option might be to inject ReadQueries and use it directly...
    Any advice on which is best?
    Thanks in advance and cheers!

@fzaninotto
Copy link
Member

Doing anything else than the first suggestion would imply deep (and non-BC) changes to ng-admin routing.

Related to #409

@xbgmsharp
Copy link

I do have the exact same concern. I need to implement a hard dependencies between the route. The first CRUD is a list of servers and you must select one server to get the next sub level. I manage using global variable (mention in previous post) to have a CRUD of the second level. However I get a HTTP/404 by default as no servers is selected. :id must not be null and valid from the previous server list. How could I ensure a server is selected?
The route is like /servers/:id/entries/:param.
Any hints?

@cmnstmntmn
Copy link

i have an entity with a custom url

admin.addEntity(nga.entity('recent').url('customEdge'));

then, in my dashboard ii make a restangular request on this entity

Restangular
                .one('recent')
                .get()
                ...

but the request is still made on /recent instead of /customEdge

what i am missing?

@fzaninotto
Copy link
Member

@cmnstmntmn you're mixing up two things:

  • entities, which are internal to ng-admin
  • resources, which are handled by Restangular, and are the basis for ng-admin's entities

When you customize an entity baseUrl, it is only taken into account in this entity - not in Restangular in general.

@cmnstmntmn
Copy link

yes, you're right.

i like the entity way of doing things, but is hard to deal with scope logic, i think.

the best example is the dashboard, in your demo; where both Restangular, used for dashboard-summary, and entities, for customizing panels, are used.

can i alter data inside return nga.dashboard() .. before i extract it in custom directive?

to make an ideea, from a single entity, having

"versions":[
     {"id":1, "name":"test 1"},
     {"id":2, "name":"test 2"},
     {"id":3, "name":"test 3"}
]

dashboard_campaign_versions

can choices-field handle the state of some fields inside entity?

@cmnstmntmn
Copy link

i think i found the answer by reading on your blog ng-admin-callback-customization

@cmnstmntmn
Copy link

@fzaninotto is this a good aproach?

dashboard/config.js

export default function (nga, admin) {
    return nga.dashboard()

        .addCollection(nga.collection(admin.getEntity('recent'))
            .name('id')
        // .title('Monthly revenue')
            .fields([
                nga.field('id'),
                nga.field('total', 'amount')
            ])
            .sortField('date')
            .sortDir('ASC')
            .perPage(100)
            )
        .template(`<dashboard-summary name="{{ collection().name() }}"
    entries="entries()"
    fields="::collection().fields()"
    entity="::collection().entity"
    list-actions="::collection().listActions()"
    datastore="datastore()"></dashboard-summary>`);
}

dashboardSummary.js

import dashboardSummaryTemplate from './dashboardSummary.html';
function dashboardSummary($state) {
    return {
        restrict: 'E',
        scope: {
            collection: '&',
            entries: '&',
            datastore: '&'
        },
        link: function (scope) {
            scope.gotoList = function () {
                $state.go($state.get('list'), { entity: scope.collection().entity.name() });
            };
        },

        testsample: function (scope) {
            console.log('ceva');
        },       

    template: dashboardSummaryTemplate
};
}

dashboardSummary.$inject = ['$state'];

export default dashboardSummary;

@jpetitcolas
Copy link
Contributor

@cmnstmntmn: it looks good to me. We already use something similar in some of our custom directive.

@fzaninotto
Copy link
Member

I think a global interceptor similar to the one described in #711 fits your need. I'm closing this issue, feel free to reopen if you need more assistance.

@cmnstmntmn
Copy link

@fzaninotto i am having the following edges

/stats - that provides an object; used all over the app + stats entity based on it

the object is

{
"STATS": {
    "count": 100
  }
}

then, in another entity, i'm trying to reference this entity, and do the math based on count value

            nga.field('stats', 'reference')
                .targetEntity(admin.getEntity('stats'))
                .targetField(nga.field('STATS'))
                .permanentFilters({})

but it doesn't work, becauze the call is made to /stats/[object%20Object]

is there a way to call an api edge with static objects ?

@fzaninotto
Copy link
Member

Nope, that's not very RESTY. But I did something similar in ng-admin demo, see marmelab/ng-admin-demo@a26c4e1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants