GyverLibs/GyverPortal

Идеи/проблемы на обновление v3.3

GyverLibs opened this issue · 375 comments

CHANGELOG v3.3

  • Улучшена работа парсеров
  • Улучшены встроенные JS скрипты
  • Префикс макросов сокращён с GP_MAKE_ до M_, подсветка синтаксиса заменена на жирную
  • GP_EDGES заменён на GP_JUSTIFY, у SPAN выравнивание теперь тоже задаётся через GPalign
  • Добавлен url encode, в TEXT теперь можно вставлять текст со "опасными" символами (+#<>` итд)
  • Компоненту SWITCH теперь можно задавать цвет
  • click/update/copy Int теперь работает со всеми целочисленными типами (int, byte, long...)
  • Добавлен FORM_SEND и FORM_SEND_MINI - новый вариант отправки формы без редиректа
  • Добавлен RELOAD_CLICK для перезагрузки страницы по клику по указанным компонентам
  • Добавлены стили "отключенным" компонентам
  • Добавлен SLIDER_C, отправляющий значения в процессе изменения положения
  • Нажатие и отпускание кнопки теперь работает со смартфона (тачскрина)
  • Переделан стиль SPINNER, теперь он более компактный
  • Добавлены таблицы (TABLE_BEGIN, TABLE_END, TD, TR), макросы (GP_MAKE_TABLE, GP_MAKE_TD, GP_MAKE_TR, GP_ALS)
  • Ширину лога можно настраивать
  • Для TEXT добавлены атрибуты "паттерн" и максимальная длина ввода. Изменился последний аргумент в функции
  • Добавлен SUBMIT_MINI
  • Добавлен модуль реального локального времени (запрос с браузера), функции getSystemDate(), getSystemTime(), а также getUnix()
  • Улучшено ОТА обновление, можно шить через curl
  • Чуть оптимизирован механизм Update, также сам вырезает лишние пробелы в списке
  • FOLDER_UPLOAD() теперь работает на ESP32
  • Добавлен FILE_MANAGER() - вывод списка файлов из памяти с кнопками удалить, а также обработчики deleteFile(), deleteAuto(), deletePath()
  • Добавлены компоненты PLAIN() и BOLD() для вывода текста
  • Добавлен компонент SYSTEM_INFO() - вывод таблицы с системной информацией
  • Добавлен "глаз" для поля ввода пароля
  • Добавлен цвет GRAY_B
  • Блоки BLOCK... теперь создаются одним компонентом. У THIN блока добавилась настройка цвета

TODO

Осмыслить

  • ОТА через cmd/shell curl -vF firmware=@firmware.bin http://x.x.x.х/GP_OTAupload
  • Кастом чекбокс
.custom-checkbox>input{position:absolute;opacity:0;display:none;}
.custom-checkbox>span::before{content:'';border-radius:8px;padding:4px 12px;color:#bbb;background-color:#fff;border:1px solid #adb5bd;border-radius:0.25em;transition:.1s;cursor:pointer;}
.custom-checkbox>input:checked+span::before{border-color:#4CAF50;background-color:#4CAF50;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath d='m12.82,3l-6.6,6.6l-3,-3-1.9,1.9l5,5.00687l8.5,-8.5-1.9,-1.9z' fill='%23fff'/%3e%3c/svg%3e");}
.custom-checkbox>input:disabled+span::before{background-color:#e9ecef;}
.custom-checkbox>input:hover+span::before{filter:brightness(0.85);}

Когда выйдет

Думаю в начале ноября, не хватает времени доделать, проверить и релизнуть. А потом доку дописать

DAK85 commented

Подглядел в форуме монитор статистики...
Может сделаешь потом GP.STATS() который будет выводить монитор ресурсов МК.
https://community.alexgyver.ru/threads/wifi-lampa-budilnik-obsuzhdenie-proshivki-fieryledlamp-ot-alvikskor.7223/post-91880

Ребят, что-то не вижу компонента, с помощью которого можно вывести число?
LABEL не подходит, только текст.

LABEL не подходит, только текст

А String давно отменили?

Создал свою страницу от CustomOTA, назвал /ota
загружаю прошивку и после загрузки перекидывает на /ota_update и с темной темой

Приколы от Дениса подъехали)

так, попробуй в customOTA строки 72 и 76 заменить window.location.href='/ota_update' на location.reload() и отпишись о результатах

192.168.1.76/GP_OTAupload

вот собака..

Создал свою страницу от CustomOTA, назвал /ota загружаю прошивку и после загрузки перекидывает на /ota_update и с темной темой

надо страницу делать не в главном билдере а в билдере portal.OTA.attachUpdateBuild(OTAbuild); void OTAbuild(bool OTAend, const String& UpdateError) {}

а если делать череp просто кнопки OTA_FRIMWARE() OTA_FILESYSTEM() будет перекидывать на страницу /ota_update

и да если отак сделать плата не перезагрузиться и не обновиться

так, попробуй в customOTA строки 72 и 76 заменить window.location.href='/ota_update' на location.reload() и отпишись о результатах

Завтра попробую, что получится)

а поповоду темной темы есть настройка на светлую

#define GP_OTA_LIGHT

https://github.com/GyverLibs/GyverPortal/blob/main/src/CustomOTA.h
настройки 21-23 рядок и дэфайнить перед подключением портала

Приколы от Дениса подъехали)

С стандартним httpUpdateServer тоже перекидует на /ota_update

Это видел, но это уже чисто под себя сборка) После каждого обновления править конфиг вручную?

