Создать пользовательскую мини-карточку

Сложный

Пример. Создать пользовательскую мини-карточку для раздела База знаний (Knowledge base). Мини-карточка будет служить для просмотра базового набора полей Название (Name) и Теги (Tags) с возможностью скачивания прикрепленных файлов.

1. Создать схему модели представления мини-карточки 

  1. Перейдите в раздел Конфигурация (Configuration) и выберите пользовательский пакет, в который будет добавлена схема.
  2. На панели инструментов реестра раздела нажмите Добавить —> Модель представления страницы (Add —> Page view model).

  3. В дизайнере схем заполните свойства схемы:

    • Код (Code) — "UsrKnowledgeBaseArticleMiniPage".
    • Заголовок (Title) — "Миникарточка базы знаний" ("KnowledgeBase Mini Page").
    • Родительский объект (Parent object) — выберите "BaseMiniPage".

    Для применения заданных свойств нажмите Применить (Apply).

2. Отобразить поля основного объекта 

В дизайнере схем добавьте необходимый исходный код.

  1. В качестве схемы объекта укажите схему KnowledgeBase .
  2. Добавьте необходимые модификации в массив модификаций модели представления diff.

    Элементы модели представления базовой мини-карточки:

    • MiniPage — поле карточки.
    • HeaderContainer — заголовок карточки (по умолчанию размещается в первом ряду поля карточки).

    В примере в массив модификаций diff добавлены два объекта, которые конфигурируют поля Name и Keywords.

Исходный код схемы модели представления приведен ниже.

UsrKnowledgeBaseArticleMiniPage.js
define("UsrKnowledgeBaseArticleMiniPage", [], function() {
    return {
        entitySchemaName: "KnowledgeBase",
        attributes: {
            "MiniPageModes": {
                "value": [this.Terrasoft.ConfigurationEnums.CardOperation.VIEW]
            }
        },
        diff: /**SCHEMA_DIFF*/[
            {
                "operation": "insert",
                "name": "Name",
                "parentName": "HeaderContainer",
                "propertyName": "items",
                "index": 0,
                "values": {
                    "labelConfig": {
                        "visible": false
                    },
                    "isMiniPageModelItem": true
                }
            },
            {
                "operation": "insert",
                "name": "Keywords",
                "parentName": "MiniPage",
                "propertyName": "items",
                "values": {
                    "labelConfig": {
                        "visible": false
                    },
                    "isMiniPageModelItem": true,
                    "layout": {
                        "column": 0,
                        "row": 1,
                        "colSpan": 24
                    }
                }
            }
        ]/**SCHEMA_DIFF*/
    };
});

3. Добавить функциональную кнопку в мини-карточку 

По условию примера карточка должна обеспечивать скачивание файлов, связанных со статьей базы знаний.

Работа с дополнительными данными обеспечивается с помощью механизма их отображения в виде выпадающего списка преднастроенной кнопки.

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

Для добавления кнопки выбора файлов статьи базы знаний:

  1. Добавьте в массив diff элемент FilesButton, который является описанием кнопки
  2. Добавьте в свойство attributes виртуальную колонку Article, которая связывает основную и дополнительные записи.
  3. Добавьте в свойство attributes трибут MiniPageModes — массив, который содержит коллекцию необходимых операций, выполняемых мини-карточкой.
  4. Добавьте в ресурсы схемы изображение кнопки. Например, можно использовать это изображение — AddButtonImage.png. Добавление изображения в ресурсы описано в статье Добавить поле с изображением.
  5. Добавьте в свойство methods методы работы с выпадающим списком кнопки выбора файла:
    • init() — переопределенный базовый метод.
    • onEntityInitialized() — переопределенный базовый метод.
    • setArticleInfo() — устанавливает значение атрибута Article.
    • getFiles(callback, scope) — получает информацию о файлах текущей статьи базы знаний.
    • initFilesMenu(files) — наполняет коллекцию выпадающего списка кнопки выбора файлов.
    • fillFilesExtendedMenuData() — инициирует загрузку файлов и их добавление в выпадающий список кнопки выбора файлов.
    • downloadFile() — инициирует скачивание выбранного файла.

Исходный код схемы модели представления, который добавляет функциональную кнопку, приведен ниже.

