jrrmt / ng-admin

Add an AngularJS admin GUI to any RESTful API

Home Page:http://ng-admin.marmelab.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ng-admin Build Status

Plug me to your RESTFul API to get a complete administration tool (CRUD, multi-model relationships, dashboard, complex form widgets) in no time!

http://static.marmelab.com/ng-admin.png

Check out the online demo (source), and the launch post.

Installation

Retrieve the module from bower:

bower install ng-admin --save

Include it:

<link rel="stylesheet" href="/path/to/bower_components/ng-admin/build/ng-admin.min.css">

<script src="/path/to/bower_components/ng-admin/build/ng-admin.min.js" type="text/javascript"></script>

Make your application depends on it:

var app = angular.module('myApp', ['ng-admin']);

Configure ng-admin:

app.config(function(NgAdminConfigurationProvider, Application, Entity, Field, Reference, ReferencedList, ReferenceMany) {
    // See below for more information about the configuration

    var app = new Application('My backend')
        .baseApiUrl('http://localhost:3000/')
        .addEntity(/* ... */)

    NgAdminConfigurationProvider.configure(app);
});

Your application should use a ui-view:

<div ui-view></div>

Configuration

We chose to define the entities directly into a javascript file to allow greater freedom in the configuration. For some part of the configuration, you'll be able to define directly the function that match your specific needs to fit your API.

Here is a full example for a backend that will let you create, update, delete some posts (posts entity). Those posts can be tagged (tags entity) and commented (comments entity).

app.config(function(NgAdminConfigurationProvider, Application, Entity,
    Field, Reference, ReferencedList, ReferenceMany) {

    var postBody, postId;

    // Declare a new entity
    var tag = new Entity('tags')
        .label('Tags')
        // how many element should be displayed in dashboard ?
        .dashboard(10)
        // define your specific pagination function returning GET parameters
        .pagination(function(page, maxPerPage) {
            return {
                offset: (page - 1) * maxPerPage,
                limit: maxPerPage
            }
        })
        // enable lazyload pagination
        .infinitePagination(true)
        // Set specific parameter for search
        .filterQuery(function(query) {
            return {
                filter: query
            };
        })
        .addField(new Field('id')
            .order(1)
            .label('ID')
            .type('number')
            .identifier(true)
            .edition('read-only')
        )
        .addField(new Field('name')
            .order(2)
            .label('Name')
            .edition('editable')
            .validation({
                "required": true,
                "max-length" : 150
            })
        );

    var comment = new Entity('comments')
        .label('Comments')
        .dashboard(10)
        .infinitePagination(true)
        .filterQuery(false)
        .sortParams(function(field, dir) {
            return {
                // Change sorting params
                params: {
                    sort: field,
                    sortDir: dir
                },
                // You can also want to sort via headers
                headers: {
                }
            }
        })
        .addField(postId = new Field('id')
            .order(1)
            .label('ID')
            .type('number')
            .identifier(true)
            .edition('read-only')
        )
        .addField(postBody = new Field('body')
            .order(2)
            .label('Comment')
            .edition('editable')
            .validation({
                "required": true,
                "max-length" : 150,
                // define your custom validation function
                "validator" : function(value) {
                    return value.indexOf('cat') > -1;
                }
            })
        )
        .filterParams(function(params) {
            // Allows to return custom specific search params
            return params;
        })
        .addField(new Field('created_at')
            .order(3)
            .label('Creation Date')
            .type('date')
            .edition('editable')
            .validation({
                "required": true
            })
        ).addQuickFilter('Today', function() {
             var now = new Date(),
                 year = now.getFullYear(),
                 month = now.getMonth() + 1,
                 day = now.getDate();

             month = month < 10 ? '0' + month : month;
             day = day < 10 ? '0' + day : day;

             return {
                 created_at: [year, month, day].join('-')
             }
        })
		.addField(new Field('actions')
            .type('callback')
            .list(true)
            .label('Big value')
            // Disable default link on the list view
            .isEditLink(false)
            // Add a new link to the post thanks to callback
            .callback(function(entity) {
                // Directive can also be included
                return '{{ entity.getField("name").value.toUpperCase() }}';
            })
        );

    var post = new Entity('posts')
        .label('Posts')
        .dashboard(null)
        .pagination(false)
        .addField(new Field('id')
            .label('ID')
            .type('number')
            .identifier(true)
            .edition('read-only')
        )
        .addField(new Field('body')
            .label('Body')
            .type('wysiwyg')
            .edition('editable')
        )
        .addField(new ReferencedList('comments')
            .label('Comments')
            .targetEntity(comment)
            .targetField('post_id')
            .targetFields([postId, postBody])
             )
        .addField(new ReferenceMany('tags')
            .label('Tags')
            .targetEntity(tag)
            .targetLabel('name')
        );

    var app = new Application('My backend')
        // Add extra headers for each actions
        .headers(function(entityName, action) {
            return {
                'X-User': entityName === 'post' ? 'username' : 'user2',
                'X-Password': 'pwd'
            }
        })
        .baseApiUrl('http://localhost:3000/')
        .addEntity(post)
        .addEntity(comment)
        .addEntity(tag);

    NgAdminConfigurationProvider.configure(app);
});