всм? в скэтч перед #include <GyverPortal.h> и всё

они там просто для справки

Ну, ок)

а в билдере portal.OTA.attachUpdateBuild(OTAbuild); void OTAbuild(bool OTAend, const String& UpdateError) {}

есть дєфолтна страница рядок 189, так что делай как она и будет удобно.

Я с 189 и начал изучать, в итоге дошел к тому, что получилось) Мне нужна только одна кнопка для обновления скетча.

Переделаю к следующему обновлению

DAK85 commented

Как идеи для рассмотрения....
Добавить возможность в jquery update по принципу GP.RELOAD, то есть обновлять только в том случае, если МК даст на это команду. Произошли изменения, обновляем, нет изменений, не обновляем. Позволит уменьшить нагрузку на мк и не делать лишних запросов.
Так же рассмотреть добавление в твой упдейт немного нишятков, а именно - нет кликов по элементам из списка лист, то обновляем по таймеру, если происходят события кликов по элементам из списка на обновление, то делаем ребут через 150 мс, а следующий ребут по интервалу пропускаем.

Может добавить меню? Себе сделал вот такое.

MenuBurger.mp4

Я не профи но даже у меня получилось. Так, как мне кажется, намного удобнее, меню всегда под рукой.

Вот код из custom, может кому то пригодится.

void GP_MENU_BURGER(const String& urls, const String& names) { String s; s += "<div class='conteiner'>\n"; s += "<div class='menu-burger'>\n"; s += "<span class='burger-menu_lines'></span>"; s += "</div>\n"; s +="<div class='navmenu'>"; s +="<ul>"; GP.SEND(s); s = ""; GP_parser n; GP_parser u; while (n.parse(names)) { u.parse(urls); s += F("<li "); if (_gp_uri->equals(u.str)) s += F("style='background:#4CAF50' "); s += F("onclick='location.href=\""); s += u.str; s += F("\";'>"); s += n.str; s += F("</li>\n"); } s += F("</ul></div></div>\n"); GP.SEND(s); }

void GP_BURGER_STYLE() { GP.SEND_P(PSTR("<style type='text/css'>.conteiner{position:absolute;display:flex;justify-content: end;max-width:inherit;width:100%;top:0;z-index:50;}\n" ".menu-burger{position:fixed;display:block;top:15px;width:36px;height:36px;border-radius:8px;background:#4CAF50;z-index:3;box-shadow:#3c4048 0px 0px 5px;}\n" ".menu-burger:before,.menu-burger:after,.menu-burger span{content:'';background-color:#fff;width:70%;position:absolute;height:2px;left:5px;}\n" ".menu-burger span{top:17px;transition:all 0.3s ease 0s;}\n" ".menu-burger:before{top:10px;transition:all 0.3s ease 0s;}\n" ".menu-burger:after{bottom:10px;transition:all 0.3s ease 0s;}\n" ".menu-burger.active span{transform: scale(0);transition:all 0.3s ease 0s;}\n" ".menu-burger.active:before{transform: rotate(45deg);top:17px;transition:all 0.3s ease 0s;}\n" ".menu-burger.active:after{transform: rotate(-45deg);bottom:17px;transition:all 0.3s ease 0s;}\n" ".navmenu{top:-100%;position:fixed;max-width:inherit;width:100%;height:100%;overflow:auto;background-color: #3c4048;z-index:2;transition:all 0.3s ease 0s;}\n" ".navmenu.active{top:0;}\n" ".navmenu>ul{list-style-type:none;color:white;font-size: 22px;padding: 20px;text-align: left;}\n" ".navmenu>ul>li{padding: 5px 5px;border-bottom: groove 1px #4CAF50;cursor:pointer;}body.lock{overflow:hidden;}" ".navmenu>ul>li:hover{background-color:#4caf505e;}</style>\n" )); }

