Диалог выбора папки на сервере

2 0

Нередко перед разработчиком стоит задача создания настройки для хранения пути к папкам на сервере, например, папкам для импорта / экспорта тел документов в систему / из системы. Безусловно, можно показать администратору системы простейший диалог с одним текстовым полем, в которое последний вставит путь, скопированный вручную, и сохранить результат диалога в таблицу с параметрами Sungero_Docflow_Params стандартным способом. Но такой подход не назовешь образчиком дружелюбного интерфейса на мой взгляд. К сожалению, показать полноценный диалог выбора папки невозможно из-за ограничений, налагаемых веб-браузером.

Столкнувшись с данной проблемой, я нашел свой немудреный подход, которым и спешу поделиться. Хотя в коде и используется запрещенный класс System.IO, но нанести какой-то вред файловой системе сервера, или дискредитировать какие-то данные таким образом, на мой взгляд, невозможно, ведь  производится всего лишь чтение имен папок на сервере (имена файлов в директории не отображаются). При этом учитываются права доступа к папкам. К тому же доступ к подобному функционалу обычно ограничивается средствами самого RX и предоставляется только участникам группы "Администраторы". Работу с нелегалом System.IO необходимо вынести в изолированную область.

Приведенный ниже код позволяет довольно удобно совершать навигацию по папкам сервера, начиная от выбора диска до самых нижних папок в иерархии, где вложенные папки уже отсутствуют. Кнопка «<<» (назад) поднимает выбор по иерархии выше в родительскую папку. При закрытии диалога по кнопке «Ок» выбранный путь сохраняется в таблице с параметрами. Сам диалог был реализован мной в функции обложки модуля в разделе "Настройки".

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


 

      var param = Sungero.Docflow.PublicFunctions.Module.Remote.GetDocflowParamsStringValue(Constants.Module.TimeSheetInputFolderPath);
      var dialog = Dialogs.CreateInputDialog("Папка экспорта Табелей учета рабочего времени");
      var drives = IsolatedFunctions.SystemIO.GetDrives().ToArray();
      dialog.Width = 500;
      var pathString = dialog.AddString(string.Empty, false);
      pathString.IsEnabled = false;
      pathString.Value = param;
      var folderPath = dialog.AddSelect(string.Empty, false);
      var back = dialog.Buttons.AddCustom("<<");
      dialog.Buttons.AddCancel();
      dialog.Buttons.AddOk();
      
      folderPath.SetOnValueChanged((x) => {pathString.Value =  x.NewValue;});
      
      dialog.SetOnRefresh((x) =>
                          {
                            if (string.IsNullOrEmpty(pathString.Value))
                              folderPath.From(drives);
                            else
                            {
                              // обработка исключения при отсутствии прав доступа к папке
                              try
                              {                                
                                folderPath.From(IsolatedFunctions.SystemIO.GetDirectories(pathString.Value).ToArray());
                              }
                              catch (Exception e)
                              {
                                x.AddError(e.Message);
                              }
                            }
                          }
                         );
      
      dialog.SetOnButtonClick((d) =>
                              {
                                if (d.Button == back)
                                {
                                  var lastSlashIndex = pathString.Value.LastIndexOf('\\');

                                  if (pathString.Value.Length == 3)
                                    pathString.Value = string.Empty;
                                  else if (lastSlashIndex == 2)
                                    pathString.Value =  pathString.Value.Substring(0, lastSlashIndex + 1);
                                  else
                                    pathString.Value =  pathString.Value.Substring(0, lastSlashIndex);

                                  d.CloseAfterExecute = false;
                                }
                                if (d.Button == DialogButtons.Ok)
                                {
                                  Sungero.Docflow.PublicFunctions.Module.InsertOrUpdateDocflowParam(Constants.Module.TimeSheetInputFolderPath, pathString.Value);
                                }
                              }
                             );
      
      dialog.Show();

В изолированной области модуля необходимо добавить две функции для работы с классом System.IO

  public class IsolatedFunctions
  {
    [Public]
    public static List<string> GetDrives()
    {
      return System.IO.DriveInfo.GetDrives().Select(d => d.Name).ToList();
    }
    
    [Public]
    public static List<string> GetDirectories(string path)
    {
      return System.IO.Directory.GetDirectories(path).ToList();
    }
  }

 

2
Авторизуйтесь, чтобы оценить материал.
Пока комментариев нет.

Авторизуйтесь, чтобы написать комментарий