Перейти к основному содержимому

AiChat

Отображает чат с языковой моделью

Используется для взаимодействия с большой языковой моделью. Представляет собой окно с чатом и боковой панелью для выбора истории чата при значении true свойства MultiChat. Отправка запросов и получение ответов от большой языковой модели является зоной ответственности разработчика, и выполняется обработчиком события OnRequest.

Массив параметров чатов должен иметь следующий формат:

  [
{
"id": "0d536d5a",
"title": "Мой новый чат",
"messagesCount": 4,
"lastMessage": "2024-07-22T13:08:18.958155",
"contextId": 1,
"thinkMode": true
},
]

Массив истории сообщений чата должен иметь следующий формат:

[
{
"id": "8aae6118-ac48-411e-8d80-de196f44d7ba",
"role": "human",
"timestamp": "2024-07-22T13:08:06.421111"
"type": "file",
"fileId": "8ebb7c66-3b64-4a02-b626-b2d8e096e427",
"fileName": "Руководство_по_разработке_на_базе_Платформы.pdf",
"fileType": "pdf",
"contentType": "application/pdf",
"fullPath": "/some/path/yeah/Руководство_по_разработке_на_базе_Платформы.pdf",
},
{
"id": "8aae6118-ac48-411e-8d80-de196f44d7bf",
"role": "ai",
"timestamp": "2024-07-22T13:08:06.420996"
"type": "message",
"content": "Да, Платформу можно использовать на мобильных устройствах под управленем iOS и Android.
Разработчики приложений на базе Платформы могут создавать мобильные приложения, которые можно запускать на различных мобильных устройствах.",
"sources": {
"3cdb2314-9751-4969-a4b9-14da8a757c61": {
"id": "3cdb2314-9751-4969-a4b9-14da8a757c61",
"seqNr": 1,
"fileType": "pdf",
"fileId": "8ebb7c66-3b64-4a02-b626-b2d8e096e427",
"path": "/some/path/yeah/Руководство_по_разработке_на_базе_Платформы.pdf",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.pdf",
"content": "Каждый пользователь приложения может иметь одну или несколько ролей. Пользователь может выполнить определенное действие, если в наборе его ролей есть роль с разрешением на это действие. Пользователь не может выполнить определенное действие, если в наборе его ролей есть роль с запретом на это действие. Для каждой роли пользователя вы формируете правила, включающие разрешение или запрет на выполнение пользовательской ролью действия над объектом."
},
},
},
]

Пример использования

  <AiChat
Prompt-var="Prompts"
Chats={[{ id: "0", title: "New chat" }]}
MultiChat={true}
OnRequest={() => { const { query, chatId, chat, files } = getEvent(); }}
/>

Свойства

AllowedFileTypes

Массив разрешенных расширений и/или MIME-типов файлов для загрузки

Тип: array

AttachedFiles

Псевдоним для InputAttachedFiles, OutputAttachedFiles

Тип: object

Значение по умолчанию: <pre>{}</pre>

Badge

Количественная информация в компонентах Menu, Accordion, Link, Text.

В качестве значения может использоваться объект с полями: counter (число), position ("post" или "pre"), color (цвет)

Тип: any

CSS

Массив строк-классов CSS-стилей, описанных в файле CSS.css разрабатываемого проекта или встроенных CSS-стилей Платформы.

Пример:

// внешние (m) и внутренние (p) отступы для компонента. Число после символа "-" (в этом примере - 4) должно быть кратно величине, указанной в параметре, определяющем кратность отступов, в файле Style.mdtheme разрабатываемого проекта.
CSS={["m-4", "p-4"]}

Тип: array

ChatId

Псевдоним свойств InputChatId и OutputChatId

Тип: string

Chats

Псевдоним свойств InputChats и OutputChats

Тип: array

CombineConfig

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

Тип: object

ContextsList

Массив контекстов поиска согласно установленному формату (см. описание компонента)

Тип: array

Hidden

Признак состояния компонента Скрыт.

Тип: boolean

Hint

Текст, отображаемый при наведении указателя мыши на компонент. Текст отображается на белом фоне

Тип: any

Id

Идентификатор компонента для навигации к нему на HTML-странице. Подробнее см. HTML id Attribute или ID

Тип: string

InputAttachedFiles

Входной параметр компонента: словарь с ключами - идентификаторами чатов и значеними - массивами файлов

Тип: object

Значение по умолчанию: <pre>{}</pre>

InputChatId

Входной параметр компонента: идентификатор открытого чата

