1
0
mirror of https://github.com/ViktorErmakov/OneKanban.git synced 2025-10-30 23:17:52 +02:00

Выполняется задача #44 и задача #22

This commit is contained in:
ViktorErmakov
2025-04-17 23:21:28 +03:00
parent 08a7c28c94
commit 971d7f2893
54 changed files with 6773 additions and 324 deletions

View File

@@ -5,12 +5,15 @@
// Получить текст HTML.
//
// Параметры:
// ПоказыватьФотоПользователя - Булево - Показывать фото пользователя
//
// Возвращаемое значение:
// Строка
// Строка - Текст HTMLКанбан доски
//
Функция ТекстHTMLКанбанДоски() Экспорт
Функция ТекстHTMLКанбанДоски(ПоказыватьФотоПользователя = Истина) Экспорт
ТекстHTML = Обработки.Канбан_Доска_HTML.ТекстHTMLКанбанДоски();
ТекстHTML = Обработки.Канбан_Доска_HTML.ТекстHTMLКанбанДоски(ПоказыватьФотоПользователя);
Возврат ТекстHTML;
КонецФункции
@@ -47,8 +50,6 @@
Исключение
Отказ = Истина;
ЗаписьЖурналаРегистрации(
"Запись настроек канбан доски HTML",
УровеньЖурналаРегистрации.Ошибка,,
@@ -170,16 +171,35 @@
//
Функция ДанныеДляКанбанДоски() Экспорт
ТекстЗапросаДанныеЗадач = канбан_КанбанДоскаПереопределяемый.ТекстЗапросаДанныеЗадач();
ДанныеДляКанбанДоски = НовыйДанныеДляКанбанДоски();
ДанныеДляКанбанДоски.Проекты = ИспользуемыеПроектыДоскиЗагрузить();
// TODO вынести в отдельную процедуру
Если ДанныеДляКанбанДоски.Проекты.Количество() = 0 Тогда
Запрос = Новый Запрос;
Запрос.Текст = ТекстЗапросаДанныеЗадач;
РезультатЗапроса = Запрос.Выполнить();
ТаблицаПроектов = РезультатЗапроса.Выгрузить();
ТаблицаПроектов.Свернуть("Проект");
Для Каждого СтрокаПроекта Из ТаблицаПроектов Цикл
НоваяСтрокаПроектов = ДанныеДляКанбанДоски.Проекты.Добавить();
НоваяСтрокаПроектов.Проект = СтрокаПроекта.Проект;
НоваяСтрокаПроектов.ПредставлениеПроекта = СтрокаПроекта.Проект.Наименование;
НоваяСтрокаПроектов.ИдентификаторПроектаСтрока = Строка(СтрокаПроекта.Проект.УникальныйИдентификатор());
КонецЦикла;
КонецЕсли;
ПараметрыОтбора = НовыйПараметрыОтбораЗадач();
ПараметрыОтбора.Проекты = ДанныеДляКанбанДоски.Проекты.ВыгрузитьКолонку("Проект"); // Массив из ОпределяемыйТип.канбан_Проекты
ТекстЗапросаДанныеЗадач = канбан_КанбанДоскаПереопределяемый.ТекстЗапросаДанныеЗадач();
ТекстЗапросаСтатусы = канбан_КанбанДоскаПереопределяемый.ТекстЗапросаСтатусы();
РегистрыСведений.канбан_ИспользуемыеСтатусыДоски.Статусы(ТекстЗапросаСтатусы, ДанныеДляКанбанДоски);
@@ -279,19 +299,17 @@
// Возвращаемое значение:
// ТаблицаЗначений - Новый статусы доски:
// * СтатусЗадачи - ОпределяемыйТип.канбан_СтатусыЗадач
// * Представление - Строка
// * УникальныйИдентификатор - Строка
// * НомерПоПорядку - Число
// * КнопкаДобавить - Булево
// * Представление - Строка
//
Функция НовыйСтатусыДоски() Экспорт
СтатусыДоски = Новый ТаблицаЗначений;
СтатусыДоски.Колонки.Добавить("СтатусЗадачи", Метаданные.ОпределяемыеТипы.канбан_СтатусыЗадач.Тип);
СтатусыДоски.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
СтатусыДоски.Колонки.Добавить("УникальныйИдентификатор", Новый ОписаниеТипов("Строка"));
СтатусыДоски.Колонки.Добавить("НомерПоПорядку", Новый ОписаниеТипов("Число"));
СтатусыДоски.Колонки.Добавить("КнопкаДобавить", Новый ОписаниеТипов("Булево"));
СтатусыДоски.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Возврат СтатусыДоски;
@@ -399,6 +417,7 @@
Оператор.Источники[3].Соединения.Очистить();
// TODO тут нужно заменить условие, т.к. я не знаю что есть справочник"узЗадачи.Проект" нужно искать это поле по наименованию
Оператор.Источники[0].Соединения.Добавить(
ИспользуемыеСтатусыДоски,
"узЗадачи.Статус = ИспользуемыеСтатусыДоски.СтатусЗадачи И ИспользуемыеСтатусыДоски.Пользователь = &ТекущийПользователь");
@@ -414,18 +433,22 @@
Оператор.Источники[4].Соединения.Очистить();
// TODO тут нужно заменить условие, т.к. я не знаю что есть справочник"узЗадачи.Проект" нужно искать это поле по наименованию
Оператор.Источники[0].Соединения.Добавить(
ИспользуемыеПроектыДоски,
"ЕСТЬNULL(узЗадачиОсновные.Проект, узЗадачи.Проект) = ИспользуемыеПроектыДоски.Проект И ИспользуемыеПроектыДоски.Пользователь = &ТекущийПользователь");
Оператор.Источники[0].Соединения[3].ТипСоединения = ТипСоединенияСхемыЗапроса.Внутреннее;
Оператор.Источники[0].Соединения[3].ТипСоединения = ТипСоединенияСхемыЗапроса.ЛевоеВнешнее; // Получаем все проекты, отберем их условием
Оператор.ВыбираемыеПоля.Добавить("ИспользуемыеПроектыДоски.Цвет", 7);
Оператор.ВыбираемыеПоля.Добавить("ЕСТЬNULL(ИспользуемыеПроектыДоски.Цвет, """")", 7);
ПервыйПакет.Колонки[7].Псевдоним = "ЦветПроекта";
Оператор.ВыбираемыеПоля.Добавить("ИспользуемыеПроектыДоски.ИдентификаторПроектаСтрока", 8);
Оператор.ВыбираемыеПоля.Добавить("УНИКАЛЬНЫЙИДЕНТИФИКАТОР(ЕСТЬNULL(узЗадачиОсновные.Проект, узЗадачи.Проект))", 8);
ПервыйПакет.Колонки[8].Псевдоним = "ИдентификаторПроектаСтрока";
// TODO тут нужно заменить условие, т.к. я не знаю что есть справочник"узЗадачи.Проект" нужно искать это поле по наименованию
Оператор.Отбор.Добавить("ЕСТЬNULL(узЗадачиОсновные.Проект, узЗадачи.Проект) В (&Проекты)");
#КонецОбласти
Запрос = Новый Запрос;

View File

@@ -21,7 +21,7 @@
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| узЗадачи.Ссылка КАК Задача,
| узЗадачи.Код КАК КодЗадачи,
| узЗадачи.Статус КАК СтатусЗадачи,
@@ -55,7 +55,7 @@
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| узСтатусыЗадачи.Ссылка КАК Статус,
| ВЫБОР
| КОГДА узСтатусыЗадачи.НаименованиеДляКанбанДоски = """"
@@ -83,9 +83,7 @@
ЗадачаОбъект = Задача.ПолучитьОбъект();
Если Не ЗадачаОбъект.Заблокирован() Тогда
ЗадачаОбъект.Заблокировать();
КонецЕсли;
ЗадачаОбъект.Заблокировать();
ЗадачаОбъект.Статус = Статус;

View File

@@ -59,6 +59,8 @@
// Пропускаем обработку для быстрого фильтра проектов
Если Кнопка.type = "INPUT" Тогда
// TODO тут возводим флаг что фильтры менялись. При любом обновлении доски, кроме как при создани на сервере, обновлять только задачи с учетом быстрых фильтров.
Возврат;
ИначеЕсли Кнопка.id = "update_svg" Тогда
@@ -77,7 +79,7 @@
СписокКлассовКнопки = Кнопка.className;
ОсновноеИмяКлассаКнопки = СтрРазделить(СписокКлассовКнопки, " ")[0];
Если ОсновноеИмяКлассаКнопки = "changeStatus" Тогда
Если ОсновноеИмяКлассаКнопки = "changeStatus" Тогда // Изменение статуса задаче
СтандартнаяОбработка = Ложь;

View File

@@ -284,6 +284,40 @@
<items xsi:type="form:FormGroup">
<name>ГруппаСтатусыЗадач</name>
<id>20</id>
<items xsi:type="form:Decoration">
<name>ДекорацияСтатусы</name>
<id>101</id>
<title>
<key>ru</key>
<value>На доске будут отображаться только выбранные статусы в указанном порядке следования.
Рекомендуется использовать не более 6 статусов, с короткими представлениями.</value>
</title>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<extendedTooltip>
<name>ДекорацияСтатусыРасширеннаяПодсказка</name>
<id>103</id>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<contextMenu>
<name>ДекорацияСтатусыКонтекстноеМеню</name>
<id>102</id>
<autoFill>true</autoFill>
</contextMenu>
<type>Label</type>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</items>
<items xsi:type="form:Table">
<name>СтатусыЗадач</name>
<id>22</id>
@@ -301,9 +335,10 @@
<excludedCommands>EndEdit</excludedCommands>
<toolTip>
<key>ru</key>
<value>На доске будут отображаться только выбранные статусы в указанном порядке следования.</value>
<value>На доске будут отображаться только выбранные статусы в указанном порядке следования.
Рекомендуется использовать не более 6 статусов, с короткими представлениями.</value>
</toolTip>
<toolTipRepresentation>ShowTop</toolTipRepresentation>
<toolTipRepresentation>None</toolTipRepresentation>
<items xsi:type="form:FormField">
<name>СтатусыЗадачНомерПоПорядку</name>
<id>89</id>
@@ -736,7 +771,7 @@
</extendedTooltip>
<type>UsualGroup</type>
<extInfo xsi:type="form:UsualGroupExtInfo">
<group>HorizontalIfPossible</group>
<group>Vertical</group>
<behavior>Collapsible</behavior>
<controlRepresentation>Picture</controlRepresentation>
<representation>WeakSeparation</representation>
@@ -750,6 +785,41 @@
<items xsi:type="form:FormGroup">
<name>ГруппаПроекты</name>
<id>54</id>
<items xsi:type="form:Decoration">
<name>ДекорацияПроекты</name>
<id>98</id>
<title>
<key>ru</key>
<value>На доске отображаются задачи из выбранных проектов. Если проекты не выбраны, отображаются задачи из всех доступных пользователю проектов.
Выбранные проекты включаются в быстрые фильтры доски.
Каждому проекту можно определить персональный цвет.</value>
</title>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<extendedTooltip>
<name>ДекорацияПроектыРасширеннаяПодсказка</name>
<id>100</id>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<contextMenu>
<name>ДекорацияПроектыКонтекстноеМеню</name>
<id>99</id>
<autoFill>true</autoFill>
</contextMenu>
<type>Label</type>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</items>
<items xsi:type="form:Table">
<name>ИспользуемыеПроектыДоски</name>
<id>56</id>
@@ -769,10 +839,11 @@
<excludedCommands>MoveUp</excludedCommands>
<toolTip>
<key>ru</key>
<value>На доске будут отображаться задачи только по выбранным проектам.
<value>На доске отображаются задачи из выбранных проектов. Если проекты не выбраны, отображаются задачи из всех доступных пользователю проектов.
Выбранные проекты включаются в быстрые фильтры доски.
Каждому проекту можно определить персональный цвет.</value>
</toolTip>
<toolTipRepresentation>ShowTop</toolTipRepresentation>
<toolTipRepresentation>None</toolTipRepresentation>
<items xsi:type="form:FormField">
<name>ИспользуемыеПроектыДоскиПроект</name>
<id>75</id>
@@ -1115,7 +1186,7 @@
</extendedTooltip>
<type>UsualGroup</type>
<extInfo xsi:type="form:UsualGroupExtInfo">
<group>HorizontalIfPossible</group>
<group>Vertical</group>
<behavior>Collapsible</behavior>
<controlRepresentation>Picture</controlRepresentation>
<representation>WeakSeparation</representation>

View File

@@ -7,10 +7,13 @@
// Получить текст HTML.
//
// Параметры:
// ПоказыватьФотоПользователя - Булево - Показывать фото пользователя
//
// Возвращаемое значение:
// Строка
// Строка - Текст HTMLКанбан доски
//
Функция ТекстHTMLКанбанДоски() Экспорт
Функция ТекстHTMLКанбанДоски(ПоказыватьФотоПользователя) Экспорт
ДанныеДляДоски = канбан_КанбанДоска.ДанныеДляКанбанДоски();
@@ -81,6 +84,8 @@
Для Каждого ДанныеСтатуса Из ДанныеДляДоски.Статусы Цикл
УникальныйИдентификаторСтатуса = Строка(ДанныеСтатуса.СтатусЗадачи.УникальныйИдентификатор());
ПараметрыОтбора = Новый Структура;
ПараметрыОтбора.Вставить("Статус", ДанныеСтатуса.СтатусЗадачи);
ЗадачиСоСтатусом = ДанныеДляДоски.ЗадачиИСтатусы.НайтиСтроки(ПараметрыОтбора);
@@ -91,7 +96,7 @@
// Наименование статуса
УзелРазделаИмяСтатуса = ДокументHTML.СоздатьЭлемент("strong");
УзелРазделаИмяСтатуса.УстановитьАтрибут("class", "kanban-block__name");
УзелРазделаИмяСтатуса.ТекстовоеСодержимое = СтрШаблон("%1", ДанныеСтатуса.Представление);
УзелРазделаИмяСтатуса.ТекстовоеСодержимое = СтрШаблон("%1", Строка(ДанныеСтатуса.Представление));
УзелБлокХедера.ДобавитьДочерний(УзелРазделаИмяСтатуса);
// Количество задач
@@ -104,7 +109,7 @@
Если ДанныеСтатуса.КнопкаДобавить Тогда
ИдентификаторСтатуса = СтрШаблон("status%1", Строка(ДанныеСтатуса.СтатусЗадачи.УникальныйИдентификатор()));
ИдентификаторСтатуса = СтрШаблон("status%1", УникальныйИдентификаторСтатуса);
// Блок кнопки добавления задачи
УзелСсылкаЗадача = ДокументHTML.СоздатьЭлемент("a");
@@ -133,7 +138,7 @@
УзелРазделаСтатуса = ДокументHTML.СоздатьЭлемент("div");
УзелРазделаСтатуса.УстановитьАтрибут("class", "kanban-block");
УзелРазделаСтатуса.УстановитьАтрибут("id", ДанныеСтатуса.УникальныйИдентификатор);
УзелРазделаСтатуса.УстановитьАтрибут("id", УникальныйИдентификаторСтатуса);
УзелРазделаСтатуса.УстановитьАтрибут("ondragover", "allowDrop(event)");
УзелКанбанТело.ДобавитьДочерний(УзелРазделаСтатуса);
@@ -174,12 +179,16 @@
УзелШапкаКарточки.ДобавитьДочерний(УзелШапкаКарточкиСсылка);
УзелШапкаКарточкиИзображение = ДокументHTML.СоздатьЭлемент("img");
УзелШапкаКарточкиИзображение.УстановитьАтрибут("class", "card__photo");
УзелШапкаКарточкиИзображение.УстановитьАтрибут("alt", "foto");
УзелШапкаКарточкиИзображение.УстановитьАтрибут("src", Задача.ФотографияИсполнителя);
УзелШапкаКарточки.ДобавитьДочерний(УзелШапкаКарточкиИзображение);
Если ПоказыватьФотоПользователя Тогда
УзелШапкаКарточкиИзображение = ДокументHTML.СоздатьЭлемент("img");
УзелШапкаКарточкиИзображение.УстановитьАтрибут("class", "card__photo");
УзелШапкаКарточкиИзображение.УстановитьАтрибут("alt", "foto");
УзелШапкаКарточкиИзображение.УстановитьАтрибут("src", Задача.ФотографияИсполнителя);
УзелШапкаКарточки.ДобавитьДочерний(УзелШапкаКарточкиИзображение);
КонецЕсли;
УзелКарточка.ДобавитьДочерний(УзелШапкаКарточки);

View File

@@ -41,7 +41,7 @@
display: flex;
flex-direction: column;
position: absolute;
top: 6rem;
top: 8rem;
width: 100%;
}
@@ -102,6 +102,8 @@
.checkboxes {
display: flex;
flex-direction: row;
max-width: 170rem;
overflow-x: auto; /* Показывает прокрутку только при необходимости */
}
.checkboxes > * {
@@ -116,7 +118,7 @@
.tag {
/* внешние отступы */
padding: .6rem 1.2rem;
max-height: 2.5rem;
/*min-height: 2.5rem;*/
/* подгоняем размер блока под содержимое */
width: -webkit-fit-content;
width: -moz-fit-content;
@@ -124,8 +126,8 @@
/* радиус скругления */
border-radius: .4rem;
/* отступ сверху */
margin-top: 1.2rem;
margin-bottom: 1.2rem;
margin-top: .5rem;
margin-bottom: .5rem;
/* запрещаем выделять мышкой этот элемент */
-webkit-user-select: none;
-moz-user-select: none;
@@ -293,11 +295,12 @@
position: fixed;
z-index: 100;
width: 100%;
height: 6rem;
/*height: 6rem;*/
padding-left: .5rem;
padding-right: .5rem;
background-color: white;
justify-content: start;
margin-top: .5rem;
}
.command_panel_buttons {

View File

@@ -34,7 +34,6 @@
СтрокаЗаписи = НаборЗаписей.Добавить();
СтрокаЗаписи.Пользователь = ТекущийПользователь;
СТрокаЗаписи.Проект = ДанныеПроекта.Проект;
СтрокаЗаписи.ИдентификаторПроектаСтрока = Строка(ДанныеПроекта.Проект.УникальныйИдентификатор());
СтрокаЗаписи.Цвет = ДанныеПроекта.Цвет;
КонецЦикла;
@@ -51,8 +50,6 @@
ОтменитьТранзакцию();
КонецЕсли;
Отказ = Истина;
ЗаписьЖурналаРегистрации(
"Запись регистра сведений канбан_ИспользуемыеПроектыДоски для проекта: ",
УровеньЖурналаРегистрации.Ошибка,,
@@ -85,6 +82,7 @@
СтрокаПроектыДоски = ПроектыДоски.Добавить();
ЗаполнитьЗначенияСвойств(СтрокаПроектыДоски, СтрокаНабора);
СтрокаПроектыДоски.ПредставлениеПроекта = Строка(СтрокаНабора.Проект);
СтрокаПроектыДоски.ИдентификаторПроектаСтрока = Строка(СтрокаНабора.Проект.УникальныйИдентификатор());
КонецЦикла;

View File

@@ -35,24 +35,6 @@
<dataHistory>Use</dataHistory>
<fillValue xsi:type="core:UndefinedValue"/>
</attributes>
<attributes uuid="5af1e3eb-1fd5-4adf-a6eb-0a4ff8f7dec5">
<name>ИдентификаторПроектаСтрока</name>
<synonym>
<key>ru</key>
<value>Идентификатор проекта строка</value>
</synonym>
<type>
<types>String</types>
<stringQualifiers>
<length>36</length>
</stringQualifiers>
</type>
<minValue xsi:type="core:UndefinedValue"/>
<maxValue xsi:type="core:UndefinedValue"/>
<fullTextSearch>Use</fullTextSearch>
<dataHistory>Use</dataHistory>
<fillValue xsi:type="core:UndefinedValue"/>
</attributes>
<dimensions uuid="90a1b083-2819-45f0-9ccd-ad174b22e5f0">
<name>Пользователь</name>
<synonym>

View File

@@ -49,8 +49,6 @@
ОтменитьТранзакцию();
КонецЕсли;
Отказ = Истина;
ЗаписьЖурналаРегистрации(
"Запись регистра сведений канбан_ИспользуемыеСтатусыДоски для проекта: ",
УровеньЖурналаРегистрации.Ошибка,,

Binary file not shown.

View File

@@ -1,3 +1,3 @@
Manifest-Version: 1.0
Runtime-Version: 8.3.10
Base-Project: configuration
Base-Project: Управление_задачами

View File

@@ -21,7 +21,6 @@
Функция СкомпилироватьВнешнююОбработку(ТекстМодуляОбъект = "", Знач ТекстМодуляОбычнойФормы = "", Знач ТекстМодуляУправляемойФормы = "") Экспорт
// Для сборки используется утилита v8unpack - https://github.com/e8tools/v8unpack
ИдентификаторМодуляОбъекта = "00ab4620-8498-4b18-a4f8-18b53138fcb5.0";
ИдентификаторФормы = "a10cd1fd-c4ba-437c-9925-b7354192a1ea.0";

View File

@@ -0,0 +1,250 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
#Область СлужебныйПрограммныйИнтерфейс
Процедура ПодключитсяКСерверу(ПараметрыПодключения) Экспорт
Порт = ЮТКоллекции.ЗначениеСтруктуры(ПараметрыПодключения, "port", 0);
КлючКлиента = ЮТКоллекции.ЗначениеСтруктуры(ПараметрыПодключения, "key", Неопределено);
Транспорт = ЮТКоллекции.ЗначениеСтруктуры(ПараметрыПодключения, "transport", 0);
Если СтрСравнить(Транспорт, "ws") <> 0 Тогда
ВызватьИсключение "Неизвестный транспорт взаимодействия (`rpc.transport`) с 1С:EDT. Поддерживается `ws`";
КонецЕсли;
Если НЕ ЗначениеЗаполнено(Порт) Тогда
ВызватьИсключение "Не указан порт (`rpc.port`) для подключения к 1С:EDT";
КонецЕсли;
Если НЕ ЗначениеЗаполнено(КлючКлиента) Тогда
ВызватьИсключение "Не указан ключ клиента (`rpc.key`) для подключения к 1С:EDT";
КонецЕсли;
АдресСервера = СтрШаблон("ws://localhost:%1", ЮТОбщий.ЧислоВСтроку(Порт));
ЮТПараметрыПодключенияКВнешнемуСервису = Новый Структура("КлючКлиента, АдресСервера, Соединение", КлючКлиента, АдресСервера);
ЮТПараметрыПодключенияКВнешнемуСервису.Вставить("СчетчикОшибок", 0);
Если ЮТОкружение.ВерсияПлатформыБольшеИлиРавна("8.3.27") Тогда
ПодключениеВебСокет8_3_27(АдресСервера);
Иначе
ПодключениеВебСокетДо8_3_27(АдресСервера);
КонецЕсли;
КонецПроцедуры
Процедура ОповеститьОСохраненииОтчета(ИмяФайла) Экспорт
Соединение = Соединение();
Если Соединение = Неопределено Тогда
Возврат;
КонецЕсли;
ОтправитьСообщение(Соединение, "reportFile", Новый Структура("reportFile", ИмяФайла));
КонецПроцедуры
Процедура ПолучитьСообщениеДо8_3_27() Экспорт
Соединение = Соединение();
Если Соединение = Неопределено Тогда
Возврат;
КонецЕсли;
Попытка
Ответ = Соединение.ПолучитьСообщение(100);
Исключение
ОбработатьОшибкуСоединения(ИнформацияОбОшибке());
КонецПопытки;
Если ЗначениеЗаполнено(Ответ) Тогда
ПодключениеКСерверуОбработчикПолученияСообщения(Соединение, Ответ);
КонецЕсли;
ПодключитьОбработчикОжидания("ЮТОпросВебСокетСоединения", 1, Истина);
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Процедура ПодключениеВебСокетДо8_3_27(АдресСервера)
// Для подключения используется компонента https://github.com/dlyubanevich/websocket1c
// Автор - Дмитрий Любаневич
Соединение = ЮТКомпоненты.СоздатьКомпоненту(ЮТКомпоненты.ОписаниеКомпонентыВебСокет());
Попытка
Соединение.Подключиться(АдресСервера);
Исключение
ОбработатьОшибкуСоединения(ИнформацияОбОшибке());
КонецПопытки;
ЗапомнитьСоединение(Соединение);
ПодключениеКСерверуОбработчикОткрытияСоединения(Соединение);
ПодключитьОбработчикОжидания("ЮТОпросВебСокетСоединения", 0.2, Истина);
КонецПроцедуры
Процедура ПодключениеВебСокет8_3_27(АдресСервера)
//@skip-check bsl-legacy-check-string-literal
Обработчики = Новый (Тип("ОбработчикиWebSocketКлиентСоединения"), ЮТКоллекции.ЗначениеВМассиве("ПодключениеКСерверуОбработчикОткрытияСоединения",
"ПодключениеКСерверуОбработчикПолученияСообщения",
"ПодключениеКСерверуОбработчикОшибки",
"ПодключениеКСерверуОбработчикЗакрытияСоединения",
ЭтотОбъект));
МенеджерСоединений = ЮТМетодыСлужебный.ВычислитьБезопасно("WebSocketКлиентСоединения");
Соединение = МенеджерСоединений.ОткрытьСоединение("yaxunit-rpc", АдресСервера, Обработчики);
ЗапомнитьСоединение(Соединение);
КонецПроцедуры
Процедура ПодключениеКСерверуОбработчикОткрытияСоединения(Соединение) Экспорт
Оповещение("Подключено");
ОтправитьСообщение(Соединение, "hello", Новый Структура("protocolVersion, key", "1.0.0", ЮТПараметрыПодключенияКВнешнемуСервису.КлючКлиента));
КонецПроцедуры
Процедура ПодключениеКСерверуОбработчикПолученияСообщения(Соединение, Сообщение) Экспорт
Оповещение("Получено сообщение: " + Сообщение);
ДанныеСообщение = ЮТОбщий.ЗначениеИзJSON(Сообщение);
ТипСообщения = ДанныеСообщение.type;
Если СтрСравнить(ТипСообщения, "runTest") = 0 Тогда
ЗапуститьТест(ДанныеСообщение, Соединение);
КонецЕсли;
КонецПроцедуры
Процедура ПодключениеКСерверуОбработчикОшибки(Соединение, КодОшибки, Описание) Экспорт
Оповещение(СтрШаблон("Ошибка с кодом %1. %2", КодОшибки, Описание));
КонецПроцедуры
Процедура ПодключениеКСерверуОбработчикЗакрытияСоединения(Соединение, КодЗакрытия) Экспорт
Оповещение("Подключение закрыто");
КонецПроцедуры
Процедура ОтправитьСообщение(Соединение, ТипСообщения, Данные, Идентификатор = 0)
Сообщение = НовоеСообщение(ТипСообщения, Данные, Идентификатор);
Попытка
Соединение.ОтправитьСообщение(ЮТОбщий.СтрокаJSON(Сообщение, Ложь, Истина));
Исключение
ОбработатьОшибкуСоединения(ИнформацияОбОшибке());
КонецПопытки;
КонецПроцедуры
Функция НовоеСообщение(Тип, Данные, Идентификатор = 0)
Возврат Новый Структура("type, data, id", Тип, Данные, Идентификатор);
КонецФункции
Процедура ЗапуститьТест(Сообщение, Соединение)
Данные = Сообщение.data;
ОписаниеМодуля = ЮТИсполнительСлужебныйКлиент.ОписаниеВременногоМодуля();
ОписаниеМодуля.Текст = Данные.module;
ОписаниеМодуля.ИмяМодуля = Данные.moduleName;
ОписаниеМодуля.КлиентУправляемое = Данные.client;
ОписаниеМодуля.КлиентОбычное = Данные.ordinaryClient;
ОписаниеМодуля.Сервер = Данные.server;
ОбработчикЗавершения = Новый ОписаниеОповещения("ПослеВыполненияТестов", ЭтотОбъект, Новый Структура("Соединение, id", Соединение, Сообщение.id));
ЮТИсполнительСлужебныйКлиент.ВыполнитьТестыВременногоМодуля(ЮТПараметрыЗапускаСлужебный.ПараметрыТестированияПоУмолчанию(),
ОписаниеМодуля,
Данные.methods,
ОбработчикЗавершения);
КонецПроцедуры
Процедура ПослеВыполненияТестов(Результат, ДополнительныеПараметры) Экспорт
ОтправитьСообщение(Соединение(), "report", Отчет(Результат), ДополнительныеПараметры.id);
КонецПроцедуры
Функция Отчет(Результат) Экспорт
Ответ = Новый Массив;
Номер = 1;
Для Каждого Набор Из Результат[0].НаборыТестов Цикл
Ответ.Добавить(ЮТОтчетJUnitСлужебный.ОписаниеНабора(Неопределено, Набор, Номер));
Номер = Номер + 1;
КонецЦикла;
Возврат Ответ;
КонецФункции
Процедура Оповещение(Текст)
ПоказатьОповещениеПользователя("Подключение WebSoket", , Текст);
ЮТЛогирование.Информация("Подключение WebSoket: " + Текст);
КонецПроцедуры
Процедура ЗапомнитьСоединение(Соединение)
ЮТПараметрыПодключенияКВнешнемуСервису.Соединение = Соединение;
КонецПроцедуры
Функция Соединение()
Если ЮТПараметрыПодключенияКВнешнемуСервису <> Неопределено Тогда
Возврат ЮТКоллекции.ЗначениеСтруктуры(ЮТПараметрыПодключенияКВнешнемуСервису, "Соединение");
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Процедура ОбработатьОшибкуСоединения(Ошибка = Неопределено, Критичная = Ложь)
Если ЮТПараметрыПодключенияКВнешнемуСервису = Неопределено Тогда
Возврат;
КонецЕсли;
ЮТПараметрыПодключенияКВнешнемуСервису.СчетчикОшибок = ЮТПараметрыПодключенияКВнешнемуСервису.СчетчикОшибок + 1;
Если Критичная Или ЮТПараметрыПодключенияКВнешнемуСервису.СчетчикОшибок > 5 Тогда
Оповещение("Ошибка web socket: " + КраткоеПредставлениеОшибки(Ошибка));
ЮТПараметрыПодключенияКВнешнемуСервису.Соединение = Неопределено;
КонецЕсли;
КонецПроцедуры
#КонецОбласти

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="a78779dc-f0ad-4037-bb2c-d6880b8c6e61">
<name>ЮТВнешнийЗапускТестовСлужебныйКлиент</name>
<synonym>
<key>ru</key>
<value>Внешний запуск тестов служебный</value>
</synonym>
<clientManagedApplication>true</clientManagedApplication>
<clientOrdinaryApplication>true</clientOrdinaryApplication>
</mdclass:CommonModule>

View File

@@ -67,7 +67,7 @@
ОписаниеЗапроса = ЮТЗапросыСлужебныйКлиентСервер.ОписаниеЗапроса(ИмяТаблицы, Предикат, "*");
//@skip-check constructor-function-return-section
Возврат ЮТЗапросыСлужебныйВызовСервера.Записи(ОписаниеЗапроса, Истина);
Возврат ЮТЗапросыСлужебныйВызовСервера.Записи(ОписаниеЗапроса, Истина, Истина);
КонецФункции
@@ -84,7 +84,7 @@
Функция Записи(ИмяТаблицы, Предикат) Экспорт
ОписаниеЗапроса = ЮТЗапросыСлужебныйКлиентСервер.ОписаниеЗапроса(ИмяТаблицы, Предикат, "*");
Возврат ЮТЗапросыСлужебныйВызовСервера.Записи(ОписаниеЗапроса, Ложь);
Возврат ЮТЗапросыСлужебныйВызовСервера.Записи(ОписаниеЗапроса, Ложь, Истина);
КонецФункции
@@ -144,6 +144,25 @@
КонецФункции
// Возвращает количество записей таблицы удовлетворяющих переданным условиям
//
// Параметры:
// ИмяТаблицы - Строка - Имя таблицы базы
// Предикат - Массив из см. ЮТФабрика.ВыражениеПредиката - Набор условий, см. ЮТПредикаты.Получить
// - см. ЮТФабрика.ВыражениеПредиката
// - ОбщийМодуль - Модуль настройки предикатов, см. ЮТест.Предикат
// - Неопределено - Проверит, что таблица не пустая
//
// Возвращаемое значение:
// Число - Количество записей
//
Функция КоличествоЗаписей(ИмяТаблицы, Предикат = Неопределено) Экспорт
ОписаниеЗапроса = ЮТЗапросыСлужебныйКлиентСервер.ОписаниеЗапроса(ИмяТаблицы, Предикат);
Возврат ЮТЗапросыСлужебныйВызовСервера.КоличествоЗаписей(ОписаниеЗапроса);
КонецФункции
// Возвращает результат выполнения простого запроса.
//
// Параметры:
@@ -209,8 +228,8 @@
// ИмяРегистра - Строка - Короткое или полное имя регистра движений
//
// Возвращаемое значение:
// Массив из Структура - Движения документа для клиента
// ТаблицаЗначений - Движения документа для сервера
// - Массив из Структура - Движения документа для клиента
// - ТаблицаЗначений - Движения документа для сервера
Функция ДвиженияДокумента(Документ, Знач ИмяРегистра) Экспорт
Если СтрНайти(ИмяРегистра, ".") = 0 Тогда
@@ -227,7 +246,11 @@
ОписаниеЗапроса = ЮТЗапросыСлужебныйКлиентСервер.ОписаниеЗапроса(ИмяРегистра, Предикат, "*");
ОписаниеЗапроса.Порядок.Добавить("НомерСтроки");
Возврат ЮТЗапросыСлужебныйВызовСервера.Записи(ОписаниеЗапроса, Ложь);
#Если Клиент Тогда
Возврат ЮТЗапросыСлужебныйВызовСервера.Записи(ОписаниеЗапроса, Ложь, Истина);
#Иначе
Возврат ЮТЗапросыСлужебныйВызовСервера.Записи(ОписаниеЗапроса, Ложь, Ложь);
#КонецЕсли
КонецФункции

View File

@@ -75,10 +75,12 @@
// Параметры:
// ОписаниеЗапроса - см. ЮТЗапросы.ОписаниеЗапроса
// ОднаЗапись - Булево - Вернуть первую запись
// ДляКлиента - Булево - Вернуть записи для клиента
//
// Возвращаемое значение:
// Массив из Структура, Структура, Неопределено - Записи
Функция Записи(Знач ОписаниеЗапроса, Знач ОднаЗапись) Экспорт
// - Массив из Структура, Структура, Неопределено - Записи для клиента
// - ТаблицаЗначений, СтрокаТаблицыЗначений, Неопределено - Записи для сервера
Функция Записи(Знач ОписаниеЗапроса, Знач ОднаЗапись, Знач ДляКлиента) Экспорт
Если ОднаЗапись Тогда
ОписаниеЗапроса.КоличествоЗаписей = 1;
@@ -87,7 +89,7 @@
Запрос = Запрос(ОписаниеЗапроса);
РезультатЗапроса = Запрос.Выполнить();
Записи = ВыгрузитьРезультатЗапроса(РезультатЗапроса, Истина);
Записи = ВыгрузитьРезультатЗапроса(РезультатЗапроса, ДляКлиента);
Если НЕ ОднаЗапись Тогда
Возврат Записи;
@@ -111,7 +113,7 @@
//
Функция ЗначенияРеквизитовЗаписи(Знач ОписаниеЗапроса, Знач ОдинРеквизит) Экспорт
Запись = Записи(ОписаниеЗапроса, Истина);
Запись = Записи(ОписаниеЗапроса, Истина, Истина);
Если ТипЗнч(Запись) <> Тип("Структура") Тогда
Если ОдинРеквизит Тогда
@@ -132,6 +134,21 @@
КонецФункции
// Возвращает количество записей результата запроса
//
// Параметры:
// ОписаниеЗапроса - см. ЮТЗапросы.ОписаниеЗапроса
//
// Возвращаемое значение:
// Число
//
Функция КоличествоЗаписей(Знач ОписаниеЗапроса) Экспорт
Записи = РезультатЗапроса(ОписаниеЗапроса, Ложь);
Возврат Записи.Количество();
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции

View File

@@ -61,7 +61,7 @@
Данные = ЮТВнешниеОбработкиСлужебныйСервер.СкомпилироватьВнешнююОбработку(ТекстМодуляОбъект,
ТекстМодуляОбычнойФормы,
ТекстМодуляУправляемойФормы);
Возврат ВнешниеОбработки.Подключить(ПоместитьВоВременноеХранилище(Данные), ОписаниеМодуля.ИмяМодуля);
Возврат ВнешниеОбработки.Подключить(ПоместитьВоВременноеХранилище(Данные), ОписаниеМодуля.ИмяМодуля, Ложь);
КонецФункции

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -24,4 +24,10 @@
КонецПроцедуры
Процедура ЮТОпросВебСокетСоединения() Экспорт
ЮТВнешнийЗапускТестовСлужебныйКлиент.ПолучитьСообщениеДо8_3_27();
КонецПроцедуры
#КонецОбласти

View File

@@ -31,6 +31,7 @@
ДобавитьОбработчикЦепочки(ПараметрыИсполнения, "ОбработчикАнализПараметровЗапуска");
ДобавитьОбработчикЦепочки(ПараметрыИсполнения, "ОбработчикПодключитьКомпоненты");
ДобавитьОбработчикЦепочки(ПараметрыИсполнения, "ОбработчикИнициализация");
ДобавитьОбработчикЦепочки(ПараметрыИсполнения, "ОбработчикПодключитсяКСерверуВнешнегоУправления");
ДобавитьОбработчикЦепочки(ПараметрыИсполнения, "ОбработчикЗагрузитьЗарегистрированныеТесты");
ДобавитьОбработчикЦепочки(ПараметрыИсполнения, "ОбработчикСформироватьИсполняемыеТесты");
ДобавитьОбработчикЦепочки(ПараметрыИсполнения, "ОбработчикПослеФормированияИсполняемыхНаборовТестов");
@@ -363,6 +364,19 @@
КонецПроцедуры
//@skip-check bsl-variable-name-invalid
//@skip-check doc-comment-parameter-section
Процедура ОбработчикПодключитсяКСерверуВнешнегоУправления(_, ПараметрыИсполнения) Экспорт
ПараметрыПодключения = ПараметрыИсполнения.ПараметрыЗапуска.rpc;
Если ЗначениеЗаполнено(ПараметрыПодключения) И ЮТКоллекции.ЗначениеСтруктуры(ПараметрыПодключения, "enable") Тогда
ЮТВнешнийЗапускТестовСлужебныйКлиент.ПодключитсяКСерверу(ПараметрыПодключения);
КонецЕсли;
ЮТАсинхроннаяОбработкаСлужебныйКлиент.ВызватьСледующийОбработчик(ПараметрыИсполнения);
КонецПроцедуры
#КонецОбласти
Процедура ДобавитьОбработчикЦепочки(ПараметрыИсполнения, ИмяМетода)

View File

@@ -147,7 +147,7 @@
КонецФункции
// Возврашает мдентификатор теста.
// Возврашает идентификатор теста.
//
// Параметры:
// ТестовыйМодуль - см. ЮТФабрика.ОписаниеИсполняемогоТестовогоМодуля
@@ -372,7 +372,7 @@
#Если Клиент Тогда
Возврат ПолучитьФорму(СтрШаблон("ВнешняяОбработка.%1.Форма", ОписаниеТестовогоОбъекта.Метаданные.Имя));
#Иначе
Возврат ВнешниеОбработки.Создать(ОписаниеТестовогоОбъекта.Метаданные.Имя);
Возврат ВнешниеОбработки.Создать(ОписаниеТестовогоОбъекта.Метаданные.Имя, Ложь);
#КонецЕсли
КонецЕсли;

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -141,6 +141,16 @@
КонецФункции
// Описание компоненты реализующей функциональность регулярных выражений.
//
// Возвращаемое значение:
// см. ОписаниеКомпоненты
Функция ОписаниеКомпонентыВебСокет() Экспорт
Возврат ОписаниеКомпоненты("ОбщийМакет.ЮТWebSocketAddIn", "WebSocket1C", "WebSocket1CAddIn");
КонецФункции
// Описание внешней компоненты.
//
// Параметры:

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -81,13 +81,14 @@
КонецФункции
Функция ДвоичныеДанныеЭлемента(ЧтениеАрхива, ИмяФайла)
Функция ДвоичныеДанныеЭлемента(ЧтениеАрхива, Знач ИмяФайла)
ИмяФайла = НРег(ИмяФайла);
ЭлементФайла = Неопределено;
Для Каждого Элемент Из ЧтениеАрхива.Элементы Цикл
Если СтрСравнить(Элемент.ПолноеИмя, ИмяФайла) = 0 Тогда
Если НРег(Элемент.ПолноеИмя) = ИмяФайла Тогда
ЭлементФайла = Элемент;
Прервать;
КонецЕсли;
КонецЦикла;
@@ -98,7 +99,7 @@
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
ЧтениеАрхива.Извлечь(ЭлементФайла, ИмяВременногоФайла, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
Данные = Новый ДвоичныеДанные(ЮТФайлы.ОбъединитьПути(ИмяВременногоФайла, ИмяФайла));
Данные = Новый ДвоичныеДанные(ЮТФайлы.ОбъединитьПути(ИмяВременногоФайла, ЭлементФайла.Имя));
УдалитьФайлы(ИмяВременногоФайла);
Возврат Данные;

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@
ПараметрыТихойУстановки = ПараметрыТихойУстановки();
ПараметрыТихойУстановки.Компоненты.Добавить(ЮТКомпоненты.ОписаниеКомпонентыСервисногоНазначения());
ПараметрыТихойУстановки.Компоненты.Добавить(ЮТКомпоненты.ОписаниеКомпонентыРегулярныхВыражений());
ПараметрыТихойУстановки.Компоненты.Добавить(ЮТКомпоненты.ОписаниеКомпонентыВебСокет());
ЮТАсинхроннаяОбработкаСлужебныйКлиент.ДобавитьОбработчикЦепочки(ПараметрыТихойУстановки,
ЭтотОбъект,
@@ -31,9 +32,6 @@
ЭтотОбъект,
"ТихаяУстановкаВнешнихКомпонент");
ЮТАсинхроннаяОбработкаСлужебныйКлиент.ДобавитьОбработчикЦепочки(ПараметрыТихойУстановки,
ЭтотОбъект,
"ТихаяУстановкаВнешнихКомпонент");
Если НЕ ЮТМетаданные.РазрешеныСинхронныеВызовы() Тогда
ЮТАсинхроннаяОбработкаСлужебныйКлиент.ДобавитьОбработчикЦепочки(ПараметрыТихойУстановки,
ЭтотОбъект,
@@ -103,10 +101,12 @@
Возврат;
#Иначе
Если ПараметрыТихойУстановки.ИзмененРеестр Тогда
ЮТЛогирование.Отладка("Обновление файла registry.xml");
ФайлРеестра = ЮТФайлы.ОбъединитьПути(ПараметрыТихойУстановки.РабочийКаталог, "registry.xml");
Запись = Новый ЗаписьТекста(ФайлРеестра);
Запись.Записать(ПараметрыТихойУстановки.ДанныеРеестра);
Запись.Закрыть();
ЮТЛогирование.Отладка("Файл обновлен");
КонецЕсли;
#КонецЕсли
@@ -114,6 +114,7 @@
Процедура ТихаяУстановкаВнешнихКомпонент(Результат, ПараметрыТихойУстановки) Экспорт
ЮТЛогирование.Отладка("Тихая установка компонент");
ПрочитатьФайлRegistry(ПараметрыТихойУстановки);
Для Каждого Компонента Из ПараметрыТихойУстановки.Компоненты Цикл
@@ -121,6 +122,7 @@
КонецЦикла;
ЗаписатьФайлRegistry(ПараметрыТихойУстановки);
ЮТЛогирование.Отладка("Тихая установка компонент завершена");
ЮТАсинхроннаяОбработкаСлужебныйКлиент.ВызватьСледующийОбработчик(ПараметрыТихойУстановки);
@@ -128,6 +130,10 @@
Процедура ПодключениеВнешнихКомпонент(Результат, ПараметрыТихойУстановки) Экспорт
Если Результат <> Неопределено Тогда
ЮТЛогирование.Отладка("Компонента подключена: " + Результат);
КонецЕсли;
КомпонентаДляПодключения = Неопределено;
Для Каждого Компонента Из ПараметрыТихойУстановки.Компоненты Цикл
@@ -144,6 +150,7 @@
ПараметрыТихойУстановки.ПодключенныеКомпоненты.Добавить(КомпонентаДляПодключения);
Обработчик = ЮТАсинхроннаяОбработкаСлужебныйКлиент.ТекущийОбработчик(ПараметрыТихойУстановки);
ЮТЛогирование.Отладка("Подключение компоненты: " + КомпонентаДляПодключения.ИмяКласса);
НачатьПодключениеВнешнейКомпоненты(Обработчик,
КомпонентаДляПодключения.ИмяМакета,
КомпонентаДляПодключения.ИмяКомпоненты,
@@ -153,14 +160,20 @@
Процедура ТихаяУстановкаВнешнейКомпоненты(Компонента, Параметры)
ДанныеФайла = ЮТКомпонентыСлужебныйВызовСервера.ФайлКомпоненты(Компонента.ИмяМакета, Параметры.ОперационнаяСистема, Параметры.Архитектура);
Если ЗаписатьВРеестр(Параметры.ДанныеРеестра, ДанныеФайла.ИмяФайла) Тогда
Параметры.ИзмененРеестр = Истина;
КонецЕсли;
ФайлКомпоненты = ЮТФайлы.ОбъединитьПути(Параметры.РабочийКаталог, ДанныеФайла.ИмяФайла);
ДанныеФайла.Данные.Записать(ФайлКомпоненты);
ЮТЛогирование.Отладка(СтрШаблон("Установка компоненты: %1", Компонента.ИмяКласса));
Попытка
ДанныеФайла = ЮТКомпонентыСлужебныйВызовСервера.ФайлКомпоненты(Компонента.ИмяМакета, Параметры.ОперационнаяСистема, Параметры.Архитектура);
Если ЗаписатьВРеестр(Параметры.ДанныеРеестра, ДанныеФайла.ИмяФайла) Тогда
Параметры.ИзмененРеестр = Истина;
КонецЕсли;
ФайлКомпоненты = ЮТФайлы.ОбъединитьПути(Параметры.РабочийКаталог, ДанныеФайла.ИмяФайла);
ДанныеФайла.Данные.Записать(ФайлКомпоненты);
Компонента.Вставить("Установлено", Истина);
Исключение
ЮТЛогирование.Ошибка("Не удалось установить компоненту", ИнформацияОбОшибке());
КонецПопытки;
КонецПроцедуры

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -52,8 +52,10 @@
//
// Параметры:
// Сообщение - Строка - Сообщение
Процедура Ошибка(Сообщение) Экспорт
// Ошибка - ИнформацияОбОшибке
Процедура Ошибка(Знач Сообщение, Ошибка = Неопределено) Экспорт
Сообщение = ЮТРегистрацияОшибок.ПредставлениеОшибки(Сообщение, Ошибка);
ЮТЛогированиеСлужебный.Записать("ERR", Сообщение, 99);
КонецПроцедуры

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -25,7 +25,13 @@
Функция ОписаниеОкружения() Экспорт
//@skip-check constructor-function-return-section
Возврат ЮТКонтекстСлужебный.ЗначениеКонтекста("Окружение");
ЗначениеКонтекста = ЮТКонтекстСлужебный.ЗначениеКонтекста("Окружение");
Если ЗначениеКонтекста = Неопределено Тогда // TODO Реализовать кеширование при использовании вне тестов
// Получаем явно окружение.
ЗначениеКонтекста = ЮТОкружениеСлужебныйКлиентСервер.ОписаниеОкружения();
КонецЕсли;
Возврат ЗначениеКонтекста;
КонецФункции

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -133,6 +133,10 @@
ЗаписьXML.ЗаписатьАтрибут("type", XMLСтрока(ОписаниеОшибки.ТипОшибки));
КонецЕсли;
Если ЗаписатьСтек И ОписаниеОшибки.Стек <> Неопределено Тогда
ЗаписьXML.ЗаписатьТекст(ОписаниеОшибки.Стек);
КонецЕсли;
Если ЗаписатьЗначения Тогда
Если ОписаниеОшибки.ОжидаемоеЗначение <> Неопределено Тогда
ЗаписьXML.ЗаписатьНачалоЭлемента("expected");
@@ -147,10 +151,6 @@
КонецЕсли;
КонецЕсли;
Если ЗаписатьСтек И ОписаниеОшибки.Стек <> Неопределено Тогда
ЗаписьXML.ЗаписатьТекст(ОписаниеОшибки.Стек);
КонецЕсли;
ЗаписьXML.ЗаписатьКонецЭлемента();
КонецЦикла;
@@ -225,6 +225,7 @@
ЗаписьXML.ЗаписатьНачалоЭлемента("testsuite");
ЗаписьXML.ЗаписатьАтрибут("id", XMLСтрока(Номер));
ЗаписьXML.ЗаписатьАтрибут("name", СтрШаблон("%1 [%2]", Набор.Представление, Набор.Режим));
ЗаписьXML.ЗаписатьАтрибут("classname", Модуль.Метаданные.Имя);
ЗаписьXML.ЗаписатьАтрибут("tests", XMLСтрока(КоличествоТестов));
ЗаписьXML.ЗаписатьАтрибут("errors", XMLСтрока(КоличествоСломанных));
ЗаписьXML.ЗаписатьАтрибут("skipped", XMLСтрока(КоличествоПропущенных));
@@ -371,4 +372,147 @@
КонецПроцедуры
Функция ОписаниеНабора(Модуль, Набор, Номер) Экспорт
Статусы = ЮТФабрика.СтатусыИсполненияТеста();
Описание = Новый Структура;
Описание.Вставить("id", Номер);
Описание.Вставить("name", СтрШаблон("%1 [%2]", Набор.Представление, Набор.Режим));
Описание.Вставить("tests", Набор.Тесты.Количество());
Описание.Вставить("errors", 0);
Описание.Вставить("skipped", 0);
Описание.Вставить("failures", 0);
Описание.Вставить("timestamp", ЮТОбщий.МестноеВремяПоВременнойМетке(Набор.ДатаСтарта));
Описание.Вставить("time", ЮТОбщий.ПродолжительностьВСекундах(Набор.Длительность));
Описание.Вставить("context", Набор.Режим);
Если Модуль <> Неопределено Тогда
Описание.Вставить("package", Модуль.Метаданные.Расширение);
КонецЕсли;
Описание.Вставить("testcase", Новый Массив);
Для Каждого Тест Из Набор.Тесты Цикл
Описание.testcase.Добавить(ОписаниеТеста(Тест, Статусы));
Если Тест.Статус = Статусы.Ошибка Тогда
Описание.failures = Описание.failures + 1;
ИначеЕсли Тест.Статус = Статусы.Пропущен ИЛИ Тест.Статус = Статусы.Ожидание Тогда
Описание.skipped = Описание.skipped + 1;
ИначеЕсли Тест.Статус <> Статусы.Успешно Тогда
Описание.errors = Описание.errors + 1;
КонецЕсли;
КонецЦикла;
ОшибкиНабора = Новый Массив;
Для Каждого ОписаниеОшибки Из Набор.Ошибки Цикл
Сообщение = СообщениеОбОшибке(ОписаниеОшибки);
Ошибка = Новый Структура;
Ошибка.Вставить("message", Сообщение);
Если ЗначениеЗаполнено(ОписаниеОшибки.ТипОшибки) Тогда
Ошибка.Вставить("type", ОписаниеОшибки.ТипОшибки);
КонецЕсли;
Если ОписаниеОшибки.Стек <> Неопределено Тогда
Ошибка.Вставить("trace", ОписаниеОшибки.Стек);
КонецЕсли;
ОшибкиНабора.Добавить(Ошибка);
КонецЦикла;
Если ЗначениеЗаполнено(ОшибкиНабора) Тогда
Описание.Вставить("error", ОшибкиНабора);
КонецЕсли;
Возврат Описание;
КонецФункции
Функция ОписаниеТеста(РезультатТеста, Статусы)
Описание = Новый Структура;
Описание.Вставить("name", РезультатТеста.Имя);
Описание.Вставить("classname", РезультатТеста.ПолноеИмяМетода);
Описание.Вставить("time", ЮТОбщий.ПродолжительностьВСекундах(РезультатТеста.Длительность));
Описание.Вставить("context", РезультатТеста.Режим);
Для Каждого ОписаниеОшибки Из РезультатТеста.Ошибки Цикл
Статус = ЮТРегистрацияОшибокСлужебный.СтатусОшибки(ОписаниеОшибки.ТипОшибки);
ИмяУзла = Неопределено;
ЗаписатьЗначения = Ложь;
ЗаписатьСтек = Ложь;
Если Статус = Статусы.Ошибка Тогда
ИмяУзла = "failure";
ЗаписатьЗначения = Истина;
ЗаписатьСтек = Истина;
ИначеЕсли Статус = Статусы.Пропущен Тогда
ИмяУзла = "skipped";
ЗаписатьСтек = Истина;
ИначеЕсли Статус = Статусы.Ожидание Тогда
ИмяУзла = "skipped";
ЗаписатьСтек = Истина;
ИначеЕсли Статус <> Статусы.Успешно Тогда
ИмяУзла = "error";
ЗаписатьСтек = Истина;
КонецЕсли;
Сообщение = СообщениеОбОшибке(ОписаниеОшибки);
Ошибка = Новый Структура;
Ошибка.Вставить("message", Сообщение);
Если ЗначениеЗаполнено(ОписаниеОшибки.ТипОшибки) Тогда
Ошибка.Вставить("type", ОписаниеОшибки.ТипОшибки);
КонецЕсли;
Если ЗаписатьЗначения Тогда
Если ОписаниеОшибки.ОжидаемоеЗначение <> Неопределено Тогда
Ошибка.Вставить("expected", ЗначениеВСтрокуjUnit(ОписаниеОшибки.ОжидаемоеЗначение));
КонецЕсли;
Если ОписаниеОшибки.ПроверяемоеЗначение <> Неопределено Тогда
Ошибка.Вставить("actual", ЗначениеВСтрокуjUnit(ОписаниеОшибки.ПроверяемоеЗначение));
КонецЕсли;
КонецЕсли;
Если ЗаписатьСтек И ОписаниеОшибки.Стек <> Неопределено Тогда
Ошибка.Вставить("trace", ОписаниеОшибки.Стек);
КонецЕсли;
Если НЕ Описание.Свойство(ИмяУзла) Тогда
Описание.Вставить(ИмяУзла, Новый Массив);
КонецЕсли;
Описание[ИмяУзла].Добавить(Ошибка);
КонецЦикла;
Если РезультатТеста.Ошибки.Количество() = 0 И РезультатТеста.Статус <> Статусы.Успешно Тогда
Если РезультатТеста.Статус = Статусы.Ожидание Тогда
ИмяУзла = "skipped";
Ошибка = Новый Структура("message", "Тест не был вызван");
Иначе
ИмяУзла = "error";
Ошибка = Новый Структура("message", "Тест не успешен, но нет сообщений об ошибках");
КонецЕсли;
Если НЕ Описание.Свойство(ИмяУзла) Тогда
Описание.Вставить(ИмяУзла, Новый Массив);
КонецЕсли;
Описание[ИмяУзла].Добавить(Ошибка);
КонецЕсли;
Возврат Описание;
КонецФункции
#КонецОбласти

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -82,6 +82,7 @@
Если Формат.СамостоятельнаяЗаписьОтчета Тогда
ГенераторОтчета.ЗаписатьОтчет(РезультатВыполнения, ИмяФайлаОтчета, Формат, Обработчик);
ЮТЛогирование.Информация("Сохранен отчет о тестировании " + ИмяФайлаОтчета);
ЮТВнешнийЗапускТестовСлужебныйКлиент.ОповеститьОСохраненииОтчета(ИмяФайлаОтчета);
Иначе
ДанныеОтчета = ГенераторОтчета.ДанныеОтчета(РезультатВыполнения, Формат);
@@ -90,6 +91,7 @@
Иначе
ДанныеОтчета.Записать(ИмяФайлаОтчета);
ЮТЛогирование.Информация("Сохранен отчет о тестировании " + ИмяФайлаОтчета);
ЮТВнешнийЗапускТестовСлужебныйКлиент.ОповеститьОСохраненииОтчета(ИмяФайлаОтчета);
КонецЕсли;
ЮТАсинхроннаяОбработкаСлужебныйКлиент.ВызватьОбработчик(Обработчик);

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -101,7 +101,7 @@
// ПрочитатьПараметрыЗапуска
// Читает параметры из строки запуска
// Параметры:
// ПараметрыЗапускаПредприятия - Соответствие - Соответствие параметров запуска предприятия полученные из `ПараметрЗапуска`
// ПараметрыЗапускаПредприятия - Соответствие из Произвольный - Соответствие параметров запуска предприятия полученные из `ПараметрЗапуска`
// Обработчик - ОписаниеОповещения
//
// Возвращаемое значение:

View File

@@ -723,21 +723,18 @@
Разделитель = "|";
Кодировка = КодировкаТекста.UTF8;
Поток = ПолучитьДвоичныеДанныеИзСтроки(Строки, Кодировка).ОткрытьПотокДляЧтения();
Чтение = Новый ЧтениеТекста(Поток, Кодировка);
Линии = СтрРазделить(Строки, Символы.ПС);
ПропуститьСтроку = Ложь;
Пока Истина Цикл
Строка = Чтение.ПрочитатьСтроку();
Если Строка = Неопределено Тогда
Прервать;
КонецЕсли;
Для Каждого Строка Из Линии Цикл
Строка = СокрЛП(Строка);
Если ПустаяСтрока(Строка) Тогда
Продолжить;
ИначеЕсли ПропуститьСтроку Тогда
ПропуститьСтроку = Ложь;
Продолжить;
ИначеЕсли НЕ СтрНачинаетсяС(Строка, Разделитель) Тогда
Если ЗагрузилиЗаголовок Тогда
Прервать;
@@ -760,20 +757,21 @@
СтрокаРезультата.Вставить(Ключи[Инд], СокрЛП(Блоки[Инд]));
КонецЦикла;
Результат.Добавить(СтрокаРезультата);
Иначе
Ключи = Новый Массив();
Для Инд = 0 По Блоки.ВГраница() Цикл
Ключи.Добавить(СокрЛП(Блоки[Инд]));
КонецЦикла;
Чтение.ПрочитатьСтроку(); // Пропуск строки разделителя
ПропуститьСтроку = Истина; // Пропуск строки разделителя
ЗагрузилиЗаголовок = Истина;
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
Поток.Закрыть();
Возврат Результат;
КонецФункции

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -440,7 +440,8 @@
ИначеЕсли ТипЗначения = Тип("Строка") Тогда
ПараметрыЧтения.ИзЧтенияТекста = Истина;
Кодировка = КодировкаТекста.UTF8;
Поток = ПолучитьДвоичныеДанныеИзСтроки(Источник, Кодировка).ОткрытьПотокДляЧтения();
ИсточникБезПробелов = СокрЛП(Источник);
Поток = ПолучитьДвоичныеДанныеИзСтроки(ИсточникБезПробелов, Кодировка).ОткрытьПотокДляЧтения();
Чтение = Новый ЧтениеТекста(Поток, Кодировка);
ПараметрыЧтения.Вставить("Чтение", Чтение);
ПараметрыЧтения.Вставить("Поток", Поток);

View File

@@ -127,6 +127,60 @@
КонецФункции
// Проверяет, что в таблице содержится только одна запись удовлетворяющая условиям
//
// Параметры:
// Предикат - ОбщийМодуль - Модуль настройки предикатов, см. ЮТест.Предикат
// - Массив из см. ЮТФабрика.ВыражениеПредиката - Набор условий, см. ЮТПредикаты.Получить
// - см. ЮТФабрика.ВыражениеПредиката
// - Неопределено - Проверит, что таблица не пустая
// ОписаниеУтверждения - Строка - Описание конкретного утверждения
//
// Возвращаемое значение:
// ОбщийМодуль - Этот модуль для замыкания
Функция СодержитТолькоОднуЗапись(Знач Предикат = Неопределено, Знач ОписаниеУтверждения = Неопределено) Экспорт
Контекст = Контекст();
УстановитьОписаниеПроверки(Контекст, ОписаниеУтверждения);
ФактическоеКоличествоЗаписей = ЮТЗапросы.КоличествоЗаписей(Контекст.ОбъектПроверки.Значение, Предикат);
Если ФактическоеКоличествоЗаписей <> 1 Тогда
Контекст = Контекст();
СгенерироватьОшибкуУтверждения(Контекст, Предикат, "содержит только одну запись");
КонецЕсли;
Возврат ЮТУтвержденияИБ;
КонецФункции
// Проверяет, что в таблице содержится несколько записей удовлетворяющих условиям
//
// Параметры:
// КоличествоЗаписей - Число - Ожидаемое количество записей в таблицы
// Предикат - ОбщийМодуль - Модуль настройки предикатов, см. ЮТест.Предикат
// - Массив из см. ЮТФабрика.ВыражениеПредиката - Набор условий, см. ЮТПредикаты.Получить
// - см. ЮТФабрика.ВыражениеПредиката
// - Неопределено - Проверит, что таблица не пустая
// ОписаниеУтверждения - Строка - Описание конкретного утверждения
//
// Возвращаемое значение:
// ОбщийМодуль - Этот модуль для замыкания
Функция СодержитНесколькоЗаписей(Знач КоличествоЗаписей, Знач Предикат = Неопределено, Знач ОписаниеУтверждения = Неопределено) Экспорт
Контекст = Контекст();
УстановитьОписаниеПроверки(Контекст, ОписаниеУтверждения);
ФактическоеКоличествоЗаписей = ЮТЗапросы.КоличествоЗаписей(Контекст.ОбъектПроверки.Значение, Предикат);
Если ФактическоеКоличествоЗаписей <> КоличествоЗаписей Тогда
Контекст = Контекст();
Сообщение = СтрШаблон("содержит несколько записей (%1)", КоличествоЗаписей);
СгенерироватьОшибкуУтверждения(Контекст, Предикат, Сообщение);
КонецЕсли;
Возврат ЮТУтвержденияИБ;
КонецФункции
// Проверяет наличие в таблице записей с указанным кодом
//
// Параметры:

View File

@@ -153,6 +153,7 @@
// то компоненты можно установить вручнуюи тогда они будут доступны на клиенте.
// * ДымовыеТесты - Булево - Рубильник использования дымовых тестов
// - Структура - Настройки дымовых тестов
// * rpc - Структура - Параметры внешнего запуска тестов. Параметры запуска тестов из EDT без перезапуска предприятия.
Функция ПараметрыЗапуска() Экспорт
Параметры = Новый Структура;
@@ -169,7 +170,7 @@
Параметры.Вставить("exitCode", "");
Параметры.Вставить("projectPath", "");
Параметры.Вставить("ДымовыеТесты", Ложь);
Параметры.Вставить("rpc", ПараметрыВнешнегоЗапускаТестов());
Параметры.Вставить("ПодключатьВнешниеКомпоненты", Истина);
Возврат Параметры;
@@ -513,6 +514,26 @@
КонецФункции
// Структура параметров подключения к серверу внешнего управления
//
// Возвращаемое значение:
// Структура - Параметры внешнего запуска тестов:
// * port - Число - Порт сервера
// * enable - Булево - Использовать внешнее управление
// * key - Строка - Ключ клиента, для приветствия
// * transport - Строка - используемый транспортный протокол
Функция ПараметрыВнешнегоЗапускаТестов() Экспорт
Параметры = Новый Структура();
Параметры.Вставить("port", 0);
Параметры.Вставить("enable", Ложь);
Параметры.Вставить("key", "");
Параметры.Вставить("transport", "ws");
Возврат Параметры;
КонецФункции
Функция БазовоеОписаниеИсполняемогоОбъекта() Экспорт
Возврат Новый Структура("Теги, НастройкиВыполнения, Зависимости, Ошибки");

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonTemplate xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="5fe4036f-10e3-4a3c-a82e-06158728e7c3">
<name>ЮТWebSocketAddIn</name>
<synonym>
<key>ru</key>
<value>Web socket add in</value>
</synonym>
<templateType>BinaryData</templateType>
</mdclass:CommonTemplate>

View File

@@ -20,7 +20,7 @@
<configurationExtensionCompatibilityMode>8.3.10</configurationExtensionCompatibilityMode>
<configurationExtensionPurpose>AddOn</configurationExtensionPurpose>
<scriptVariant>Russian</scriptVariant>
<version>24.12</version>
<version>25.03</version>
<languages uuid="b8fdae66-bc14-47de-9a8d-e0323e0d9ce8">
<name>Русский</name>
<objectBelonging>Adopted</objectBelonging>
@@ -57,6 +57,7 @@
<commonTemplates>CommonTemplate.ЮТMonacoEditor</commonTemplates>
<commonTemplates>CommonTemplate.ЮТRegEx1CAddin</commonTemplates>
<commonTemplates>CommonTemplate.ЮТV8UnpackWS</commonTemplates>
<commonTemplates>CommonTemplate.ЮТWebSocketAddIn</commonTemplates>
<commonTemplates>CommonTemplate.ЮТYaxUnitAddIn</commonTemplates>
<commonTemplates>CommonTemplate.ЮТИнформацияОбОшибке</commonTemplates>
<commonTemplates>CommonTemplate.ЮТОписаниеМетаданных</commonTemplates>
@@ -67,6 +68,7 @@
<commonModules>CommonModule.МокитоСлужебный</commonModules>
<commonModules>CommonModule.ЮТАсинхроннаяОбработкаСлужебныйКлиент</commonModules>
<commonModules>CommonModule.ЮТВнешниеОбработкиСлужебныйСервер</commonModules>
<commonModules>CommonModule.ЮТВнешнийЗапускТестовСлужебныйКлиент</commonModules>
<commonModules>CommonModule.ЮТДымовыеТесты</commonModules>
<commonModules>CommonModule.ЮТДымовыеТестыСлужебныйВызовСервера</commonModules>
<commonModules>CommonModule.ЮТДымовыеТестыСлужебныйКлиентСервер</commonModules>
@@ -165,9 +167,11 @@
<dataProcessors>DataProcessor.ЮТHTTPОтвет</dataProcessors>
<dataProcessors>DataProcessor.ЮТHTTPСервисЗапрос</dataProcessors>
<dataProcessors>DataProcessor.ЮТRecordSet</dataProcessors>
<dataProcessors>DataProcessor.ЮТГенераторКода</dataProcessors>
<dataProcessors>DataProcessor.ЮТКонструкторДвижений</dataProcessors>
<dataProcessors>DataProcessor.ЮТКонструкторОбъектаXDTO</dataProcessors>
<dataProcessors>DataProcessor.ЮТКонструкторТестовыхДанных</dataProcessors>
<dataProcessors>DataProcessor.ЮТРедакторМакетаСТестовымиДанными</dataProcessors>
<dataProcessors>DataProcessor.ЮТРедакторТестов</dataProcessors>
<dataProcessors>DataProcessor.ЮТСообщениеСервисаИнтеграции</dataProcessors>
<dataProcessors>DataProcessor.ЮТЮнитТесты</dataProcessors>

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
#Область ОписаниеПеременных
Перем ЮТДанныеКонтекста Экспорт;
Перем ЮТПараметрыПодключенияКВнешнемуСервису Экспорт;
#КонецОбласти
@@ -42,12 +43,12 @@
&After("OnStart")
Procedure ЮТOnStart()
ЮТИсполнительСлужебныйКлиент.ВыполнитьМодульноеТестирование();
ЮТПриНачалеРаботыСистемы();
EndProcedure
&After("ОбработкаОтображенияОшибки")
&После("ОбработкаОтображенияОшибки")
Процедура ЮТОбработкаОтображенияОшибки(ИнформацияОбОшибке, ТребуетсяЗавершениеСеанса, СтандартнаяОбработка)
Если ЮТКонтекстСлужебный.ЭтоЭтапТестовогоПрогона() И ЮТЛогирование.Включено() Тогда
@@ -57,4 +58,11 @@ EndProcedure
КонецПроцедуры
&After("ErrorDisplayProcessing")
Процедура ЮТErrorDisplayProcessing(ИнформацияОбОшибке, ТребуетсяЗавершениеСеанса, СтандартнаяОбработка)
ЮТОбработкаОтображенияОшибки(ИнформацияОбОшибке, ТребуетсяЗавершениеСеанса, СтандартнаяОбработка);
КонецПроцедуры
#КонецОбласти

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
#Область ОписаниеПеременных
Перем ЮТДанныеКонтекста Экспорт;
Перем ЮТПараметрыПодключенияКВнешнемуСервису Экспорт;
#КонецОбласти
@@ -40,4 +41,21 @@
КонецПроцедуры
&After("OnStart")
Procedure ЮТOnStart()
ЮТПриНачалеРаботыСистемы();
EndProcedure
&После("ОбработкаОтображенияОшибки")
Процедура ЮТОбработкаОтображенияОшибки(ИнформацияОбОшибке, ТребуетсяЗавершениеСеанса, СтандартнаяОбработка)
Если ЮТКонтекстСлужебный.ЭтоЭтапТестовогоПрогона() И ЮТЛогирование.Включено() Тогда
СтандартнаяОбработка = Ложь;
ЮТЛогирование.Ошибка(ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
КонецЕсли;
КонецПроцедуры
#КонецОбласти

View File

@@ -0,0 +1,715 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
#Область ОбработчикиСобытийФормы
&НаКлиенте
Процедура ПриОткрытии(Отказ)
КартинкаРеквизит = БиблиотекаКартинок.Реквизит;
КартинкаТаблица = БиблиотекаКартинок.ВложеннаяТаблица;
УсловноеОформление();
Если Не ЗначениеЗаполнено(ТипКодаДляФормирования) Тогда
ТипКодаДляФормирования = "ОсновнойКод";
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовШапкиФормы
&НаКлиенте
Процедура ТипКодаДляФормированияПриИзменении(Элемент)
УсловноеОформление();
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура СформироватьКодПоМетаданным(Команда)
СформироватьКодПоМетаданнымНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура СформироватьКодПоСписку(Команда)
СформироватьКодПоСпискуНаСервере();
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьСтруктуруМетаданныхВопрос(Команда)
ПоказатьВопрос(Новый ОписаниеОповещения("ОбновитьСтруктуруМетаданныхЗавершение", ЭтотОбъект), "Этот процесс может занять длительное время. Вы действительно хотите Обновить структуру метаданных?", РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
&НаКлиенте
Процедура РедактироватьТаблицуMarkdown(Команда)
КодДляРедактирования = СформироватьКодMarkdownДляРедактирования();
ПараметрОткрытия = Новый Структура("РедактированиеMarkDown, КодMarkDown", Истина, КодДляРедактирования);
ОткрытьФорму("Обработка.ЮТРедакторМакетаСТестовымиДанными.Форма.Форма", ПараметрОткрытия);
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьКод(Команда)
Если ТипКодаДляФормирования = "КонструкторОбъектаYaxunit"
Или ТипКодаДляФормирования = "ТаблицаMarkdownYaxunit" Тогда
Сообщить(НСтр("ru = 'Для Yaxunit нельзя выполнить код.'"));
Возврат;
КонецЕсли;
ПоказатьВопрос(Новый ОписаниеОповещения("ВыполнитьКодЗавершение", ЭтотОбъект), "Вы действительно хотите выполнить код?", РежимДиалогаВопрос.ДаНет);
КонецПроцедуры
&НаКлиенте
Процедура ВыполнитьКодЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
ВыполнитьКодНаСервере();
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ВыполнитьКодНаСервере()
Выполнить(ТекстКод1С.ПолучитьТекст());
КонецПроцедуры
&НаКлиенте
Процедура СкопироватьКод(Команда)
ТекстКода = ТекстКод1С.ПолучитьТекст();
Если Не ПустаяСтрока(ТекстКода) Тогда
COM = Новый COMОбъект("htmlfile");
COM.ParentWindow.ClipboardData.Setdata("Text", ТекстКода);
COM = Неопределено;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Очистить(Команда)
ТекстКод1С.Очистить();
КонецПроцедуры
&НаКлиенте
Процедура Загрузить(Команда)
ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогВыбораФайла.Показать(Новый ОписаниеОповещения("ВыборФайлаЗавершение", ЭтотОбъект, "Открытие"));
КонецПроцедуры
&НаКлиенте
Процедура Сохранить(Команда)
ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
ДиалогВыбораФайла.Показать(Новый ОписаниеОповещения("ВыборФайлаЗавершение", ЭтотОбъект));
КонецПроцедуры
&НаКлиенте
Процедура ВыборФайлаЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если ТипЗнч(Результат) = Тип("Массив") Тогда
Если ДополнительныеПараметры = "Открытие" Тогда
ТекстКод1С.Прочитать(Результат[0]);
Иначе
ТекстКод1С.Записать(Результат[0]);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
&НаСервере
Процедура УсловноеОформление()
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветТекста", WebЦвета.ТемноКрасный);
ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ДеревоМетаданных.СтандартныйРеквизит");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Истина;
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("ДеревоМетаданныхПредставление");
Элементы.КодДляОбработчиковОбновления.Видимость = ТипКодаДляФормирования = "ОсновнойКод";
Элементы.СписокЗначенийПоСсылкеРедактироватьТаблицуMarkdown.Видимость = ТипКодаДляФормирования = "ТаблицаMarkdownYaxunit";
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьСтруктуруМетаданныхЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
ОбновитьСтруктуруМетаданных();
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьСтруктуруМетаданных()
ДеревоМетаданных.ПолучитьЭлементы().Очистить();
Состояние("Анализ типов Справочники...");
ДобавлениеМетаданныхГруппы("Справочник", "Справочники");
Состояние("Анализ типов Документы...");
ДобавлениеМетаданныхГруппы("Документ", "Документы");
КонецПроцедуры
#Область ФормированиеКодаПоСсылке
&НаСервере
Процедура СформироватьКодПоСпискуНаСервере()
МассивСсылок = СписокЗначенийПоСсылке.ВыгрузитьЗначения();
ПараметрыФормирования = Новый Структура;
ПараметрыФормирования.Вставить("ТипКода", ТипКодаДляФормирования);
ПараметрыФормирования.Вставить("КодДляОбработчиковОбновления", КодДляОбработчиковОбновления);
ТекстКод1С = РеквизитФормыВЗначение("Объект").СформироватьКодПоСсылкамНаОбъекты(МассивСсылок, ПараметрыФормирования);
// Отображение объектов метаданных на ДеревоМетаданных из списка ссылок.
Для Каждого ЭлементСписка Из СписокЗначенийПоСсылке Цикл
ЗначениеСсылка = ЭлементСписка.Значение;
СтрокаОбъектМетаданных = ПолучитьСтрокуДереваМетаданных(ЗначениеСсылка);
КонецЦикла;
КонецПроцедуры
&НаСервере
Функция СформироватьКодMarkdownДляРедактирования()
МассивСсылок = СписокЗначенийПоСсылке.ВыгрузитьЗначения();
ПараметрыФормирования = Новый Структура;
ПараметрыФормирования.Вставить("ТипКода", ТипКодаДляФормирования);
ПараметрыФормирования.Вставить("КодДляОбработчиковОбновления", КодДляОбработчиковОбновления);
РезультатФормирования = РеквизитФормыВЗначение("Объект").СформироватьТаблицуMarkdownПоСсылкам(МассивСсылок, ПараметрыФормирования);
Возврат РезультатФормирования.СтрокаТаблицMarkdown;
КонецФункции
&НаСервере
Функция НайтиСтрокуДерева(ВидОбъекта, ИмяОбъекта)
Результат = Новый Структура("СтрокаВидОбъекта,СтрокаОбъектМетаданных");
ЭлементыДерева = ДеревоМетаданных.ПолучитьЭлементы();
Для Каждого СтрокаТекущая Из ЭлементыДерева Цикл
Если СтрокаТекущая.Данные = ВидОбъекта Тогда
Результат.СтрокаВидОбъекта = СтрокаТекущая;
Прервать;
КонецЕсли;
КонецЦикла;
Если Результат.СтрокаВидОбъекта <> Неопределено Тогда
СтрокиВидаОбъекта = Результат.СтрокаВидОбъекта.ПолучитьЭлементы();
Для Каждого СтрокаТекущая Из СтрокиВидаОбъекта Цикл
Если СтрокаТекущая.Данные = ИмяОбъекта Тогда
Результат.СтрокаОбъектМетаданных = СтрокаТекущая;
Прервать
КонецЕсли;
КонецЦикла;
КонецЕсли;
Возврат Результат;
КонецФункции
&НаСервере
Функция ПолучитьСтрокуДереваМетаданных(ЗначениеСсылка)
ТипЗначения = ТипЗнч(ЗначениеСсылка);
ОбъектМетаданных = ЗначениеСсылка.Метаданные();
//ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗначения);
ВидОбъекта = "";
Если Метаданные.Справочники.Содержит(ОбъектМетаданных) Тогда
ВидОбъекта = "Справочник";
ПредставлениеГруппа = "Справочники";
ИначеЕсли Метаданные.Документы.Содержит(ОбъектМетаданных) Тогда
ВидОбъекта = "Документ";
ПредставлениеГруппа = "Документы";
ИначеЕсли Метаданные.ПланыВидовХарактеристик.Содержит(ОбъектМетаданных) Тогда
ВидОбъекта = "ПланВидовХарактеристик";
ПредставлениеГруппа = "ПланыВидовХарактеристик";
КонецЕсли;
Если ВидОбъекта <> "" Тогда
СтруктураСтрок = НайтиСтрокуДерева(ВидОбъекта, ОбъектМетаданных.Имя);
Если СтруктураСтрок.СтрокаВидОбъекта = Неопределено Тогда
СтруктураСтрок.СтрокаВидОбъекта = СоздатьГруппуМетаданных(ВидОбъекта, ПредставлениеГруппа);
КонецЕсли;
Если СтруктураСтрок.СтрокаОбъектМетаданных = Неопределено Тогда
СтруктураСтрок.СтрокаОбъектМетаданных = ДобавлениеМетаданных(СтруктураСтрок.СтрокаВидОбъекта, ОбъектМетаданных);
КонецЕсли;
Возврат СтруктураСтрок.СтрокаОбъектМетаданных;
КонецЕсли;
КонецФункции
#КонецОбласти
#Область ФормированиеКодаПоОтмеченнымМетаданным
&НаСервере
Процедура СформироватьКодПоМетаданнымНаСервере()
ТекстКод1С.Очистить();
ЭлементыДерева = ДеревоМетаданных.ПолучитьЭлементы();
Для Каждого ЭлементКласс Из ЭлементыДерева Цикл
ЭлементыКласса = ЭлементКласс.ПолучитьЭлементы();
Для Каждого ЭлементКласса Из ЭлементыКласса Цикл
СформироватьКодОтмеченногоЭлементаНаСервере(ЭлементКласса);
КонецЦикла;
КонецЦикла;
КонецПроцедуры
&НаСервере
Процедура СформироватьКодОтмеченногоЭлементаНаСервере(ТекЭлемент)
Если ТекЭлемент = Неопределено ИЛИ ТекЭлемент.Пометка = 0 Тогда
Возврат;
КонецЕсли;
ТекстКод = Новый ТекстовыйДокумент;
ТекстСтандартныеРеквизиты = Новый ТекстовыйДокумент;
ТекстРеквизиты = Новый ТекстовыйДокумент;
ТекстРеквизитыТЧ = Новый ТекстовыйДокумент;
ТекстТабличнаяЧасть = Новый ТекстовыйДокумент;
Родитель = ТекЭлемент.ПолучитьРодителя();
ТекЭлементы = ТекЭлемент.ПолучитьЭлементы();
КлассЭлементов = Родитель.Данные;
ЭлементКласса = ТекЭлемент.Данные;
НовыйОбъект = КлассЭлементов+"Объект"; //$+ CaSH Это может быть совсем не Новый, но Объект
СтарыйОбъект = "Старый"+КлассЭлементов;
СтруктураСозданияОбъекта = РеквизитФормыВЗначение("Объект").ПараметрыСтруктурыСозданияОбъекта();
ТекстКод.ДобавитьСтроку(НовыйОбъект+" = "+Родитель.Представление+"."+ЭлементКласса+""+СтруктураСозданияОбъекта[КлассЭлементов]);
ТекстКод.ДобавитьСтроку("");
// Формируем текст кода
Если ИспользоватьЗаполнитьЗначения Тогда
Для Каждого ТекРеквизит Из ТекЭлементы Цикл
Если ТекРеквизит.Пометка = 0 Тогда
Продолжить;
КонецЕсли;
ИмяРеквизита = ТекРеквизит.Данные;
ЭтоТЧ = ТекРеквизит.ТипыРеквизитов = "ТабличнаяЧасть";
// Реквизиты
Если НЕ ЭтоТЧ Тогда
Если НЕ УчитыватьСтандартныеРеквизиты
И ТекРеквизит.СтандартныйРеквизит
ИЛИ УчитыватьСтандартныеРеквизиты
И ТекЭлемент.Пометка = 1 // Если отмечены все элементы объекта, то не нужно перечислять реквизиты
Тогда
Продолжить;
КонецЕсли;
ТекстРеквизиты.ДобавитьСтроку(ТекРеквизит.Данные);
// Табличная часть
Иначе
ЭлементыТЧ = ТекРеквизит.ПолучитьЭлементы();
СтрокаРеквизитовТЧ = "";
Если ТекРеквизит.Пометка <> 1 Тогда // Если отмечены все элементы ТЧ, то не нужно перечислять реквизиты
Для Каждого ТекРеквизитаТЧ Из ЭлементыТЧ Цикл
Если ТекРеквизитаТЧ.Пометка > 0 Тогда
ТекстРеквизитыТЧ.ДобавитьСтроку(ТекРеквизитаТЧ.Данные);
КонецЕсли;
КонецЦикла;
СтрокаРеквизитовТЧ = СтрЗаменить(ТекстРеквизитыТЧ.ПолучитьТекст(), Символы.ПС, ", ");
СтрокаРеквизитовТЧ = Лев(СтрокаРеквизитовТЧ, СтрДлина(СтрокаРеквизитовТЧ) - 2);
СтрокаРеквизитовТЧ = ", """ + СтрокаРеквизитовТЧ + """";
КонецЕсли;
ТекстТабличнаяЧасть.ДобавитьСтроку("// заполняем ТЧ."+ТекРеквизит.Данные+" ("+ТекРеквизит.Представление+")");
ТекстТабличнаяЧасть.ДобавитьСтроку("Для каждого ТекСтрока Из "+СтарыйОбъект+"."+ИмяРеквизита+" Цикл");
ТекстТабличнаяЧасть.ДобавитьСтроку(" НоваяСтрока = "+НовыйОбъект+"."+ИмяРеквизита+".Добавить();");
ТекстТабличнаяЧасть.ДобавитьСтроку(" ЗаполнитьЗначенияСвойств(НоваяСтрока, ТекСтрока" + СтрокаРеквизитовТЧ + ");");
ТекстТабличнаяЧасть.ДобавитьСтроку("КонецЦикла;");
КонецЕсли;
КонецЦикла;
СтрокаРеквизиты = "";
Если ТекстРеквизиты.КоличествоСтрок() > 0 Тогда
СтрокаРеквизиты = СтрЗаменить(ТекстРеквизиты.ПолучитьТекст(), Символы.ПС, ", ");
СтрокаРеквизиты = Лев(СтрокаРеквизиты, СтрДлина(СтрокаРеквизиты) - 2);
СтрокаРеквизиты = ", """ + СтрокаРеквизиты + """";
КонецЕсли;
ТекстКод.ДобавитьСтроку("ЗаполнитьЗначенияСвойств("+НовыйОбъект+","+СтарыйОбъект + СтрокаРеквизиты + ");");
Если ТекстТабличнаяЧасть.КоличествоСтрок() > 0 Тогда
ТекстКод.ДобавитьСтроку(ТекстТабличнаяЧасть.ПолучитьТекст());
КонецЕсли;
Иначе
ТекстСтандартныеРеквизиты.ДобавитьСтроку("// заполняем Стандартные реквизиты");
ТекстРеквизиты.ДобавитьСтроку("// заполняем Реквизиты");
Для Каждого ТекРеквизит Из ТекЭлементы Цикл
Если ТекРеквизит.Пометка = 0 Тогда
Продолжить;
КонецЕсли;
ЭтоТЧ = ТекРеквизит.ТипыРеквизитов = "ТабличнаяЧасть";
// Реквизиты
Если НЕ ЭтоТЧ Тогда
Если НЕ УчитыватьСтандартныеРеквизиты
И ТекРеквизит.СтандартныйРеквизит
Тогда
Продолжить;
КонецЕсли;
ТекстКодаРеквизита = ""+НовыйОбъект+"."+ТекРеквизит.Данные;
КолВоПробелов = ТекЭлемент.ИмяДлина - СтрДлина(ТекРеквизит.Данные);
Для Сч=0 По КолВоПробелов Цикл
ТекстКодаРеквизита = ТекстКодаРеквизита + " " ;
КонецЦикла;
ТекстКодаРеквизита = ТекстКодаРеквизита + "= Неопределено; // " + ПолучитьТипыРеквизитовКомментарий(ТекРеквизит.ТипыРеквизитов);
Если ТекРеквизит.СтандартныйРеквизит Тогда
ТекстСтандартныеРеквизиты.ДобавитьСтроку(ТекстКодаРеквизита);
Иначе
ТекстРеквизиты.ДобавитьСтроку(ТекстКодаРеквизита);
КонецЕсли;
// Табличная часть
Иначе
ТекстРеквизитыТЧ.Очистить();
ТекстРеквизитыТЧ.ДобавитьСтроку(" ");
ТекстРеквизитыТЧ.ДобавитьСтроку(" // заполняем Реквизиты ТЧ");
ЭлементыТЧ = ТекРеквизит.ПолучитьЭлементы();
Для Каждого РеквизитыТЧ Из ЭлементыТЧ Цикл
Если РеквизитыТЧ.Пометка = 0 Тогда
Продолжить;
КонецЕсли;
ТекстКодаРеквизита = " НоваяСтрока."+РеквизитыТЧ.Данные;
КолВоПробелов = ТекРеквизит.ИмяДлина - СтрДлина(РеквизитыТЧ.Данные);
Для Сч=0 По КолВоПробелов Цикл
ТекстКодаРеквизита = ТекстКодаРеквизита + " " ;
КонецЦикла;
ТекстКодаРеквизита = ТекстКодаРеквизита + "= Неопределено; // " + ПолучитьТипыРеквизитовКомментарий(РеквизитыТЧ.ТипыРеквизитов);
ТекстРеквизитыТЧ.ДобавитьСтроку(ТекстКодаРеквизита);
КонецЦикла;
ТекстТабличнаяЧасть.ДобавитьСтроку("");
ТекстТабличнаяЧасть.ДобавитьСтроку("// заполняем ТЧ."+ТекРеквизит.Данные+" ("+ТекРеквизит.Представление+")");
ТекстТабличнаяЧасть.ДобавитьСтроку("Для каждого ТекСтрока Из "+СтарыйОбъект+"."+ТекРеквизит.Данные+" Цикл");
ТекстТабличнаяЧасть.ДобавитьСтроку(" НоваяСтрока = "+НовыйОбъект+"."+ТекРеквизит.Данные+".Добавить();");
ТекстТабличнаяЧасть.ДобавитьСтроку(ТекстРеквизитыТЧ.ПолучитьТекст());
ТекстТабличнаяЧасть.ДобавитьСтроку("КонецЦикла;");
КонецЕсли;
КонецЦикла;
Если ТекстСтандартныеРеквизиты.КоличествоСтрок() > 1 Тогда
ТекстКод.ДобавитьСтроку(ТекстСтандартныеРеквизиты.ПолучитьТекст());
КонецЕсли;
ТекстКод.ДобавитьСтроку(ТекстРеквизиты.ПолучитьТекст());
Если ТекстТабличнаяЧасть.КоличествоСтрок() > 1 Тогда
ТекстКод.ДобавитьСтроку(ТекстТабличнаяЧасть.ПолучитьТекст());
КонецЕсли;
КонецЕсли;
ТекстКод1С.ДобавитьСтроку(ТекстКод.ПолучитьТекст());
КонецПроцедуры
&НаСервере
Функция ПолучитьТипыРеквизитовКомментарий(ТипыРеквизитов)
ТипыРеквизитовКомментарий = СтрЗаменить(ТипыРеквизитов, Символы.ПС, Символы.ПС + " //");
Возврат ТипыРеквизитовКомментарий;
КонецФункции
&НаСервере
Функция СоздатьГруппуМетаданных(Группа, ПредставлениеГруппа)
НоваяГруппа = ДеревоМетаданных.ПолучитьЭлементы().Добавить();
НоваяГруппа.Представление = ПредставлениеГруппа;
НоваяГруппа.Данные = Группа;
НоваяГруппа.Картинка = БиблиотекаКартинок[Группа];
Возврат НоваяГруппа;
КонецФункции
&НаСервере
Процедура ДобавлениеМетаданныхГруппы(Группа, ПредставлениеГруппа)
ДобавляемыеМетаданные = Метаданные[ПредставлениеГруппа];
НоваяГруппа = СоздатьГруппуМетаданных(Группа, ПредставлениеГруппа);
Для Каждого ОбъектМетаданных Из ДобавляемыеМетаданные Цикл
ДобавлениеМетаданных(НоваяГруппа, ОбъектМетаданных);
КонецЦикла;
КонецПроцедуры
&НаСервере
Функция ДобавлениеМетаданных(ГруппаДерева, ОбъектМетаданных)
ТекЭлемент = ОбъектМетаданных;
НовСтрока = ГруппаДерева.ПолучитьЭлементы().Добавить();
НовСтрока.Представление = ТекЭлемент.Синоним;
НовСтрока.Данные = ТекЭлемент.Имя;
НовСтрока.Картинка = ГруппаДерева.Картинка;
НовСтрока.ИмяДлина = 0;
// По стандартным реквизтам
Для Каждого Реквизита Из ТекЭлемент.СтандартныеРеквизиты Цикл
НовРеквизит = НовСтрока.ПолучитьЭлементы().Добавить();
НовРеквизит.Представление = Реквизита.Представление(); //$* CaSH вместо ".Синоним" нужно писать ".Представление()"
НовРеквизит.Данные = Реквизита.Имя;
НовРеквизит.ТипыРеквизитов = ПолучитьТипыСтрокой(Реквизита.Тип); //$* CaSH
НовРеквизит.СтандартныйРеквизит = Истина;
НовРеквизит.Картинка = КартинкаРеквизит;
ИмяДлина = СтрДлина(НовРеквизит.Данные);
Если НовСтрока.ИмяДлина < ИмяДлина Тогда
НовСтрока.ИмяДлина = ИмяДлина;
КонецЕсли;
КонецЦикла;
// По реквизитам
Для Каждого Реквизита Из ТекЭлемент.Реквизиты Цикл
НовРеквизит = НовСтрока.ПолучитьЭлементы().Добавить();
НовРеквизит.Представление = Реквизита.Представление(); //$* CaSH
НовРеквизит.Данные = Реквизита.Имя;
НовРеквизит.ТипыРеквизитов = ПолучитьТипыСтрокой(Реквизита.Тип); //$* CaSH
НовРеквизит.Картинка = КартинкаРеквизит;
ИмяДлина = СтрДлина(НовРеквизит.Данные);
Если НовСтрока.ИмяДлина < ИмяДлина Тогда
НовСтрока.ИмяДлина = ИмяДлина;
КонецЕсли;
КонецЦикла;
// По табличным частям
Для Каждого ТабличнаяЧасть Из ТекЭлемент.ТабличныеЧасти Цикл
НовРеквизит = НовСтрока.ПолучитьЭлементы().Добавить();
НовРеквизит.Представление = ТабличнаяЧасть.Представление(); //$* CaSH
НовРеквизит.Данные = ТабличнаяЧасть.Имя;
НовРеквизит.Картинка = КартинкаТаблица;
НовРеквизит.ТипыРеквизитов = "ТабличнаяЧасть";
НовРеквизит.ИмяДлина = 0;
РеквизитыТЧ = ТабличнаяЧасть.Реквизиты;
Для Каждого РеквизитТЧ Из РеквизитыТЧ Цикл
НовРеквизитТЧ = НовРеквизит.ПолучитьЭлементы().Добавить();
НовРеквизитТЧ.Представление = РеквизитТЧ.Представление(); //$* CaSH
НовРеквизитТЧ.Данные = РеквизитТЧ.Имя;
НовРеквизитТЧ.ТипыРеквизитов= ПолучитьТипыСтрокой(РеквизитТЧ.Тип); //$* CaSH
НовРеквизитТЧ.Картинка = КартинкаРеквизит;
ИмяДлина = СтрДлина(НовРеквизитТЧ.Данные);
Если НовРеквизит.ИмяДлина < ИмяДлина Тогда
НовРеквизит.ИмяДлина = ИмяДлина;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат НовСтрока;
КонецФункции
&НаСервере
Функция ПолучитьТипыСтрокой(Тип)
Если ТипЗнч(Тип) = Тип("ОписаниеТипов") Тогда
РезультатТекст = Новый ТекстовыйДокумент;
Типы = Тип.Типы();
//Для Каждого ТекТип Из Типы Цикл
Инд = 0;
Пока ВыводитьВсеТипы И Инд < Типы.Количество()
ИЛИ НЕ ВыводитьВсеТипы И Инд = 0
Цикл
ТекТип = Типы[Инд];
Инд = Инд + 1;
Если ТекТип = Тип("Строка") Тогда
РезультатТекст.ДобавитьСтроку("Строка (" + Тип.КвалификаторыСтроки.Длина + ?(Тип.КвалификаторыСтроки.ДопустимаяДлина=ДопустимаяДлина.Переменная, "*", "!") + ")");
ИначеЕсли ТекТип = Тип("Число") Тогда
РезультатТекст.ДобавитьСтроку("Число (" + Тип.КвалификаторыЧисла.Разрядность + "." + Тип.КвалификаторыЧисла.РазрядностьДробнойЧасти + ")");
ИначеЕсли ТекТип = Тип("Дата") Тогда
РезультатТекст.ДобавитьСтроку("Дата (" + Тип.КвалификаторыДаты.ЧастиДаты + ")");
Иначе
РезультатТекст.ДобавитьСтроку(ПолучитьТипСтрокой(ТекТип));
КонецЕсли;
КонецЦикла;
РезультатТекст = РезультатТекст.ПолучитьТекст();
Возврат Лев(РезультатТекст, СтрДлина(РезультатТекст) - 1);
Иначе
Возврат ПолучитьТипСтрокой(Тип);
КонецЕсли;
КонецФункции
&НаСервере
Функция ПолучитьТипСтрокой(Тип)
ТекТип = Тип;
Если ТекТип = Тип("Булево") Тогда
Возврат "Булево"
ИначеЕсли ТекТип = Тип("Строка") Тогда
Возврат "Строка";
ИначеЕсли ТекТип = Тип("Число") Тогда
Возврат "Число";
ИначеЕсли ТекТип = Тип("Дата") Тогда
Возврат "Дата";
ИначеЕсли Справочники.ТипВсеСсылки().СодержитТип(ТекТип) Тогда
Результат = "Справочник.";
ИначеЕсли Перечисления.ТипВсеСсылки().СодержитТип(ТекТип) Тогда
Результат = "Перечисление.";
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(ТекТип) Тогда
Результат = "Документ.";
Иначе
Возврат Строка(ТекТип);
КонецЕсли;
МетаданныеТипа = Метаданные.НайтиПоТипу(ТекТип);
Возврат Результат + МетаданныеТипа.Имя+" ("+МетаданныеТипа.Представление()+")";
КонецФункции
#Область ПометкаЭлементов
&НаКлиенте
Процедура ДеревоМетаданныхПометкаПриИзменении(Элемент)
ИдСтроки = Элементы.ДеревоМетаданных.ТекущаяСтрока;
Пометка = Элементы.ДеревоМетаданных.ТекущиеДанные.Пометка;
Если Пометка = 2 Тогда
Пометка = 0;
Элементы.ДеревоМетаданных.ТекущиеДанные.Пометка = Пометка;
КонецЕсли;
ОтметитьВыбранныйЭлемент(ИдСтроки, Пометка);
КонецПроцедуры
&НаКлиенте
Процедура ОтметитьВыбранныйЭлемент(ИдСтроки, Пометка)
Элемент = ДеревоМетаданных.НайтиПоИдентификатору(ИдСтроки);
Элемент.Пометка = Пометка;
ОтметитьДочерниеЭлементы(Элемент, Пометка);
ОтметитьРодителейВыбранногоЭлемента(Элемент);
КонецПроцедуры
&НаКлиенте
Процедура ОтметитьРодителейВыбранногоЭлемента(Элемент)
Элемент = Элемент.ПолучитьРодителя();
Если Элемент = Неопределено Тогда
Возврат;
КонецЕсли;
ЕстьОтмеченные = ПроверкаФлага(Элемент, Истина);
ЕстьНЕОтмеченные = ПроверкаФлага(Элемент, Ложь);
Если ЕстьОтмеченные И ЕстьНЕОтмеченные Тогда
Элемент.Пометка = 2;
ИначеЕсли ЕстьОтмеченные Тогда
Элемент.Пометка = 1;
Иначе
Элемент.Пометка = 0;
КонецЕсли;
ОтметитьРодителейВыбранногоЭлемента(Элемент);
КонецПроцедуры
&НаКлиенте
Процедура ОтметитьДочерниеЭлементы(Элемент, Пометка)
ЭлементыДерева = Элемент.ПолучитьЭлементы();
Для Каждого Элемент Из ЭлементыДерева Цикл
Элемент.Пометка = Пометка;
ОтметитьДочерниеЭлементы(Элемент, Пометка);
КонецЦикла;
КонецПроцедуры
&НаКлиенте
Функция ПроверкаФлага(Элемент, Отметка = Истина)
Результат = Ложь;
ЭлементыДерева = Элемент.ПолучитьЭлементы();
Для Каждого ЭлементДерева Из ЭлементыДерева Цикл
Если ЭлементДерева.Пометка = Отметка ИЛИ Результат Тогда
Результат = Истина;
Прервать;
КонецЕсли;
Результат = ПроверкаФлага(ЭлементДерева, Отметка);
КонецЦикла;
Возврат Результат;
КонецФункции
#КонецОбласти
#КонецОбласти
#КонецОбласти

View File

@@ -0,0 +1,3 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html><head><meta content="text/html;charset=utf-8" http-equiv="content-type"></meta><link rel="stylesheet" type="text/css" href="v8help://service_book/service_style"></link><meta name="GENERATOR" content="MSHTML 11.00.10570.1001"></meta></head><body>
<p>CaSH:<br>+ нормальное представление типов данных ссылочных, а для Строка, Число, Дата теперь показывает Квалификатор типа, например вместо:<br><font color="#008000">// Физические лица<br>// Строка<br>// Число<br>// Дата<br></font>теперь так:<br><font color="#008000">// Справочник.ФизическиеЛица (Физические лица)<br></font><font color="#000000">тут в скобках Представление типа т.к. оно иногда сильно отличается от Имени</font><br><font color="#008000">// Строка (100*) </font><br>тут 0 - как всегда неограниченная динна, * - длина переменная, если "!" - то фиксированная, т.е. на нее стоит обратить внимание<br><font color="#008000">// Число (15.2)</font><br><font color="#008000">// Дата (Дата и время)</font></p>
<p>+ Мелкие украшательства типа: состояние при открытии обработки, картинки на кнопки</p></body></html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:DataProcessor xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="507e5e24-db8a-4b5e-a6de-2340df51d47c">
<producedTypes>
<objectType typeId="32f73ef1-8755-4e27-b57a-37b9619029fa" valueTypeId="e5fa2eee-8dc5-4142-bed8-c267e52b3629"/>
<managerType typeId="ad3f6a53-5c45-475c-90c5-d2a834f837c5" valueTypeId="a974b36e-cd5c-4cf7-8b72-a3bee2d65fb5"/>
</producedTypes>
<name>ЮТГенераторКода</name>
<synonym>
<key></key>
<value>ЮТГенератор кода</value>
</synonym>
<synonym>
<key>ru</key>
<value>Генератор кода</value>
</synonym>
<useStandardCommands>true</useStandardCommands>
<defaultForm>DataProcessor.ЮТГенераторКода.Form.Форма</defaultForm>
<help>
<pages>
<lang>ru</lang>
</pages>
</help>
<forms uuid="c07a80c3-1784-48d4-973a-c3009a09c1d7">
<name>Форма</name>
<synonym>
<key>ru</key>
<value>Форма</value>
</synonym>
<usePurposes>PersonalComputer</usePurposes>
<usePurposes>MobileDevice</usePurposes>
</forms>
</mdclass:DataProcessor>

View File

@@ -0,0 +1,793 @@
<?xml version="1.0" encoding="UTF-8"?>
<form:Form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:core="http://g5.1c.ru/v8/dt/mcore" xmlns:form="http://g5.1c.ru/v8/dt/form">
<items xsi:type="form:FormGroup">
<name>Страницы</name>
<id>37</id>
<items xsi:type="form:FormGroup">
<name>СтраницаТабличногоДокумента</name>
<id>9</id>
<items xsi:type="form:FormField">
<name>МакетТабличногоДокумента</name>
<id>13</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<dataPath xsi:type="form:DataPath">
<segments>МакетТабличногоДокумента</segments>
</dataPath>
<titleLocation>None</titleLocation>
<extendedTooltip>
<name>МакетТабличногоДокументаРасширеннаяПодсказка</name>
<id>15</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<contextMenu>
<name>МакетТабличногоДокументаКонтекстноеМеню</name>
<id>14</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<autoFill>true</autoFill>
</contextMenu>
<type>SpreadsheetDocumentField</type>
<editMode>Enter</editMode>
<showInHeader>true</showInHeader>
<headerHorizontalAlign>Left</headerHorizontalAlign>
<showInFooter>true</showInFooter>
<extInfo xsi:type="form:SpreadSheetDocFieldExtInfo">
<width>50</width>
<autoMaxWidth>true</autoMaxWidth>
<height>10</height>
<autoMaxHeight>true</autoMaxHeight>
<horizontalStretch>true</horizontalStretch>
<verticalStretch>true</verticalStretch>
<showGrid>true</showGrid>
<showHeaders>true</showHeaders>
<showRowAndColumnNames>true</showRowAndColumnNames>
<pointerType>Special</pointerType>
<verticalScrollBar>ScrollAuto</verticalScrollBar>
<horizontalScrollBar>ScrollAuto</horizontalScrollBar>
<selectionShowMode>Always</selectionShowMode>
<edit>true</edit>
<showGroups>true</showGroups>
<enableStartDrag>true</enableStartDrag>
<enableDrag>true</enableDrag>
</extInfo>
</items>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<title>
<key>ru</key>
<value>Страница табличного документа</value>
</title>
<extendedTooltip>
<name>СтраницаТабличногоДокументаРасширеннаяПодсказка</name>
<id>10</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<type>Page</type>
<extInfo xsi:type="form:PageGroupExtInfo">
<group>Vertical</group>
<showTitle>true</showTitle>
</extInfo>
</items>
<items xsi:type="form:FormGroup">
<name>СтраницаТекстовогоДокумента</name>
<id>11</id>
<items xsi:type="form:FormField">
<name>МакетТекстовогоДокумента</name>
<id>16</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<dataPath xsi:type="form:DataPath">
<segments>МакетТекстовогоДокумента</segments>
</dataPath>
<titleLocation>None</titleLocation>
<extendedTooltip>
<name>МакетТекстовогоДокументаРасширеннаяПодсказка</name>
<id>18</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<contextMenu>
<name>МакетТекстовогоДокументаКонтекстноеМеню</name>
<id>17</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<autoFill>true</autoFill>
</contextMenu>
<type>TextDocumentField</type>
<editMode>Enter</editMode>
<showInHeader>true</showInHeader>
<headerHorizontalAlign>Left</headerHorizontalAlign>
<showInFooter>true</showInFooter>
<extInfo xsi:type="form:TextDocFieldExtInfo">
<width>50</width>
<height>10</height>
<autoMaxHeight>true</autoMaxHeight>
<horizontalStretch>true</horizontalStretch>
<verticalStretch>true</verticalStretch>
</extInfo>
</items>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<title>
<key>ru</key>
<value>Страница текстового документа</value>
</title>
<extendedTooltip>
<name>СтраницаТекстовогоДокументаРасширеннаяПодсказка</name>
<id>12</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<type>Page</type>
<extInfo xsi:type="form:PageGroupExtInfo">
<group>Vertical</group>
<showTitle>true</showTitle>
</extInfo>
</items>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<title>
<key>ru</key>
<value>Страницы</value>
</title>
<extendedTooltip>
<name>СтраницыРасширеннаяПодсказка</name>
<id>39</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<type>Pages</type>
<extInfo xsi:type="form:PagesGroupExtInfo">
<currentRowUse>DontUse</currentRowUse>
</extInfo>
</items>
<autoCommandBar>
<name>ФормаКоманднаяПанель</name>
<id>-1</id>
<items xsi:type="form:FormGroup">
<name>ГруппаКомандРежимаРедактирования</name>
<id>41</id>
<items xsi:type="form:Button">
<name>ВключитьРедактированиеТабличногоДокумента</name>
<id>45</id>
<title>
<key>ru</key>
<value>Таблица</value>
</title>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<extendedTooltip>
<name>ВключитьРедактированиеТабличногоДокументаРасширеннаяПодсказка</name>
<id>6</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<commandName>Form.Command.ВключитьРедактированиеТабличногоДокумента</commandName>
<representation>Auto</representation>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<placementArea>UserCmds</placementArea>
<representationInContextMenu>Auto</representationInContextMenu>
</items>
<items xsi:type="form:Button">
<name>ВключитьРедактированиеТекстовогоДокумента</name>
<id>7</id>
<title>
<key>ru</key>
<value>Текст</value>
</title>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<extendedTooltip>
<name>ВключитьРедактированиеТекстовогоДокументаРасширеннаяПодсказка</name>
<id>8</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<commandName>Form.Command.ВключитьРедактированиеТекстовогоДокумента</commandName>
<representation>Auto</representation>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<placementArea>UserCmds</placementArea>
<representationInContextMenu>Auto</representationInContextMenu>
</items>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<title>
<key>ru</key>
<value>Группа команд режима редактирования</value>
</title>
<extendedTooltip>
<name>ГруппаКомандРежимаРедактированияРасширеннаяПодсказка</name>
<id>43</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<extInfo xsi:type="form:ButtonGroupExtInfo">
<representation>Compact</representation>
</extInfo>
</items>
<items xsi:type="form:FormGroup">
<name>ГруппаКомандТабличногоДокумента</name>
<id>19</id>
<items xsi:type="form:FormGroup">
<name>КомандыВыгрузиЗагрузкиТабличногоДокумента</name>
<id>21</id>
<items xsi:type="form:Button">
<name>СохранитьТабличныйДокумент</name>
<id>23</id>
<title>
<key>ru</key>
<value>Сохранить в файл</value>
</title>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<extendedTooltip>
<name>СохранитьТабличныйДокументРасширеннаяПодсказка</name>
<id>24</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<commandName>Form.Item.МакетТабличногоДокумента.StandardCommand.SaveAs</commandName>
<representation>Picture</representation>
<onlyInAllActions>false</onlyInAllActions>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<placementArea>UserCmds</placementArea>
<picture xsi:type="core:PictureRef">
<picture>StdPicture.SaveFile</picture>
</picture>
<representationInContextMenu>Auto</representationInContextMenu>
</items>
<items xsi:type="form:Button">
<name>ЗагрузитьТабличныйДокумент</name>
<id>25</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<extendedTooltip>
<name>ЗагрузитьТабличныйДокументРасширеннаяПодсказка</name>
<id>26</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<commandName>Form.Command.ЗагрузитьТабличныйДокумент</commandName>
<representation>Auto</representation>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<placementArea>UserCmds</placementArea>
<representationInContextMenu>Auto</representationInContextMenu>
</items>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<title>
<key>ru</key>
<value>Команды выгрузки загрузки табличного документа</value>
</title>
<extendedTooltip>
<name>КомандыВыгрузиЗагрузкиТабличногоДокументаРасширеннаяПодсказка</name>
<id>22</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<extInfo xsi:type="form:ButtonGroupExtInfo">
<representation>Compact</representation>
</extInfo>
</items>
<items xsi:type="form:Button">
<name>НазначитьИмяОбластьТабличногоДокумента</name>
<id>27</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<extendedTooltip>
<name>НазначитьИмяОбластьТабличногоДокументаРасширеннаяПодсказка</name>
<id>28</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<commandName>Form.Item.МакетТабличногоДокумента.StandardCommand.SetName</commandName>
<representation>Picture</representation>
<onlyInAllActions>false</onlyInAllActions>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<placementArea>UserCmds</placementArea>
<representationInContextMenu>Auto</representationInContextMenu>
</items>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<title>
<key>ru</key>
<value>Форма группа1</value>
</title>
<extendedTooltip>
<name>ГруппаКомандТабличногоДокументаРасширеннаяПодсказка</name>
<id>20</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<extInfo xsi:type="form:ButtonGroupExtInfo"/>
</items>
<items xsi:type="form:FormGroup">
<name>ГруппаКомандТекстовогоДокумента</name>
<id>29</id>
<items xsi:type="form:FormGroup">
<name>КомандыВыгрузкиЗагрузкиТекстовогоДокумента</name>
<id>31</id>
<items xsi:type="form:Button">
<name>СохранитьТекстовыйДокумент</name>
<id>33</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<extendedTooltip>
<name>СохранитьТекстовыйДокументРасширеннаяПодсказка</name>
<id>34</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<commandName>Form.Command.СохранитьТекстовыйДокумент</commandName>
<representation>Auto</representation>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<placementArea>UserCmds</placementArea>
<representationInContextMenu>Auto</representationInContextMenu>
</items>
<items xsi:type="form:Button">
<name>ЗагрузитьТекстовыйДокумент</name>
<id>35</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<extendedTooltip>
<name>ЗагрузитьТекстовыйДокументРасширеннаяПодсказка</name>
<id>36</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<commandName>Form.Command.ЗагрузитьТекстовыйДокумент</commandName>
<representation>Auto</representation>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<placementArea>UserCmds</placementArea>
<representationInContextMenu>Auto</representationInContextMenu>
</items>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<title>
<key>ru</key>
<value>Команды выгрузки загрузки текстового документа</value>
</title>
<extendedTooltip>
<name>КомандыВыгрузкиЗагрузкиТекстовогоДокументаРасширеннаяПодсказка</name>
<id>32</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<extInfo xsi:type="form:ButtonGroupExtInfo">
<representation>Compact</representation>
</extInfo>
</items>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<title>
<key>ru</key>
<value>Группа команд текстового документа</value>
</title>
<extendedTooltip>
<name>ГруппаКомандТекстовогоДокументаРасширеннаяПодсказка</name>
<id>30</id>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<type>Label</type>
<autoMaxWidth>true</autoMaxWidth>
<autoMaxHeight>true</autoMaxHeight>
<extInfo xsi:type="form:LabelDecorationExtInfo">
<horizontalAlign>Left</horizontalAlign>
</extInfo>
</extendedTooltip>
<extInfo xsi:type="form:ButtonGroupExtInfo"/>
</items>
<visible>true</visible>
<enabled>true</enabled>
<userVisible>
<common>true</common>
</userVisible>
<horizontalAlign>Left</horizontalAlign>
<autoFill>true</autoFill>
</autoCommandBar>
<handlers>
<event>OnOpen</event>
<name>ПриОткрытии</name>
</handlers>
<handlers>
<event>OnCreateAtServer</event>
<name>ПриСозданииНаСервере</name>
</handlers>
<autoSaveDataInSettings>Use</autoSaveDataInSettings>
<autoTitle>true</autoTitle>
<autoUrl>true</autoUrl>
<group>Vertical</group>
<autoFillCheck>true</autoFillCheck>
<allowFormCustomize>true</allowFormCustomize>
<enabled>true</enabled>
<showTitle>true</showTitle>
<showCloseButton>true</showCloseButton>
<attributes>
<name>Объект</name>
<id>38</id>
<valueType>
<types>DataProcessorObject.ЮТРедакторМакетаСТестовымиДанными</types>
</valueType>
<view>
<common>true</common>
</view>
<edit>
<common>true</common>
</edit>
<main>true</main>
</attributes>
<attributes>
<name>МакетТабличногоДокумента</name>
<title>
<key>ru</key>
<value>Макет табличного документа</value>
</title>
<id>40</id>
<valueType>
<types>SpreadsheetDocument</types>
</valueType>
<view>
<common>true</common>
</view>
<edit>
<common>true</common>
</edit>
<extInfo xsi:type="form:SpreadsheetDocumentExtInfo"/>
</attributes>
<attributes>
<name>МакетТекстовогоДокумента</name>
<title>
<key>ru</key>
<value>Макет текстового документа</value>
</title>
<id>42</id>
<valueType>
<types>String</types>
<stringQualifiers/>
</valueType>
<view>
<common>true</common>
</view>
<edit>
<common>true</common>
</edit>
</attributes>
<attributes>
<name>РедактированиеТабличногоДокумента</name>
<title>
<key>ru</key>
<value>Редактирование табличного документа</value>
</title>
<id>44</id>
<valueType>
<types>Boolean</types>
</valueType>
<view>
<common>true</common>
</view>
<edit>
<common>true</common>
</edit>
</attributes>
<formCommands>
<name>ВключитьРедактированиеТабличногоДокумента</name>
<title>
<key>ru</key>
<value>Включить редактирование табличного документа</value>
</title>
<id>1</id>
<use>
<common>true</common>
</use>
<picture xsi:type="core:PictureRef">
<picture>StdPicture.SpreadsheetShowHeaders</picture>
</picture>
<action xsi:type="form:FormCommandHandlerContainer">
<handler>
<name>ВключитьРедактированиеТабличногоДокумента</name>
</handler>
</action>
<representation>TextPicture</representation>
<currentRowUse>DontUse</currentRowUse>
</formCommands>
<formCommands>
<name>ВключитьРедактированиеТекстовогоДокумента</name>
<title>
<key>ru</key>
<value>Включить редактирование текстового документа</value>
</title>
<id>2</id>
<use>
<common>true</common>
</use>
<picture xsi:type="core:PictureRef">
<picture>StdPicture.Document</picture>
</picture>
<action xsi:type="form:FormCommandHandlerContainer">
<handler>
<name>ВключитьРедактированиеТекстовогоДокумента</name>
</handler>
</action>
<representation>TextPicture</representation>
<currentRowUse>DontUse</currentRowUse>
</formCommands>
<formCommands>
<name>ЗагрузитьТабличныйДокумент</name>
<title>
<key>ru</key>
<value>Открыть файл</value>
</title>
<id>3</id>
<use>
<common>true</common>
</use>
<picture xsi:type="core:PictureRef">
<picture>StdPicture.OpenFile</picture>
</picture>
<action xsi:type="form:FormCommandHandlerContainer">
<handler>
<name>ЗагрузитьТабличныйДокумент</name>
</handler>
</action>
<currentRowUse>DontUse</currentRowUse>
</formCommands>
<formCommands>
<name>СохранитьТекстовыйДокумент</name>
<title>
<key>ru</key>
<value>Сохранить текстовый документ</value>
</title>
<id>4</id>
<use>
<common>true</common>
</use>
<picture xsi:type="core:PictureRef">
<picture>StdPicture.Write</picture>
</picture>
<action xsi:type="form:FormCommandHandlerContainer">
<handler>
<name>СохранитьТекстовыйДокумент</name>
</handler>
</action>
<currentRowUse>DontUse</currentRowUse>
</formCommands>
<formCommands>
<name>ЗагрузитьТекстовыйДокумент</name>
<title>
<key>ru</key>
<value>Загрузить текстовый документ</value>
</title>
<id>5</id>
<use>
<common>true</common>
</use>
<picture xsi:type="core:PictureRef">
<picture>StdPicture.OpenFile</picture>
</picture>
<action xsi:type="form:FormCommandHandlerContainer">
<handler>
<name>ЗагрузитьТекстовыйДокумент</name>
</handler>
</action>
<currentRowUse>DontUse</currentRowUse>
</formCommands>
<commandInterface>
<navigationPanel/>
<commandBar/>
</commandInterface>
<extInfo xsi:type="form:ObjectFormExtInfo"/>
</form:Form>

View File

@@ -0,0 +1,274 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
#Область ОбработчикиСобытийФормы
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("РедактированиеMarkDown")
И Параметры.РедактированиеMarkDown Тогда
РедактированиеТабличногоДокумента = Ложь;
МакетТекстовогоДокумента = Параметры.КодMarkDown;
Иначе
РедактированиеТабличногоДокумента = Истина;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
НастроитьЭлементыФормы(ЭтотОбъект);
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура ВключитьРедактированиеТабличногоДокумента(Команда)
КонвертироватьВТабличныйДокумент();
РедактированиеТабличногоДокумента = Истина;
НастроитьЭлементыФормы(ЭтотОбъект);
СохраняемыеВНастройкахДанныеМодифицированы = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ВключитьРедактированиеТекстовогоДокумента(Команда)
КонвертироватьВТекстовыйДокумент();
РедактированиеТабличногоДокумента = Ложь;
НастроитьЭлементыФормы(ЭтотОбъект);
СохраняемыеВНастройкахДанныеМодифицированы = Истина;
КонецПроцедуры
&НаКлиенте
Процедура ЗагрузитьТабличныйДокумент(Команда)
НачатьЧтениеТабличногоДокумента();
КонецПроцедуры
&НаКлиенте
Процедура СохранитьТекстовыйДокумент(Команда)
НачатьЗаписьТекстовогоДокумента();
КонецПроцедуры
&НаКлиенте
Процедура ЗагрузитьТекстовыйДокумент(Команда)
НачатьЧтениеТекстовогоДокумента();
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
&НаКлиентеНаСервереБезКонтекста
Процедура НастроитьЭлементыФормы(Форма)
Элементы = Форма.Элементы;
Элементы.ВключитьРедактированиеТабличногоДокумента.Пометка = Форма.РедактированиеТабличногоДокумента;
Элементы.ВключитьРедактированиеТекстовогоДокумента.Пометка = Не Форма.РедактированиеТабличногоДокумента;
Если Форма.РедактированиеТабличногоДокумента Тогда
Элементы.Страницы.ТекущаяСтраница = Элементы.СтраницаТабличногоДокумента;
Иначе
Элементы.Страницы.ТекущаяСтраница = Элементы.СтраницаТекстовогоДокумента;
КонецЕсли;
Элементы.ГруппаКомандТабличногоДокумента.Видимость = Форма.РедактированиеТабличногоДокумента;
Элементы.ГруппаКомандТекстовогоДокумента.Видимость = Не Форма.РедактированиеТабличногоДокумента;
КонецПроцедуры
&НаСервере
Процедура КонвертироватьВТабличныйДокумент()
МакетТабличногоДокумента = Обработки.ЮТРедакторМакетаСТестовымиДанными.КонвертироватьВТабличныйДокумент(
МакетТекстовогоДокумента);
КонецПроцедуры
&НаСервере
Процедура КонвертироватьВТекстовыйДокумент()
МакетТекстовогоДокумента = Обработки.ЮТРедакторМакетаСТестовымиДанными.КонвертироватьВТекстовыйДокумент(
МакетТабличногоДокумента);
КонецПроцедуры
#Область ЧтениеТабличногоДокумента
&НаКлиенте
Процедура НачатьЧтениеТабличногоДокумента()
Фильтры = Новый Массив();
Фильтры.Добавить(НСтр("ru = 'Табличный документ'") + "|*.mxl");
Фильтры.Добавить(НСтр("ru = 'Лист Excel'") + "|*.xls");
Фильтры.Добавить(НСтр("ru = 'Лист Excel2007-...'") + "|*.xlsx");
Фильтры.Добавить(НСтр("ru = 'Электронная таблица ODF'") + "|*.ods");
//@skip-check bsl-legacy-check-dynamic-feature-access
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Фильтр = СтрСоединить(Фильтры, "|");
Диалог.ИндексФильтра = 0;
Диалог.МножественныйВыбор = Ложь;
Обработчик = Новый ОписаниеОповещения("ПродолжитьВыборФайлаТабличногоДокумента", ЭтотОбъект);
Диалог.Показать(Обработчик);
КонецПроцедуры
&НаКлиенте
Процедура ПродолжитьВыборФайлаТабличногоДокумента(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Если ВыбранныеФайлы = Неопределено Тогда
Возврат;
КонецЕсли;
Обработчик = Новый ОписаниеОповещения("ПродолжитьЧтениеТабличногоДокумента", ЭтотОбъект);
НачатьПомещениеФайла(Обработчик, , ВыбранныеФайлы[0], Ложь, УникальныйИдентификатор);
КонецПроцедуры
&НаКлиенте
Процедура ПродолжитьЧтениеТабличногоДокумента(Результат, Адрес, ВыбранноеИмяФайла, ДополнительныеПараметры) Экспорт
ВыбранныйФайл = Новый Файл(ВыбранноеИмяФайла);
ПрочитатьТабличныйДокументНаСервере(Адрес, ВыбранныйФайл.Расширение);
УдалитьИзВременногоХранилища(Адрес);
КонецПроцедуры
&НаСервере
Процедура ПрочитатьТабличныйДокументНаСервере(АдресФайла, РасширениеФайла)
ВременныйФайл = ПолучитьИмяВременногоФайла(РасширениеФайла);
ДанныеФайла = ПолучитьИзВременногоХранилища(АдресФайла); // ДвоичныеДанные
ДанныеФайла.Записать(ВременныйФайл);
МакетТабличногоДокумента.Прочитать(ВременныйФайл);
УдалитьФайлы(ВременныйФайл);
КонецПроцедуры
#КонецОбласти
//@skip-check bsl-legacy-check-dynamic-feature-access
//@skip-check bsl-legacy-check-type-environments
#Область ЗаписьТекстовогоДокумент
&НаКлиенте
Процедура НачатьЗаписьТекстовогоДокумента()
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Диалог.Фильтр = НСтр("ru = 'Текстовый документ'") + "|*.txt";
Диалог.ИндексФильтра = 0;
Обработчик = Новый ОписаниеОповещения("ПродолжитьЗаписьТекстовогоДокумента", ЭтотОбъект);
Диалог.Показать(Обработчик);
КонецПроцедуры
&НаКлиенте
Процедура ПродолжитьЗаписьТекстовогоДокумента(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Если ВыбранныеФайлы = Неопределено Тогда
Возврат;
КонецЕсли;
ЗаписатьТекстовыйДокументНаКлиенте(ВыбранныеФайлы[0]);
КонецПроцедуры
&НаКлиенте
Процедура ЗаписатьТекстовыйДокументНаКлиенте(ИмяФайла)
Писатель = Новый ЗаписьТекста();
Писатель.Открыть(ИмяФайла);
Писатель.ЗаписатьСтроку(МакетТекстовогоДокумента);
Писатель.Закрыть();
КонецПроцедуры
#КонецОбласти
//@skip-check bsl-legacy-check-dynamic-feature-access
//@skip-check bsl-legacy-check-type-environments
#Область ЧтениеТекстовогоДокумента
&НаКлиенте
Процедура НачатьЧтениеТекстовогоДокумента()
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Фильтр = НСтр("ru = 'Текстовый документ'") + "|*.txt";
Диалог.ИндексФильтра = 0;
Обработчик = Новый ОписаниеОповещения("ПродолжитьЧтениеТекстовогоДокумента", ЭтотОбъект);
Диалог.Показать(Обработчик);
КонецПроцедуры
&НаКлиенте
Процедура ПродолжитьЧтениеТекстовогоДокумента(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Если ВыбранныеФайлы = Неопределено Тогда
Возврат;
КонецЕсли;
ПрочитатьТекстовыйДокументНаКлиенте(ВыбранныеФайлы[0]);
КонецПроцедуры
&НаКлиенте
Процедура ПрочитатьТекстовыйДокументНаКлиенте(ИмяФайла)
Читатель = Новый ЧтениеТекста();
Читатель.Открыть(ИмяФайла);
МакетТекстовогоДокумента = Читатель.Прочитать();
Читатель.Закрыть();
КонецПроцедуры
#КонецОбласти
#КонецОбласти

View File

@@ -0,0 +1,376 @@
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Область ПрограммныйИнтерфейс
// Преобразует markdown-таблицы в табличный документ
// с сохранением группировки таблиц по областям.
//
// Параметры:
// ТекстовыйДокумент - ТекстовыйДокумент
//
// Возвращаемое значение:
// ТабличныйДокумент
//
Функция КонвертироватьВТабличныйДокумент(ТекстовыйДокумент) Экспорт
Результат = Новый ТабличныйДокумент();
СписокОбластей = КоллекцияТаблицИзТекста(ТекстовыйДокумент);
МакетРазделителя = МакетРазелителяТаблиц();
Для НомерОбласти = 1 По СписокОбластей.Количество() Цикл
Если НомерОбласти > 1 Тогда
Результат.Вывести(МакетРазделителя);
КонецЕсли;
МакетОбласти = СписокОбластей[НомерОбласти - 1].Значение; // ТабличныйДокумент
ИмяОбласти = СписокОбластей[НомерОбласти - 1].Представление;
ИзменитьШиринуПоСодержимому(МакетОбласти);
ВывестиВТабличныйДокумент(Результат, МакетОбласти, ИмяОбласти);
КонецЦикла;
Возврат Результат;
КонецФункции
// Преобразует содержимое табличного документа в markdown-таблицы
// с сохранением группировки таблиц по областям.
//
// Параметры:
// ТабличныйДокумент - ТабличныйДокумент
//
// Возвращаемое значение:
// Строка
//
Функция КонвертироватьВТекстовыйДокумент(ТабличныйДокумент) Экспорт
Если ТабличныйДокумент.Области.Количество() = 0 Тогда
ТекстовыйДокумент = ОбластьТабличногоМакетаВТекст(ТабличныйДокумент);
Иначе
Результат = Новый Массив();
Для Каждого ОбластьМакета Из ТабличныйДокумент.Области Цикл
Документ = ТабличныйДокумент.ПолучитьОбласть(ОбластьМакета.Имя);
ТаблицаТекстом = ОбластьТабличногоМакетаВТекст(Документ, ОбластьМакета.Имя);
Результат.Добавить(ТаблицаТекстом);
КонецЦикла;
ТекстовыйДокумент = СтрСоединить(Результат, Символы.ПС + Символы.ПС);
КонецЕсли;
Возврат ТекстовыйДокумент;
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
#Область КонвертацияВТабличныйДокумент
Функция КоллекцияТаблицИзТекста(Текст)
СписокОбластей = Новый СписокЗначений(); // СписокЗначений из ТабличныйДокумент
МакетОбласти = Неопределено;
ИмяОбластиМакета = "";
Для Каждого ТекущаяСтрока Из СтрРазделить(Текст, Символы.ПС) Цикл
Если ПустаяСтрока(ТекущаяСтрока) Тогда
Продолжить;
КонецЕсли;
ТекущаяСтрока = СокрЛП(ТекущаяСтрока);
Если СтрНачинаетсяС(ТекущаяСтрока, "#Область ") Тогда
Если МакетОбласти = Неопределено Тогда
ИмяОбластиМакета = Сред(ТекущаяСтрока, 10);
КонецЕсли;
ИначеЕсли ТекущаяСтрока = "#КонецОбласти" Тогда
Если МакетОбласти <> Неопределено Тогда
СписокОбластей.Добавить(МакетОбласти, ИмяОбластиМакета);
МакетОбласти = Неопределено;
ИмяОбластиМакета = "";
КонецЕсли;
ИначеЕсли МакетОбласти <> Неопределено
И МакетОбласти.ВысотаТаблицы = 1
И СтрРазделить(ТекущаяСтрока, " -|", Ложь).Количество() = 0 Тогда
// Игорируем разделитель шапки и содержимого таблицы.
Иначе
Если МакетОбласти = Неопределено Тогда
МакетОбласти = Новый ТабличныйДокумент();
КонецЕсли;
Если СтрНачинаетсяС(ТекущаяСтрока, "|") И СтрЗаканчиваетсяНа(ТекущаяСтрока, "|") Тогда
ТекущаяСтрока = Сред(ТекущаяСтрока, 2, СтрДлина(ТекущаяСтрока) - 2);
КонецЕсли;
НомерСтроки = МакетОбласти.ВысотаТаблицы + 1;
ЗначенияЯчеек = СтрРазделить(ТекущаяСтрока, "|", Истина);
Для Индекс = 0 По ЗначенияЯчеек.ВГраница() Цикл
НомерКолонки = Индекс + 1;
Ячейка = МакетОбласти.Область(НомерСтроки, НомерКолонки);
Ячейка.Текст = СокрЛП(ЗначенияЯчеек[Индекс]);
КонецЦикла;
КонецЕсли;
КонецЦикла;
Если МакетОбласти <> Неопределено Тогда
СписокОбластей.Добавить(МакетОбласти, ИмяОбластиМакета);
КонецЕсли;
Возврат СписокОбластей
КонецФункции
Функция МакетРазелителяТаблиц()
Макет = Новый ТабличныйДокумент();
Макет.Область(1, 1).Текст = "";
Возврат Макет;
КонецФункции
Процедура ИзменитьШиринуПоСодержимому(Документ)
МинимальнаяШирина = 5;
МаксимальнаяШирина = 25;
Для НомерКолонки = 1 По Документ.ШиринаТаблицы Цикл
ШиринаВСимволах = МаксимальнаяДлиннаТекстаВКолонке(Документ, НомерКолонки);
ШиринаВТочках = Мин(Макс(МинимальнаяШирина, ШиринаВСимволах), МаксимальнаяШирина);
Колонка = Документ.Область(, НомерКолонки, , НомерКолонки);
Колонка.ШиринаКолонки = ШиринаВТочках;
КонецЦикла;
КонецПроцедуры
Функция МаксимальнаяДлиннаТекстаВКолонке(Документ, НомерКолонки)
Результат = 0;
Для НомерСтроки = 1 По Документ.ВысотаТаблицы Цикл
ТекстЯчейки = Документ.Область(НомерСтроки, НомерКолонки).Текст;
Результат = Макс(Результат, СтрДлина(ТекстЯчейки));
КонецЦикла;
Возврат Результат;
КонецФункции
Процедура ВывестиВТабличныйДокумент(Документ, МакетОбласти, ИмяОбласти = "")
НачалоВывода = Документ.ВысотаТаблицы + 1;
Документ.Вывести(МакетОбласти);
КонецВывода = Документ.ВысотаТаблицы;
ОбластьШапки = Документ.Область(НачалоВывода, , НачалоВывода);
ОбластьШапки.Шрифт = Новый Шрифт(ОбластьШапки.Шрифт, , , Истина); //@skip-check new-font
Если Не ПустаяСтрока(ИмяОбласти) Тогда
ОбластьМакета = Документ.Область(НачалоВывода, , КонецВывода, );
ОбластьМакета.Имя = ИмяОбласти;
ОбластьМакета.СоздатьФорматСтрок();
КонецЕсли;
Для НомерКолонки = 1 По МакетОбласти.ШиринаТаблицы Цикл
КолонкаИсточника = МакетОбласти.Область(, НомерКолонки, , НомерКолонки);
КолонкаПриемника = Документ.Область(НачалоВывода, НомерКолонки, КонецВывода, НомерКолонки);
КолонкаПриемника.ШиринаКолонки = КолонкаИсточника.ШиринаКолонки;
КонецЦикла;
КонецПроцедуры
#КонецОбласти
#Область КонвертацияВТекстовыйДокумент
Функция ОбластьТабличногоМакетаВТекст(Документ, Имя = "")
Результат = Новый Массив();
Если Не ПустаяСтрока(Имя) Тогда
Результат.Добавить("#Область " + Имя);
Результат.Добавить("");
КонецЕсли;
Если Документ.ВысотаТаблицы > 0 Тогда
ТаблицаДанных = ОбластьТабличногоМакетаВТаблицуЗначений(Документ);
РассчитатьШиринуКолонок(ТаблицаДанных);
ВывестиИменаКолонокВТекстовыйДокумент(Результат, ТаблицаДанных);
ВывестиРазделительШапкиВТекстовыйДокумент(Результат, ТаблицаДанных);
Для Каждого СтрокаТаблицы Из ТаблицаДанных Цикл
ВывестиЗначенияКолонокВТекстовыйДокумент(Результат, СтрокаТаблицы);
КонецЦикла;
КонецЕсли;
Если Не ПустаяСтрока(Имя) Тогда
Результат.Добавить("");
Результат.Добавить("#КонецОбласти");
КонецЕсли;
Возврат СтрСоединить(Результат, Символы.ПС);
КонецФункции
Функция ОбластьТабличногоМакетаВТаблицуЗначений(Документ)
ТаблицаДанных = Новый ТаблицаЗначений();
Для НомерКолонки = 1 По Документ.ШиринаТаблицы Цикл
ИмяКолонки = "_" + Формат(НомерКолонки, "ЧН=; ЧГ=;");
ЗаголовокКолонки = Документ.Область(1, НомерКолонки).Текст;
ТипКолонки = Новый ОписаниеТипов("Строка");
ТаблицаДанных.Колонки.Добавить(ИмяКолонки, ТипКолонки, ЗаголовокКолонки);
КонецЦикла;
Для НомерСтроки = 2 По Документ.ВысотаТаблицы Цикл
НоваяСтрока = ТаблицаДанных.Добавить();
Для НомерКолонки = 1 По Документ.ШиринаТаблицы Цикл
НоваяСтрока[НомерКолонки - 1] = Документ.Область(НомерСтроки, НомерКолонки).Текст;
КонецЦикла;
КонецЦикла;
Возврат ТаблицаДанных;
КонецФункции
Процедура РассчитатьШиринуКолонок(ТаблицаДанных)
Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл
Колонка.Ширина = СтрДлина(Колонка.Заголовок);
Для Каждого СтрокаТаблицы Из ТаблицаДанных Цикл
Значение = СтрокаТаблицы[Колонка.Имя];
Колонка.Ширина = Макс(Колонка.Ширина, СтрДлина(Значение));
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Процедура ВывестиИменаКолонокВТекстовыйДокумент(Результат, ТаблицаДанных)
ТекущаяСтрока = "|";
Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл
ТекущаяСтрока = ТекущаяСтрока
+ " "
+ ДополнитьСтроку(Колонка.Заголовок, Колонка.Ширина)
+ " |";
КонецЦикла;
Результат.Добавить(ТекущаяСтрока);
КонецПроцедуры
Процедура ВывестиРазделительШапкиВТекстовыйДокумент(Результат, ТаблицаДанных)
ТекущаяСтрока = "|";
Для Каждого Колонка Из ТаблицаДанных.Колонки Цикл
ТекущаяСтрока = ТекущаяСтрока
+ ДополнитьСтроку("", Колонка.Ширина + 2, "-")
+ "|";
КонецЦикла;
Результат.Добавить(ТекущаяСтрока);
КонецПроцедуры
Процедура ВывестиЗначенияКолонокВТекстовыйДокумент(Результат, СтрокаТаблицы)
ТекущаяСтрока = "|";
Для Каждого Колонка Из СтрокаТаблицы.Владелец().Колонки Цикл
ТекущаяСтрока = ТекущаяСтрока
+ " "
+ ДополнитьСтроку(СтрокаТаблицы[Колонка.Имя], Колонка.Ширина)
+ " |";
КонецЦикла;
Результат.Добавить(ТекущаяСтрока);
КонецПроцедуры
Функция ДополнитьСтроку(ИсходнаяСтрока, ОжидаемаяДлина, Символ = " ")
ДлинаСтроки = СтрДлина(ИсходнаяСтрока);
ДополнениеСтроки = "";
Для Счетчик = 1 По (ОжидаемаяДлина - ДлинаСтроки) Цикл
ДополнениеСтроки = ДополнениеСтроки + Символ;
КонецЦикла;
Возврат ИсходнаяСтрока + ДополнениеСтроки;
КонецФункции
#КонецОбласти
#КонецОбласти
#КонецЕсли

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:DataProcessor xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="0e483442-9bcd-46e7-92fd-5f894adfdcd3">
<producedTypes>
<objectType typeId="faf65759-b01b-476a-8829-5229fbcb4b0a" valueTypeId="4f49cd17-6f13-4455-af7d-8a2c1271f60d"/>
<managerType typeId="d747597d-7637-48ce-a4ba-c36883bfde36" valueTypeId="5e7273e9-8a18-4fda-a496-8538c064af6c"/>
</producedTypes>
<name>ЮТРедакторМакетаСТестовымиДанными</name>
<synonym>
<key>ru</key>
<value>Редактор макета с тестовыми данными</value>
</synonym>
<useStandardCommands>true</useStandardCommands>
<defaultForm>DataProcessor.ЮТРедакторМакетаСТестовымиДанными.Form.Форма</defaultForm>
<forms uuid="13f59e91-1b7c-4300-9980-34221e137bca">
<name>Форма</name>
<synonym>
<key>ru</key>
<value>Форма</value>
</synonym>
<usePurposes>PersonalComputer</usePurposes>
<usePurposes>MobileDevice</usePurposes>
</forms>
</mdclass:DataProcessor>

View File

@@ -46,7 +46,7 @@
Каталог = ПолучитьИмяВременногоФайла();
ЮТОбщийСлужебный.РаспаковатьМакет("ОбщийМакет.ЮТMonacoEditor", Каталог);
EditorURL = ЮТФайлы.ОбъединитьПути(Каталог, "index.html");
Исключение8
Исключение
ВызватьИсключение "Не удалось инициализировать редактор: " + ОписаниеОшибки();
КонецПопытки;
@@ -130,43 +130,7 @@
Процедура ПослеВыполненияТестирования(Результат, Сообщение) Экспорт
ПоказатьОповещениеПользователя("Прогон тестов", , "Завершено выполнение тестов", БиблиотекаКартинок.ЮТПодсистема);
Ответ = Новый Структура("tests, errors", Новый Массив, Новый Массив);
Для Каждого Набор Из Результат[0].НаборыТестов Цикл
Для Каждого ОписаниеОшибки Из Набор.Ошибки Цикл
Если ЗначениеЗаполнено(ОписаниеОшибки.Стек) Тогда
Ответ.errors.Добавить(ОписаниеОшибки.Стек);
КонецЕсли;
КонецЦикла;
Для Каждого Тест Из Набор.Тесты Цикл
ОписаниеТеста = Новый Структура;
ОписаниеТеста.Вставить("status", Тест.Статус);
ОписаниеТеста.Вставить("present", Тест.Имя);
ОписаниеТеста.Вставить("method", Тест.Метод);
ОписаниеТеста.Вставить("duration", Тест.Длительность);
ОписаниеТеста.Вставить("message", "");
Ответ.tests.Добавить(ОписаниеТеста);
Для Каждого ОписаниеОшибки Из Тест.Ошибки Цикл
Если ЗначениеЗаполнено(ОписаниеОшибки.Стек) Тогда
Ответ.errors.Добавить(ОписаниеОшибки.Стек);
КонецЕсли;
ОписаниеТеста.message = ОписаниеТеста.message + Символы.ПС + ОписаниеОшибки.Сообщение;
КонецЦикла;
КонецЦикла;
КонецЦикла;
Ответ = ЮТВнешнийЗапускТестовСлужебныйКлиент.Отчет(Результат);
ЮТРеактивныйКлиент.ОтправитьОтвет(Элементы.EditorURL, Сообщение, Ответ);
КонецПроцедуры

View File

@@ -1,6 +1,6 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
// Copyright 2021-2025 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<cmi:CommandInterface xmlns:cmi="http://g5.1c.ru/v8/dt/cmi"/>

View File

@@ -48,9 +48,11 @@
<content>DataProcessor.ЮТHTTPServiceRequest</content>
<content>DataProcessor.ЮТHTTPСервисЗапрос</content>
<content>DataProcessor.ЮТRecordSet</content>
<content>DataProcessor.ЮТГенераторКода</content>
<content>DataProcessor.ЮТКонструкторОбъектаXDTO</content>
<content>DataProcessor.ЮТКонструкторТестовыхДанных</content>
<content>DataProcessor.ЮТРедакторТестов</content>
<content>DataProcessor.ЮТСообщениеСервисаИнтеграции</content>
<content>DataProcessor.ЮТЮнитТесты</content>
<content>DataProcessor.ЮТРедакторМакетаСТестовымиДанными</content>
</mdclass:Subsystem>

154
Untitled-1.bsl Normal file
View File

@@ -0,0 +1,154 @@
//©///////////////////////////////////////////////////////////////////////////©//
//
// Copyright 2021-2024 BIA-Technologies Limited Liability Company
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//©///////////////////////////////////////////////////////////////////////////©//
#Область СлужебныйПрограммныйИнтерфейс
Процедура ИсполняемыеСценарии() Экспорт
ЮТТесты
.ДобавитьТест("СПараметрами")
.ДобавитьТест("Представление")
.ДобавитьТест("СПараметрамиНаКлиенте")
.ДобавитьТест("СПараметрамиНаСервере")
;
КонецПроцедуры
Процедура ПередКаждымТестом() Экспорт
ОписаниеМодуля = ЮТФабрика.ОписаниеМетаданныеМодуля();
ОписаниеМодуля.КлиентУправляемоеПриложение = Истина;
ОписаниеМодуля.КлиентОбычноеПриложение = Истина;
ОписаниеМодуля.Сервер = Истина;
ЮТТестыСлужебный.ПередЧтениемСценариевМодуля(ОписаниеМодуля);
КонецПроцедуры
Процедура СПараметрами() Экспорт
ЮТТесты
.ДобавитьТест("Тест1")
.ДобавитьТест("Тест2").СПараметрами(1, 2, 3)
.ДобавитьТест("Тест3")
.СПараметрами(1)
.СПараметрами(2)
.СПараметрами(3)
;
ЮТест.ОжидаетЧто(ТестыТекущегоНабора())
.ИмеетДлину(5)
.Свойство("[0].Параметры").ЭтоНеопределено()
.Свойство("[1].Параметры").ИмеетДлину(3)
.Свойство("[1].Параметры[0]").Равно(1)
.Свойство("[1].Параметры[1]").Равно(2)
.Свойство("[1].Параметры[2]").Равно(3)
.Свойство("[2].Параметры").ИмеетДлину(1)
.Свойство("[3].Параметры[0]").Равно(2)
.Свойство("[4].Параметры[0]").Равно(3)
;
КонецПроцедуры
Процедура Представление() Экспорт
ЮТТесты
.ДобавитьТестовыйНабор("Набор1").Представление("Представление набора")
.ДобавитьТест("Тест1").Представление("Представление теста")
.ДобавитьТест("Тест2")
.СПараметрами(1).Представление("Представление теста 2", Истина)
.СПараметрами(2).Представление("Представление теста 3")
;
ЮТест.ОжидаетЧто(ТекущийНабор())
.Свойство("Представление").Равно("Представление набора")
.Свойство("Тесты[0].Представление").Равно("Представление теста")
.Свойство("Тесты[1].Представление").Равно("Тест2. Представление теста 2")
.Свойство("Тесты[2].Представление").Равно("Представление теста 3");
КонецПроцедуры
Процедура СПараметрамиНаКлиенте() Экспорт
КонтекстыВызова = ЮТФабрика.КонтекстыВызова();
ЮТТесты
.ДобавитьКлиентскийТест("Тест1")
.СПараметрамиНаКлиенте(1)
.ДобавитьТест("Тест2")
.СПараметрамиНаКлиенте(1, 2, 3)
.СПараметрами(2)
;
ЮТест.ОжидаетЧто(ТестыТекущегоНабора())
.ИмеетДлину(3)
.Свойство("[0].Параметры").ИмеетДлину(1)
.Свойство("[0].КонтекстВызова").Равно(ЮТКоллекции.ЗначениеВМассиве(КонтекстыВызова.КлиентУправляемоеПриложение, КонтекстыВызова.КлиентОбычноеПриложение))
.Свойство("[1].Параметры").ИмеетДлину(3)
.Свойство("[1].КонтекстВызова").Равно(ЮТКоллекции.ЗначениеВМассиве(КонтекстыВызова.КлиентУправляемоеПриложение, КонтекстыВызова.КлиентОбычноеПриложение))
.Свойство("[2].КонтекстВызова").ИмеетДлину(3)
;
ЮТест.ОжидаетЧто(ЮТТесты.ДобавитьСерверныйТест("Тест3"))
.Метод("СПараметрамиНаКлиенте").Параметр(1)
.ВыбрасываетИсключение("Не пересекаются контексты базового теста [Сервер] и устанавливаемые [КлиентУправляемоеПриложение, КлиентОбычноеПриложение]");
КонецПроцедуры
Процедура СПараметрамиНаСервере() Экспорт
КонтекстыВызова = ЮТФабрика.КонтекстыВызова();
ЮТТесты
.ДобавитьСерверныйТест("Тест1")
.СПараметрамиНаСервере(1)
.ДобавитьТест("Тест2")
.СПараметрамиНаСервере(1, 2, 3)
.СПараметрами(2)
;
ЮТест.ОжидаетЧто(ТестыТекущегоНабора())
.ИмеетДлину(3)
.Свойство("[0].Параметры").ИмеетДлину(1)
.Свойство("[0].КонтекстВызова").Равно(ЮТКоллекции.ЗначениеВМассиве(КонтекстыВызова.Сервер))
.Свойство("[1].Параметры").ИмеетДлину(3)
.Свойство("[1].КонтекстВызова").Равно(ЮТКоллекции.ЗначениеВМассиве(КонтекстыВызова.Сервер))
.Свойство("[2].КонтекстВызова").ИмеетДлину(3)
;
ЮТест.ОжидаетЧто(ЮТТесты.ДобавитьКлиентскийТест("Тест3"))
.Метод("СПараметрамиНаСервере").Параметр(1)
.ВыбрасываетИсключение("Не пересекаются контексты базового теста [КлиентУправляемоеПриложение, КлиентОбычноеПриложение] и устанавливаемые [Сервер]");
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ТекущийНабор()
Возврат ЮТТестыСлужебный.Контекст().ТекущийНабор;
КонецФункции
Функция ТестыТекущегоНабора()
Возврат ТекущийНабор().Тесты;
КонецФункции
#КонецОбласти

View File

@@ -45,7 +45,7 @@
display: flex;
flex-direction: column;
position: absolute;
top: 6rem;
top: 9rem;
width: 100%;
}
@@ -106,6 +106,9 @@
.checkboxes {
display: flex;
flex-direction: row;
max-width: 170rem;
overflow-x: auto;
/* Показывает прокрутку только при необходимости */
}
.checkboxes>* {
@@ -122,7 +125,7 @@
.tag {
/* внешние отступы */
padding: .6rem 1.2rem;
max-height: 2.5rem;
/*min-height: 2.5rem;*/
/* подгоняем размер блока под содержимое */
width: -webkit-fit-content;
width: -moz-fit-content;
@@ -130,8 +133,8 @@
/* радиус скругления */
border-radius: .4rem;
/* отступ сверху */
margin-top: 1.2rem;
margin-bottom: 1.2rem;
/*margin-top: .5rem;*/
/*margin-bottom: .5rem;*/
/* запрещаем выделять мышкой этот элемент */
-webkit-user-select: none;
-moz-user-select: none;
@@ -300,11 +303,12 @@
position: fixed;
z-index: 100;
width: 100%;
height: 6rem;
/*height: 6rem;*/
padding-left: .5rem;
padding-right: .5rem;
background-color: white;
justify-content: start;
margin-top: .5rem;
}
.command_panel_buttons {
@@ -517,7 +521,7 @@
/* кнопка добавления задач --- */
</style>
<base
href="v8config://0ed33609472ecfbbe793f5952935f8d197d25ce7/mdobject/idd2e72251-d28f-4ee6-983a-a99008a98bd1/8eb4fad1-1fa6-403e-970f-2c12dbb43e23">
href="v8config://89d6d638f84f1abbb41c735a5f6b175195089233/mdobject/idd2e72251-d28f-4ee6-983a-a99008a98bd1/8eb4fad1-1fa6-403e-970f-2c12dbb43e23">
</base>
</head>
@@ -537,20 +541,78 @@
<div class="checkbox"><input type="checkbox" id="project8e7227e2-c296-11ee-93e4-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="project8e7227e2-c296-11ee-93e4-107b4419808b">
<div class="tag project8e7227e2-c296-11ee-93e4-107b4419808b"
style="background-color: rgb(238,130,238);">Первый проект</div>
<div class="tag project8e7227e2-c296-11ee-93e4-107b4419808b">Первый проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="project8d9f5c04-ea3a-11ef-9500-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="project8d9f5c04-ea3a-11ef-9500-107b4419808b">
<div class="tag project8d9f5c04-ea3a-11ef-9500-107b4419808b"
style="background-color: rgb(204,255,204);">Второй проект</div>
<div class="tag project8d9f5c04-ea3a-11ef-9500-107b4419808b">Второй проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="project8d9f5c05-ea3a-11ef-9500-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="project8d9f5c05-ea3a-11ef-9500-107b4419808b">
<div class="tag project8d9f5c05-ea3a-11ef-9500-107b4419808b">Третий проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecte6f2f9fb-1bb1-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecte6f2f9fb-1bb1-11f0-9517-107b4419808b">
<div class="tag projecte6f2f9fb-1bb1-11f0-9517-107b4419808b">Четвертый проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecte6f2f9fc-1bb1-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecte6f2f9fc-1bb1-11f0-9517-107b4419808b">
<div class="tag projecte6f2f9fc-1bb1-11f0-9517-107b4419808b">Пятый проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecte6f2f9fd-1bb1-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecte6f2f9fd-1bb1-11f0-9517-107b4419808b">
<div class="tag projecte6f2f9fd-1bb1-11f0-9517-107b4419808b">Шестой проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecte6f2f9fe-1bb1-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecte6f2f9fe-1bb1-11f0-9517-107b4419808b">
<div class="tag projecte6f2f9fe-1bb1-11f0-9517-107b4419808b">Седьмой проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecte6f2f9ff-1bb1-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecte6f2f9ff-1bb1-11f0-9517-107b4419808b">
<div class="tag projecte6f2f9ff-1bb1-11f0-9517-107b4419808b">Восьмой проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecte6f2fa00-1bb1-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecte6f2fa00-1bb1-11f0-9517-107b4419808b">
<div class="tag projecte6f2fa00-1bb1-11f0-9517-107b4419808b">Девятый проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecte6f2fa01-1bb1-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecte6f2fa01-1bb1-11f0-9517-107b4419808b">
<div class="tag projecte6f2fa01-1bb1-11f0-9517-107b4419808b">Десятый проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecte6f2fa02-1bb1-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecte6f2fa02-1bb1-11f0-9517-107b4419808b">
<div class="tag projecte6f2fa02-1bb1-11f0-9517-107b4419808b">Одиннадцатый проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecte6f2fa03-1bb1-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecte6f2fa03-1bb1-11f0-9517-107b4419808b">
<div class="tag projecte6f2fa03-1bb1-11f0-9517-107b4419808b">Двенадцатый проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecta4366321-1bb4-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecta4366321-1bb4-11f0-9517-107b4419808b">
<div class="tag projecta4366321-1bb4-11f0-9517-107b4419808b">Тренадцатый проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecta4366322-1bb4-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecta4366322-1bb4-11f0-9517-107b4419808b">
<div class="tag projecta4366322-1bb4-11f0-9517-107b4419808b">Четырнадцатый проект</div>
</label></div>
<div class="checkbox"><input type="checkbox" id="projecta4366323-1bb4-11f0-9517-107b4419808b"
checked="true" onclick="checkFluency(id, id)"></input><label
for="projecta4366323-1bb4-11f0-9517-107b4419808b">
<div class="tag projecta4366323-1bb4-11f0-9517-107b4419808b">Пятнадцатый проект</div>
</label></div>
</div>
<div class="command_panel_buttons">
@@ -599,22 +661,22 @@
<div class="kanban_header">
<div class="block_header"><strong class="kanban-block__name">Зарегистрирована</strong><strong
class="kanban-block__number">12</strong><a href="#"
class="kanban-block__number">5</strong><a href="#"
class="add_task statusa1ca3366-c296-11ee-93e4-107b4419808b"><svg viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path d="M12 4V20M4 12H20" stroke="rgb(121, 121, 121)" stroke-width="2"
stroke-linecap="round"></path>
</svg></a></div>
<div class="block_header"><strong class="kanban-block__name">Ожидает ответа</strong><strong
class="kanban-block__number">1</strong></div>
class="kanban-block__number">4</strong></div>
<div class="block_header"><strong class="kanban-block__name">В процессе выполнения</strong><strong
class="kanban-block__number">1</strong></div>
class="kanban-block__number">2</strong></div>
<div class="block_header"><strong class="kanban-block__name">На тестировании</strong><strong
class="kanban-block__number">0</strong></div>
class="kanban-block__number">1</strong></div>
<div class="block_header"><strong class="kanban-block__name">К переносу в рабочую</strong><strong
class="kanban-block__number">0</strong></div>
class="kanban-block__number">1</strong></div>
<div class="block_header"><strong class="kanban-block__name">Готово</strong><strong
class="kanban-block__number">0</strong></div>
class="kanban-block__number">1</strong></div>
</div>
<div class="kanban_body">
<div class="kanban-block" id="a1ca3366-c296-11ee-93e4-107b4419808b" ondragover="allowDrop(event)">
@@ -629,55 +691,7 @@
class="changeStatus task27c345a8-042a-11f0-9507-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8e7227e2-c296-11ee-93e4-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc3c-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb(238,130,238);"></div><a
class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc3c">Задача
№4</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Первая задача первого эпика</span></div><button
class="changeStatus task6251cc3c-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8e7227e2-c296-11ee-93e4-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc3e-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb(238,130,238);"></div><a
class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc3e">Задача
№5</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Вторая задача первого эпика</span></div><button
class="changeStatus task6251cc3e-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8d9f5c04-ea3a-11ef-9500-107b4419808b user5127bf5c-9ae0-11ef-94b1-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc42-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb(204,255,204);"></div><a
class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc42">Задача
№7</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Первая задача второго эпика</span></div><button
class="changeStatus task6251cc42-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8d9f5c04-ea3a-11ef-9500-107b4419808b user5127bf5c-9ae0-11ef-94b1-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc43-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb(204,255,204);"></div><a
class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc43">Задача
№8</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Вторая задача второго эпика</span></div><button
class="changeStatus task6251cc43-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8d9f5c05-ea3a-11ef-9500-107b4419808b user0ce47597-de78-11ef-94fc-107b4419808b"
<div class="card project8d9f5c05-ea3a-11ef-9500-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc45-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
@@ -688,7 +702,7 @@
class="changeStatus task6251cc45-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8d9f5c05-ea3a-11ef-9500-107b4419808b user0ce47597-de78-11ef-94fc-107b4419808b"
<div class="card project8d9f5c05-ea3a-11ef-9500-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc49-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
@@ -699,43 +713,7 @@
class="changeStatus task6251cc49-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8e7227e2-c296-11ee-93e4-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc40-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb(238,130,238);"></div><a
class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc40">Задача
№6</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Третья задача первого эпика</span></div><button
class="changeStatus task6251cc40-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8e7227e2-c296-11ee-93e4-107b4419808b user0ce47597-de78-11ef-94fc-107b4419808b"
draggable="true" ondragstart="drag(event)" id="taskb5c689c0-f6d2-11ef-9503-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb(238,130,238);"></div><a
class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9503107b4419808b11eff6d2b5c689c0">Задача
№13</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Четвертая задача первого эпика</span></div><button
class="changeStatus taskb5c689c0-f6d2-11ef-9503-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8d9f5c04-ea3a-11ef-9500-107b4419808b user5127bf5c-9ae0-11ef-94b1-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc44-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb(204,255,204);"></div><a
class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc44">Задача
№9</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Третья задача второго эпика</span></div><button
class="changeStatus task6251cc44-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8d9f5c05-ea3a-11ef-9500-107b4419808b user0ce47597-de78-11ef-94fc-107b4419808b"
<div class="card project8d9f5c05-ea3a-11ef-9500-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc47-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
@@ -746,7 +724,7 @@
class="changeStatus task6251cc47-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8d9f5c05-ea3a-11ef-9500-107b4419808b user0ce47597-de78-11ef-94fc-107b4419808b"
<div class="card project8d9f5c05-ea3a-11ef-9500-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task27c345a9-042a-11f0-9507-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
@@ -759,11 +737,10 @@
</div>
</div>
<div class="kanban-block" id="a1ca3369-c296-11ee-93e4-107b4419808b" ondragover="allowDrop(event)">
<div class="card project8d9f5c04-ea3a-11ef-9500-107b4419808b user0ce47597-de78-11ef-94fc-107b4419808b"
<div class="card project8d9f5c04-ea3a-11ef-9500-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task26933748-db5e-11ef-94fc-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb(204,255,204);"></div><a
class="card__link"
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=94fc107b4419808b11efdb5e26933748">Задача
№2</a><img class="card__photo" alt="foto"></img>
</div>
@@ -771,13 +748,45 @@
class="changeStatus task26933748-db5e-11ef-94fc-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8d9f5c04-ea3a-11ef-9500-107b4419808b user5127bf5c-9ae0-11ef-94b1-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc42-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc42">Задача
№7</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Первая задача второго эпика</span></div><button
class="changeStatus task6251cc42-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8d9f5c04-ea3a-11ef-9500-107b4419808b user5127bf5c-9ae0-11ef-94b1-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc43-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc43">Задача
№8</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Вторая задача второго эпика</span></div><button
class="changeStatus task6251cc43-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8d9f5c04-ea3a-11ef-9500-107b4419808b user5127bf5c-9ae0-11ef-94b1-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc44-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc44">Задача
№9</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Третья задача второго эпика</span></div><button
class="changeStatus task6251cc44-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
</div>
<div class="kanban-block" id="a1ca3363-c296-11ee-93e4-107b4419808b" ondragover="allowDrop(event)">
<div class="card project8e7227e2-c296-11ee-93e4-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task8e7227e3-c296-11ee-93e4-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb(238,130,238);"></div><a
class="card__link"
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=93e4107b4419808b11eec2968e7227e3">Задача
№1</a><img class="card__photo" alt="foto"></img>
</div>
@@ -785,10 +794,57 @@
class="changeStatus task8e7227e3-c296-11ee-93e4-107b4419808b"
style="visibility: hidden;"></button>
</div>
<div class="card project8e7227e2-c296-11ee-93e4-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="taskb5c689c0-f6d2-11ef-9503-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9503107b4419808b11eff6d2b5c689c0">Задача
№13</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Четвертая задача первого эпика</span></div><button
class="changeStatus taskb5c689c0-f6d2-11ef-9503-107b4419808b"
style="visibility: hidden;"></button>
</div>
</div>
<div class="kanban-block" id="a1ca3368-c296-11ee-93e4-107b4419808b" ondragover="allowDrop(event)">
<div class="card project8e7227e2-c296-11ee-93e4-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc3e-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc3e">Задача
№5</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Вторая задача первого эпика</span></div><button
class="changeStatus task6251cc3e-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
</div>
<div class="kanban-block" id="a1ca3367-c296-11ee-93e4-107b4419808b" ondragover="allowDrop(event)">
<div class="card project8e7227e2-c296-11ee-93e4-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc40-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc40">Задача
№6</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Третья задача первого эпика</span></div><button
class="changeStatus task6251cc40-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
</div>
<div class="kanban-block" id="a1ca3364-c296-11ee-93e4-107b4419808b" ondragover="allowDrop(event)">
<div class="card project8e7227e2-c296-11ee-93e4-107b4419808b user8e7227e4-c296-11ee-93e4-107b4419808b"
draggable="true" ondragstart="drag(event)" id="task6251cc3c-f606-11ef-9500-107b4419808b">
<div class="card__header">
<div class="tag_task" style="background-color: rgb();"></div><a class="card__link"
href="e1c://filev/D/1С/_1C_BASE/Управление задачами#e1cib/data/Справочник.узЗадачи?ref=9500107b4419808b11eff6066251cc3c">Задача
№4</a><img class="card__photo" alt="foto"></img>
</div>
<div class="card__text"><span>Первая задача первого эпика</span></div><button
class="changeStatus task6251cc3c-f606-11ef-9500-107b4419808b"
style="visibility: hidden;"></button>
</div>
</div>
<div class="kanban-block" id="a1ca3368-c296-11ee-93e4-107b4419808b" ondragover="allowDrop(event)"></div>
<div class="kanban-block" id="a1ca3367-c296-11ee-93e4-107b4419808b" ondragover="allowDrop(event)"></div>
<div class="kanban-block" id="a1ca3364-c296-11ee-93e4-107b4419808b" ondragover="allowDrop(event)"></div>
</div>
</div>

View File

@@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
span {
font-size: 3rem;
}
.block {
display: flex;
flex-direction: column;
align-items: center;
}
button {
width: 20rem;
height: 5rem;
margin-top: 5rem;
cursor: pointer;
background-color: gold;
opacity: .8;
font-size: 2rem;
}
button:hover {
opacity: 1;
}
</style>
</head>
<body>
<div class="block">
<span>Не заполнены статусы задач в настройках доски</span>
<button class="settings">Настройки</button>
</div>
</body>
</html>