UsrKnowledgeBaseArticleMiniPage.js
define("UsrKnowledgeBaseArticleMiniPage",
["terrasoft", "KnowledgeBaseFile", "ConfigurationConstants"],
    function(Terrasoft, KnowledgeBaseFile, ConfigurationConstants) {
        return {
            entitySchemaName: "KnowledgeBase",
            attributes: {
                "MiniPageModes": {
                    "value": [this.Terrasoft.ConfigurationEnums.CardOperation.VIEW]
                },
                "Article": {
                    "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                    "referenceSchemaName": "KnowledgeBase"
                }
            },
            methods: {
                /* Инициализирует коллекцию выпадающего списка кнопки выбора файлов.*/
                init: function() {
                    this.callParent(arguments);
                    this.initExtendedMenuButtonCollections("File", ["Article"], this.close);
                },
                /* Инициализирует значение атрибута, связывающего основную и дополнительные записи.
                Наполняет коллекцию выпадающего списка кнопки выбора файлов.*/
                onEntityInitialized: function() {
                    this.callParent(arguments);
                    this.setArticleInfo();
                    this.fillFilesExtendedMenuData();
                },
                /* Инициирует загрузку файлов и их добавление в выпадающий список кнопки выбора файлов.*/
                fillFilesExtendedMenuData: function() {
                    this.getFiles(this.initFilesMenu, this);
                },
                /* Устанавливает значение атрибута, связывающего основную и дополнительные записи.*/
                setArticleInfo: function() {
                    this.set("Article", {
                        value: this.get(this.primaryColumnName),
                        displayValue: this.get(this.primaryDisplayColumnName)
                    });
                },
                /* Получает информацию о файлах текущей статьи базы знаний.*/
                getFiles: function(callback, scope) {
                    var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                        rootSchema: KnowledgeBaseFile
                    });
                    esq.addColumn("Name");
                    var articleFilter = >this.Terrasoft.createColumnFilterWithParameter(
                        this.Terrasoft.ComparisonType.EQUAL, "KnowledgeBase", this.get(this.primaryColumnName));
                    var typeFilter = this.Terrasoft.createColumnFilterWithParameter(
                        this.Terrasoft.ComparisonType.EQUAL, "Type", ConfigurationConstants.FileType.File);
                    esq.filters.addItem(articleFilter);
                    esq.filters.addItem(typeFilter);
                    esq.getEntityCollection(function(response) {
                        if (!response.success) {
                            return;
                        }
                        callback.call(scope, response.collection);
                    }, this);
                },
                /* Наполняет коллекцию выпадающего списка кнопки выбора файлов.*/
                initFilesMenu: function(files) {
                    if (files.isEmpty()) {
                        return;
                    }
                    var data = [];
                    files.each(function(file) {
                        data.push({
                            caption: file.get("Name"),
                            tag: file.get("Id")
                        });
                    }, this);
                    var recipientInfo = this.fillExtendedMenuItems("File", ["Article"]);
                    this.fillExtendedMenuData(data, recipientInfo, this.downloadFile);
                },
                /* Инициирует скачивание выбранного файла.*/
                downloadFile: function(id) {
                    var element = document.createElement("a");
                    element.href = "../rest/FileService/GetFile/" + KnowledgeBaseFile.uId + "/" + id;
                    document.body.appendChild(element);
                    element.click();
                    document.body.removeChild(element);
                }
            },
            diff: /**SCHEMA_DIFF*/[
                {
                    "operation": "insert",
                    "name": "Name",
                    "parentName": "HeaderContainer",
                    "propertyName": "items",
                    "index": 0,
                    "values": {
                        "labelConfig": {
                            "visible": true
                        },
                        "isMiniPageModelItem": true
                    }
                },
                {
                    "operation": "insert",
                    "name": "Keywords",
                    "parentName": "MiniPage",
                    "propertyName": "items",
                    "values": {
                        "labelConfig": {
                            "visible": true
                        },
                        "isMiniPageModelItem": true,
                        "layout": {
                            "column": 0,
                            "row": 1,
                            "colSpan": 24
                        }
                    }
                },
                {
                    "operation": "insert",
                    "parentName": "HeaderContainer",
                    "propertyName": "items",
                    "name": "FilesButton",
                    "values": {
                        "itemType": Terrasoft.ViewItemType.BUTTON,
                        /* Настройка изображения кнопки.*/
                        "imageConfig": {
                            /* Изображение предварительно необходимо добавить в ресурсы мини-карточки.*/
                            "bindTo": "Resources.Images.FilesImage"
                        },
                        /* Настройка выпадающего списка.*/
                        "extendedMenu": {
                            /* Название элемента выпадающего списка.*/
                            "Name": "File",
                            /* Название атрибута миникарточки, связывающего основную и дополнительные                                   записи.*/
                            "PropertyName": "Article",
                            /* Настройка обработчика нажатия на кнопку.*/
                            "Click": {
                                "bindTo": "fillFilesExtendedMenuData"
                            }
                        }
                    },
                    "index": 1
                }
            ]/**SCHEMA_DIFF*/
        };
    });

