Joseph Nuthalapati e5b7ed4faf
*: Implements tags for apps
- Add tags to Info component of apps. Use only English tags for all operations.
Localized tags are used for presentation to the user only. Add tags to all the
apps. Conventions (English):

  1. Tags describing use cases should be in kebab case.

  2. Protocols in tag names should be in their canonical format.

  3. Tags needn't be 100% technically correct. This can get in the way of
  comparing apps using a tag. Words that describe use cases that users can
  easily understand should be preferred over being pedantic.

  4. Tags should be short, ideally not more than 2 words. Avoid conjunctions
  like "and", "or" in tags.

  5. Avoid redundant words like "server", or "web-clients". Most apps on
  FreedomBox are either servers or web clients.

  6. Keep your nouns singular in tags.

- Use query
params to filter the Apps page by tags. When all tags are removed, redirect to /apps.

- Add UI elements to add and remove tag filters in the Apps page. Make the UI
similar to GitLab issue tags. Since there are 40 apps, there will be at least 40
tags. Selecting a tag from a dropdown will be difficult on mobile devices. A
fuzzy search is useful to find tags to add to the filter. Allow user to find the
best match for the search term and highlight it visually. The user can then
press Enter to select the highlighted tag. Make tag search case-insensitive.
Make the dropdown menu scrollable with a fixed size. User input is debounced by
300 ms during search.

- tests: Add missing mock in test_module_loader.py

- Add functional tests

[sunil]

- 'list' can be used instead of 'List' for typing in recent Python versions.

- Reserve tripe-quoted strings for docstrings.

- Undo some changes in module initialization, use module_name for logging
errors.

- isort and yapf changes.

- Encode parameters before adding them to the URL.

Tests:

- Tested the functionality of filtering by tag with one tag and two tags.

Signed-off-by: Joseph Nuthalapati <njoseph@riseup.net>
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
2024-10-16 21:07:54 -07:00

1035 lines
21 KiB
CSS

/*
# SPDX-License-Identifier: AGPL-3.0-or-later
*/
:root {
--background-color: #f1f1f1; /* Light grey */
--neutral-light-color: #f5f5f5; /* Light grey */
--neutral-dark-color: #d4d4d4; /* Grey */
--info-color: #5bc0de; /* Pale blue, almost turquoise */
--freedombox-blue-color: #4989D4; /* Blue */
--progress-color: #3498db; /* Blue */
--error-color: #d9534f; /* Red */
--warning-color: #ec971f; /* Orange */
}
@font-face {
font-family: 'Lato';
src: url('../lato/Lato-Italic.woff2') format('woff2');
font-style: italic;
font-weight: 400;
}
@font-face {
font-family: 'Lato';
src: url('../lato/Lato-Regular.woff2') format('woff2');
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: 'Lato';
src: url('../lato/Lato-Semibold.woff2') format('woff2');
font-style: normal;
font-weight: 600;
}
@font-face {
font-family: 'Lato';
src: url('../lato/Lato-SemiboldItalic.woff2') format('woff2');
font-style: italic;
font-weight: 600;
}
@font-face {
font-family: 'Lato';
src: url('../lato/Lato-Bold.woff2') format('woff2');
font-style: normal;
font-weight: 700;
}
@font-face {
font-family: 'Lato';
src: url('../lato/Lato-BoldItalic.woff2') format('woff2');
font-style: italic;
font-weight: 700;
}
@font-face {
font-family: 'Lato';
src: url('../lato/Lato-Heavy.woff2') format('woff2');
font-style: normal;
font-weight: 800;
}
@font-face {
font-family: 'Lato';
src: url('../lato/Lato-HeavyItalic.woff2') format('woff2');
font-style: italic;
font-weight: 800;
}
/*
* Bootstrap override
*/
/* Heading margins from bootstrap 3 */
h1, h2, h3, h4, h5, h6 {
margin-top: 1.25rem;
margin-bottom: 0.625rem;
}
/* Warning colors from bootstrap 3 */
.badge-warning,
.bg-warning,
.btn-warning {
background-color: #f0ad4e !important;
color: #fff !important;
}
.btn-warning:hover,
.btn-warning:active,
.btn-warning:focus,
.btn-warning:disabled,
.btn-warning.disabled,
.btn-warning[disabled] {
background-color: var(--warning-color) !important;
color: #fff !important;
}
.btn[disabled] {
cursor: not-allowed !important;
opacity: .65;
box-shadow: none;
}
/* Primary color changed in bootstrap 4 */
.btn-primary {
background-color: #337ab7;
border-color: #2e6da4;
}
.btn-primary:hover,
.btn-primary:active,
.btn-primary:focus,
.btn-primary:disabled,
.btn-primary.disabled,
.btn-primary[disabled] {
background-color: #286090;
border-color: #204d74;
}
/* Default style removed in bootstrap 4 */
.btn-default {
color: #333;
background-color: #fff;
border-color: #ccc;
}
.btn-default:hover,
.btn-default:focus,
.btn-default:active {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
/* Help block removed from bootstrap 4, needs updated django-bootstrap-from */
.help-block {
display: block;
margin-top: 0.3125rem;
margin-bottom: 0.625rem;
color: #737373;
}
/* form-horizontal removed in bootstrap, needs updated django-bootstrap-form */
.form-horizontal > .form-group {
display: flex;
flex-wrap: wrap;
margin-right: -0.9375rem;
margin-left: -0.9375rem;
}
.radio .help-block {
padding-left: 1.2rem;
}
.checkbox .help-block {
padding-left: 1.4rem;
}
/* Form error display was changed in bootstrap 4, provide compatibility */
.has-error .help-block,
.has-error .control-label,
.has-error .radio,
.has-error .checkbox,
.has-error .radio-inline,
.has-error .checkbox-inline,
.has-error.radio label,
.has-error.checkbox label,
.has-error.radio-inline label,
.has-error.checkbox-inline label {
color: #a94442;
}
.has-error .form-control {
border-color: #a94442;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
/*
* Basic styling
*/
body {
padding-top: 6rem;
position: relative;
font-family: Lato, sans-serif;
background: url('../img/noise.png') var(--background-color);
}
@media (max-width: 767px) {
body {
background: none;
}
body.index-page,
body.apps-page,
body.system-page {
background: url('../img/noise.png') var(--background-color);
}
}
.multiple-checkbox li {
list-style-type: none;
}
.multiple-checkbox > div {
padding-left: 40px;
}
.navbar .fa:not(.fa-bars) {
margin-right: 0.25rem;
}
.no-brand .navbar-brand {
display: none;
}
.navbar-brand .fa {
float: left;
margin-top: -0.4375rem;
padding: 0.5rem;
}
.navbar-brand {
height: 3.3125rem;
margin-right: -1.25rem;
}
@media (max-width: 767px) {
.navbar-brand {
margin-right: auto;
}
}
.nav-tabs {
margin-bottom: 1.25rem;
}
.dropdown-toggle::after {
vertical-align: middle;
}
.running-status-parent {
display: inline-block;
}
.running-status {
border-radius: 50%;
border: 1px solid black;
width: 0.5rem;
height: 0.5rem;
display: inline-block;
}
.running-status.loading {
border: 0.25rem solid var(--neutral-light-color);
border-top: 0.25rem solid var(--progress-color);
border-radius: 50%;
width: 1rem;
height: 1rem;
display: inline-block;
animation: spin 1s linear infinite;
}
.nav-link:hover, .nav-link:visited, .nav-link:link, .nav-link:active {
text-decoration: none;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* Hide log out button if user dropdown is available */
.js #logout-nojs {
display: none;
}
/* Hide the dropdown icon when javascript is not available */
.no-js .dropdown-toggle:after {
display: none;
}
.diagnostics-results .diagnostics-result {
width: 3.75rem;
text-align: center;
}
.centered-column {
text-align: center;
}
/* Sticky footer styles
-------------------------------------------------- */
.footer-logo {
width: 8.75rem;
}
html {
position: relative;
}
body,
html {
height: 100%;
}
#wrapper {
position: relative;
}
.container {
max-width: 1000px;
}
.content-container {
margin-bottom: 1.25rem;
}
/* Tag Input Container */
.tag-input {
display: flex;
align-items: center;
border: 1px solid #ced4da;
border-radius: .25rem;
padding: .375rem .75rem;
width: 100%;
background-color: #fff;
margin-bottom: 3rem;
}
/* Selected Tags */
.tag-input #selected-tags {
display: flex;
flex-wrap: wrap;
margin-right: .5rem;
}
.tag-input .tag {
background-color: #e9ecef; /* Light gray background */
border-radius: .25rem;
padding: .25rem .5rem;
margin-right: .25rem;
margin-bottom: .25rem;
display: flex;
align-items: center;
}
/* Remove tag button */
.tag-badge .remove-tag {
background-color: #f8f9fa; /* Match the tag's background color */
border: none;
padding: 0.25rem 0.5rem;
cursor: pointer;
}
/* Adjust input field width */
.tag-input input[type="search"] {
flex-grow: 1;
border: none;
outline: none;
box-shadow: none;
width: auto;
min-width: 3rem;
}
/* dropdown-menu for tags is a scrollable list */
.tag-input .dropdown-menu {
bottom: calc(-100% - 10px);
overflow-y: auto;
}
@media (min-width: 768px) {
.content-container {
padding: 1.5rem 3rem 3rem;
background-color: white;
border: 1px solid #ddd;
border-radius: 0.25rem;
}
}
footer {
text-align: center;
position: relative;
bottom: 0;
width: 100%;
height: 9.375rem;
padding-top: 9.375rem;
}
/*
* Bootstrap extensions
*/
/* Use .list-group-two-column when there are some items aligned to right */
.list-group-two-column .list-group-item {
display: flex;
align-items: center;
}
.list-group-two-column .list-group-item > :not(:last-child) {
margin-right: 0.25rem;
}
.list-group-two-column .list-group-item > .secondary {
margin-left: auto;
margin-top: -0.25rem;
margin-bottom: -0.25rem;
}
.list-group-two-column .list-group-item > .secondary ~ .secondary {
margin-left: 0;
}
/* Hack to avoid inline styling on bootstrap progress bars */
.w-0 {width: 0%;} .w-1 {width: 1%;} .w-2 {width: 2%;} .w-3 {width: 3%;}
.w-4 {width: 4%;} .w-5 {width: 5%;} .w-6 {width: 6%;} .w-7 {width: 7%;}
.w-8 {width: 8%;} .w-9 {width: 9%;} .w-10 {width: 10%;} .w-11 {width: 11%;}
.w-12 {width: 12%;} .w-13 {width: 13%;} .w-14 {width: 14%;} .w-15 {width: 15%;}
.w-16 {width: 16%;} .w-17 {width: 17%;} .w-18 {width: 18%;} .w-19 {width: 19%;}
.w-20 {width: 20%;} .w-21 {width: 21%;} .w-22 {width: 22%;} .w-23 {width: 23%;}
.w-24 {width: 24%;} .w-25 {width: 25%;} .w-26 {width: 26%;} .w-27 {width: 27%;}
.w-28 {width: 28%;} .w-29 {width: 29%;} .w-30 {width: 30%;} .w-31 {width: 31%;}
.w-32 {width: 32%;} .w-33 {width: 33%;} .w-34 {width: 34%;} .w-35 {width: 35%;}
.w-36 {width: 36%;} .w-37 {width: 37%;} .w-38 {width: 38%;} .w-39 {width: 39%;}
.w-40 {width: 40%;} .w-41 {width: 41%;} .w-42 {width: 42%;} .w-43 {width: 43%;}
.w-44 {width: 44%;} .w-45 {width: 45%;} .w-46 {width: 46%;} .w-47 {width: 47%;}
.w-48 {width: 48%;} .w-49 {width: 49%;} .w-50 {width: 50%;} .w-51 {width: 51%;}
.w-52 {width: 52%;} .w-53 {width: 53%;} .w-54 {width: 54%;} .w-55 {width: 55%;}
.w-56 {width: 56%;} .w-57 {width: 57%;} .w-58 {width: 58%;} .w-59 {width: 59%;}
.w-60 {width: 60%;} .w-61 {width: 61%;} .w-62 {width: 62%;} .w-63 {width: 63%;}
.w-64 {width: 64%;} .w-65 {width: 65%;} .w-66 {width: 66%;} .w-67 {width: 67%;}
.w-68 {width: 68%;} .w-69 {width: 69%;} .w-70 {width: 70%;} .w-71 {width: 71%;}
.w-72 {width: 72%;} .w-73 {width: 73%;} .w-74 {width: 74%;} .w-75 {width: 75%;}
.w-76 {width: 76%;} .w-77 {width: 77%;} .w-78 {width: 78%;} .w-79 {width: 79%;}
.w-80 {width: 80%;} .w-81 {width: 81%;} .w-82 {width: 82%;} .w-83 {width: 83%;}
.w-84 {width: 84%;} .w-85 {width: 85%;} .w-86 {width: 86%;} .w-87 {width: 87%;}
.w-88 {width: 88%;} .w-89 {width: 89%;} .w-90 {width: 90%;} .w-91 {width: 91%;}
.w-92 {width: 92%;} .w-93 {width: 93%;} .w-94 {width: 94%;} .w-95 {width: 95%;}
.w-96 {width: 96%;} .w-97 {width: 97%;} .w-98 {width: 98%;} .w-99 {width: 99%;}
.w-100 {width: 100%;}
/*
* Clients information
*/
.client-icon {
display: inline-block;
width: 100%;
height: auto;
max-height: 1.25rem;
max-width: 1.25rem;
margin: auto;
}
#clients .btn {
width: 9rem;
margin-right: 1rem;
}
#clients th, #clients td {
line-height: 3rem;
}
/* Icon when collapsible content is shown */
.collapsible-button .fa {
margin-left: 0.3125rem;
}
.collapsible-button .fa-chevron-right:before,
.no-js .collapsible-button.collapsed .fa-chevron-right:before {
content: "\f078";
}
.collapsible-button.collapsed .fa-chevron-right:before {
content: "\f054";
}
/* No-JS fallbacks for collapsible content */
.no-js .collapse {
display: block;
}
.manual-page {
text-align: right;
}
/*
* Top navigation
*/
.main-header {
background: var(--freedombox-blue-color);
box-shadow: 0 0.25rem 0.375rem 0 rgba(0, 0, 0, 0.25);
border: none;
}
.main-header > .container > nav.navbar {
padding: 0;
}
.main-header .navbar-nav > li > a,
.main-header .navbar-toggler {
color: #FFF;
}
.main-header .nav-item .nav-link {
padding: 0.9375rem !important;
height: 3.25rem;
}
.main-header .nav-link,
.main-header .nav-link:hover {
color: white;
}
.main-header .navbar-toggler {
border: 1px solid #ddd;
/* In mobile layout, during first setup, maintain the height of the navbar */
margin: 0.6875rem 0;
}
@media screen and (max-width: 767px) {
.main-header .navbar-nav .dropdown-menu {
background-color: var(--freedombox-blue-color);
}
.main-header .navbar-nav > li > a:focus,
.main-header .navbar-nav > li > a:hover,
.main-header .navbar-nav li > form > input,
.main-header .navbar-nav li > form > input:focus,
.main-header .navbar-nav li > form > input:hover,
.main-header .navbar-nav .show a,
.main-header .navbar-nav .show a:hover,
.main-header .navbar-nav .show a:focus {
color: #FFF;
background: transparent;
}
.main-header .navbar-nav .nav-item:last-of-type .dropdown-menu {
margin-bottom: 1.25rem;
}
}
/* Cards in Apps, System and Help pages */
.card-list {
display: flex;
flex-wrap: wrap;
justify-content: left;
}
.card-section-title, .system-section-title {
display: flex;
font-weight: 800;
font-size: 1.25rem;
margin-bottom: 1.25rem;
border-bottom: var(--neutral-dark-color) solid 2px;
}
.card-section-title {
margin-top: 1.25rem;
}
a.menu_link {
text-decoration: none;
}
a.menu_link:hover,a.menu_link:active {
text-decoration: none;
}
a.menu_link_active {
border-bottom: white 3px solid;
}
.card {
display: block;
line-height: 1.42857143;
text-align: center;
box-shadow: 0 0.1875rem 0.3125rem 0 rgba(0,0,0,0.12);
width: 10rem;
padding: 0;
margin: 0 0.625rem 1.25rem;
border: none;
border-radius: 0.5rem;
transition: border .2s ease-in-out;
}
.card:hover {
box-shadow: 0 0.3125rem 0.9375rem 0.125rem rgba(0, 0, 0, 0.2);
}
.card .nav-link {
display: block;
padding: 0.25rem;
color: #646464;
}
.card-title {
font-weight: 800;
font-size: 1.25rem;
padding: 0.75rem 0;
margin-bottom: 0;
}
.card-description {
font-weight: 400;
padding: 0.75rem 0;
color: #646464;
font-size: 0.75rem;
}
.card-icon span,
.card-icon img {
width: 6.25rem;
height: 6.25rem;
font-size: 5rem;
}
/* System page - special card styling */
.system-page .card {
text-align: left;
width: 14.375rem;
}
.system-page .card .nav-link {
display: grid;
grid-template-columns: 2.1875rem auto;
grid-column-gap: 0.625rem;
padding: 0.8125rem;
}
.system-page .card-title {
font-size: 1.125rem;
font-style: normal;
font-weight: bold;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
grid-row: 1;
grid-column: 2;
padding: 0;
}
.system-page .card-icon {
grid-row: 1 / 3;
grid-column: 1;
}
.system-page .card-icon span {
height: auto;
font-size: 2.1875rem;
}
.system-page .card-description {
grid-row: 2;
grid-column: 2;
padding: 0;
min-height: 1.125rem;
}
/* Button table - Tables with a list of actions as buttons on top */
.index-page .card-list:before,
.apps-page .card-list:before,
.system-page .system-section-title:first-child:before {
position: relative;
width: 25rem;
height: 25rem;
margin-left: -25rem;
margin-bottom: -25rem;
left: 18.75rem;
top: -1.25rem;
content: " ";
background-size: 100%;
background-repeat: no-repeat;
z-index: -1;
}
.index-page .card-list:before {
background-image: url('../img/freedombox-logo-background.svg');
}
.apps-page .card-list-primary:before {
background-image: url('../img/apps-background.svg');
}
.system-page .system-section-title:first-child:before {
background-image: url('../img/system-background.svg');
}
.names-table {
table-layout: fixed;
overflow-wrap: break-word;
}
.names-domain-column {
width: 50%;
}
/*
* First setup pages
*/
.firstboot-spinner {
text-align: center;
}
.firstboot-spinner span.fa {
float: none;
margin: auto;
}
.next-steps {
list-style: none;
margin-top: 1.5rem;
padding: 0;
}
.next-steps li {
display: flex;
align-items: center;
padding: 0.75rem 0;
}
.next-steps .app-icon {
font-size: 3rem;
margin-right: 1rem;
width: 3rem;
text-align: center;
}
.next-steps form {
display: inline;
}
/*
* Toggle button
*/
.toggle-button {
border-radius: 0.8125rem;
width: 3.125rem;
height: 1.625rem;
background: #ccc;
position: relative;
}
.toggle-button::before {
content: '';
display: block;
height: 1.5rem;
width: 1.5rem;
border-radius: 100%;
background: #fff;
position: absolute;
top: 50%;
left: 0%;
transform: translateY(-50%);
}
.toggle-button--toggled {
background: var(--freedombox-blue-color);
}
.toggle-button--toggled::before {
left: 100%;
transform: translateY(-50%) translateX(-100%);
}
.toggle-button.running-status-button::before {
top: 0;
border: 0.25rem solid var(--neutral-light-color);
border-top: 0.25rem solid var(--progress-color);
animation: spin 1s linear infinite;
}
.toggle-button.toggle-button--toggled.running-status-button::before {
margin-left: -1.5rem;
}
/*
* Form button with loading progress.
*/
.running-status-button-before {
display: inline-block;
border: 0.25rem solid var(--neutral-light-color);
border-top: 0.25rem solid var(--progress-color);
border-radius: 50%;
width: 1rem;
height: 1rem;
animation: spin 1s linear infinite;
margin-left: 0.625rem;
margin-bottom: -0.25rem;
margin-right: -1.625rem;
}
.running-status-button:disabled {
cursor: default;
}
input[type='submit'].running-status-button {
padding-left: 2rem;
}
/*
* Select all checkbox for multiple checkboxes field.
*/
.select-all-label {
border: 1px solid var(--neutral-dark-color);
background-color: var(--neutral-light-color);
border-radius: 0.25rem;
padding: 0.5rem 1rem 0.25rem;
margin-left: -1rem;
}
/*
* Button toolbar
*/
.btn-toolbar {
margin-top: 0.625rem;
margin-bottom: 0.625rem;
}
.btn-toolbar > :not(:last-child):not(.running-status-button-before) {
margin-right: 0.5rem;
}
.btn-toolbar .button-secondary:first-child,
.btn-toolbar .form:not(.button-secondary) + .button-secondary,
.btn-toolbar .form:not(.button-secondary) + .running-status-button-before,
.btn-toolbar .btn:not(.button-secondary) + .button-secondary,
.btn-toolbar .btn:not(.button-secondary) + .running-status-button-before {
margin-left: auto;
}
.btn-toolbar > .running-status-button-before {
margin-bottom: 0;
align-self: center;
}
/*
* App's header
*/
.app-header {
display: grid;
grid-template-columns: 0.2fr 1fr;
column-gap: 1.25rem;
margin-bottom: 1.25rem;
}
.app-header > img {
margin: 1.5625rem auto 0;
width: 100%;
}
.app-description {
grid-column: 2;
}
.app-header-single-column {
grid-template-columns: 1fr;
}
.app-header-single-column .app-description {
grid-column: 1;
}
.app-titles {
display: flex;
flex-flow: row;
justify-content: space-between;
}
.app-titles h3 {
margin-top: -0.3125rem;
margin-bottom: 1rem;
font-size: 1rem;
font-weight: normal;
font-style: italic;
}
.form-app-enable-disable {
margin: auto 0;
}
@media screen and (max-width: 767px) {
.app-header {
display: flex;
flex-flow: column;
}
.app-header img {
width: 9.375rem;
height: 9.375rem;
margin-top: 0;
}
.app-titles {
display: flex;
flex-flow: column-reverse;
justify-content: center;
height: auto;
}
.app-titles h2 {
margin: 0 0 0.9375rem 0;
}
.app-titles .form-app-enable-disable {
margin: 1.875rem auto;
}
.app-titles .toggle-button {
transform: scale(1.2);
}
}
/* Help manual - anchor is below navbar */
*[id^='idm']:before {
display: block;
content: " ";
margin-top: -3.75rem;
height: 3.75rem;
visibility: hidden;
}
/*
* Notifications
*/
.notifications {
margin-left: -0.9375rem;
margin-right: -0.9375rem;
}
.notifications .dropdown-menu {
width: 100%;
padding: 0;
float: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
margin-top: 0;
background-clip: border-box;
}
/* Style for individual notification */
.notification {
padding: 0.625rem 0.9375rem;
border-left: 0.3125rem solid;
}
.notification:not(:first-child) {
border-top: 1px solid #ddd;
}
.notification-title {
font-weight: bold;
}
img.notification-icon {
display: inline-block;
width: 0.875rem;
height: 0.875rem;
margin-top: -0.25rem;
}
/* Show badge with various colors and overlap it onto icon */
.notifications-dropdown .badge {
padding: 0.125rem 0.3125rem;
margin-left: -0.75rem;
color: #fff;
}
/* TODO: match with or use bootstrap 4 colors */
.badge-exception, .badge-error {
background-color: var(--error-color);
}
.badge-warning {
background-color: var(--warning-color);
}
.badge-info, .badge-debug {
background-color: var(--info-color);
}
.notification-exception, .notification-error {
border-left-color: var(--error-color);
}
.notification-warning {
border-left-color: var(--warning-color);
}
.notification-info, .notification-debug {
border-left-color: var(--info-color)
}
.warning {
color: var(--warning-color);
}
.processing {
color: var(--progress-color);
}
.normal {
color: var(--neutral-dark-color);
}
/* Two different notifications for each small and one for large screens */
.notifications-dropdown {
display: none;
}
.collapse .notifications-dropdown {
display: block;
}
@media screen and (max-width: 767px) {
.notifications-dropdown {
display: block;
}
.collapse .notifications-dropdown {
display: none;
}
}
/* Accordion */
.accordion {
margin-bottom: 1.25rem;
}
.accordion .card-header h4 {
margin: 0;
}