Перем мЧистыйЗаголовокФормы;
Перем мИндикатор;

Функция СохраняемаяНастройкаФормы(выхНаименование, выхИменаСвойств) Экспорт 
	выхИменаСвойств = "Реквизит.Репозиторий, Реквизит.КаталогКэша";
	Возврат Неопределено;
КонецФункции

Процедура ПриОткрытии()
	ирКлиент.Форма_ПриОткрытииЛкс(ЭтаФорма);
	мЧистыйЗаголовокФормы = Заголовок;
	РепозиторийПриИзменении();
	ОбновитьЗаголовокФормы();
КонецПроцедуры

Процедура ПриЗакрытии()
	ирКлиент.Форма_ПриЗакрытииЛкс(ЭтаФорма);
КонецПроцедуры

Процедура КаталогКэшаНачалоВыбора(Элемент, СтандартнаяОбработка)
	ирКлиент.ПолеФайловогоКаталога_НачалоВыбораЛкс(Элемент, СтандартнаяОбработка);
КонецПроцедуры

Процедура ВнешнееСобытие(Источник, Событие, Данные) Экспорт
	ирКлиент.Форма_ВнешнееСобытиеЛкс(ЭтаФорма, Источник, Событие, Данные);
КонецПроцедуры

Процедура ТабличноеПолеПриПолученииДанных(Элемент, ОформленияСтрок) Экспорт
	ирКлиент.ТабличноеПолеПриПолученииДанныхЛкс(ЭтаФорма, Элемент, ОформленияСтрок);
КонецПроцедуры

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник) Экспорт
	ирКлиент.Форма_ОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник);
КонецПроцедуры

Процедура КлсКомандаНажатие(Кнопка) Экспорт
	ирКлиент.УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка);
КонецПроцедуры
         