4. Выполнить стилизацию мини-карточки 

Для добавления стилей в модель представления необходимо создать отдельный модуль со стилями и подключить этот модуль к схеме модели представелния.

  1. Перейдите в раздел Конфигурация (Configuration) и выберите пользовательский пакет, в который будет добавлена схема.
  2. На панели инструментов реестра раздела нажмите Добавить —> Модуль (Add —> Module).

  3. В дизайнере схем заполните свойства схемы:

    • Код (Code) — "UsrKnowledgeBaseArticleMiniPageCss".
    • Заголовок (Title) — "Стили миникарточки базы знаний" ("Knowledge base minipage styles ").

    Для применения заданных свойств нажмите Применить (Apply).

  4. В контекстном меню узла LESS укажите необходимые стили.

    UsrKnowledgeBaseArticleMiniPageCss.js
    div[data-item-marker="UsrKnowledgeBaseArticleMiniPageContainer"] > div {
    width: 250px;
    }
  5. В дизайнере схем измените код схемы модели представления: добавьте загрузку этого модуля в исходном коде.

    Ниже приведен полный исходный код мини-карточки:

    UsrKnowledgeBaseArticleMiniPage.js
    define("UsrKnowledgeBaseArticleMiniPage",
    ["terrasoft", "KnowledgeBaseFile", "ConfigurationConstants", "css!UsrKnowledgeBaseArticleMiniPageCss"],
        function(Terrasoft, KnowledgeBaseFile, ConfigurationConstants) {
            return {
                entitySchemaName: "KnowledgeBase",
                attributes: {
                    "MiniPageModes": {
                        "value": [this.Terrasoft.ConfigurationEnums.CardOperation.VIEW]
                    },
                    "Article": {
                        "type": Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
                        "referenceSchemaName": "KnowledgeBase"
                    }
                },
                methods: {
                    init: function() {
                        this.callParent(arguments);
                        this.initExtendedMenuButtonCollections("File", ["Article"], this.close);
                    },
                    onEntityInitialized: function() {
                        this.callParent(arguments);
                        this.setArticleInfo();
                        this.fillFilesExtendedMenuData();
                    },
                    fillFilesExtendedMenuData: function() {
                        this.getFiles(this.initFilesMenu, this);
                    },
                    setArticleInfo: function() {
                        this.set("Article", {
                            value: this.get(this.primaryColumnName),
                            displayValue: this.get(this.primaryDisplayColumnName)
                        });
                    },
                    getFiles: function(callback, scope) {
                        var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
                            rootSchema: KnowledgeBaseFile
                        });
                        esq.addColumn("Name");
                        var articleFilter = this.Terrasoft.createColumnFilterWithParameter(
                            this.Terrasoft.ComparisonType.EQUAL, "KnowledgeBase", this.get(this.primaryColumnName));
                        var typeFilter = this.Terrasoft.createColumnFilterWithParameter(
                            this.Terrasoft.ComparisonType.EQUAL, "Type", ConfigurationConstants.FileType.File);
                        esq.filters.addItem(articleFilter);
                        esq.filters.addItem(typeFilter);
                        esq.getEntityCollection(function(response) {
                            if (!response.success) {
                                return;
                            }
                            callback.call(scope, response.collection);
                        }, this);
                    },
                    initFilesMenu: function(files) {
                        if (files.isEmpty()) {
                            return;
                        }
                        var data = [];
                        files.each(function(file) {
                            data.push({
                                caption: file.get("Name"),
                                tag: file.get("Id")
                            });
                        }, this);
                        var recipientInfo = this.fillExtendedMenuItems("File", ["Article"]);
                        this.fillExtendedMenuData(data, recipientInfo, this.downloadFile);
                    },
                    downloadFile: function(id) {
                        var element = document.createElement("a");
                        element.href = "../rest/FileService/GetFile/" + KnowledgeBaseFile.uId + "/" + id;
                        document.body.appendChild(element);
                        element.click();
                        document.body.removeChild(element);
                    }
                },
                diff: /**SCHEMA_DIFF*/[
                    {
                        "operation": "insert",
                        "name": "Name",
                        "parentName": "HeaderContainer",
                        "propertyName": "items",
                        "index": 0,
                        "values": {
                            "labelConfig": {
                                "visible": true
                            },
                            "isMiniPageModelItem": true
                        }
                    },
                    {
                        "operation": "insert",
                        "name": "Keywords",
                        "parentName": "MiniPage",
                        "propertyName": "items",
                        "values": {
                            "labelConfig": {
                                "visible": true
                            },
                            "isMiniPageModelItem": true,
                            "layout": {
                                "column": 0,
                                "row": 1,
                                "colSpan": 24
                            }
                        }
                    },
                    {
                        "operation": "insert",
                        "parentName": "HeaderContainer",
                        "propertyName": "items",
                        "name": "FilesButton",
                        "values": {
                            "itemType": Terrasoft.ViewItemType.BUTTON,
                            "imageConfig": {
                                "bindTo": "Resources.Images.FilesImage"
                            },
                            "extendedMenu": {
                                "Name": "File",
                                "PropertyName": "Article",
                                "Click": {
                                    "bindTo": "fillFilesExtendedMenuData"
                                }
                            }
                        },
                        "index": 1
                    }
                ]/**SCHEMA_DIFF*/
            };
        });

5. Зарегистрировать мини-карточку в базе данных 

Создание мини-карточки предполагает ее обязательную регистрацию в базе данных. Для внесения изменений в базу данных выполните следующий SQL-запрос.

Запрос на создание мини-карточки
DECLARE 
    -- Название схемы представления создаваемой мини-карточки.
    @ClientUnitSchemaName NVARCHAR(100) = 'UsrKnowledgeBaseArticleMiniPage',
    -- Название схемы объекта, к которому привязывается мини-карточка.
    @EntitySchemaName NVARCHAR(100) = 'KnowledgeBase'

UPDATE SysModuleEdit
SET MiniPageSchemaUId = (
    SELECT TOP 1 UId
    FROM SysSchema
    WHERE Name = @ClientUnitSchemaName
)
WHERE SysModuleEntityId = (
    SELECT TOP 1 Id
    FROM SysModuleEntity
    WHERE SysEntitySchemaUId = (
        SELECT TOP 1 UId
        FROM SysSchema
        WHERE Name = @EntitySchemaName
            AND ExtendParent = 0
    )
);

В результате выполнения запроса уникальный идентификатор мини-карточки будет добавлен  в таблицу [SysModuleEdit] в поле [MiniPageSchemaUId] записи, соответствующей разделу База знаний (Knowledge base) .

scr_minicard_creating_3.png

6. Добавить системную настройку 

В разделе Системные настройки (System settings) дизайнера системы добавьте системную настройку со следующими свойствами :

  • Название (Name) — "HasKnowledgeBaseMiniPageAddMode".
  • Код (Code) — "HasKnowledgeBaseMiniPageAddMode".
  • Тип (Type) — "Логическое" ("Boolean").
  • Значение по умолчанию (Default value) — признак установлен.
scr_minicard_creating_system_setting.png

Результат выполнения примера 

После сохранения схемы и обновления веб-страницы приложения в разделе База знаний (Knowledge base) при наведении курсора на название будет отображаться пользовательская мини-карточка, в которой будут отображены связанные с записью файлы и реализована возможность скачать их.

scr_minicard_creating_4.png