void GP_BURGER_SCRIPT() { GP.SEND_P(PSTR("<script>\n" "let menuBtn = document.querySelector('.menu-burger');\n" "let menu = document.querySelector('.navmenu');\n" "let body = document.body;\n" "menuBtn.addEventListener('click', function(){menu.classList.toggle('active');menuBtn.classList.toggle('active');body.classList.toggle('lock');})\n" "</script>\n")); }

Ну а так в билдере собираю в самом начале.
GP_BURGER_STYLE(); GP_MENU_BURGER("/,/form,/button,/led,/menu5,/menu6,/menu7,/menu8,/menu9", "Домашняя,Форма,Кнопка,Лампочка,Меню 5,Меню 6,Меню 7,Меню 8,Меню 9"); GP_BURGER_SCRIPT();

офигеть, не знал что так можно) добавим

По сути, также можно сделать и виртуальную мультистраничность. Надо только добавить JS кода чтобы закрывать меню после клика по пункту меню.
Мне вообще думается что меню должно быть по дефолту, даже с пустой страницей. Еще портал должен быть адаптивным. Если открывать портал на компе, с большим разрешением, то ширина портала 700+ пикселей и слева меню без кнопки всегда доступное. Если разрешение мобильное, то показывать меню бургер.

это уже прям готовая контрольная панель получится) нужно пересматривать весь дизайн главного блока

это уже прям готовая контрольная панель получится) нужно пересматривать весь дизайн главного блока

Это да )

что то типа такого
image

Ну да) Только чтобы такое сверстать, на мой взгляд, нужен профи в дизайне. Мне такое не дано(

я вообще не знал что такое javascript и как оно работает до недавнего времени) попробую, сами блоки то уже готовы, считай надо внешний каркас доделать и всё

я вообще не знал что такое javascript и как оно работает до недавнего времени) попробую, сами блоки то уже готовы, считай надо внешний каркас доделать и всё

Просто отлично! А я свое меню бургер часов 10 собирал, у меня все куда то съезжало, падало, пропадало, все эти флексы, шмексы, ужас))) Тонны мануалов перечитал прежде чем хоть что то получилось. Опыт конечно отличный, css мощная штука оказывается)

Алекс, а я предупреждал) Что появятся новые специалисты и будет 4 версия портала)
Думаю надо внедрять как дополнения, если что-то возможно. Если ещё и делиться народ будет своими дополнениями, как во второй версии... Глядя на html, можно внести в дизайн какую-то табличность. Посмотри последние страницы форума.

Посмотри последние страницы форума.

не понял куда смотреть. Обсуждают как выровнять свой дизайн, в примерах это есть, но в документации пока нету

DAK85 commented

Никуда не смотри, я уже почти всё допилил, скоро сюда скину

мне страшно, перестань)))

Никуда не смотри, я уже почти всё допилил, скоро сюда скину

Я немного подготовил, чтобы не напугать)

я свое меню бургер часов 10 собирал

я нашёл простой вариант чисто на css) скорее всего его буду добавлять

я нашёл простой вариант чисто на css) скорее всего его буду добавлять

Ага, видел такое. Я больше мучался с Position:fixed, странная штука.

DAK85 commented

Давным давно, когда мамонты ещё не вымерли... многие люди для позиционирования элементов использовали таблицы. По сей день часто встречаются таблицы на страницах, только мы их не видим, поверх них тянут css.
для примера ниже картинка, верхний блок собран на таблице, нижний - через боксы. Можно заметить как кое-где не хватает кнопок, но при этом интерфейс никуда не уезжает....
tables

