Управление задачами является одной из наиболее важных функций для бизнеса. Хотя есть много решений этой проблемы, пока еще нет серебряной пули, потому что каждая сфера бизнеса имеет свою специфику. Разработка приложения для удовлетворения конкретных требований в этих условиях не редкость. AllcountJS позволяет довольно быстро создавать собственные приложения для управления задачами.
Если вы не знакомы с AllcountJS, сначала ознакомьтесь с руководством по началу работы . Хотя AllcountJS позволяет вам использовать всю мощь Node.js, в этой статье мы будем работать только с кодом App Config. Для того , чтобы запустить демо — код , который вы должны сделать npm install allcountjs-cli
то allcountjs init
или просто запустить код из нашей демонстрационной страницы здесь , и вы получите что — то вроде:
модель
Давайте начнем с объявления модели. Вероятно, наиболее важной вещью в управлении задачами является наличие объекта задачи (очевидно) и некоторого потока состояния. Давайте определим нашу модель в main.js
:
A.app({
appName: "Task manager",
onlyAuthenticated: true,
menuItems: [
{
name: "Planning",
entityTypeId: "Task"
}, {
name: "Statuses",
entityTypeId: "Status"
}
],
entities: function(Fields) {
return {
Task: {
fields: {
summary: Fields.textarea("Summary").required(),
dueDate: Fields.date("Due Date").required(),
status: Fields.fixedReference("Status", "Status")
}
},
Status: {
fields: {
name: Fields.text("Name").required(),
order: Fields.integer("Order").required()
},
referenceName: "name"
}
}
}
});
Этот App Config создает рабочее приложение, которое имеет две сущности: Task и Status. Объект задачи имеет поля сводки и даты выполнения, а также ссылку на статус. Сущность состояния имеет поле имени, используемое в качестве ссылочного имени при отображении поля со списком, и поле заказа, которое будет использоваться позже для определения порядка статусов. Как видите, обязательные поля помечены .required()
. Это означает, что объект не может быть создан или сохранен, пока эти поля не будут заполнены. Также вы можете отметить onlyAuthenticated
флаг, который обозначает, что приложение не может быть доступно без аутентификации.
Порядок статусов
Мы могли бы определить наши приоритеты статуса, просто добавив sorting: [['order', 1]],
к Status
типу объекта:
A.app({
appName: "Task manager",
onlyAuthenticated: true,
menuItems: [
{
name: "Planning",
entityTypeId: "Task"
}, {
name: "Statuses",
entityTypeId: "Status"
}
],
entities: function(Fields) {
return {
Task: {
fields: {
summary: Fields.textarea("Summary").required(),
dueDate: Fields.date("Due Date").required(),
status: Fields.fixedReference("Status", "Status")
}
},
Status: {
fields: {
name: Fields.text("Name").required(),
order: Fields.integer("Order").required()
},
sorting: [['order', 1]],
referenceName: "name"
}
}
}
});
Это объявление указывает AllcountJS сортировать Status
сущность по полю заказа в порядке возрастания.
Board View
Одной из самых мощных функций AllcountJS является концепция Views. Представление также является сущностью, но в качестве хранилища оно использует другую сущность. Таким образом, существует возможность создания множества вариантов поведения и визуализаций для одного и того же источника данных. Давайте создадим представление доски для нашей Task
сущности, добавив следующее свойство
views: {
TaskBoard: {
customView: "board"
}
}
И создайте новый пункт меню, чтобы открыть доску:
{
name: "Board",
entityTypeId: "TaskBoard",
icon: "bars"
}
Также мы должны создать пользовательскую доску просмотра, на которую мы ссылаемся ( board.jade
)
extends project/card-board
block panelBody
.panel-body
h4 {{item.summary}}
p {{item.dueDate | date}}
AllcountJS по умолчанию использует язык шаблонов Jade . Код в board.jade
определяет шаблон для пользовательского просмотра нашего форума. Он определяет panelBody
блок, который описывает, как будет выглядеть карта. Мы должны получить следующий результат для main.js
A.app({
appName: "Task manager",
onlyAuthenticated: true,
menuItems: [
{
name: "Planning",
entityTypeId: "Task"
}, {
name: "Board",
entityTypeId: "TaskBoard",
icon: "bars"
}, {
name: "Statuses",
entityTypeId: "Status"
}
],
entities: function(Fields) {
return {
Task: {
fields: {
summary: Fields.textarea("Summary").required(),
dueDate: Fields.date("Due Date").required(),
status: Fields.fixedReference("Status", "Status")
},
views: {
TaskBoard: {
customView: "board"
}
}
},
Status: {
fields: {
name: Fields.text("Name").required(),
order: Fields.integer("Order").required()
},
sorting: [['order', 1]],
referenceName: "name"
}
}
}
});
Если вы запустите этот пример кода, вы увидите доску Канбан со статусом, где вы можете перемещать карты между статусами. Порядок статусов определяется order
полем из-за сортировки.
Полировка
Для полировки вещей вы, вероятно, хотите добавить значки для пунктов меню и приложения. Вы можете сделать это, просто обратившись к значкам Font Awesome . Давайте добавим appIcon
и иконки для меню, и мы получим финальную версию для приложения.
A.app({
appName: "Task manager",
appIcon: "book",
onlyAuthenticated: true,
menuItems: [
{
name: "Planning",
entityTypeId: "Task",
icon: "tasks"
}, {
name: "Board",
entityTypeId: "TaskBoard",
icon: "bars"
}, {
name: "Statuses",
entityTypeId: "Status",
icon: "sort"
}
],
entities: function(Fields) {
return {
Task: {
fields: {
summary: Fields.textarea("Summary").required(),
dueDate: Fields.date("Due Date").required(),
status: Fields.fixedReference("Status", "Status")
},
views: {
TaskBoard: {
customView: "board"
}
}
},
Status: {
fields: {
name: Fields.text("Name").required(),
order: Fields.integer("Order").required()
},
sorting: [['order', 1]],
referenceName: "name"
}
}
}
});
Попробуйте запустить это в нашей демо-галерее .