///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	УстановитьУсловноеОформление();

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

&НаСервере
Процедура ПриЗагрузкеДанныхИзНастроекНаСервере(Настройки)
	
	Если Параметры.ИспользованиеОтбор <> Неопределено Тогда
		ИспользованиеОтбор = Параметры.ИспользованиеОтбор;
	КонецЕсли;
	
	УстановитьОтбор();
	
КонецПроцедуры

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

КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура ИспользованиеОтборПриИзменении(Элемент)
	
	УстановитьОтбор();
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовТаблицыФормыСписок

&НаКлиенте
Процедура СписокПередНачаломДобавления(Элемент, Отказ, Копирование, Родитель, Группа, Параметр)
	
	Если Копирование Тогда 
		Отказ = Истина;
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура ОбновитьСПортала(Команда)
	
	МассивСсылок = Элементы.Список.ВыделенныеСтроки;
	
	Если МассивСсылок.Количество() = 0 Тогда 
		Возврат;
	КонецЕсли;
	
	Оповещение = Новый ОписаниеОповещения("ПослеОбновленияКомпонентыСПортала", ЭтотОбъект);
	ВнешниеКомпонентыСлужебныйКлиент.ОбновитьКомпонентыСПортала(Оповещение, МассивСсылок);
	
КонецПроцедуры

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

&НаКлиенте
Процедура СохранитьКак(Команда)
	
	МассивСсылок = Элементы.Список.ВыделенныеСтроки;
	
	Если МассивСсылок.Количество() = 0 Тогда 
		Возврат;
	КонецЕсли;
	
	ВнешниеКомпонентыСлужебныйКлиент.СохранитьКомпонентуВФайл(МассивСсылок);
	
КонецПроцедуры

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

&НаКлиенте
Процедура ДобавитьИзСервиса(Команда)
	
	МодульПолучениеВнешнихКомпонентКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ПолучениеВнешнихКомпонентКлиент");
	МодульПолучениеВнешнихКомпонентКлиент.ОбновитьВнешниеКомпоненты();

КонецПроцедуры

&НаКлиенте
Процедура УдалитьНеиспользуемые(Команда)
	
	УдалитьНеиспользуемыеКомпоненты();
	Элементы.Список.Обновить();
	
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьИзФайлов(Команда)
	
	ОчиститьСообщения();
	
	Оповещение = Новый ОписаниеОповещения("ДобавитьКомпонентыПослеПомещенияФайлов",
		ЭтотОбъект);
	
	ПараметрыЗагрузки = ФайловаяСистемаКлиент.ПараметрыЗагрузкиФайла();
	ПараметрыЗагрузки.Диалог.Заголовок = НСтр("ru = 'Выберите файл(ы) компонент'");
	ПараметрыЗагрузки.Диалог.Фильтр = НСтр("ru = 'Архив (*.zip)|*.zip'") + "|"
			+ СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Все файлы (%1)|%1'"), ПолучитьМаскуВсеФайлы());
	
	ПараметрыЗагрузки.Диалог.МножественныйВыбор = Истина;
	Элементы.СтраницыГруппа.ТекущаяСтраница = Элементы.ОжиданиеСтраница;
	ФайловаяСистемаКлиент.ЗагрузитьФайлы(Оповещение, ПараметрыЗагрузки);
	
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

// Продолжение процедуры ДобавитьИзКаталога.

&НаКлиенте
Процедура ДобавитьКомпонентыИзКаталогаПослеПодключенияРасширения(Результат, ПараметрыСоздания) Экспорт
	
	Если Результат <> Истина Тогда
		Возврат;
	КонецЕсли;
		
	Оповещение = Новый ОписаниеОповещения("ДобавитьКомпонентыПослеВыбораКаталога", ЭтотОбъект);
	Элементы.СтраницыГруппа.ТекущаяСтраница = Элементы.ОжиданиеСтраница;
	ФайловаяСистемаКлиент.ВыбратьКаталог(Оповещение, НСтр("ru = 'Выберите каталог с файлами компонент'"));
	
КонецПроцедуры

// Продолжение процедуры ДобавитьИзКаталога.

&НаКлиенте
Асинх Процедура ДобавитьКомпонентыПослеВыбораКаталога(ВыбранныйКаталог, ДополнительныеПараметры) Экспорт
	
	Если Не ЗначениеЗаполнено(ВыбранныйКаталог) Тогда
		Элементы.СтраницыГруппа.ТекущаяСтраница = Элементы.СписокСтраница;
		Возврат;
	КонецЕсли;
	
	Оповещение = Новый ОписаниеОповещения("ДобавитьКомпонентыПослеПомещенияФайлов",
		ЭтотОбъект);
	
	ОписаниеПередаваемыхФайлов = Новый Массив;
	
	Файлы = Ждать НайтиФайлыАсинх(ВыбранныйКаталог,"*.zip", Истина);

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