void GP_TABLE_BEGIN() {
        GP.SEND_P(PSTR("<table width=100% border=0>"));
}
void GP_TR() {
    GP.SEND_P(PSTR("<tr>"));
}
void GP_TD(const String& w = "", const String& al = "", const String& val = "", uint8_t cs = 1, uint8_t rs = 1) {
    String s;
    s += F("<td");
    if (w.length()>1){
        s += F(" width=");
        s += w;
    }
    if (al.length()>1){
        s += F(" align=");
        s += al;
    }
    if (val.length()>1){
        s += F(" valign=");
        s += val;
    }
    if (cs>1){
        s += F(" coolspan=");
        s += cs;
    }
    if (rs>1){
        s += F(" rowspan=");
        s += rs;
    }
    s += F(">");
    GP.SEND(s);
}
void GP_TABLE_END(){
    GP.SEND_P(PSTR("</table>"));
}

Я взял только самый минимум из таблиц, и надо понимать, что если это внедрять, то надо всё таки align пихать из GPAlign

DAK85 commented

На идею толкнула картинка с форума
https://community.alexgyver.ru/threads/gyverportal.6632/post-129436
изображение

именно это хотел добавить в следующей версии. А что даёт coolspan rowspan?

DAK85 commented

объединяет ячейки горизонтально и вертикально

На идею толкнула картинка с форума https://community.alexgyver.ru/threads/gyverportal.6632/post-129436 изображение

По идее, так как все мк про датчи, сенсоры и всякие метеостанции, то можно вообще сделать готовый компонент и в него передавать что выводим, само значение и в каких папугаях измеряется(температура, влажность, итд). Выводить это уже выравненой готовой строкой. Можно с бордером снизу для удобности чтения. И чтобы была возможность изменить цвет показаний, типа, холодно синий, жарко красный итд.

пихать из GPAlign

Не выйдет... GPAlign сделан для flex бокса, там другие значения. Я что нибудь придумаю

цвет показаний

в моей версии лейбл можно красить

цвет показаний

в моей версии лейбл можно красить

Это просто замечательно! )

@DAK85, не понял как работает таблица у тебя. Должно ведь быть

  <tr>
    <td>foo</td>
    <td>bar</td>
    <td>gay</td>
  </tr>
DAK85 commented

Пока надо пилить вики под то, что уже есть.... Это всё потом:) Если таблицы делать, то в принципе надо не забыть для таблицы сделать макрос. GP_MAKE_TABLE. Очень эффектно, если первый столбик объединяется по всем ячейкам таблицы и в него выводится текст через <br>
В
Х
О
Д
Ы
Теги <tr> и <td> можно не закрывать, это уже 100 лет назад браузеры делают сами

100 лет назад браузеры делают сами

я думаю суть всё таки в версии стандарта HTML

DAK85 commented

100 лет назад браузеры делают сами

я думаю суть всё таки в версии стандарта HTML

Все ныне существующие браузеры имеют алгоритм проверки на ошибки и уже многие давно перестали закрывать эти теги.

DAK85 commented

Есть где то список всех тегов, которые не обязательно закрывать, я с ним вчера знакомился, когда в голову пришла эта идея. и да, забыл... на TD можно зацепить событие клика

Вообще, я как то натыкался на верстку ява скриптом. Так вот там, html код зашит сразу в скрипт. С контроллера будут передаватся только названия и данные, все собирается в браузере клиента. Нагрузка на контроллер меньше, трафик меньше. Но это так, в порядке бреда) Это вообще новая библиотека получится, со всеми сопутствующими недостатками.

верстку ява скриптом

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

DAK85 commented

Надо гнать эту идею... Это осложнит возможность понимания кода, скорее всего будет куча глюков... Сейчас и так очень даже быстро всё собирается!

Надо гнать эту идею... Это осложнит возможность понимания кода, скорее всего будет куча глюков... Сейчас и так очень даже быстро всё собирается!

Когда на этой библиотеке вся верстка обкатается, компоненты и всякое добавится итд. То вполне себе, верстка явой, следующий шаг.

верстка явой, следующий шаг

без меня)

DAK85 commented

верстка явой, следующий шаг

без меня)

Согласен с обоими последними сообщениями. Это можно делать без тебя. Брать твой конструктор, каждый элемент облегчать, при этом писать скрипт. Я тоже думал об этом, но пока не вижу необходимости. У меня в зоне слабой вафли после перехода на файлы всё и так стало летать....

Пофиксить переадресацию customOTA + компоненты

А что именно нужно? Переадресацию легко исправить, я уже придумал как и с копмонентов на других страницах можна и на страници /ota_update, только будут разные компоненты.

только будут разные компоненты.

Хоча можно и с одними и теми же только + 1 пареметр.

Сделать?)

Так пробуй, там будет видно, что получится)

я уже, ток проверить нужно)

Здравствуйте,сори может я не совсем в тему влезаю, но и правда теги "<tr>" и "<td>" закрывающий не обязателен http://htmlbook.ru/html/tr
<td colspan="2"> Объединяет горизонтальные ячейки.
<td rowspan="2"> Объединяет вертикальные ячейки.

Безымянный
с помощью таблиц форматировал...

а як ти інформацію береш з іншого сайту?

https://openweathermap.org/api
https://developer.accuweather.com/
но там регаться надо а есть еще без регистрации
https://export.yandex.ru/bar/reginfo.xml?region=213
в моем скетче уже есть выбор первых двух, а с яндекса только научился получать, еще не успел разобрать на составляющие...

И еще центровку в теге <td> через атрибут "align" прописывать не обязательно...
GP.SPAN(F("м/с"), F("right")); срабатывает
если еще к GP.LABEL дописать выравнивание то наверное будет лучше

DAK85 commented

Если align указать в tr, то он применится во всех вложенных td, это надо просто предусмотреть изначально, чтобы потом не мучаться. Чаще будут использовать align, реже valign, ежё реже будут объединять ячейки. Я сделал как пример и обкатал. В моём варианте выше можно просто написать GP_TD() и будет просто td, можно взять css и натянуть hover на строки, что очень удобно с компа и совершенно вбестолку с телефона. Тема - идеи, я кинул, знаю что Алекс прежде чем такое влупить, ещё 20 раз продумает и сделает ещё круче. Выравнивание в td лучше оставить, иначе теряется вся тема.

Добрый вечер т.к. теперь тема может хранится в отдельном файле в файловой системе есп, к ней можно обращаться через
GP.THEME_FILE(FPSTR(theme_list[cfg2.theme]));
а вот с цветом такая фишка не срабатывает...

а вот с цветом такая фишка не срабатывает...

Как передавать цвет указано в документации

да я понял как передавать просто хотел не PSTR("#rrggbb") а передавать список Ваших готовых цветов...

и еще у элемента GP.SWITCH нельзя поменять цвет?

список Ваших готовых цветов

Пожалуйста, можно сделать список указателей и передавать из него

у элемента GP.SWITCH нельзя поменять цвет?

Нельзя и не планируется

Добрый вечер, насчет нельзя... Все таки можно если после добавления темы добавить строку
GP.SEND(String("<style type='text/css'>\n#blockBack input:checked+.slider{background-color:") + FPSTR(colour_list[cfg2.colour]) + F("}\ninput:checked+.slider{background-color:") + FPSTR(colour_list[cfg2.colour]) + F("}\n</style>\n"));
и еще ранее писали что не все элементы красиво отображаются на фаерфокс, мне кажется что может помочь статья
https://habr.com/ru/post/420539/
и как минимум в стили добавить строку: body {-webkit-tap-highlight-color:transparent;}
убирает синее подсвечивание при клике на девайсах, на телефонах при взаимодействиях убирает подсвечивание....

Это сменит цвет всех свитчей на странице. Я уже придумал решение для индивидуальной установки цвета

Круто, буду ждать... Спасибо...
Вроде собрал форму для настройки дизайна без перепрошивки...
Было бы неплохо если что-то подобное появится в примерах

можно ли доработать инструмент copyInt(имя, int& t); чтоб получать в переменную типа byte?

можно сделать copyByte =)

да, я сделаю тогда template <typename T> bool copyInt(const String& name, T& val). Тогба можно будет пихать туда любые целочисленные int long byte int8_t

Спасибо

Не уверен что по теме, но похоже выявил баг.
Если имя формы (/form1) отличается от адреса страницы(192.168.4.1/page), то по нажатию на submit происходит редирект на имя формы (192.168.4.1/form1).
Как по мне так быть не должно.
Или я что то не так делаю....

Как по мне так быть не должно

У html другое мнение на этот счёт, сабмит отправляет на указанный урл. Читаем документацию, раздел многостраничность

Juri4 commented

Для GP.NUMBER пригодился бы ограничитель диапазона значений.
тем долее в большинстве случаев этот диапазон заранее известен.