Field types

  • Field : simple field
  • Reference : association 1-N with another entity
  • ReferenceList : association N-1
  • ReferenceMany : association N-N

List of options for Field type

  • type(string ['number'|'string'|'text'|'wysiwyg'|'email'|'date'|'choice']) Define the field type.

  • label(string label) Define the label of the field.

  • defaultValue(v) Define the default value of the field.

  • edition(string ['read-only'|'editable']) Define if the field is editable in the edition form.

  • order(number|null) Define the position of the field in the form.

  • identifier(boolean [true|false]) Define if this field is the entity's identifier (to build the REST requests).

  • format(string ['yyyy-MM-dd' by default]) Define the format for date type.

  • choices([{value: '', label: ''}, ...]) Define array of choices for choice` type. A choice has both a value and a label.

  • valueTransformer(function) Define a custom function to transform the value.

.addField(new Field('characters')
    .valueTransformer(function(value) {
        return value && value.items ? value.items[0] : value;
    })
)
  • list(boolean) Define if the field should be displayed in the list.

  • dashboard(number|false) Number of elements displayed in dashboard.

  • validation(function) Define a custom validation function.

List of options for Reference type

The Reference type also defines label, order, valueTransformer, list & validation options like the Field type.

  • targetEntity(Entity) Define the referenced entity.

  • targetLabel(string) Define the target field name used to retrieve the label of the referenced element.

List of options for ReferencedList type

The ReferencedList type also defines label, order, valueTransformer, list & validation options like the Field type.

  • targetEntity(Entity) Define the referenced entity.

  • targetField(string) Define the field name used to link the referenced entity.

  • targetFields(Array(Field)) Define an array of fields that will be display in the list of the form.

List of options for ReferencedMany type

The ReferencedMany type also defines label, order, valueTransformer, list & validation options like the Field type.

  • targetEntity(Entity) Define the referenced entity.

  • targetField(string) Define the field name used to link the referenced entity.

  • targetLabel(string) Define the target field name used to retrieve the label of the referenced element.

Build

Concatenate and minify the app with:

grunt build

Tests

Tests are lunched with karma by grunt:

grunt test

A new build/ng-admin.min.js file will be created.

Contributing

Your feedback about the usage of ng-admin in your specific context is valuable, don't hesitate to open GitHub Issues for any problem or question you may have.

All contributions are welcome. New applications or options should be tested with go unit test tool.

License

ng-admin is licensed under the MIT Licence, courtesy of marmelab.

About

Add an AngularJS admin GUI to any RESTful API

http://ng-admin.marmelab.com/

License:MIT License