&НаКлиенте
Процедура ЗагрузитьКомпонентыПослеПредупрежденияБезопасности(Ответ, ПомещенныеФайлы) Экспорт
	
	Если Ответ <> "Продолжить" Тогда
		Элементы.СтраницыГруппа.ТекущаяСтраница = Элементы.СписокСтраница;
		Возврат;
	КонецЕсли;
	
	Если ПомещенныеФайлы.Количество() = 1 Тогда
		Элементы.СтраницыГруппа.ТекущаяСтраница = Элементы.СписокСтраница;
		Если ЭтоФайлСервиса(ПомещенныеФайлы[0].Хранение) Тогда
			МодульПолучениеВнешнихКомпонентКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ПолучениеВнешнихКомпонентКлиент");
			МодульПолучениеВнешнихКомпонентКлиент.ОбновитьВнешниеКомпоненты(Неопределено, ПомещенныеФайлы[0].ПолноеИмя);
			Возврат;
		КонецЕсли;
		ПараметрыФормы = Новый Структура;
		ПараметрыФормы.Вставить("ПомещенныйФайл", ПомещенныеФайлы[0]);
		ОткрытьФорму("Справочник.ВнешниеКомпоненты.ФормаОбъекта", ПараметрыФормы);
		Возврат;
	КонецЕсли;
	
	Результат = ЗагрузитьКомпонентыНаСервере(ПомещенныеФайлы);
	Элементы.СтраницыГруппа.ТекущаяСтраница = Элементы.СписокСтраница;
	
	Если Результат.Количество() > 0 Тогда
		ТекстовыйДокумент = Новый ТекстовыйДокумент;
		ТекстовыйДокумент.УстановитьТекст(СтрСоединить(Результат, Символы.ПС));
		ТекстовыйДокумент.ВставитьСтроку(0, НСтр(
			"ru = 'Не удалось загрузить компоненты, загружайте файлы по одному для заполнения свойств компонент вручную:'")
			+ Символы.ПС);
		ТекстовыйДокумент.Показать(НСтр("ru = 'Не удалось загрузить компоненты'"));
	КонецЕсли;
	
	Элементы.Список.Обновить();
	
КонецПроцедуры

&НаСервере
Функция ЗагрузитьКомпонентыНаСервере(Знач ПомещенныеФайлы)
	
	ОписаниеОшибок = Новый Массив;
	
	ИспользуемыеВнешниеКомпоненты = ВнешниеКомпонентыСлужебный.ИспользуемыеВнешниеКомпоненты();
	
	Для Каждого ФайлКомпоненты Из ПомещенныеФайлы Цикл

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

	КонецЦикла;
	
	Возврат ОписаниеОшибок;
	
КонецФункции

&НаКлиенте
Процедура ДобавитьКомпонентыПослеПомещенияФайлов(ПомещенныеФайлы, ДополнительныеПараметры) Экспорт
	
	Если Не ЗначениеЗаполнено(ПомещенныеФайлы) Тогда
		Элементы.СтраницыГруппа.ТекущаяСтраница = Элементы.СписокСтраница;
		Возврат;
	КонецЕсли;
	
	Оповещение = Новый ОписаниеОповещения("ЗагрузитьКомпонентыПослеПредупрежденияБезопасности", ЭтотОбъект, ПомещенныеФайлы);
	ПользователиСлужебныйКлиент.ПоказатьПредупреждениеБезопасности(Оповещение,
		ПользователиСлужебныйКлиентСервер.ВидыПредупрежденийБезопасности().ПередДобавлениемВнешнейКомпоненты);
	
КонецПроцедуры

&НаКлиенте
Процедура ПослеОбновленияКомпонентыСПортала(Результат, ДополнительныеПараметры) Экспорт
	
	Элементы.Список.Обновить();
	
КонецПроцедуры

/////////////////////////////////////////////////////////
// Представление данных на форме.

&НаСервере
Процедура УстановитьОтбор()
	
	ПараметрыОтбора = Новый Соответствие();
	ПараметрыОтбора.Вставить("ИспользованиеОтбор", ИспользованиеОтбор);
	УстановитьОтборСписка(Список, ПараметрыОтбора);
	
	Элементы.УдалитьНеиспользуемые.Видимость = ИспользованиеОтбор = 3 И ПравоДоступа("Редактирование", Метаданные.Справочники.ВнешниеКомпоненты);
	
КонецПроцедуры

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

&НаСервереБезКонтекста
Процедура УдалитьНеиспользуемыеКомпоненты()
	
	ВнешниеКомпонентыСлужебный.УдалитьНеиспользуемыеКомпоненты();
	
КонецПроцедуры

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

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

#КонецОбласти