Клонировать git
репозиторий:
git clone [email protected]:spbd/dashboard.git dashboard && cd $_
Установить npm
и bower
зависимости:
npm i && bower i
Проект собирается с помощью enb-сборщика.
Собрать проект:
./node_modules/.bin/enb make
Так как у нас всего одна нода, ее можно не указывать (enb make dashboard
).
От однократной сборки проекта пользы мало. Для комфортной разработки необходимо запустить сервер:
./node_modules/.bin/enb server
Страница будет доступна по адресу - localhost:8080. При обновлении страницы сборщик будет выполнять сборку автоматически.
Рекомендации по именованию веток:
widgets/base/<block-name>
widgets/specific/<block-name>
core/<block-name>
core/ui/<block-name>
Для веток c правками добавляется префикс fix, refactor, etc (fix/core/server
).
Перед тем как сделать push ветки, необходимо убедиться, что код соответствует заданному CodeStyle:
npm run lint
Перед созданием PR, следует сделать rebase по ветке master:
git rebase master
После создания PR, запустится процесс сборки и выкладки проекта, результаты которого
будут доступны по адресу http://spbd.github.io/builds/pr-<PRno>/src
.
Имеет смысл добавить в описание PR эту ссылку.
При push в ветку master, так же запускается процесс сборки и выкладки. Последний build доступен по адресу - http://spbd.github.io/builds/stable.
Макеты к виджетам доступны по адресу: https://github.com/spbd/specs
Конкретные виджеты находятся в директории ./widgets.specific
. Для добавления виджета на
dashboard, никаких манипуляций проводить не нужно. В процессе сборки произойдет все необходимое.
А именно:
- Технология
widgets-list
прочитает список директорий (одна директория = один виджет) из./widgets.specific
, и создаст CommonJS-модуль, экспортирующий список виджетов и preview для них:
module.exports = [
{
"widget": "simple",
"image": "simple.preview.png"
}
];
- Технология
widgets-decl
расширит файл декларации и допишет имена виджетов, чтобы они попали в зависимости. - Технология
widgets-manifest
создаст CSS файл (он приклеится к основному CSS), который описывает preview виджетов:
.widget-name__manifest_preview
{
background-image: url(path-to-widget/widget-name.preview.png);
/* ... */
}
Эти классы автоматически проставятся к нужным виджетам.
- Технология
widgets-ym
создаст ym-модуль, содержащий список виджетов, чтобы они были доступны из клиентского кода:
modules.define('widgets-list', function(provide) {
provide(["widget1", "widget2"]);
});
Стили можно писать как на CSS так и на Stylus. В роли шаблонизатора выступает BH.
Виджет обязательно должен включать файл изображения в технологии preview
- .preview.{svg,png,jpg,etc}
.
Например: ./widgets.specific/name/name.preview.svg
.
Базовым блоком для виджета всегда должен служить блок widget
, либо блок, который наследует от него.
name.deps.js
:
({
shouldDeps: [
{block: 'widget'}
]
});
Конкретный виджет обязательно должен быть инициализирован (метод init()
).
modules.define(
'simple',
['i-bem__dom', 'jquery', 'widget'],
function(provide, BEMDOM, $, Widget) {
provide(BEMDOM.decl({block: this.name, baseBlock: Widget}, {
onSetMod: {
js: {
inited: function() {
// Если базовым классом является не `widget`,
// нужно вызвать родительский конструктор
//
// this.__base.apply(this, arguments);
this
.widgetAPI()
.configure(function(widget, settings) {
// Конфигурация виджета
// Конфигурация окна настроек
})
.onSaveSettings(function(controls) {
// Сработает, когда будет нажата кнопка
// "save" в окне настроеек.
//
// controls - значение всех элементов окна настроек
})
.onShowSettings(function() {
// Сработает, когда будет нажата кнопка "SET".
})
.onLoadWidget(function(controls) {
// Сработает, когда виджет будет загружен из хранилища
// "save" в окне настроеек.
//
// controls - значение всех элементов окна настроек
})
.init(); // Инициализировать базовый виджет
}
}
}
}));
});
//...
.configure(function(widget, settings) {
widget.setProps({
width: 200, // ширина виджета по умолчанию
height: 260 // высота виджета по умолчанию
});
settings.setProps({
width: 200, // ширина окна настроеек
height: 260 // высота окна настроеек
})
.input({ // cоздать input
placeholder: 'hint', // подсказка
label: 'Text area', // метка (опциональное поле)
handler: this.handle // обработчик состояние change
})
.checkbox({ // cоздать checkbox
text: 'Simple checkbox', // текст перед элементов
handler: this.handle // обработчик события change
})
.select({ // создать select
options: [ // элементы
{val: '1', text: 'text1'},
{val: '2', text: 'text2', checked: true},
{val: '3', text: 'text3'}
],
handler: this.handle, // обработчик состояния change
label: 'Foo select' // метка (опциональное поле)
});
.radioGroup({ // создать radio-group
options: [ // элементы
{val: '1', text: 'text1'},
{val: '2', text: 'text2', checked: true},
{val: '3', text: 'text3'}
],
handler: this.handle, // обработчик состояния change
label: 'This is super radio-group' // метка (опциональное поле)
});
// Во все обработчики приходит параметр,
// содержащий новое состояние элемента
})
//...
Общение с сервером происходит посредством модуля server, который общается с реальным сервером через WebSocket. Достаточно добавить модуль в зависиомсти и подисаться на события для конкретного виджета.
server.on('widgets/name/event', function(e, data) {
console.log(data);
});
В данный момент сервер не реализован. В модуле server описаны фикстурные данные для разработки.
Базовый виджет отличается от конкретного лишь тем, что в нем не выполняется инициализация
(метод конфигуратора .init()
). Распологаются такие виджеты в директории ./widgets.base
.