Многооконное веб приложение — решение для перегруженных интерфейсов
- воскресенье, 26 ноября 2023 г. в 00:00:14
В данной статье будет рассмотрено возможное решение для разгрузки интерфейсов веб приложений – создание приложения с возможностью выноса части функционала в дополнительные окна, или же просто многооконное приложение.
Основа стека React + Redux.
Встречалось ли вам браузерное приложение с чересчур нагруженным интерфейсом, в котором боковые панели с настройками или данными перекрывают основное окно?
Мне практически нет, но это не значит, что их не существует.
Устроившись на новую работу мне повезло попасть на проект, в котором столкнулся с данной ситуацией. Приложение было наполнено множеством дополнительных панелей с разного рода информацией и кнопками. И всё это было рассчитано на большой экран и эргономично спроектировано, однако видя это на своём более-менее стандартном экране я ощущал дискомфорт.
Естественно, можно было бы забить, ведь заказчик будет пользоваться приложением только на огромных мониторах, но мне всё же ближе система из нескольких обычных мониторов.
Скорее всего, на моё видение данного вопроса повлияло то, что я пришёл во фронтенд из инженерной области, где использовал программы с нагруженным интерфейсом, которые удобно разделялись на разные окна. Зачастую в процессе работы одна программа занимала 2 полных монитора.
В результате мысль о разделении веб приложения на несколько окон засела в голове, сопротивлялся я ей совсем не долго и быстро полез изучать данный вопрос. Как и было очевидно никому данный функционал особо не нужен, никто так не делает и описание готового решения я не нашёл. Но подобрав всего пару инструментов достичь цели оказалось легко.
Решение подбиралось для популярного стека React + Redux.
Потребовалось дополнительно установить React Router и redux state sync
В качестве примера используем написанное в образовательных целях классическое todo. Да, интерфейс явно не перегружен, но показывать на чем-то надо.
Идея максимально простая:
1. Разрабатываем приложение.
2. Осознаем, что есть панель, которая мешает основному контенту и было бы круто дать возможность пользователю вынести её в отдельное окно.
3. С помощью React Router делаем дополнительную страницу, которая содержит тот самый компонент, который мы хотим вынести в отдельное окно. В коде ниже это страница по пути "/settings".
function App() {
const mainState = useTypedSelector(state => state.main);
return (
<ThemeProvider theme={mainState.theme === 'light' ? lightTheme : darkTheme}>
<BrowserRouter>
<Routes>
<Route path="/" element={
<AppContainer>
<TodoContainer>
<Header />
<Main />
<Footer />
</TodoContainer>
</AppContainer>
} />
<Route path="settings" element={
<TodoFooter />
} />
</Routes>
</BrowserRouter>
</ThemeProvider >
);
}
4. Далее делаем кнопку, которая по нажатию открывает новое окно с вынесенным компонентом.
* Приложение с использованием styled‑components, ButtonOpenSettings просто стилизованный button
<ButtonOpenSettings
onClick={() => {
const params = 'scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no,width=500,height=60,left=100,top=100';
open('/settings', 'test', params);
}}
>Открыть настройки</ButtonOpenSettings>
5. Для синхронизации состояния redux между вкладками подключаем Middleware readux state sync
https://www.npmjs.com/package/redux-state-sync
6. Вот и всё, теперь у пользователя есть возможность вынести часть функционала приложения в отдельное окно.
Приложение можно посмотреть тут - https://todo-app-liart-rho-37.vercel.app/
Репозиторий - https://github.com/GragertVD/todo-app/tree/master
7. Было бы правильнее ещё добавить состояние открытого окна в state, чтобы скрывать настройки в основном окне, дабы избежать дублирования кнопок и действительно разгрузить интерфейс основного окна, но я оставил так, чтобы лучше наблюдать синхронное изменение состояния.
P.S.
Из явных недостатков хочется отметить то, что я ещё не нашел способ сделать открытое окно браузера постоянно на переднем плане относительно всех остальных окон браузера.
Пишу с осознанием того, что рассмотренный метод достаточно специфичен и мало кому пригодится. Но я верю, что в определенных условиях это может быть прекрасным решением.
Да и просто хотел поделиться интересной идеей. Всем спасибо за внимание.