mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
acccount tabs working + enhance select settings
* retrieve and update old tab logic to make account page work * update tab select settings script : now dropdown btn handle space and filter settings too *enhance tabs style
This commit is contained in:
parent
2266299c8a
commit
9573d8b458
9 changed files with 131 additions and 81 deletions
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,4 @@
|
|||
import { TabsSelect, Popover } from "./utils/settings.js";
|
||||
import { Tabs, Popover } from "./utils/settings.js";
|
||||
|
||||
class SubmitAccount {
|
||||
constructor() {
|
||||
|
|
@ -130,6 +130,6 @@ class SwitchTabForm {
|
|||
|
||||
const setPWBtn = new PwBtn();
|
||||
const setSubmit = new SubmitAccount();
|
||||
const setTabsSelect = new TabsSelect();
|
||||
const setTabs = new Tabs();
|
||||
const setPopover = new Popover();
|
||||
const setSwitchTabForm = new SwitchTabForm();
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ class TabsSelect {
|
|||
//get needed data
|
||||
const tab = e.target.closest("button");
|
||||
const tabAtt = tab.getAttribute("data-tab-select-handler");
|
||||
const text = tab.textContent;
|
||||
// change style
|
||||
this.resetTabsStyle();
|
||||
this.highlightClicked(tabAtt);
|
||||
|
|
@ -69,7 +70,7 @@ class TabsSelect {
|
|||
this.hideAllSettings();
|
||||
this.showSettingClicked(tabAtt);
|
||||
//close dropdown and change btn textcontent on mobile
|
||||
this.setDropBtnText(tabAtt);
|
||||
this.setDropBtnText(tabAtt, text);
|
||||
this.closeDropdown();
|
||||
}
|
||||
} catch (e) {}
|
||||
|
|
@ -117,11 +118,12 @@ class TabsSelect {
|
|||
plugin.classList.remove("hidden");
|
||||
}
|
||||
|
||||
setDropBtnText(tabAtt) {
|
||||
setDropBtnText(tabAtt, text) {
|
||||
const dropBtn = this.tabContainer.querySelector(
|
||||
"[data-tab-select-dropdown-btn]",
|
||||
);
|
||||
dropBtn.querySelector("span").textContent = tabAtt;
|
||||
dropBtn.setAttribute("data-tab-id", tabAtt);
|
||||
dropBtn.querySelector("span").textContent = text;
|
||||
}
|
||||
|
||||
closeDropdown() {
|
||||
|
|
@ -238,6 +240,9 @@ class FilterSettings {
|
|||
|
||||
// case no tab match
|
||||
if (isAllHidden) {
|
||||
this.tabContainer
|
||||
.querySelector("[data-tab-select-dropdown-btn] span")
|
||||
.setAttribute("data-tab-id", "no-match");
|
||||
return (this.tabContainer.querySelector(
|
||||
"[data-tab-select-dropdown-btn] span",
|
||||
).textContent = "No match");
|
||||
|
|
@ -247,10 +252,11 @@ class FilterSettings {
|
|||
const currTabEl = this.tabContainer.querySelector(
|
||||
"[data-tab-select-dropdown-btn] span",
|
||||
);
|
||||
const currTabName = currTabEl.textContent.toLowerCase().trim();
|
||||
|
||||
const currTabName = currTabEl.getAttribute("data-tab-id");
|
||||
|
||||
// case previously no match
|
||||
if (currTabName.toLowerCase() === "no match") {
|
||||
if (currTabName === "no-match") {
|
||||
return firstNotHiddenEl.click();
|
||||
}
|
||||
|
||||
|
|
@ -295,6 +301,57 @@ class FilterSettings {
|
|||
}
|
||||
}
|
||||
|
||||
class Tabs {
|
||||
constructor() {
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener("click", (e) => {
|
||||
try {
|
||||
if (e.target.closest("button").hasAttribute("data-tab-handler")) {
|
||||
//get needed data
|
||||
const tab = e.target.closest("button");
|
||||
const tabAtt = tab.getAttribute("data-tab-handler");
|
||||
const container = tab.closest("div[data-service-content]");
|
||||
// change style
|
||||
this.resetTabsStyle(container);
|
||||
this.highlightClicked(container, tabAtt);
|
||||
this.hideAllSettings(container);
|
||||
this.showSettingClicked(container, tabAtt);
|
||||
}
|
||||
} catch (err) {}
|
||||
});
|
||||
}
|
||||
|
||||
resetTabsStyle(container) {
|
||||
//reset desktop style
|
||||
const tabsEk = container.querySelectorAll("button[data-tab-handler]");
|
||||
tabsEk.forEach((tab) => {
|
||||
tab.classList.remove("active");
|
||||
});
|
||||
}
|
||||
|
||||
highlightClicked(container, tabAtt) {
|
||||
//desktop case
|
||||
const tab = container.querySelector(`button[data-tab-handler='${tabAtt}']`);
|
||||
tab.classList.add("active");
|
||||
}
|
||||
|
||||
hideAllSettings(container) {
|
||||
const tabsContent = container.querySelectorAll("[data-tab-item]");
|
||||
|
||||
tabsContent.forEach((tabContent) => {
|
||||
tabContent.classList.add("hidden");
|
||||
});
|
||||
}
|
||||
|
||||
showSettingClicked(container, tabAtt) {
|
||||
const tabContent = container.querySelector(`[data-tab-item='${tabAtt}']`);
|
||||
tabContent.classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
class CheckNoMatchFilter {
|
||||
constructor(
|
||||
input,
|
||||
|
|
@ -361,4 +418,11 @@ class CheckNoMatchFilter {
|
|||
}
|
||||
}
|
||||
|
||||
export { Popover, TabsSelect, FormatValue, FilterSettings, CheckNoMatchFilter };
|
||||
export {
|
||||
Popover,
|
||||
Tabs,
|
||||
TabsSelect,
|
||||
FormatValue,
|
||||
FilterSettings,
|
||||
CheckNoMatchFilter,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -106,6 +106,26 @@
|
|||
/*---------------SETTINGS_TABS-----------------*/
|
||||
/*---------------------------------------------*/
|
||||
|
||||
.active.tabs-tab-btn {
|
||||
@apply dark:bg-gray-700 dark:hover:bg-gray-700 bg-gray-200 hover:bg-gray-200;
|
||||
}
|
||||
|
||||
.tabs-tab-btn {
|
||||
@apply border-primary dark:hover:bg-slate-800 dark:border-slate-600 dark:bg-slate-700 border my-1 relative px-3 py-3 font-bold text-center uppercase align-middle transition-all rounded-none cursor-pointer bg-white hover:bg-gray-100 leading-normal text-sm ease-in tracking-tight-rem shadow-xs hover:shadow-md;
|
||||
}
|
||||
|
||||
.tabs-name {
|
||||
@apply text-primary transition duration-300 ease-in-out pl-3 pr-2 dark:text-gray-100;
|
||||
}
|
||||
|
||||
.tabs-popover-container {
|
||||
@apply top-[60px] min-w-[150px] dark:brightness-90 bg-blue-500 transition z-50 rounded-md p-3 left-0 absolute;
|
||||
}
|
||||
|
||||
.tabs-popover-text {
|
||||
@apply font-bold text-sm text-white m-0;
|
||||
}
|
||||
|
||||
.settings-tabs-select-btn {
|
||||
@apply dark:hover:brightness-95 dark:border-slate-600 dark:bg-slate-700 border-primary border w-full flex items-center justify-between rounded-lg hover:-translate-y-px my-1 px-4 py-2 md:px-6 md:py-3 font-bold text-center uppercase align-middle transition-all cursor-pointer bg-white hover:bg-gray-50 leading-normal text-sm ease-in tracking-tight-rem shadow-xs hover:shadow-md;
|
||||
}
|
||||
|
|
|
|||
100
src/ui/templates/account.html
vendored
100
src/ui/templates/account.html
vendored
|
|
@ -7,94 +7,60 @@
|
|||
{
|
||||
"name": "Global",
|
||||
"id": "global",
|
||||
"popover": "Global informations"
|
||||
"description": "Global informations"
|
||||
},
|
||||
{
|
||||
"name": "Username",
|
||||
"id": "username",
|
||||
"popover": "Edit your username"
|
||||
"description": "Edit your username"
|
||||
},
|
||||
{
|
||||
"name": "Password",
|
||||
"id": "password",
|
||||
"popover": "Update your password"
|
||||
"description": "Update your password"
|
||||
},
|
||||
{
|
||||
"name": "TOTP",
|
||||
"id": "totp",
|
||||
"popover": "Enabled / Disabled TOTP"
|
||||
"description": "Enabled / Disabled TOTP"
|
||||
}
|
||||
] %}
|
||||
<!-- desktop tabs -->
|
||||
<div role="tablist"
|
||||
data-account-tabs-desktop
|
||||
class="hidden md:block col-span-12 mb-4 mx-2">
|
||||
<!-- tabs -->
|
||||
{% for tab in tabs %}
|
||||
<button role="tab"
|
||||
data-tab-handler="{{ tab['id'] }}"
|
||||
class="{% if loop.first %} active {% endif %} settings-tabs-tab-btn">
|
||||
<span class="w-full flex justify-between items-center">
|
||||
<!-- text and icon -->
|
||||
<span class="settings-tabs-name">{{ tab['name'] }}</span>
|
||||
<svg data-popover-btn="{{ tab['id'] }}"
|
||||
class="fill-blue-500 h-5 w-5 mr-2 hover:brightness-95"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144c-17.7 0-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32s-14.3 32-32 32z" />
|
||||
</svg>
|
||||
<!-- end text and icon -->
|
||||
<!-- popover -->
|
||||
<span data-popover-content="{{ tab['id'] }}"
|
||||
class="settings-tabs-popover-container hidden">
|
||||
<span class="settings-tabs-popover-text">{{ tab['popover'] }}</span>
|
||||
</span>
|
||||
<!-- end popover -->
|
||||
</span>
|
||||
</button>
|
||||
{% endfor %}
|
||||
<!--end tabs-->
|
||||
</div>
|
||||
<!-- end desktop tabs -->
|
||||
<!-- mobile tabs -->
|
||||
<div class="md:hidden relative col-span-12 mb-4 mt-2 mx-2">
|
||||
<button data-tab-dropdown-btn
|
||||
aria-controls="tab-dropdown-mobile"
|
||||
class="settings-tabs-mobile-btn">
|
||||
<span aria-description="current tab" class="settings-tabs-mobile-btn-text">{{ tabs[0]['name'] }}</span>
|
||||
<!-- chevron -->
|
||||
<svg class="transition-transform h-4 w-4 fill-primary dark:fill-gray-300"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" />
|
||||
</svg>
|
||||
<!-- end chevron -->
|
||||
</button>
|
||||
<!-- dropdown-->
|
||||
<div id="tab-dropdown-mobile"
|
||||
role="listbox"
|
||||
data-tab-dropdown
|
||||
class="hidden z-100 absolute flex-col w-full overflow-hidden overflow-y-auto max-h-90">
|
||||
<div data-account-tabs class="col-span-12 grid grid-cols-12">
|
||||
<div role="tablist" data-account-tabs class="block col-span-12 mb-4">
|
||||
<!-- tabs -->
|
||||
{% for tab in tabs %}
|
||||
<button role="option"
|
||||
data-tab-handler-mobile="{{ tab['id'] }}"
|
||||
data-select="{% if loop.first %}true{% else %}false{% endif %}"
|
||||
id="edit-account-{{ tab['id'] }}-tab"
|
||||
class="{% if loop.first %} active first {% endif %} {% if loop.last %}last{% endif %} settings-tabs-mobile-dropdown-btn">
|
||||
{{ tab['name'] }}
|
||||
</button>
|
||||
<button role="tab"
|
||||
data-tab-handler="{{ tab['id'] }}"
|
||||
class="{% if loop.first %}active{% endif %} tabs-tab-btn">
|
||||
<span class="w-full flex justify-between items-center">
|
||||
<!-- text and icon -->
|
||||
<span class="tabs-name">{{ tab['name'] }}</span>
|
||||
<svg data-popover-btn="{{ tab['name'] }}"
|
||||
class=" fill-blue-500 h-5 w-5 mr-2 hover:brightness-95"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path d="M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-144c-17.7 0-32-14.3-32-32s14.3-32 32-32s32 14.3 32 32s-14.3 32-32 32z" />
|
||||
</svg>
|
||||
<!-- end text and icon -->
|
||||
<!-- popover -->
|
||||
<span data-popover-content="{{ tab['name'] }}"
|
||||
class="tabs-popover-container hidden">
|
||||
<span class="tabs-popover-text">{{ tab['description'] }}</span>
|
||||
</span>
|
||||
<!-- end popover -->
|
||||
</span>
|
||||
</button>
|
||||
{% endfor %}
|
||||
<!--end tabs-->
|
||||
</div>
|
||||
<!-- end dropdown-->
|
||||
</div>
|
||||
<!-- end mobile tabs -->
|
||||
{% set global_info = {
|
||||
"message" : "You are using pro version" if is_pro_version and pro_status else "Pro version is expired" if is_pro_version and not pro_status else "You are using free version",
|
||||
"link_message" : "Upgrade to pro" if not is_pro_version else "Renew my license" if is_pro_version and not pro_status else "",
|
||||
"icon" : "pro" if is_pro_version and pro_status else "free"
|
||||
}
|
||||
%}
|
||||
<div data-plugin-item="global"
|
||||
<div data-tab-item="global"
|
||||
class="grid grid-cols-12 w-full justify-items-center">
|
||||
<div class="col-span-12">
|
||||
<h5 class="text-xl my-1 text-center transition duration-300 ease-in-out font-bold m-0 mb-4 dark:text-gray-200">
|
||||
|
|
@ -158,7 +124,7 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
<div data-plugin-item="username"
|
||||
<div data-tab-item="username"
|
||||
class="hidden grid grid-cols-12 w-full justify-items-center">
|
||||
<div class="col-span-12">
|
||||
<h5 class="text-xl my-1 transition duration-300 ease-in-out font-bold m-0 mb-4 dark:text-gray-200">USERNAME</h5>
|
||||
|
|
@ -236,7 +202,7 @@
|
|||
</form>
|
||||
<!-- end update username -->
|
||||
</div>
|
||||
<form data-plugin-item="password"
|
||||
<form data-tab-item="password"
|
||||
class="hidden col-span-12 grid grid-cols-12 w-full justify-items-center mt-4"
|
||||
id="password-form"
|
||||
action="account"
|
||||
|
|
@ -365,7 +331,7 @@
|
|||
<button type="submit" id="pw-button" name="pw-button" class="edit-btn">Edit</button>
|
||||
</div>
|
||||
</form>
|
||||
<form data-plugin-item="totp"
|
||||
<form data-tab-item="totp"
|
||||
class="hidden grid grid-cols-12 w-full justify-items-center"
|
||||
id="totp-form"
|
||||
action="account"
|
||||
|
|
|
|||
2
src/ui/templates/global_config.html
vendored
2
src/ui/templates/global_config.html
vendored
|
|
@ -6,7 +6,7 @@ class="z-100 w-full grid grid-cols-12 h-fit max-h-100 sm:max-h-125 col-span-12
|
|||
<div class="flex flex-col xs:flex-row xs:justify-start xs:items-center gap-x-4 gap-y-2 my-3">
|
||||
<h5 class="transition duration-300 ease-in-out 0 ml-2 font-bold text-md uppercase dark:text-white/90 mb-0">PLUGINS</h5>
|
||||
</div>
|
||||
{% include "settings_tabs.html" %}
|
||||
{% include "settings_tabs_select.html" %}
|
||||
</div>
|
||||
</div>
|
||||
<!-- filter -->
|
||||
|
|
|
|||
2
src/ui/templates/services_modal.html
vendored
2
src/ui/templates/services_modal.html
vendored
|
|
@ -46,7 +46,7 @@
|
|||
class="flex flex-col">
|
||||
<div class="flex flex-col sm:flex-row justify-start w-full items-start sm:items-center gap-y-3 gap-x-4">
|
||||
<div class="w-full sm:min-w-[250px] max-w-[300px]">
|
||||
{% include "settings_tabs.html" %}
|
||||
{% include "settings_tabs_select.html" %}
|
||||
</div>
|
||||
<!-- search inpt-->
|
||||
<div class="flex relative w-full max-w-[200px]">
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ try:
|
|||
|
||||
assert_button_click(DRIVER, "//button[@data-tab-handler='password']")
|
||||
|
||||
password_input = safe_get_element(DRIVER, By.XPATH, "//form[@data-plugin-item='password']//input[@id='curr_password']")
|
||||
password_input = safe_get_element(DRIVER, By.XPATH, "//form[@data-tab-item='password']//input[@id='curr_password']")
|
||||
assert isinstance(password_input, WebElement), "The password input is not an instance of WebElement"
|
||||
|
||||
if password_input.get_attribute("value") != "":
|
||||
|
|
@ -169,7 +169,7 @@ try:
|
|||
assert isinstance(totp_input, WebElement), "The TOTP input is not an instance of WebElement"
|
||||
totp_input.send_keys(totp.now())
|
||||
|
||||
password_input = safe_get_element(DRIVER, By.XPATH, "//form[@data-plugin-item='totp']//input[@id='curr_password']")
|
||||
password_input = safe_get_element(DRIVER, By.XPATH, "//form[@data-tab-item='totp']//input[@id='curr_password']")
|
||||
assert isinstance(password_input, WebElement), "The password input is not an instance of WebElement"
|
||||
|
||||
if password_input.get_attribute("value") != "":
|
||||
|
|
@ -252,7 +252,7 @@ try:
|
|||
assert isinstance(totp_input, WebElement), "The TOTP input is not an instance of WebElement"
|
||||
totp_input.send_keys(totp.now())
|
||||
|
||||
password_input = safe_get_element(DRIVER, By.XPATH, "//form[@data-plugin-item='totp']//input[@id='curr_password']")
|
||||
password_input = safe_get_element(DRIVER, By.XPATH, "//form[@data-tab-item='totp']//input[@id='curr_password']")
|
||||
assert isinstance(password_input, WebElement), "The password input is not an instance of WebElement"
|
||||
password_input.send_keys("P@ssw0rd")
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue