Giter VIP home page Giter VIP logo

digitalwand.admin_helper's Introduction

digitalwand.admin_helper

API для сборки кастомных админок в Битриксе

Документация по модулю доступна по адресу http://api.digitalwand.ru/admin_helper/. Её же можно прочитать в комментариях в коде модуля.

Есть хорошая вводная статья в блоге: Генератор админок «Битрикса».

Простой рабочий пример реализован отдельным модулем demo.adminhelper

Концепция

Данный модуль реализует подход MVC для создания административного интерфейса.

Возможность построения административного интерфейса появляется благодаря наличию единого API для CRUD-операциями над сущностями. Поэтому построение админ. интерфейса средствами данного модуля возможно только для классов, реализующих API ORM Битрикс. При желании использовать данный модуль для сущностей, не использующих ORM Битрикс, можно подготовить для таких сущностей класс-обёртку, реализующий необходимые функции.

Основные понятия модуля:

  • Модель: "model" в терминах MVC. Класс, унаследованный от DataManager или реализующий аналогичный API.
  • Хэлпер: "view" в терминах MVC. Класс, реализующий отрисовку интерфейса списка или детальной страницы.
  • Роутер: "controller" в терминах MVC. Файл, принимающий все запросы к админке данного модуля, создающий нужные хэлперы с нужными настройками. С ним напрямую работать не придётся.
  • Виджеты: "delegate" в терминах MVC. Классы, отвечающие за отрисовку элементов управления для отдельных полей сущностей. В списке и на детальной.

Схема работы с модулем следующая:

  • Реализация класса AdminListHelper - для управления страницей списка элементов
  • Реализация класса AdminEditHelper - для управления страницей просмотра/редактирования элемента
  • Создание файла Interface.php с вызовом AdminBaseHelper::setInterfaceSettings(), в которую передается конфигурация полей админки и классы, используемые для её построения.
  • Если не хватает возможностей виджетов, идущих с модулем, можно реализовать свой виджет, унаследованный от любого другого готового виджета или от абстрактного класса HelperWidget

Рекомендуемая файловая структура для модулей, использующих данный функционал:

  • Каталог admin. Достаточно поместить в него файл menu.php, отдельные файлы для списка и детальной создавать не надо благодаря единому роутингу.
  • Каталог classes (или lib): содержит классы модели, представлений и делегатов.
  • -- classes/helper: каталог, содержащий классы "view", унаследованные от AdminListHelper и AdminEditHelper.
  • -- classes/widget: каталог, содержащий виджеты ("delegate"), если для модуля пришлось создавать свои.
  • -- classes/model: каталог с моделями, если пришлось переопределять поведение стандартных функций getList и т.д.

Использовать данную структуру не обязательно, это лишь рекомендация, основанная на успешном опыте применения модуля в ряде проектов.

Разработчики

digitalwand.admin_helper's People

Contributors

ademidemko avatar asgalex avatar chilikina avatar coldshine avatar denx-b avatar dmitriy-fullstack-2010 avatar egorzot avatar impcyber avatar may-cat avatar mfilin avatar mgnexus avatar mmjurov avatar mrdim avatar niksamokhvalov avatar nixmen avatar nook-ru avatar npman avatar s-sementsov avatar saljukinmn avatar xdpugachevx avatar zedsh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

digitalwand.admin_helper's Issues

Нет Limit в запросах при использовании пагинации

Пример из жизни:

  1. Заходим в список из 10 000 элементов
  2. Видим первые 20 элементов
  3. При этом формируется запрос без LIMIT, т.е. выбираются все 10 000 записей.

Надо, чтобы было LIMIT 0, 20 в конце такого запроса.

При смешанном отображении разделов/элементов нельзя выбрать элементы внутри раздела

Можно воспроизвести на demo.adminhelper:

  1. Контент → Новости
  2. Добавляем к URL страницы &popup=Y
  3. Кликаем на название любого раздела чтобы перейти в него

Дальше два варианта ошибочного поведения:

  • Будут выведены только подразделы без элементов
  • Если подразделов нет, получим страницу без стилей и скриптов (см. скрин)

В попапах для ссылок на подразделы используется url от AdminSectionListHelper, для чего — не очень понятно. @lithium-li, можешь пояснить, твой код вроде бы?

image

Автозагрузка модуля в админке

Нужно сделать так, что бы модуль автоматически загружался в админке, без необходимости вызова \Bitrix\Main\Loader. Таки образом, не будет необходимости прописывать в своих модулях подключение Админ-хелпера.

Проблема с виджетом ComboBoxWidget в множественном режиме.

При любом изменении элемента, значения для множественного поля ComboBoxWidget создаются заново.

Т.к. данный виджет не передаёт id текущего значения в таблице, и мы всегда попадаем в блок создания связанных данных.

public function processEditAction()
{
    if ($this->getSettings('MULTIPLE')) {
        $sphere = $this->data[$this->getCode()];
        unset($this->data[$this->getCode()]);

        foreach ($sphere as $sphereKey) {
            $this->data[$this->getCode()][] = array('VALUE' => $sphereKey);
        }
    }

    parent::processEditAction();
}

Т.е. empty($referenceData['ID']) всегда true.

foreach ($referenceDataSet as $referenceData) {
    if (empty($referenceData[$fieldWidget->getMultipleField('ID')])) {
        // Создание связанных данных
        if (!empty($referenceData[$fieldWidget->getMultipleField('VALUE')])) {
            $result = $this->createReferenceData($reference, $referenceData);

            if ($result->isSuccess()) {
                $processedDataIds[] = $result->getId();
            } else {
                break; // ошибка, прерываем обработку данных
            }
        }
    } else {
        // Обновление связанных данных
        $result = $this->updateReferenceData($reference, $referenceData, $referenceStaleDataSet);

        if ($result->isSuccess()) {
            $processedDataIds[] = $referenceData[$fieldWidget->getMultipleField('ID')];
        } else {
            break; // ошибка, прерываем обработку данных
        }
    }
}

Вопрос о создании взаимосвязанных полей при редактировании элемента

Доброго дня!
Есть ли в модуле возможность создавать взаимосвязанные поля? Например есть выпадашка ComboBoxWidget со списком инфоблоков и чтобы при выборе инфоблока в другом поле отображался список разделов выбранного инфоблока?
Если да, то подскажите, пожалуйста, как подобное реализовать)

Проект еще поддерживается?

доброго дня, собственно вопрос в топике
что с поддержкой? проект еще живой? будут ли какие то подвижки для поддержки php 8.1 ?

Тип чекбокса определяется неправильно

В getCheckboxType() тип чекбокса определяется по типу поля в модели. Однако в битриксе часто существует следующая конструкция (пример из bitrix\modules\main\lib\user.php):
'ACTIVE' => array( 'data_type' => 'boolean', 'values' => array('N','Y') ),

тип чекбокса будет определен как TYPE_BOOLEAN, хотя на самом деле он TYPE_STRING

Проблема с постраничкой

При переходе в раздел сохраняется номер текущей страницы в постраничной навигации. При этом целевой раздел может содержать м̀еньшее количество страниц, и список окажется пустым.

Наблюдается как при переходе по ссылке на раздел в списке, так и по кнопке На раздел выше.

Можно воспроизвести на demo.adminhelper, набив текстовые данные с помощью этого скрипта.

2017-04-12_12-47-59

Сортировка работает некорректно при примененном фильтре

Если перейти на страницу списка записей с установленными в URL параметрами сортировки, то битрикс на бекенде генерирует корректный вариант списка. Однако после того, как загрузился js, битрикс пытается применить фильтр, и вот он уже выставляет дефолтную сортировку.

Для исправления этого поведения добавил ПР #63

Групповое удаление

При попытке группового удаления возникает исключение вида:

[Bitrix\Main\ArgumentException] 
Unknown primary `0` found when trying to query Poi row. (100)
/home/bitrix/www/bitrix/modules/main/lib/entity/datamanager.php:350
#0: Bitrix\Main\Entity\DataManager::validatePrimary(array)
    /home/bitrix/www/bitrix/modules/highloadblock/lib/datamanager.php:297
#1: Bitrix\Highloadblock\DataManager::delete(array)
    /home/bitrix/www/local/modules/digitalwand.admin_helper/lib/EntityManager.php:248
#2: DigitalWand\AdminHelper\EntityManager->delete()
    /home/bitrix/www/local/modules/digitalwand.admin_helper/lib/helper/AdminListHelper.php:529
#3: DigitalWand\AdminHelper\Helper\AdminListHelper->groupActions(array, string)
    /home/bitrix/www/local/modules/digitalwand.admin_helper/lib/helper/AdminListHelper.php:224
#4: DigitalWand\AdminHelper\Helper\AdminListHelper->__construct(array, boolean)
    /home/bitrix/www/local/vendor/nav/adminhelper/AdminListHelper.php:11
#5: nav\AdminHelper\AdminListHelper->__construct(array, boolean)
    /home/bitrix/www/local/vendor/nav/adminhelper/admin/admin_interface_route.php:117
#6: require(string)
    /home/bitrix/www/bitrix/admin/nav_admin_helper_route.php:2

В \DigitalWand\AdminHelper\EntityManager::delete() идёт вызов:
$result = $model::delete($this->helper->getPk());
а в аргументах у него идёт не айди конкретной записи, а массив всех айдишников, которые надо удалить. Возможно, надо использовать $this->itemId. А может и где-то в другом месте исправить, чтобы не сломать логики.

Программная установка модуля

Пытаюсь установить модуль программно примерно таким способом:

require_once( './bitrix/modules/digitalwand.admin_helper/install/index.php');
(new digitalwand_admin_helper())->DoInstall();

В конце метода DoInstall() подключается файл, который выводит форму с предложением вернуться назад в список модулей после установки. Файл с этой кнопкой подключается с помощью инструкции $APPLICATION->IncludeAdminFile(). Однако эта инструкция после выполнения подключения файла вызывает внутри себя die(), в связи с чем работа программы, выполняющей установку, становится невозможной.

Предлагаю 2 варианта решения проблемы:

  • избавиться вообще от подключения файла step.php. Страница со списком модулей сама выведет сообщение об успешной установке модуля
  • изменить подключение файла на какой-нибудь другой способ, который не будет прекращать ход выполнения программы

ORMElementWidget в Multiple режиме

Если нет связанных данных, функция getOrmElementData

$rsMultEntity = $entityName::getList(array(
'select' => array('REFERENCE_' => $this->getCode() . '.*'),
'filter' => array('=ID' => $this->data['ID'])
));

выводит пустые поля ['REFERENCE_ID'=>NULL, 'REFERENCE_VALUE'=>NULL], которые затем записываются в список значений

while ($multEntity = $rsMultEntity->fetch()) {
$valueList[$multEntity['REFERENCE_VALUE']] = $multEntity['REFERENCE_VALUE'];
}

сформированный массив ["" => NULL] попадает в ОRM и возникает ошибка

$rsEntity = $linkedModel::getList(array(
'filter' => array('ID' => $valueList)
));

Проблема с типом Дата со временем

class CourseAdminInterface extends AdminInterface {
     public function fields() {
        return array(
            'MAIN' => array(             
                'FIELDS' => array(                    
                       "UF_DATE_LESSON" => array(
                        'WIDGET' => new HLIBlockFieldWidget()                       
                    )
                ))
        );
    } 
    public function helpers() {
        return array(
            '\Pam\HLcourse\Course\AdminInterface\CourseListHelper',
            '\Pam\HLcourse\Course\AdminInterface\CourseEditHelper'
        );
    }
}

