Skip to content

Dropdown + ellipsis fix #974

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions pgml-dashboard/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

[*.scss]
indent_style = space
indent_size = 4

[*.js]
indent_style = space
indent_size = 2

[*.rs]
indent_style = space
indent_size = 4

[*.html]
ident_style = space
indent_size = 4
112 changes: 112 additions & 0 deletions pgml-dashboard/src/components/dropdown/dropdown.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
.dropdown {
@extend .d-flex;
min-width: 100%;

.dropdown-toggle {
a {
padding: 8px 12px;
}

&:hover {
cursor: pointer;
}

&:after {
content: none;
}
}

.dropdown-menu {
width: 100%;
}

&.expandable {
.dropdown-menu {
width: auto;
min-width: 100%;
}
}

.dropdown-item {
overflow: hidden;
text-overflow: ellipsis;
}
}

.btn-dropdown {
border-radius: $border-radius;
background: #{$gray-700};
color: #{$gray-100};
display: flex;
justify-content: space-between;
font-weight: $font-weight-normal;

--bs-btn-border-color: transparent;
--bs-btn-border-width: 1px;
--bs-btn-hover-border-color: #{$neon-shade-100};
--bs-btn-active-border-color: #{$neon-shade-100};
--bs-btn-active-bg: #{$gray-700};
--bs-btn-active-color: #{$gray-100};
--bs-btn-hover-color: #{$gray-100};

.material-symbols-outlined {
color: #{$neon-shade-100};
}

&:after {
content: None;
}

&.show {
.material-symbols-outlined {
transform: rotate(-180deg);
}
}

.collapase {
width: 100%;
}

.btn-dropdown-text {
overflow: hidden;
text-overflow: ellipsis;
text-align: left;
}

.menu-item {
a {
padding: 8px 12px;
overflow: hidden;
text-overflow: ellipsis;
}

&:hover {
cursor: pointer;
}

&:after {
content: None;
}
}
}

@mixin dropdown-menu($primary-color: null) {
padding: 20px 0px 40px 0px;
overflow-y: auto;

@if ($primary-color) {
background-color: #{$primary-color};
}
}

.dropdown-menu {
@include dropdown-menu($gray-600);
max-height: $dropdown-menu-height;
overflow: hidden;
}

.sub-menu-dropdown {
@include dropdown-menu();
border-radius: 0px;
box-shadow: 1px 1px 8px 0px rgba(0, 0, 0, 0.30);
}
102 changes: 102 additions & 0 deletions pgml-dashboard/src/components/dropdown/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use crate::components::component;
use crate::components::component::Component;
use sailfish::TemplateOnce;

use crate::components::StaticNavLink;

pub enum DropdownValue {
Icon(Component),
Text(Component),
}

impl Default for DropdownValue {
fn default() -> Self {
DropdownValue::Text("Menu".into())
}
}

#[derive(TemplateOnce, Default)]
#[template(path = "dropdown/template.html")]
pub struct Dropdown {
/// The currently selected value.
value: DropdownValue,

/// The list of dropdown links to render.
links: Vec<StaticNavLink>,

/// Position of the dropdown menu.
offset: String,

/// Whether or not the dropdown is collapsble.
collapsable: bool,
offset_collapsed: String,

/// Where the dropdown menu should appear
menu_position: String,
expandable: bool,
}

impl Dropdown {
pub fn new(links: Vec<StaticNavLink>) -> Self {
let binding = links
.iter()
.filter(|link| link.active)
.collect::<Vec<&StaticNavLink>>();
let active = binding.first();
let value = if let Some(active) = active {
active.name.to_owned()
} else {
"Menu".to_owned()
};
Dropdown {
links,
value: DropdownValue::Text(value.into()),
offset: "0, 10".to_owned(),
offset_collapsed: "68, -44".to_owned(),
menu_position: "".to_owned(),
..Default::default()
}
}

pub fn text(mut self, value: Component) -> Self {
self.value = DropdownValue::Text(value);
self
}

pub fn icon(mut self, icon: Component) -> Self {
self.value = DropdownValue::Icon(icon);
self
}

pub fn collapsable(mut self) -> Self {
self.collapsable = true;
self
}

pub fn menu_end(mut self) -> Self {
self.menu_position = "dropdown-menu-end".to_owned();
self
}

pub fn menu_start(mut self) -> Self {
self.menu_position = "dropdown-menu-start".to_owned();
self
}

pub fn offset(mut self, offset: &str) -> Self {
self.offset = offset.to_owned();
self
}

pub fn offset_collapsed(mut self, offset: &str) -> Self {
self.offset_collapsed = offset.to_owned();
self
}

pub fn expandable(mut self) -> Self {
self.expandable = true;
self
}
}

component!(Dropdown);
56 changes: 56 additions & 0 deletions pgml-dashboard/src/components/dropdown/template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

<% use crate::components::dropdown::DropdownValue; %>

<!-- Dropdown component -->
<div class="dropdown <% if expandable { %>expandable<% } %>">
<% if let DropdownValue::Icon(icon) = value { %>
<a
class="topnav-controlls dropdown-toggle"
role="button"
data-bs-toggle="dropdown"
data-bs-offset="<%= offset %>"
href="#"
aria-expanded="false">
<%+ icon %>
</a>
<% } else if let DropdownValue::Text(text) = value { %>
<button
class="horizontal-hide btn btn-dropdown dropdown-toggle <% if collapsable { %> leftnav-collapse-affect <% } %>"
role="button"
data-bs-toggle="dropdown"
data-bs-offset="<%= offset %>"
aria-expanded="false">
<span class="btn-dropdown-text"><%+ text %></span>
<span class="material-symbols-outlined">
expand_more
</span>
</button>
<% } %>

<% if collapsable { %>
<div
class="menu-item horizontal-hide dropdown-toggle collapsed <% if collapsable { %> leftnav-collapse-affect <% } %>"
role="button"
data-bs-toggle="dropdown"
data-bs-offset="<%= offset_collapsed %>"
aria-expanded="false"
>
<a class="d-flex align-items-center justify-content-start gap-2">
<span class="material-symbols-outlined">grid_view</span>
</a>
</div>
<% } %>

<ul class="dropdown-menu <%= menu_position %>">
<% for link in links { %>
<li class="menu-item d-flex align-items-center <% if link.disabled { %>disabled<% } %>">
<% if link.disabled { %>
<a type="button" class="dropdown-item" disabled href="#"><%= link.name %></a>
<% } else { %>
<a type="button" class="dropdown-item" href="<%- link.href %>"><%= link.name %></a>
<% } %>
</li>
<% } %>
</ul>
</div>
<!-- /Dropdown component -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.leftnav {
@extend .navbar;
max-width: 260px;

border: none;
align-items: start;
background-color: inherit;

@include media-breakpoint-down(lg) {
background-color: #{$gray-900}
}
}
27 changes: 4 additions & 23 deletions pgml-dashboard/src/components/left_nav_web_app/template.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<% use crate::components::LeftNavMenu; %>
<% use crate::components::{LeftNavMenu, Dropdown}; %>
<nav class="leftnav nav-pills h-100" data-controller="extend-bs-collapse" data-extend-bs-collapse-affected-value=".leftnav-collapse-affect">
<div class="d-flex flex-column justify-content-between h-100 w-100">
<div class="d-flex flex-column">
Expand All @@ -11,29 +11,10 @@
</span>
</button>

<div class="dropdown nav-item d-flex w-100 mb-4 show">
<button class="horizontal-hide btn-dropdown dropdown-toggle leftnav-collapse-affect expanded" href="#" role="button" data-bs-toggle="dropdown" data-bs-offset="0, 10" aria-expanded="false">
<%- dropdown_nav.clone().get_active().name %>
<span class="material-symbols-outlined">
expand_more
</span>
</button>

<div class="btn-dropdown-menu-item horizontal-hide m-auto dropdown-toggle leftnav-collapse-affect collapsed" href="#" role="button" data-bs-toggle="dropdown" data-bs-offset="68, -44" aria-expanded="false">
<a class="d-flex align-items-center justify-content-start gap-2">
<span class="material-symbols-outlined">grid_view</span>
</a>
</div>

<ul class="dropdown-menu w-100">
<% for link in dropdown_nav.links { %>
<li class="menu-item d-flex align-items-center">
<a href="<%- link.href %>"><%- link.name %></a>
</li>
<% } %>
</ul>
<div class="mb-4">
<%+ Dropdown::new(dropdown_nav.links).collapsable() %>
</div>
<%+ LeftNavMenu { nav: upper_nav } %>
<%+ LeftNavMenu { nav: upper_nav } %>
</div>
<%+ LeftNavMenu { nav: lower_nav} %>
</div>
Expand Down
8 changes: 8 additions & 0 deletions pgml-dashboard/src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ pub use breadcrumbs::Breadcrumbs;
pub mod confirm_modal;
pub use confirm_modal::ConfirmModal;

// src/components/dropdown
pub mod dropdown;
pub use dropdown::Dropdown;

// src/components/github_icon
pub mod github_icon;
pub use github_icon::GithubIcon;
Expand Down Expand Up @@ -49,6 +53,10 @@ pub use navbar_web_app::NavbarWebApp;
pub mod postgres_logo;
pub use postgres_logo::PostgresLogo;

// src/components/profile_icon
pub mod profile_icon;
pub use profile_icon::ProfileIcon;

// src/components/static_nav
pub mod static_nav;
pub use static_nav::StaticNav;
Expand Down
23 changes: 7 additions & 16 deletions pgml-dashboard/src/components/navbar_web_app/template.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<% use crate::templates::components::GithubIcon; %>
<% use crate::templates::components::PostgresLogo; %>
<% use crate::components::{Dropdown, ProfileIcon}; %>

<div class="fixed-top-nav">
<nav class="navbar-web-app horizontal navbar-expand-lg" data-controller="search topnav-web-app">
Expand Down Expand Up @@ -57,22 +58,12 @@
</li>

<% if !account_management_nav.links.is_empty() { %>
<li class="d-none d-lg-flex nav-item align-items-center dropdown">
<a class="dropdown-toggle topnav-controlls" href="#" role="button" data-bs-toggle="dropdown" data-bs-offset="10, 15" aria-expanded="false">
<% include!("../../../templates/components/profile_icon.html"); %>
</a>
<!-- Account management for lg and up screens -->
<ul class="dropdown-menu dropdown-menu-end">
<% for item in account_management_nav.links.clone() { %>
<li class="menu-item rounded-0 d-flex align-items-center <% if item.disabled { %>disabled<% } %>">
<a class="<% if item.disabled { %>disabled<% } %>" <% if item.disabled { %>
href="" disabled <% } else { %>
href="<%- item.href %>"<% } %>>
<%- item.name %>
</a>
</li>
<% } %>
</ul>
<li class="d-none d-lg-flex nav-item align-items-center">
<%+
Dropdown::new(account_management_nav.links.clone())
.icon(ProfileIcon::new().into())
.expandable()
%>
</li>
<li class="nav-item d-flex d-lg-none align-items-center">
<a class="nav-link p-lg-0" data-bs-toggle="collapse" data-bs-target=".horizontal-collapse">Account Management</a>
Expand Down
Loading