Процедура КаталогКэшаОткрытие(Элемент, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	ЗапуститьПриложение(Элемент.Значение);
КонецПроцедуры

Процедура КаталогКэшаПриИзменении(Элемент)
	Заявки.Очистить();
	РепозиторийПриИзменении();
КонецПроцедуры

Процедура ОбновитьЗаголовокФормы() Экспорт  
	ЭтаФорма.Заголовок = мЧистыйЗаголовокФормы + ": " + Репозиторий;
	//ирКлиент.ФормаОбъекта_ОбновитьЗаголовокЛкс(ЭтаФорма, ПапкаГита);
КонецПроцедуры

Процедура ДействияФормыЗагрузить(Кнопка)
	Если ЭлементыФормы.ДействияФормы.Кнопки.Загрузить.Картинка = ирКэш.КартинкаПоИмениЛкс("ирОстановить") Тогда
		ОстановитьЗагрузку();
		Возврат;
	КонецЕсли;
	Если ПустаяСтрока(КаталогКэша) Тогда
		ирОбщий.СообщитьЛкс(НСтр("ru='Нужно указать каталог кэша'"));
		ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.КаталогКэша;
		Возврат;
	КонецЕсли;
	БазоваяСсылка = БазовыйАдресРепозитория(Репозиторий);
	СтруктураАдреса = ирОбщий.СтруктураURIЛкс(БазоваяСсылка);
	Запрос = Новый HTTPЗапрос(СтруктураАдреса.ПутьНаСервере);
	HTTPСоединение = Новый HTTPСоединение("api.github.com", 443, "", "",, Истина);
	Ответ = HTTPСоединение.Получить(Запрос);
	Если Ответ.КодСостояния <> 200 Тогда
		ВызватьИсключение "Ошибка HTTP: " + Ответ.КодСостояния + ". " + Ответ.ПолучитьТелоКакСтроку();
	КонецЕсли;
	ЧислоЗаявок = ирОбщий.ОбъектИзТекстаЖСОНЛкс(Ответ.ПолучитьТелоКакСтроку()).open_issues_count;
	мИндикатор = ирОбщий.ПолучитьИндикаторПроцессаЛкс(ЧислоЗаявок,,,,,,, Ложь);
	ЭлементыФормы.ДействияФормы.Кнопки.Загрузить.Картинка = ирКэш.КартинкаПоИмениЛкс("ирОстановить");
	ЗагрузитьПорцию();
КонецПроцедуры

Функция ЗаявкаОбразец() Экспорт
	Возврат "[{
	|  ""url"": ""https://api.github.com/repos/1C-Company/1c-edt-issues/issues/1875"",
	|  ""repository_url"": ""https://api.github.com/repos/1C-Company/1c-edt-issues"",
	|  ""labels_url"": ""https://api.github.com/repos/1C-Company/1c-edt-issues/issues/1875/labels{/name}"",
	|  ""comments_url"": ""https://api.github.com/repos/1C-Company/1c-edt-issues/issues/1875/comments"",
	|  ""events_url"": ""https://api.github.com/repos/1C-Company/1c-edt-issues/issues/1875/events"",
	|  ""html_url"": ""https://github.com/1C-Company/1c-edt-issues/issues/1875"",
	|  ""id"": 3380317330,
	|  ""node_id"": ""I_kwDOGKRgfs7Je4yS"",
	|  ""number"": 1875,
	|  ""title"": ""EDT теряет модули при экспорте в базу 1С"",
	|  ""user"": {
	|    ""login"": ""tormozit"",
	|    ""id"": 11896251,
	|    ""node_id"": ""MDQ6VXNlcjExODk2MjUx"",
	|    ""avatar_url"": ""https://avatars.githubusercontent.com/u/11896251?v=4"",
	|    ""gravatar_id"": """",
	|    ""url"": ""https://api.github.com/users/tormozit"",
	|    ""html_url"": ""https://github.com/tormozit"",
	|    ""followers_url"": ""https://api.github.com/users/tormozit/followers"",
	|    ""following_url"": ""https://api.github.com/users/tormozit/following{/other_user}"",
	|    ""gists_url"": ""https://api.github.com/users/tormozit/gists{/gist_id}"",
	|    ""starred_url"": ""https://api.github.com/users/tormozit/starred{/owner}{/repo}"",
	|    ""subscriptions_url"": ""https://api.github.com/users/tormozit/subscriptions"",
	|    ""organizations_url"": ""https://api.github.com/users/tormozit/orgs"",
	|    ""repos_url"": ""https://api.github.com/users/tormozit/repos"",
	|    ""events_url"": ""https://api.github.com/users/tormozit/events{/privacy}"",
	|    ""received_events_url"": ""https://api.github.com/users/tormozit/received_events"",
	|    ""type"": ""User"",
	|    ""user_view_type"": ""public"",
	|    ""site_admin"": false
	|  },
	|  ""labels"": [
	|    {
	|      ""id"": 3416797817,
	|      ""node_id"": ""LA_kwDOGKRgfs7LqDJ5"",
	|      ""url"": ""https://api.github.com/repos/1C-Company/1c-edt-issues/labels/bug"",
	|      ""name"": ""bug"",
	|      ""color"": ""d73a4a"",
	|      ""default"": true,
	|      ""description"": ""Something isn't working""
	|    }
	|  ],
	|  ""state"": ""open"",
	|  ""locked"": false,
	|  ""assignee"": null,
	|  ""assignees"": [],
	|  ""milestone"": null,
	|  ""comments"": 0,
	|  ""created_at"": ""2025-09-03T15:33:20Z"",
	|  ""updated_at"": ""2025-09-04T04:01:05Z"",
	|  ""closed_at"": null,
	|  ""author_association"": ""NONE"",
	|  ""active_lock_reason"": null,
	|  ""sub_issues_summary"": {
	|    ""total"": 0,
	|    ""completed"": 0,
	|    ""percent_completed"": 0
	|  },
	|  ""issue_dependencies_summary"": {
	|    ""blocked_by"": 0,
	|    ""total_blocked_by"": 0,
	|    ""blocking"": 0,
	|    ""total_blocking"": 0
	|  },
	|  ""body"": ""Куку"",
	|  ""closed_by"": null,
	|  ""reactions"": {
	|    ""url"": ""https://api.github.com/repos/1C-Company/1c-edt-issues/issues/1875/reactions"",
	|    ""total_count"": 1,
	|    ""+1"": 1,
	|    ""-1"": 0,
	|    ""laugh"": 0,
	|    ""hooray"": 0,
	|    ""confused"": 0,
	|    ""heart"": 0,
	|    ""rocket"": 0,
	|    ""eyes"": 0
	|  },
	|  ""timeline_url"": ""https://api.github.com/repos/1C-Company/1c-edt-issues/issues/1875/timeline"",
	|  ""performed_via_github_app"": null,
	|  ""state_reason"": null
	|}]";
КонецФункции

Процедура ЗагрузитьПорцию()
	ПрошлоСекунд = ТекущаяДата() - мИндикатор.ДатаНачалаПроцесса;
	ЭтаФорма.Заголовок = ирОбщий.ПредставлениеДлительностиЛкс(ПрошлоСекунд) + "-" + мЧистыйЗаголовокФормы;
	ЧислоЗаявокВПорции = 100;
	Курсор = Неопределено;
	БазоваяСсылка = БазовыйАдресРепозитория(Репозиторий);
	ПараметрыЗапроса = "?state=all&sort=updated&direction=asc&per_page=" + ЧислоЗаявокВПорции;
	Если ЗначениеЗаполнено(АктуальностьКэша) Тогда
		ПараметрыЗапроса = ПараметрыЗапроса + "&since=" + XMLСтрока(АктуальностьКэша);
	КонецЕсли;
	ПолныйАдрес = БазоваяСсылка + "/issues" + ПараметрыЗапроса;
	Если Курсор <> Неопределено Тогда
		ПолныйАдрес = ПолныйАдрес + "&after=" + Курсор;
	КонецЕсли;
	СтруктураАдреса = ирОбщий.СтруктураURIЛкс(ПолныйАдрес);
	Запрос = Новый HTTPЗапрос(СтруктураАдреса.ПутьНаСервере);
	HTTPСоединение = Новый HTTPСоединение("api.github.com", 443, "", "",, Истина);
	Ответ = HTTPСоединение.Получить(Запрос);
	Если Ответ.КодСостояния <> 200 Тогда
		ирОбщий.СообщитьЛкс("Ошибка HTTP: " + Ответ.КодСостояния + ". " + Ответ.ПолучитьТелоКакСтроку(), СтатусСообщения.Внимание);
		ПорцияЗаявок = Новый Массив;
	Иначе
		ТелоОтвета = Ответ.ПолучитьТелоКакСтроку(); // см. ЗаявкаОбразец
		ПорцияЗаявок = ирОбщий.ОбъектИзТекстаЖСОНЛкс(ТелоОтвета, Истина);
		ирОбщий.ОбработатьИндикаторЛкс(мИндикатор, мИндикатор.Счетчик + ПорцияЗаявок.Количество());
	КонецЕсли;
	Если ПорцияЗаявок.Количество() Тогда
		Для Каждого Заявка Из ПорцияЗаявок Цикл
			Номер = Заявка["number"];
			СтараяСтрока = Заявки.Найти(Номер, "Номер");
			Если СтараяСтрока <> Неопределено Тогда
				Заявки.Удалить(СтараяСтрока);
			КонецЕсли;
			СтрокаТЗ = Заявки.Вставить(0);
			СтрокаТЗ.Номер = Номер;
			СтрокаТЗ.Заголовок = Заявка["title"];
			СтрокаТЗ.Статус = Заявка["state"];
			СтрокаТЗ.ДатаСоздания = XMLЗначение(Тип("Дата"), Заявка["created_at"]);
			СтрокаТЗ.ДатаОбновления = XMLЗначение(Тип("Дата"), Заявка["updated_at"]);
			Если Заявка["closed_at"] <> Неопределено Тогда
				СтрокаТЗ.ДатаЗакрытия = XMLЗначение(Тип("Дата"), Заявка["closed_at"]);
			КонецЕсли;
			Если Заявка["user"] <> Неопределено Тогда
				СтрокаТЗ.Автор = Заявка["user"]["login"];
			КонецЕсли;
			Метки = "";
			Если Заявка["labels"] <> Неопределено Тогда
				Для Каждого Метка Из Заявка["labels"] Цикл
					Метки = Метки + ?(ПустаяСтрока(Метки), "", ", ") + Метка["name"];
				КонецЦикла;
			КонецЕсли;
			СтрокаТЗ.Метки = Метки;
			СтрокаТЗ.ЧислоКомментариев = Заявка["comments"];
			СтрокаТЗ.Адрес = Заявка["html_url"];
			Если Заявка["body"] <> Неопределено Тогда
				СтрокаТЗ.Описание = Заявка["body"];
			КонецЕсли;
		КонецЦикла;
		ЭтаФорма.АктуальностьКэша = СтрокаТЗ.ДатаОбновления;
		ЗаполнитьДанныеПоиска();
		ПодключитьОбработчикОжидания("ЗагрузитьПорцию", 0.5, Истина);
	Иначе
		ОстановитьЗагрузку();
	КонецЕсли;
КонецПроцедуры

Процедура ОстановитьЗагрузку() Экспорт
	ирОбщий.ОсвободитьИндикаторПроцессаЛкс(мИндикатор);
	мИндикатор = Неопределено;
	ОтключитьОбработчикОжидания("ЗагрузитьПорцию");
	ТаблицаЗаявок = Заявки.Выгрузить();
	ТаблицаЗаявок.Колонки.Удалить(ТаблицаЗаявок.Колонки.ДанныеПоиска1);
	ТаблицаЗаявок.Колонки.Удалить(ТаблицаЗаявок.Колонки.ДанныеПоиска2);
	ирОбщий.СохранитьЗначениеВФайлЛкс(ТаблицаЗаявок, ФайлКэша().ПолноеИмя, Истина);
	ЭлементыФормы.ДействияФормы.Кнопки.Загрузить.Картинка = Новый Картинка;
	ОбновитьЗаголовокФормы();
КонецПроцедуры

Функция БазовыйАдресРепозитория(Знач Репозиторий) Экспорт
	БазоваяСсылка = "https://api.github.com/repos/" + Репозиторий;
	Возврат БазоваяСсылка;
КонецФункции

Процедура ЗаявкиВыбор(Элемент, ВыбраннаяСтрока, Колонка, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	Если Колонка = Элемент.Колонки.Описание Тогда
		ирКлиент.ОткрытьТекстЛкс(ВыбраннаяСтрока.Описание, ВыбраннаяСтрока.Заголовок, "Markdown", Истина,,,,,, ЗаявкиСтрокаПоиска);
	Иначе
		ЗапуститьПриложение(ВыбраннаяСтрока.Адрес);
		//ирКлиент.ЯчейкаТабличногоПоляРасширенногоЗначения_ВыборЛкс(ЭтаФорма, Элемент, СтандартнаяОбработка);
	КонецЕсли;
КонецПроцедуры

Процедура РодителиПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
	ирКлиент.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
КонецПроцедуры

Процедура РепозиторийПриИзменении(Элемент = Неопределено)
	Если мИндикатор <> Неопределено Тогда
		ОстановитьЗагрузку();
	КонецЕсли;
	Элемент = ЭлементыФормы.Репозиторий;
	ирКлиент.ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(Элемент, ЭтаФорма);
	Заявки.Очистить();
	ФайлКэша = ФайлКэша();
	Если ФайлКэша.Существует() Тогда
		Заявки.Загрузить(ирОбщий.ЗагрузитьЗначениеИзФайлаЛкс(ФайлКэша.ПолноеИмя, Истина));
		ОбновитьАктуальностьКэша();
	Иначе
		ЭтаФорма.АктуальностьКэша = Неопределено;
	КонецЕсли;
	ЗаполнитьДанныеПоиска();
	ОбновитьЗаголовокФормы();
КонецПроцедуры

Процедура ОбновитьАктуальностьКэша() Экспорт
	ЭтаФорма.АктуальностьКэша = ирОбщий.ЛучшиеЭлементыКоллекцииЛкс(Заявки, "ДатаОбновления").ДатаОбновления;
КонецПроцедуры

Процедура ЗаполнитьДанныеПоиска() Экспорт
	Для Сч=1 По 2 Цикл
		ИмяКолонки = "ДанныеПоиска" + Сч;
		Для Каждого ЗаявкиЭлемент Из Заявки.НайтиСтроки(Новый Структура(ИмяКолонки, "")) Цикл
			ЗаявкиЭлемент[ИмяКолонки] = ЗаявкиЭлемент.Заголовок + " " + ЗаявкиЭлемент.Описание;
		КонецЦикла;
	КонецЦикла;
	ЭтаФорма.КоличествоЗаявок = Заявки.Количество();
КонецПроцедуры

Функция ФайлКэша() Экспорт
	ФайлКэша = Новый Файл(КаталогКэша + ирОбщий.РазделительПутиКФайлуЛкс() + ирОбщий.ЗаменитьНедопустимыеСимволыВИмениФайлаЛкс(Репозиторий) + ".ghi");
	Возврат ФайлКэша;
КонецФункции

Процедура ЗаявкиПриАктивизацииСтроки(Элемент)
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);
КонецПроцедуры

Процедура ЗаявкиПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки)
	ирКлиент.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
КонецПроцедуры

Процедура ФильтрПоПодстрокеАвтоПодборТекста(Элемент, Текст, ТекстАвтоПодбора, СтандартнаяОбработка)
	ирКлиент.ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(ЭтаФорма, Элемент, Текст);
	ПрименитьФильтрПоПодстрокеБезСохранения();
КонецПроцедуры

Процедура ФильтрПоПодстрокеНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);
КонецПроцедуры

Процедура ФильтрПоПодстрокеПриИзменении(Элемент)
	ирКлиент.ПолеВводаСИсториейВыбора_ПриИзмененииЛкс(Элемент, ЭтаФорма);
	ПрименитьФильтрПоПодстрокеБезСохранения();
КонецПроцедуры

Процедура ПрименитьФильтрПоПодстрокеБезСохранения()
	СловаПоиска = ирОбщий.РазделитьСтрокуПоискаНаСловаПоискаЛкс(ЗаявкиСтрокаПоиска);
	Если СловаПоиска.Количество() = 0 Тогда
		ФильтрПоПодстрокеОчистка();
		Возврат;
	КонецЕсли;
	Если СловаПоиска.Количество() > 2 Тогда
		ирОбщий.СообщитьЛкс("В фильтре можно использовать не более 2-х слов");
	КонецЕсли;
	ТабличноеПоле = ЭлементыФормы.Заявки;
	ЭлементОтбора1 = ТабличноеПоле.ОтборСтрок.ДанныеПоиска1;
	ЭлементОтбора1.ВидСравнения = ВидСравнения.Содержит;
	ЭлементОтбора1.Использование = Истина;
	ЭлементОтбора1.Значение = СловаПоиска[0];
	ЭлементОтбора2 = ТабличноеПоле.ОтборСтрок.ДанныеПоиска2;
	Если СловаПоиска.Количество() > 1 Тогда
		ЭлементОтбора2.ВидСравнения = ВидСравнения.Содержит;
		ЭлементОтбора2.Использование = Истина;
		ЭлементОтбора2.Значение = СловаПоиска[1];
	Иначе
		ЭлементОтбора2.Использование = Ложь;
	КонецЕсли;
КонецПроцедуры

Процедура ФильтрПоПодстрокеОчистка(Элемент = Неопределено, СтандартнаяОбработка = Ложь)
	СтандартнаяОбработка = Ложь;
	ОтборСтрок = ЭлементыФормы.Заявки.ОтборСтрок;
	ОтборСтрок.ДанныеПоиска1.Использование = Ложь;
	ОтборСтрок.ДанныеПоиска2.Использование = Ложь;
	ЭтаФорма.ЗаявкиСтрокаПоиска = "";
	//ПрименитьФильтрПоПодстрокеБезСохранения();
КонецПроцедуры

Процедура РепозиторийНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
	ирОбщий.ПолеВводаСИсториейВыбора_ОбновитьСписокЛкс(Элемент, ЭтаФорма);
КонецПроцедуры

ирКлиент.ИнициироватьФормуЛкс(ЭтаФорма, "Обработка.ирЗаявкиGithub.Форма.Форма");
