AllcountJS: Делаем простую CRM с веб-интерфейсом и REST API за 15 минут

Допустим моя компания кому-то звонит и что-то продаёт и мне нужна простая CRM, которая позволит вести справочник контактов и наглядно отслеживать их состояние в плане продажи.
Сейчас мы с вами сделаем такую систему с нуля за считанные минуты. Для этого мы будем использовать фрэймворк Allcountjs.
Самые нетерпеливые могут сразу же посмотреть на результат.
a231ff1fefae4cc0a3fce2d0b267aa10.png
Так как это первая статья на русском про AllcountJS, то скажу пару слов о самом фреймворке.
AllcountJS — это фреймворк c открытым исходным кодом для быстрой разработки веб и мобильных приложений на Node.js. AllcountJS построен на MEAN стеке (MongoDB, Express, AngularJS, NodeJS). Развивается поддержка не только MongoDB, но и других БД, в первую очередь SQL.
Центральная часть AllcountJS приложения это конфигурационный .js файл с декларативным описанием структуры приложения: сущности, отношения между ними, права доступа и т.д.
CRUD операции к сущностям, управление пользователями, настройки прав доступа, и REST API до всех функций приложения — всё это доступно сразу, без необходимости написания дополнительного кода.
Базовый веб-интерфейс приложения генерируется автоматически. Естественно его можно дорабатывать и изменять как угодно — только необходимы знания AngularJS и и языка шаблонов jade. Если возможностей фреймворка окажется недостаточно, возможно расширение функциональности через использование механизма внедрения зависимостей.
Начать работу с AllcountJS можно несколькими способами: в качестве самостоятельного приложения, как модуль другого NodeJS приложения или запустить приложение на AllcountJS.com.
Самый простой способ увидеть AllcountJS в деле — это просто запустить одно из демо-приложений в галерее.

Рассмотрим и вариант с отдельным приложением. Для этого должны быть установлены MongoDB, NodeJS и Git. (если у вас Ubuntu то вы можете посмотреть скринкаст по установке ). Для установки AllcountJS выполним:

npm install -g allcountjs-cli
allcountjs init cusdevcrm-allcount
cd cusdevcrm-allcount
npm install

Далее откройте app-config/main.js в директории с приложением и замените его содержимое следующим кодом:

A.app({
  appName: "CusDev CRM",
  appIcon: "phone",
  onlyAuthenticated: true,
  menuItems: [
    {
      name: "Contact",
      entityTypeId: "Contact",
      icon: "user"
    }, {
      name: "Board",
      entityTypeId: "FlowBoard",
      icon: "bars"
    }, {
      name: "Statuses",
      entityTypeId: "Status",
      icon: "sort"
    }
  ],
  entities: function(Fields) {
    return {
      Contact: {
        fields: {
          name: Fields.text("Name").required(),
          company: Fields.text("Company").required(),
          site: Fields.text("Site"),
          email: Fields.text("Email"),
          skype: Fields.text("Skype"),
          phone: Fields.text("Phone"),
          lastContactDate: Fields.date('Last contact date'),
          status: Fields.fixedReference("Status", "Status")
        },
        views: {
          FlowBoard: {
            customView: "board"
          }
        }
      },
      Status: {
        fields: {
          name: Fields.text("Name").required(),
          order: Fields.integer("Order").required()
        },
        sorting: [['order', 1]],
        referenceName: "name"
      }
    }
  },
});


Теперь давайте подробнее разберёмся с тем что же этот код делает.
Вся конфигурация приложения располагается внутри единственного метода. Название и иконка приложения задаются с помощью свойств appName и appIcon. AllcountJS использует иконки Font Awesome. Вы можете выбрать любую иконку и использовать её в приложении просто сославшись на неё по имени. При ссылке на иконку необходимо отбросить префикс fa-. Мы возьмем обычный телефонный значок для нашей «CusDev CRM».

 appName: "CusDev CRM",
 appIcon: "phone",


За настройку аутентификации отвечает свойство onlyAuthenticated. Оно определяет возможность использования приложения незарегистрированными пользователями. Мы же не хотим что бы доступ до CRM был у всех, поэтому:

onlyAuthenticated: true


Далее в конфигурации идёт пункт menuItems, но мы к нему вернёмся после того как опишем сущности и их представления.
Теперь мы готовы к тому что бы описать наши бизнес-сущности.
Опишем сущность Contact. Пусть у контакта будут два обязательных текстовых поля — Name и Company. Несколько текстовых полей с информацией о способах связи, дата последнего контакта и текущий статус контакта.
Поле status — это ссылка на сущность статус в которых может находиться контакт (например “Написали”, “Ответил”, “Готов на встречу”).

entities: function(Fields) {
    return {
      Contact: {   
        fields: {    
          name: Fields.text("Name").required(),    
          company: Fields.text("Company").required(),    
          site: Fields.text("Site"),   
          email: Fields.text("Email"),   
          skype: Fields.text("Skype"),    
          phone: Fields.text("Phone"),
          lastContactDate: Fields.date('Last contact date'),    
          status: Fields.fixedReference("Status", "Status")    
        }
      },    
      Status: {    
        fields: {    
          name: Fields.text("Name").required(),   
          order: Fields.integer("Order").required()    
        },    
        sorting: [['order', 1]],    
        referenceName: "name"    
      }    
    }   
  }


Каждая сущность может иметь представления (вью). Они задаются в свойстве view. Представления в AllcountJS похожи на представления в SQL. Они не занимают дополнительного места в БД, но вы можете работать с ними как с обычными сущностями. Представления можно использовать для того что бы обеспечить специальное поведение, интерфейс и права доступа.
В нашем случае мы будем использовать представления для того что бы сделать специальный UI в виде интерактивной доски для отображения контактов. Зададим для контакта представление FlowBoard а внутри него, в свойстве customView, UI шаблон board.

views: {    
  FlowBoard: {    
    customView: "board"   
  }   
}


Он ссылается на .jade файл, содержащий код шаблона. AllcountJS использует шаблонизатор jade для генерации конечного HTML для веб интерфейсов. Подробнее о jade можно прочитать на jade-lang.com
В комплекте AllcountJS есть шаблон канбан доски с драг-анд-дропом. Наше представление board является его расширением. Создадим файл board.jade со следующим кодом внутри:

extends project/card-board    
block panelBody    
  .panel-body    
    h4 {{item.name}}    
    p {{item.company}}    
    p {{item.lastContactDate | date}} 


3444162af54148be840d9f97651153e1.png
Теперь мы дошли и до меню нашего приложения. Оно задаётся в свойстве menuItems и состоит из ссылок на сущности и представления.

menuItems: [    
    {    
      name: "Contact",    
      entityTypeId: "Contact",    
      icon: "user"    
    }, {    
      name: "Board",    
      entityTypeId: "FlowBoard",    
      icon: "bars"    
    }, {    
      name: "Statuses",    
      entityTypeId: "Status",    
      icon: "sort"    
    }    
  ]


Если у нас есть какое-нибудь другое приложение, которое нужно интегрировать с нашей CRM, то это не будет проблемой, т.к. все функции приложения доступны через REST API.
Для начала нужно получить токен для доступа. Допустим наша CRM располагается на https://localhost:9080, в таком случае необходимо отправить HTTP POST запрос на
https://localhost:9080/api/sign-in
С таким JSON содержимым в теле:

{"username": "admin", "password": "admin"}


В ответ вернётся примерно такой ответ:

{"token":"56026b8ad7939dcb552a1668:PSDhU6x_VeIzqPYtIATXzEdMTLE"}


Теперь можно, например, получить список всех контактов. Для этого отправим HTTP GET запрос, но уже с заголовком
X-Access-Token в который передадим полученный токен из предыдущего запроса.
На https://localhost:9080/api/entity/FlowBoard
или напрямую на https://localhost:9080/api/entity/Contact
В ответ вы получите список всех контактов в формате JSON. Естественно что вы можете также удалять, создавать и обновлять ваши контакты через API.
В статье, на примере простой CRM показана лишь малая часть возможностей AllcountJS. В демо приложении кроме выше рассмотренного есть ещё и русская локализация, которую можно отключить вписав forcelocale: «en» в раздел с общими настройками. А завершает конфигурацию скрипт по добавлению тестовых данных.
В следующих статьях мы продолжим знакомить вас с устройством и возможностями фреймворка. В одной из следующих статей мы покажем как можно сделать и мобильное приложение к нашей CRM. Тоже достаточно быстро. Кому не терпится узнать больше и кого не пугает английский — добро пожаловать на официальный сайт allcountjs.com.

© Habrahabr.ru