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:
Jordan Blasenhauer 2024-03-01 15:47:01 +01:00
parent 2266299c8a
commit 9573d8b458
9 changed files with 131 additions and 81 deletions

File diff suppressed because one or more lines are too long

View file

@ -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();

View file

@ -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,
};

View file

@ -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;
}

View file

@ -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"

View file

@ -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 -->

View file

@ -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]">

View file

@ -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")