Тип: string

InputChats

Входной параметр компонента: массив параметров чатов согласно установленному формату (см. описание компонента)

Тип: array

InputPrompt

Входной параметр компонента: словарь с ключами - идентификаторами чатов и значеними - текстами неотправленных сообщений

Тип: object

Значение по умолчанию: <pre>{}</pre>

LocalizationDictionary

Имя словаря для локализации строк в чате

Тип: string

Messages

Массив сообщений выбранного чата согласно установленному формату (см. описание компонента)

Тип: array

MessagesDeclensionHandler

Функция получения плюральной формы для строки с ключом MessageNumeral из словаря локализации LocalizationDictionary. В качестве параметров принимает число, которое должно быть согласовано со значением в MessageNumeral в текущей локали

Тип: undefined

MultiChat

Признак организации нескольких чатов

Тип: boolean

Значение по умолчанию: True

OnChange

Обработчик события изменения параметров чата.

В качестве параметра принимает объект со следующими полями:

  • id - идентификатор чата;
  • title - имя чата;
  • contextId - идентификатор контекста диалога;
  • messagesCount - количество сообщений в чате;
  • thinkMode - признак режима размышлений;
  • lastMessage - дата последнего сообщения.

Пример:

OnChange={() => { // Получение параметра события const event = getEvent(); // Вывод параметра события в консоль браузера console.log(event); } }

Тип: undefined

OnClick

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

В качестве параметра принимает объект типа объект события компонента экранной формы с дополнительными полями типа MouseEvent.

Пример:

OnClick={() => {
// Получение параметра события
const event = getEvent();
// Вывод параметра события в консоль браузера
console.log(event);
}
}

Тип: undefined

OnCreate

Обработчик события создания чата. Не имеет параметров.

Пример:

OnCreate={() => { // Вывод в консоль информации о событии console.log("Нажата кнопка Настройки") } }

Тип: undefined

OnDelete

Обработчик события удаления чата.

В качестве параметра принимает идентификатор удаляемого чата. Пример:

OnDelete={() => { // Получение параметра события const event = getEvent(); // Вывод параметра события в консоль браузера console.log(event); } }

Тип: undefined

OnFileAttached

Обработчик события прикрепления файла.

В качестве параметра принимает словарь с ключами - идентификаторами чатов и значеними - массивами объектов со следующими полями:

  • file - объект типа File;
  • fileType - расширение файла;
  • contentType - MIME-тип файла;
  • isLoading - признак состояния загрузки;
  • fileName - имя файла.

Пример:

OnFileAttached={() => { // Вывод в консоль браузера информации о файле console.log(getEvent()); } }

Тип: undefined

OnFileClick

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

В качестве параметра принимает объект со следующими полями:

  • id - идентификатор фрагмента текста из источника информации;
  • seqNr - порядковый номер источника информации;
  • fileType - расширение файла;
  • fileId - идентификатор файла в файловом хранилище Платформы;
  • path - полный путь к файлу в файловом хранилище Платформы;
  • url - ссылка на файл во внешнем источнике, если файл не находится в файловом хранилище Платформы;
  • content - фрагмент текста из источника информации.

Пример:

OnFileClick={() => { // Вывод в консоль браузера информации о файле console.log("source:", getEvent()); } }

Тип: undefined

OnFileRemove

Обработчик события удаления прикрепленного файла.

В качестве параметра принимает идентификатор файла.

Пример:

OnFileRemove={() => { // Вывод в консоль браузера информации о событии console.log(getEvent()); } }

Тип: undefined

OnKeyDown

Обработчик события нажатия любой клавиши клавиатуры. В качестве параметра принимает объект типа объект события компонента экранной формы с дополнительными полями типа KeyboardEvent.

Пример:

OnKeyDown={() => {
// Получение параметра события
const event = getEvent();
// Вывод параметра события в консоль браузера
console.log(event);
}
}

Тип: undefined

OnKeyUp

Обработчик события отпускания любой клавиши клавиатуры. В качестве параметра принимает объект типа объект события компонента экранной формы с дополнительными полями типа KeyboardEvent.

Пример:

OnKeyUp={() => {
// Получение параметра события
const event = getEvent();
// Вывод параметра события в консоль браузера
console.log(event);
}
}

Тип: undefined

OnMouseDown

Обработчик события нажатия любой кнопки мыши, когда указатель мыши находится на компоненте. В качестве параметра принимает объект типа объект события компонента экранной формы с дополнительными полями типа MouseEvent.

Пример:

OnMouseDown={() => {
// Получение параметра события
const event = getEvent();
// Вывод параметра события в консоль браузера
console.log(event);
}
}

Тип: undefined

OnMouseEnter

Обработчик события перемещения указателя мыши на компонент. Событие срабатывает только в случае, если указатель мыши находится за пределами компонента и пользователь перемещает указатель мыши внутрь компонента. Если указатель мыши в текущий момент находится внутри компонента, для срабатывания события пользователь должен переместить указатель мыши за пределы компонента, а затем обратно внутрь компонента. В качестве параметра принимает объект типа объект события компонента экранной формы с дополнительными полями типа MouseEvent.

Пример:

OnMouseEnter={() => {
// Получение параметра события
const event = getEvent();
// Вывод параметра события в консоль браузера
console.log(event);
}
}

Тип: undefined

OnMouseLeave

Обработчик события перемещения указателя мыши за пределы компонента. Событие срабатывает, только если указатель мыши находится внутри компонента, а пользователь перемещает указатель мыши за пределы компонента. Если указатель мыши в текущий момент находится за пределами компонента, для срабатывания события пользователь должен переместить указатель мыши внутрь компонента, а затем обратно за пределы компонента. В качестве параметра принимает объект типа объект события компонента экранной формы с дополнительными полями типа MouseEvent.

Пример:

OnMouseLeave={() => {
// Получение параметра события
const event = getEvent();
// Вывод параметра события в консоль браузера
console.log(event);
}
}

Тип: undefined

OnMouseMove

Обработчик события наведения указателя мыши на компонент. В качестве параметра принимает объект типа объект события компонента экранной формы с дополнительными полями типа MouseEvent.

Пример:

OnMouseMove={() => {
// Получение параметра события
const event = getEvent();
// Вывод параметра события в консоль браузера
console.log(event);
}
}

Тип: undefined

OnMouseOut

Обработчик события перемещения указателя мыши за пределы компонента. Когда пользователь наводит указатель мыши на компонент, происходит одно событие MouseOver, за которым следует одно или несколько событий MouseMove, когда пользователь перемещает указатель мыши внутри компонента. Одно событие MouseOut возникает, когда пользователь выводит указатель мыши за пределы компонента. В качестве параметра принимает объект типа объект события компонента экранной формы с дополнительными полями типа MouseEvent.

Пример:

OnMouseOut={() => {
// Получение параметра события
const event = getEvent();
// Вывод параметра события в консоль браузера
console.log(event);
}
}

Тип: undefined

OnMouseOver

Обработчик события перемещения указателя мыши на компонент. Событие возникает, когда пользователь наводит указатель мыши на компонент, и не повторяется до тех пор, пока пользователь не выведет указатель мыши за пределы компонента и затем не вернет его обратно. В качестве параметра принимает объект типа объект события компонента экранной формы с дополнительными полями типа MouseEvent.

Пример:

OnMouseOver={() => {
// Получение параметра события
const event = getEvent();
// Вывод параметра события в консоль браузера
console.log(event);
}
}

Тип: undefined

OnMouseUp

Обработчик события отпускания кнопки мыши, когда указатель мыши находится на компоненте. В качестве параметра принимает объект типа объект события компонента экранной формы с дополнительными полями типа MouseEvent.

Пример:

OnMouseUp={() => {
// Получение параметра события
const event = getEvent();
// Вывод параметра события в консоль браузера
console.log(event);
}
}

Тип: undefined

OnRequest

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

В качестве параметра принимает объект со следующими полями:

  • query - пользовательский запрос;
  • chatId - идентификатор чата;
  • chat - текущий элемент массива Chats;
  • files - список прикрепленных файлов. Пример:

OnRequest={() => { return new Promise(resolve => { // Получение параметра события const event = getEvent(); // Вывод параметра события в консоль браузера console.log(event); resolve(); }); } }

Тип: undefined

OnSelect

Обработчик события выбора чата.

В качестве параметра принимает идентификатор выбранного чата. Пример:

OnSelect={() => { // Получение параметра события const event = getEvent(); // Вывод параметра события в консоль браузера console.log(event); } }

Тип: undefined

OnSettingsClick

Обработчик события нажатия кнопки Настройки. Не имеет параметров. Пример:

OnSettingsClick={() => { // Вывод в консоль информации о событии console.log("Нажата кнопка Настройки") } }

Тип: undefined

OnUnmount

Обработчик события размонтирования согласно жизненному циклу экранной формы. Не имеет параметров.

Пример:

OnUnmount={() => {
// Отмена выполнения периодического действия при размонтировании экранной формы
return clearInterval(getValue("pleerInterval"))
}
}

Тип: undefined

OutputAttachedFiles

Выходной параметр компонента: словарь с ключами - идентификаторами чатов и значеними - массивами файлов

Тип: object

Значение по умолчанию: <pre>{}</pre>

OutputChatId

Выходной параметр компонента: идентификатор открытого чата

Тип: string

OutputChats

Выходной параметр компонента: массив параметров чатов согласно установленному формату (см. описание компонента)

Тип: array

OutputPrompt

Выходной параметр компонента: словарь с ключами - идентификаторами чатов и значеними - текстами неотправленных сообщений

Тип: object

Значение по умолчанию: <pre>{}</pre>

Prompt

Псевдоним для InputPrompt, OutputPrompt

Тип: object

Значение по умолчанию: <pre>{}</pre>

SendOnEnter

Признак назначения клавиши "Enter" для отправки сообщения в чат и комбинации клавиш "Shift+Enter" для переноса сообщения на следующую строку

Тип: boolean

Значение по умолчанию: True

Slot

Именованное пространство во фрагменте экранной формы или именованное пространство в шаблоне компонента с возможностью шаблонизации, например, Select, DataGrid.

Тип: string

ThinkModeAvailable

Признак отображения переключателя режима размышлений

Тип: boolean

Tooltip

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

Тип: any

TraceId

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

Тип: string

Visible

Признак инверсии состояния компонента Скрыт.

Тип: boolean

Значение по умолчанию: True

Примеры

Данные:

  
"Chats": [
{
"id": "0",
"title": "Мой новый чат",
"messagesCount": 4,
"thinkMode": true,
"lastMessage": "2024-07-22T13:08:18.958157"
},
{
"id": "1",
"title": "Еще чат",
"messagesCount": 2,
"lastMessage": "2024-07-22T13:08:18.958158"
}
],
"ChatId": '0',
"HistoryMap": {
"0": [
{
"id": "0",
"role": "human",
"content": "Можно ли использовать Платформу на мобильных устройствах?",
"timestamp": "2024-07-22T13:08:06.420996"
},
{
"id": "1",
"role": "ai",
"content": "Да, Платформа может быть использована на мобильных устройствах. Она поддерживает различные мобильные платформы, такие как iOS и Android, и позволяет создавать мобильные приложения с использованием своих инструментов и технологий. Это позволяет разработчикам создавать мобильные приложения, которые могут быть запущены на различных мобильных устройствах.",
"timestamp": "2024-07-22T13:08:06.421111"
},
{
"id": "2",
"role": "human",
"content": "Как настроить доступ разных пользователей к различным функциям моего приложения?",
"timestamp": "2024-07-22T13:08:18.957967"
},
{
"id": "3",
"role": "ai",
"content": "<think>Надо подумать... Придумал!</think>Для настройки доступа разных пользователей (Source: 3cdb2314-9751-4969-a4b9-14da8a757c61) к различным функциям моего приложения (Source: 4b0b11ff-904d-4ab9-9766-782c0c831fe4), можно использовать группы объектов и правила для ролей пользователей.\n\n1. Создайте группы объектов для объектов, которые вы хотите предоставить доступ на различных уровнях. Например (Source: 5b0b11ff-904d-4ab9-9766-782c0c831fe4), вы можете создать группы объектов для компонентов экранной формы, классов модели данных и т.д.\n2. Добавьте объекты (Source: 6cdb2314-9751-4969-a4b9-14da8a757c61) в созданные группы.\n3. Создайте роли пользователей, которые будут иметь доступ к этим группам объектов.\n4. Создайте правила для ролей пользователей, определяющие доступ к функциям приложения. Например, вы можете создать правило для доступа к договорам в статусе "завершен" и суммой "более 2 миллионов":\n```C#\n.State == State.Done &&.Sum&gt; 2000000\n```\n5. Назначьте роли пользователей к группам объектов, для которых они имеют доступ.\n\nТаким образом, вы сможете настроить доступ разных пользователей к различным функциям моего приложения, определяя правила для ролей пользователей и назначая их к группам объектов.(Source: 7b0b11ff-904d-4ab9-9766-782c0c831fe4)",
"timestamp": "2024-07-22T13:08:18.958155",
"sources": {
"3cdb2314-9751-4969-a4b9-14da8a757c61": {
"id": "3cdb2314-9751-4969-a4b9-14da8a757c61",
"seqNr": 1,
"fileType": "doc",
"fileId": "8ebb7c66-3b64-4a02-b626-b2d8e096e427",
"path": "/some/path/yeah/Руководство_по_разработке_на_базе_Платформы.doc",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.doc",
"content": "Каждый пользователь приложения может иметь одну или несколько ролей. Пользователь может выполнить определенное действие, если в наборе его ролей есть роль с разрешением на это действие. Пользователь не может выполнить определенное действие, если в наборе его ролей есть роль с запретом на это действие. Для каждой роли пользователя вы формируете правила, включающие разрешение или запрет на выполнение пользовательской ролью действия над объектом."
},
"4b0b11ff-904d-4ab9-9766-782c0c831fe4": {
"id": "4b0b11ff-904d-4ab9-9766-782c0c831fe4",
"seqNr": 2,
"fileType": "pdf",
"fileId": "3ff2589d-1bb2-4e50-b70c-f9fb43977152",
"path": "Руководство_по_разработке_на_базе_Платформы.pdf",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.pdf",
"content": "Создание групп объектов. Если вы хотите предоставлять доступ идентичного уровня к нескольким объектам разрабатываемого приложения, вы можете сгруппировать такие объекты. Например, вы можете группировать объекты одного типа, такие как компоненты экранной формы или классы модели данных. После создания группы объектов вы добавляете объекты в созданную группу."
},
"5b0b11ff-904d-4ab9-9766-782c0c831fe4": {
"id": "5b0b11ff-904d-4ab9-9766-782c0c831fe4",
"seqNr": 3,
"fileType": "pdf",
"fileId": "53334ba5-472e-4d96-9c1b-1a0b94241f0f",
"path": "Руководство_по_разработке_на_базе_Платформы.pdf",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.pdf",
"content": "Создание ролей пользователей приложения. Если бизнес-требования к разрабатываемому приложению предполагают наличие пользователей с разным типом доступа к приложению, вы создаете роли пользователей. Например, вы можете создать роль администратор, которой могут быть предоставлены полные права, и роль читатель, права которой могут быть ограничены только просмотром содержимого страниц приложения."
},
"6cdb2314-9751-4969-a4b9-14da8a757c61": {
"id": "6cdb2314-9751-4969-a4b9-14da8a757c61",
"seqNr": 4,
"fileType": "pdf",
"fileId": "8ebb7c66-3b64-4a02-b626-b2d8e096e427",
"path": "Руководство_по_разработке_на_базе_Платформы.pdf",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.pdf",
"content": "Создание правил для ролей пользователей. После того, как роли пользователей определены, и группы объектов созданы, вы можете создать правила, определяющие типы операций, выполнение которых вы хотите разрешить или запретить для объектов или групп объектов разрабатываемого приложения."
},
"7b0b11ff-904d-4ab9-9766-782c0c831fe4": {
"id": "7b0b11ff-904d-4ab9-9766-782c0c831fe4",
"seqNr": 5,
"fileType": "pdf",
"fileId": "3ff2589d-1bb2-4e50-b70c-f9fb43977152",
"path": "Руководство_по_разработке_на_базе_Платформы.pdf",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.pdf",
"content": "Для ускорения назначения правил ролям пользователей используются группы объектов. В группу можно добавить только объекты одного типа. Например, можно создать группу компонентов экранной формы, а затем создать правило для отображения всех компонентов этой группы для определенной роли пользователя."
}
}
},
{
"id": "4",
"role": "human",
"timestamp": "2024-07-23T13:08:18.958155",
"type": "file",
"fileId": "123-123-123",
"fileName": "qwerty.pdf",
"fileType": "pdf",
"contentType": "application/pdf",
"fullPath": "/lalala/qwerty.pdf"
},
{
"id": "5",
"role": "human",
"timestamp": "2024-07-23T13:09:18.958155",
"type": "file",
"fileId": "123-123-123",
"fileName": "qwert2y.pdf",
"fileType": "pdf",
"contentType": "application/pdf",
"fullPath": "/lalala/qwerty.pdf"
},
{
"id": "6",
"role": "human",
"timestamp": "2024-07-23T13:10:18.958155",
"type": "file",
"fileId": "123-123-123",
"fileName": "qwert4y.pdf",
"fileType": "pdf",
"contentType": "application/pdf",
"fullPath": "/lalala/qwerty.pdf"
}
],
"1": [
{
"id": "0",
"role": "human",
"content": "Как назначить действие на кнопку?",
"timestamp": "2024-07-18T23:18:01.510334"
},
{
"id": "1",
"role": "ai",
"content": "Для назначения действия на кнопку, вы можете использовать инструкцию `SetAction`.</think>Эта инструкция назначает действие на кнопку, указанную в файле с расширением `mdcontainer`.\n\nВот пример инструкции `SetAction`:\n```\nSetAction(\n Container="MyScreenForm",\n Component="MyButton",\n Action="MyAction"\n)\n```\nВ этом примере кнопка "MyButton" на экранной форме "MyScreenForm" получает действие "MyAction".\n\nПосле назначения действия на кнопку, вы можете отредактировать файл с расширением `mdcontainer` для этой экранной формы, чтобы добавить код для обработки событий кнопки. Например, вы можете добавить код для выполнения определенных действий при нажатии на кнопку.\n\nТакже вы можете использовать инструкцию `CreateDataSource` для определения источника данных, который будет связан с кнопкой. Это позволит применять действия к кнопке и выполнять запросы данных с помощью GraphQL-запросов или бэкенд-сервисов Платформы",
"timestamp": "2024-07-18T23:18:01.511336"
}
]
},
"Messages": [
{
"id": "0",
"role": "human",
"content": "Можно ли использовать Платформу на мобильных устройствах?",
"timestamp": "2024-07-22T13:08:06.420996"
},
{
"id": "1",
"role": "ai",
"content": "Да, Платформа может быть использована на мобильных устройствах. Она поддерживает различные мобильные платформы, такие как iOS и Android, и позволяет создавать мобильные приложения с использованием своих инструментов и технологий. Это позволяет разработчикам создавать мобильные приложения, которые могут быть запущены на различных мобильных устройствах.",
"timestamp": "2024-07-22T13:08:06.421111"
},
{
"id": "2",
"role": "human",
"content": "Как настроить доступ разных пользователей к различным функциям моего приложения?",
"timestamp": "2024-07-22T13:08:18.957967"
},
{
"id": "3",
"role": "ai",
"content": "<think>Надо подумать... Придумал!</think>Для настройки доступа разных пользователей (Source: 3cdb2314-9751-4969-a4b9-14da8a757c61) к различным функциям моего приложения (Source: 4b0b11ff-904d-4ab9-9766-782c0c831fe4), можно использовать группы объектов и правила для ролей пользователей.\n\n1. Создайте группы объектов для объектов, которые вы хотите предоставить доступ на различных уровнях. Например (Source: 5b0b11ff-904d-4ab9-9766-782c0c831fe4), вы можете создать группы объектов для компонентов экранной формы, классов модели данных и т.д.\n2. Добавьте объекты (Source: 6cdb2314-9751-4969-a4b9-14da8a757c61) в созданные группы.\n3. Создайте роли пользователей, которые будут иметь доступ к этим группам объектов.\n4. Создайте правила для ролей пользователей, определяющие доступ к функциям приложения. Например, вы можете создать правило для доступа к договорам в статусе "завершен" и суммой "более 2 миллионов":\n```C#\n.State == State.Done &&.Sum&gt; 2000000\n```\n5. Назначьте роли пользователей к группам объектов, для которых они имеют доступ.\n\nТаким образом, вы сможете настроить доступ разных пользователей к различным функциям моего приложения, определяя правила для ролей пользователей и назначая их к группам объектов.(Source: 7b0b11ff-904d-4ab9-9766-782c0c831fe4)",
"timestamp": "2024-07-22T13:08:18.958155",
"sources": {
"3cdb2314-9751-4969-a4b9-14da8a757c61": {
"id": "3cdb2314-9751-4969-a4b9-14da8a757c61",
"seqNr": 1,
"fileType": "doc",
"fileId": "8ebb7c66-3b64-4a02-b626-b2d8e096e427",
"path": "/some/path/yeah/Руководство_по_разработке_на_базе_Платформы.doc",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.doc",
"content": "Каждый пользователь приложения может иметь одну или несколько ролей. Пользователь может выполнить определенное действие, если в наборе его ролей есть роль с разрешением на это действие. Пользователь не может выполнить определенное действие, если в наборе его ролей есть роль с запретом на это действие. Для каждой роли пользователя вы формируете правила, включающие разрешение или запрет на выполнение пользовательской ролью действия над объектом."
},
"4b0b11ff-904d-4ab9-9766-782c0c831fe4": {
"id": "4b0b11ff-904d-4ab9-9766-782c0c831fe4",
"seqNr": 2,
"fileType": "pdf",
"fileId": "3ff2589d-1bb2-4e50-b70c-f9fb43977152",
"path": "Руководство_по_разработке_на_базе_Платформы.pdf",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.pdf",
"content": "Создание групп объектов. Если вы хотите предоставлять доступ идентичного уровня к нескольким объектам разрабатываемого приложения, вы можете сгруппировать такие объекты. Например, вы можете группировать объекты одного типа, такие как компоненты экранной формы или классы модели данных. После создания группы объектов вы добавляете объекты в созданную группу."
},
"5b0b11ff-904d-4ab9-9766-782c0c831fe4": {
"id": "5b0b11ff-904d-4ab9-9766-782c0c831fe4",
"seqNr": 3,
"fileType": "pdf",
"fileId": "53334ba5-472e-4d96-9c1b-1a0b94241f0f",
"path": "Руководство_по_разработке_на_базе_Платформы.pdf",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.pdf",
"content": "Создание ролей пользователей приложения. Если бизнес-требования к разрабатываемому приложению предполагают наличие пользователей с разным типом доступа к приложению, вы создаете роли пользователей. Например, вы можете создать роль администратор, которой могут быть предоставлены полные права, и роль читатель, права которой могут быть ограничены только просмотром содержимого страниц приложения."
},
"6cdb2314-9751-4969-a4b9-14da8a757c61": {
"id": "6cdb2314-9751-4969-a4b9-14da8a757c61",
"seqNr": 4,
"fileType": "pdf",
"fileId": "8ebb7c66-3b64-4a02-b626-b2d8e096e427",
"path": "Руководство_по_разработке_на_базе_Платформы.pdf",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.pdf",
"content": "Создание правил для ролей пользователей. После того, как роли пользователей определены, и группы объектов созданы, вы можете создать правила, определяющие типы операций, выполнение которых вы хотите разрешить или запретить для объектов или групп объектов разрабатываемого приложения."
},
"7b0b11ff-904d-4ab9-9766-782c0c831fe4": {
"id": "7b0b11ff-904d-4ab9-9766-782c0c831fe4",
"seqNr": 5,
"fileType": "pdf",
"fileId": "3ff2589d-1bb2-4e50-b70c-f9fb43977152",
"path": "Руководство_по_разработке_на_базе_Платформы.pdf",
"url": "https://s139116.dev.cifrum.local/v2/File/ByPath/Руководство_по_разработке_на_базе_Платформы.pdf",
"content": "Для ускорения назначения правил ролям пользователей используются группы объектов. В группу можно добавить только объекты одного типа. Например, можно создать группу компонентов экранной формы, а затем создать правило для отображения всех компонентов этой группы для определенной роли пользователя."
}
}
},
{
"id": "4",
"role": "human",
"timestamp": "2024-07-23T13:08:18.958155",
"type": "file",
"fileId": "123-123-123",
"fileName": "qwerty.pdf",
"fileType": "pdf",
"contentType": "application/pdf",
"fullPath": "/lalala/qwerty.pdf"
},
{
"id": "5",
"role": "human",
"timestamp": "2024-07-23T13:09:18.958155",
"type": "file",
"fileId": "123-123-123",
"fileName": "qwert2y.pdf",
"fileType": "pdf",
"contentType": "application/pdf",
"fullPath": "/lalala/qwerty.pdf"
},
{
"id": "6",
"role": "human",
"timestamp": "2024-07-23T13:10:18.958155",
"type": "file",
"fileId": "123-123-123",
"fileName": "qwert4y.pdf",
"fileType": "pdf",
"contentType": "application/pdf",
"fullPath": "/lalala/qwerty.pdf"
}
],
"ContextsList": [
{
"id": 1,
"name": "docs",
"itemsCount": 6,
"status": "ready"
},
{
"id": 2,
"name": "test",
"itemsCount": 1,
"status": "ready"
},
{
"id": 3,
"name": "broken",
"itemsCount": 0,
"status": "empty"
},
{
"id": 4,
"name": "test2",
"itemsCount": 4,
"status": "ready"
},
{
"id": 5,
"name": "LNA",
"itemsCount": 12,
"status": "ready"
},
{
"id": 6,
"name": "uploadfiles",
"itemsCount": 22,
"status": "ready"
},
{
"id": 7,
"name": "big one",
"itemsCount": 123,
"status": "ready"
}
],

}

JSX:


<Group Height="80vh">
<AiChat
ThinkModeAvailable={true}
Chats-var="Chats"
ChatId-var="ChatId"
Prompt-var="Prompts"
Messages-var="Messages"
MultiChat={true}
OnCreate={() => {
const chats = getValue('Chats');
const newChatItem = {
id: (Number(chats[chats.length - 1]?.id || 0) + 1).toString(),
title: 'Новый разговор',
};
setState({
Chats: [...chats, newChatItem],
ChatId: newChatItem.id,
HistoryMap: { ...getValue('HistoryMap'), [newChatItem.id]: [] },
Messages: [],
});
}}
OnChange={() => {
}}
OnSelect={() => {
setState({Messages: getValue('HistoryMap')[getValue('ChatId')]});
}}
OnDelete={() => {
const idToDelete = getEvent();

const Chats = getValue("Chats").filter((chatInfo) => chatInfo.id !== idToDelete);

setState({ Chats });
}}
OnRequest={async () => {
const { query, chatId, chat, files } = getEvent();
const historyMap = getValue("HistoryMap");
if (files) files.forEach((file, i) => {
historyMap[chatId].push({
...file,
role: 'human',
timestamp: new Date(),
type: 'file',
id: +(new Date()) + i,
});
});

if (query) historyMap[chatId].push({
id: +(new Date()),
role: 'human',
content: query,
timestamp: new Date(),
type: 'message',
});

let messages = historyMap[chatId];
let Chats = getValue('Chats').map(c => {
if (c.id === chatId) {
c.messagesCount = messages.length;
c.lastMessage = messages[messages.length - 1]?.timestamp || null;
}
return c;
});

// Обновление истории через создание новой копии обязательно в целях корректной работы
setState({
HistoryMap: { ...historyMap },
Messages: messages,
attachedFiles: { ...getValue('attachedFiles'), [chatId]: [] },
Chats,
});

// Имитация ответа ИИ:
if (query === 'error') {
historyMap[chatId].push({
role: 'error',
content: 'Demo error',
timestamp: new Date(),
id: +(new Date()) + 2,
});
} else {
await new Promise(resolve => setTimeout(resolve, 2000));
const answerWithThoughts = `Можно разбить приложения на две категории: те, что используют API пользователя (дешевле, но нужно настраивать ключи) и те,
что имеют свою оплату (удобнее, но дороже).</think> Сравнение по критериям: удобство интерфейса, поддержка macOS, цена за 1 млн токенов (на основе открытых данных).
Приложения, требующие API-ключ пользователя, используют тарифы провайдеров моделей (OpenAl, Anthropiс и др.), другие имеют собственную систему оплаты.`;
historyMap[chatId].push({
role: 'ai',
content: `${chat?.thinkMode ? answerWithThoughts : 'Demo response from LLM'}`,
timestamp: +(new Date()),
sources: {},
id: +(new Date()) + 3,
});
}
messages = historyMap[chatId];
Chats = getValue('Chats').map(c => {
if (c.id === chatId) {
c.messagesCount = messages.length;
c.lastMessage = messages[messages.length - 1]?.timestamp || null;
}
return c;
});

setState({
HistoryMap: { ...historyMap },
Messages: messages,
Chats,
});
}}
ContextsList-var="ContextsList"
OnSettingsClick={() => {
Alert('Chat Settings');
}}
AttachedFiles-var="attachedFiles"
OnFileAttached={async () => {
const event = getEvent();
const ChatId = getValue('ChatId');
const attachedFiles = event[ChatId];
const promises = attachedFiles.map(file => {
if (file.fileId) return Promise.resolve(file);
return uploadFileToStorage({ file: file.file, path: '/' });
});
const response = await Promise.all(promises);
const newFiles = response.map((res, i) => {
const file = attachedFiles[i];
return res && ({
fileId: res.id,
...file,
isLoading: false,
});
});
setState({
attachedFiles: { ...event, [ChatId]: newFiles },
});
}}
OnFileRemove={() => {
const fileId = getEvent();
if (!fileId) return;
removeFileFromStorage(fileId);
const ChatId = getValue('ChatId');
const attachedFiles = getValue('attachedFiles');
const newFiles = attachedFiles[ChatId]?.filter(i => i.fileId !== fileId);
setState({ attachedFiles: { ...attachedFiles, [ChatId]: newFiles } });
}}
OnFileClick={() => {
// Вывод в консоль информации о файле
console.log('source: ', getEvent());
}}
AllowedFileTypes={['text/html', 'text/plain', '.pdf']}
/>
</Group>