DAK85 commented

Для GP.NUMBER пригодился бы ограничитель диапазона значений.

Для заранее известных есть спиннер. А тут проще в актион ловить значение и если оно выходит за нужные интервалы, то присваивается крайние значения.

DAK85 commented

Не уверен что по теме, но похоже выявил баг.

Если есть желание на одной странице использовать несколько форм, то можете воспользоваться полем gp.hidden. сперва проверяете что с формы был субмит, потом проверяете значение хидден и потом уже на основе этого значения выбираем нужный алгоритм.

Так же этот документированный баг полезен, когда Вам после отправки данных формы надо сменить страницу.

Кстати можно переделать механизм формы на js. Кнопка станет просто кнопкой, при клике на которую js соберёт запрос с именами и значениями, отправит его на есп, а потом просто перезагрузит страницу. Это избавит от всех костылей с урлами и проблем тех кто не читал доку до конца

DAK85 commented

Не не не надо! Это можно как нить отдельно сделать. Пусть субмит будет! Можно отправлять данные формы без ребута, это понятно, но тут то как раз это больше фишка чем недостаток. Я в при работе в php зачастую так и делаю, обновляю данные в массиве session при изменении элементов формы, при клике на кнопку сохранить просто передаю команду на сохранения ранее записанных данных из массива session в базу данных. Есть 1000 подходов, но иногда лучше иметь субмит с возможностью ребута и перекидыванию на новую страницу. А так то у тебя все элементы при изменении можно отловить через клик, кроме парочки.. хотел предложить, чтобы при потери фокуса текст и нумьер отправляли клик, как сделано с чеком

DAK85 commented

То есть когда уходишь с текстового поля должен улетать клик с введённым значением...

Не не не надо!

Почему? Не увидел причин

иногда лучше иметь субмит с возможностью ребута и перекидыванию на новую страницу

Зачем? Вот это то как раз и нелогично для обывателя и приводит к изобретению твоих костылей с велосипедами и хидденами

при потери фокуса текст и нумьер отправляли клик, как сделано с чеком

У меня так не сделано, по крайней мере умышленно)

Juri4 commented

Для заранее известных есть спиннер. А тут проще в актион ловить значение и если оно выходит за нужные интервалы, то присваивается крайние значения.

если в актион + дополнительно еще обновление страницы придется делать ,
спиннер немного странный компонент имеет стрелки вверх-вниз и плюс-минус одновременно (В браузерах компьютеров).
кнопки плюс-минус сьехавшие немного в низ и в целом он получается огромным, в принципе если была-бы возможность отключать боковые кнопки было- бы здорово

В браузерах компьютеров

библиотека тестировалась на Chrome, десктоп и мобильный. Как выглядит спиннер можно посмотреть на скриншоте на главной странице репозитория

Juri4 commented

Опс разные браузеры не проверил - В мозилле смотрел

Вот как раз на мозилле скорее всего будут проблемы) может мозилловоды починят и сделают PR

Некоторые элементы могут некрасиво отображаться на Firefox, т.к. сделаны под Chrome, Safari, Edge, Opera

DAK85 commented

По поводу субмит... Добавь кнопку, которая делает sendform this... Но субмит не убирай, просто новым компонентом... Плюс с возможностью обновления страницы после клика, кому надо, тот включит, кому не надо, тому не надо..

sendform это что?

субмит не убирай, просто новым компонентом...

почему? Что его держит? Одни проблемы ведь

DAK85 commented

Ну есть функция form.submit, я по привычке просто всегда создаю на Яве функцию sendform, которая как раз и делает такие штуки, как form.submit. на сколько помню это не вызывает ребута страницы. По поводу проблем .. нет никаких проблем, я их не вижу, даже сейчас не вижу, это вполне нормальный алгоритм работы, у которого есть свои плюсы и минусы. Можно сделать допустим две кнопки, одна - применить, другая ok, вот ок будет применять и переходить в другой пункт меню, а применить может просто сохранить введёные данные с формы. Либо делать такую кнопку, которая сможет после передачи данных перекидывать на другую страницу, вот это было бы круче просто кнопки вместо субмита

а в каком сценарии после нажатия субмита нужен редирект на другой урл? Это ведь запутанно в рамках портала

если была-бы возможность отключать боковые кнопки было- бы здорово

добавлю компактный вариант в следующем обновлении