UF_DATE_LESSON является типом Дата со временем в HighLoad ИБ, множественным и не объязательным. При сохранение нового элемента в сгнерированной админке появляется сообщение Значение поля «UF_DATE_LESSON» не является корректной датой/временем.
При этом само поле может быть пустым или заполеным датой из календаря. Я только смог понять что не србатывает CheckFields

Некорректная ссылка выбора элемента в OrmElementWidget в Multiple режиме

В теле функции getUrl при передаче параметра k=>'{{field_id}}' происходит экраниранирование значения, из-за чего шаблонизатор не делает замену и на выходе некорректная ссылка $popupUrl.

public function getMultipleEditHtml()
{
.....
$popupUrl = $linkedHelper::getUrl(array_merge(
array(
'popup' => 'Y',
'eltitle' => $this->getSettings('TITLE_FIELD_NAME'),
'n' => $name,
'k' => '{{field_id}}'
),
$this->getSettings('ADDITIONAL_URL_PARAMS')
));

А работают ли вообще множественные файлы?

При загрузке элемента замена полей не происходит, при сохранении не вставляется ID элемента! Или это только у меня? При сохранении тоже значения пишутся в VALUE, а не в поле замены.

Виджет для N:M

Покажите пример как реализовать виджет многие к многим

Проблема с обновлением списка при работе по https не на 443-м порту

Если к примеру HTTPS настроен не на 443-й порт, то при групповом удалении или удалении из контекстного меню строки (да и при любых действиях на странице списка) список не обновляется, т.к. браузер ругается на смешанное содержимое HTTPS.

Причина банальна: в классе AdminListHelper после указанных выше операций прописан LocalRedirect($listHelperClass::getUrl($params)) с относительным URL.
Т.к. HTTPS работает не на стандартном порту, LocalRedirect() криво определяет протокол и возвращает данные по HTTP, на что и ругается браузер.

Решение не менее банально: убираем эти LocalRedirect().

Понятно, что корень проблемы в настройках сервера, но по-моему эти LocalRedirect() в любом случае лишние, т.к. js-метод битрикса, отвечающий за операции на странице списка, сам обновляет блок с таблицей с учетом всех изменений.

Речь идет про LocalRedirect() в конструкторе и методе groupActions класса DigitalWand\AdminHelper\Helper\AdminListHelper.

Проблема с CheckboxWidget

Если в сущности присутствует ReferenceField, то происходит ошибка в виджете CheckboxWidget.
В методе getCheckboxType виджета CheckboxWidget в цикле foreach для $field вызывается метод getColumnName(), который отсутствует у ReferenceField и у его родителя Field.
Call to undefined method Bitrix\Main\Entity\ReferenceField::getColumnName() in /home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/widget/CheckboxWidget.php on line 209
модуль main 16.5.7
digitalwand.admin_helper 2.0.0

Временное решение проблемы - перемещение описания поля reference на последнее по порядку место в методе getMap сущности. Тогда цикл просто до него не добирается (при условии что искомое поле будет найдено раньше). Ну а по хорошему надо перед вызовом getColumnName сделать проверку $field на тип и если это ReferenceField - пропускать его.

Связь многий ко многим

Добрый день.
Подскажите, пожалуйста, поддерживает ли данный модуль из коробки возможность редактирования связи многий ко многим для OrmElementWidget?

После установки фильтра пропадает кнопка «На раздел выше»

Можно воспроизвести на demo.adminhelper:

  1. Контент → Новости
  2. Кликаем по разделу
  3. Происходит переход в раздел, на панели появляется кнопка На раздел выше
  4. Нажимаем Найти в блоке фильтра — кнопка На раздел выше пропадает.

При этом имя параметра с ID текущего раздела в URL меняется с ID на SECTION_ID.

2017-04-12_11-03-29

Не сохраняются введеные значения в случае ошибки

в AdminEditHelper.php в

else {
                    unset($this->data);
                    $this->data = $_REQUEST['FIELDS']; //Заполняем, чтобы в случае ошибки сохранения поля не были пустыми
                }

нало поправить т.к. например при сохранение с виджетом HL ИБ, веденные значения не хранятся в FIELDS. Или вообще убрать

Не проходит валидация OrmElementWidget в режиме Multiple

Т.к. OrmElementWidget наследуется от NumberWidget, а в режиме режиме Multiple функция getValue() возвращает массив, а не число, то валидация не проходит.

public function processEditAction()
{
if (!$this->checkRequired()) {
$this->addError('DIGITALWAND_AH_REQUIRED_FIELD_ERROR');
} else if (!$this->isNumber($this->getValue())) {
$this->addError('VALUE_IS_NOT_NUMERIC');
}
}

Удаление дочерних элементов

При удалении разделов удаление дочерних элементов остается на совести модели. Даже если это все таки реализовано в модели, то если этих элементов будет слишком много, то удаление может упасть по таймауту.

Не удаляются связанные записи при использовании виджетов в множественном режиме

Если у виджета нет настройки VARIANTS, строки из связанной таблицы не удалятся. Заметил при использовании FileWidget в режиме MULTIPLE.

В методе \DigitalWand\AdminHelper\EntityManager::processReferencesData:

$variantsField = $fieldWidget->getSettings('VARIANTS');

...

if($result->isSuccess()){ // Удаление записей, которые не были созданы или обновлены
    foreach ($referenceStaleDataSet as $referenceData) {
        if (
            !in_array($referenceData[$fieldWidget->getMultipleField('ID')], $processedDataIds) &&
	    array_key_exists($referenceData[$fieldWidget->getMultipleField('VALUE')], $variantsField)
	) {
            $result = $this->deleteReferenceData($reference,
		$referenceData[$fieldWidget->getMultipleField('ID')]);
		    if(!$result->isSuccess()) {
			break; // ошибка, прерываем удаление данных
		}
	}
    }
}

До конца не понимаю архитектуру, поэтому не знаю как лучше исправить, добавить проверку на тип виджета или реализовать настройку VARIANTS у FileWidget?

Множественная загрузка файлов у FileWidget

В модели создаю поле FILE_ID, свойство multiple =>true.
new Entity\IntegerField('FILE_ID',['multiple'=>true]),
создаю поле связку, указывающую на \Bitrix\Main\FileTable
new Entity\ReferenceField('FILES','\Bitrix\Main\FileTable',['=this.FILE_ID' => 'ref.ID'])

В классе админ интерфейса

'FILES'=>[
    'WIDGET'=>new Widget\FileWidget(),
    'IMAGE'=>true,
    'MULTIPLE'=>true
]

После этого пытаюсь создать новую запись в админке, загружаю один/несколько файлов и получаю битриксовый Exception

[Bitrix\Main\NotImplementedException]
Use CFile class. (140)
/home/bitrix/www/bitrix/modules/main/lib/file.php:191
#0: Bitrix\Main\FileTable::add(array)
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/EntityManager.php:468
#1: DigitalWand\AdminHelper\EntityManager->createReferenceData(object, array)
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/EntityManager.php:379
#2: DigitalWand\AdminHelper\EntityManager->processReferencesData()
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/EntityManager.php:213
#3: DigitalWand\AdminHelper\EntityManager->save()
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/helper/AdminEditHelper.php:527
#4: DigitalWand\AdminHelper\Helper\AdminEditHelper->saveElement()
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/helper/AdminEditHelper.php:453
#5: DigitalWand\AdminHelper\Helper\AdminEditHelper->editAction()
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/helper/AdminEditHelper.php:126
#6: DigitalWand\AdminHelper\Helper\AdminEditHelper->__construct(array, array)
/home/bitrix/www/bitrix/modules/digitalwand.admin_helper/admin/route.php:101
#7: include_once(string)
/home/bitrix/www/bitrix/admin/admin_helper_route.php:2

Вопрос: есть ли пример использования CFile или надо сделать свою таблицу и туда сохранять данные файлов?

Удаление нескольких записей

При использовании множественного удаления на листинге получаем ошибку:
[Bitrix\Main\ArgumentException] Unknown primary 0 found when trying to query News row. (100) /home/bitrix/www/bitrix/modules/main/lib/entity/datamanager.php:373 #0: Bitrix\Main\Entity\DataManager::validatePrimary(array) /home/bitrix/www/bitrix/modules/main/lib/entity/datamanager.php:116 #1: Bitrix\Main\Entity\DataManager::getByPrimary(array) /home/bitrix/www/bitrix/modules/main/lib/entity/datamanager.php:145 #2: Bitrix\Main\Entity\DataManager::getById(array) /home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/helper/AdminListHelper.php:519 #3: DigitalWand\AdminHelper\Helper\AdminListHelper->groupActions(array, string) /home/bitrix/www/bitrix/modules/digitalwand.admin_helper/lib/helper/AdminListHelper.php:224 #4: DigitalWand\AdminHelper\Helper\AdminListHelper->__construct(array, boolean) /home/bitrix/www/bitrix/modules/digitalwand.admin_helper/admin/route.php:108 #5: include_once(string) /home/bitrix/www/bitrix/admin/admin_helper_route.php:2

Замена getById на getList

В AdminEditHelper используется getById при выборке элемента. Нужно заменить это на getList и выбирать только те поля которые используются при редактировании элемента, потому что не всегда нужны все поля из записи, например в случае с модификаторами значения которые тянут что-то из АПИ.

Только страница списка

Есть ли возможность отображать только страницу списка элементов, без страницы редактирования?
Попробовал просто не создавать AdminEditHelper. Не получилось, ругается.

Описание модуля

Не хватает концептуального описания устройства АХ и принципов работы с ним. За неимением оного, новым разработчикам приходится объяснять, что такое хелперы, виджеты, Interface.php, как они взаимодействуют и т. д.

Это можно прописать для начала хотя бы в том же README.md.

Указание типа данных чекбокса

CheckboxWidget::getCheckboxType() имеет две проблемы:

  • Если поле виртуальное, то тип чекбокса не определится, т.к. в этом случае поля нет в $entityMap.
  • Нужно иметь возможность переопределить результат выполнения этой функции настройкой виджета. Когда мы лучше знаем, какого типа поля должно быть.

Ошибка удаления в списке

Уидает исключение

Unknown primary 0 found when trying to query OrderStatus row.

$this->helper->getPk()

возвращает массив и в ключе 0 вмето ID

Виджет не может изменить список полей для выборки в GetList

Метод виджета changeGetListOptions должен влиять на аргументы, передаваемые в GetList().

Изменение $select сейчас не влияет на выборку полей элементов (без разделов).

В changeGetListOptions передается переменная $visibleColumns, но её изменение не влияет на $listSelect, которая используется при выборке.

Настройки интерфейса

Не хватает конфигов, которые бы позволяли:

  • Скрывать поля в форме редактирования, но показывать их в списках.
  • Управлять кнопками «сохранить», «применить», «отменить» и др.: запрещать какие-то из них отображать, добавлять свои и т. д.
  • Так же, иметь возможность управлять кнопками в списках.
  • Метод setElementTitle() научить читать данные из интерфейса, что бы можно было описывать массивом заголовки для страниц.

Думаю, большую часть из перечисленного лучше настраивать через Interface.php. Но после выполнения задачи #1.

Пакет является брошенным, не используйте его!

Авторы! Отметьте в Packagist , что ваш пакет является заброшенным, если вы не реагируете и не исправляете его ошибки!!!

Разработчики-пользователи данного пакета: никогда его не используйте!

Причины:
1 Очень низкое качество кода: почти всё на статических методах :(
2 Для управления своей табличкой нужно делать свой модуль Битрикс. (это я попытался обойти, написав свой контроллер https://github.com/webarchitect609/bitrix-admin-helper-controller )
3 В модуле полным полно ошибок. Например, не работает массовое удаление записей.
4 Модуль по факту является брошенным: примерно с января 2017 года сообщения об ошибках (issue) плодятся, но никто их не исправляет.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.