Fixed navigation
This commit is contained in:
parent
158bf98871
commit
87be302902
14 changed files with 3873 additions and 2340 deletions
|
|
@ -75,10 +75,6 @@ public class TraderServer {
|
||||||
|
|
||||||
logger.info("Initializing HTTP Server.");
|
logger.info("Initializing HTTP Server.");
|
||||||
|
|
||||||
TraderPage.getRootNav().createSubNav("Sensors");
|
|
||||||
TraderPage.getRootNav().createSubNav("Events").setWeight(100);
|
|
||||||
TraderPage.getRootNav().createSubNav("Settings").setWeight(200);
|
|
||||||
|
|
||||||
http.setDefaultPage(new HttpFilePage(FileUtil.find(TraderContext.RESOURCE_WEB_ROOT)));
|
http.setDefaultPage(new HttpFilePage(FileUtil.find(TraderContext.RESOURCE_WEB_ROOT)));
|
||||||
http.setPage("/", new HttpRedirectPage("/symbol_overview"));
|
http.setPage("/", new HttpRedirectPage("/symbol_overview"));
|
||||||
http.setPage(AlertEndpoint.getInstance().getPath(), AlertEndpoint.getInstance());
|
http.setPage(AlertEndpoint.getInstance().getPath(), AlertEndpoint.getInstance());
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,21 @@ import java.util.Map;
|
||||||
|
|
||||||
public abstract class TraderPage implements HttpPage {
|
public abstract class TraderPage implements HttpPage {
|
||||||
private static final String TEMPLATE_MAIN = TraderContext.RESOURCE_WEB_ROOT + "/main.tmpl";
|
private static final String TEMPLATE_MAIN = TraderContext.RESOURCE_WEB_ROOT + "/main.tmpl";
|
||||||
private static final String TEMPLATE_ALERT = TraderContext.RESOURCE_WEB_ROOT + "/main_alerts.tmpl";
|
private static final String TEMPLATE_NAVIGATION = TraderContext.RESOURCE_WEB_ROOT + "/main_nav.tmpl";
|
||||||
|
private static final String TEMPLATE_SUB_NAVIGATION = TraderContext.RESOURCE_WEB_ROOT + "/main_subnav.tmpl";
|
||||||
|
|
||||||
private static Navigation rootNav = Navigation.createRootNav();
|
private static Navigation rootNav = Navigation.createRootNav();
|
||||||
private static Navigation userNav = Navigation.createRootNav();
|
private static Navigation userNav = Navigation.createRootNav();
|
||||||
|
|
||||||
private String pageId;
|
private String pageId;
|
||||||
private boolean showSubNav;
|
private boolean showSubNav = true;
|
||||||
|
|
||||||
|
|
||||||
public TraderPage(String id){
|
public TraderPage(String id){
|
||||||
this.pageId = id;
|
this.pageId = id;
|
||||||
this.showSubNav = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String getId(){
|
public String getId(){
|
||||||
return pageId;
|
return pageId;
|
||||||
}
|
}
|
||||||
|
|
@ -38,25 +41,26 @@ public abstract class TraderPage implements HttpPage {
|
||||||
Map<String, Object> session, Map<String, String> cookie,
|
Map<String, Object> session, Map<String, String> cookie,
|
||||||
Map<String, String> request) throws IOException {
|
Map<String, String> request) throws IOException {
|
||||||
try {
|
try {
|
||||||
List<UserMessageManager.UserMessage> messages = TraderContext.getMessageManager().getMessages();
|
Templator navigationTemplate = new Templator(FileUtil.find(TEMPLATE_NAVIGATION));
|
||||||
for (UserMessageManager.UserMessage msg : messages) {
|
navigationTemplate.set("rootNav", rootNav.createPagedNavInstance(header).getSubNavs());
|
||||||
msg.decreaseTTL();
|
navigationTemplate.set("userNav", userNav.createPagedNavInstance(header).getSubNavs());
|
||||||
}
|
|
||||||
|
|
||||||
Templator tmpl = new Templator(FileUtil.find(TEMPLATE_MAIN));
|
Templator subNavigationTemplate = null;
|
||||||
tmpl.set("rootNav", rootNav.createPagedNavInstance(header).getSubNavs());
|
|
||||||
tmpl.set("userNav", userNav.createPagedNavInstance(header).getSubNavs());
|
|
||||||
tmpl.set("content", httpRespond(session, cookie, request));
|
|
||||||
tmpl.set("alerts", AlertEndpoint.getInstance().generateAlerts());
|
|
||||||
|
|
||||||
tmpl.set("showSubNav", showSubNav);
|
|
||||||
if (showSubNav) {
|
if (showSubNav) {
|
||||||
|
subNavigationTemplate = new Templator(FileUtil.find(TEMPLATE_SUB_NAVIGATION));
|
||||||
List<Navigation> breadcrumb = Navigation.getBreadcrumb(Navigation.getPagedNavigation(header));
|
List<Navigation> breadcrumb = Navigation.getBreadcrumb(Navigation.getPagedNavigation(header));
|
||||||
if (!breadcrumb.isEmpty())
|
if (!breadcrumb.isEmpty())
|
||||||
tmpl.set("subNav", breadcrumb.get(1).createPagedNavInstance(header).getSubNavs());
|
subNavigationTemplate.set("sub_navigation", breadcrumb.get(1).createPagedNavInstance(header).getSubNavs());
|
||||||
}
|
}
|
||||||
|
|
||||||
out.print(tmpl.compile());
|
Templator main = new Templator(FileUtil.find(TEMPLATE_MAIN));
|
||||||
|
main.set("navigation", navigationTemplate);
|
||||||
|
main.set("sub_navigation", subNavigationTemplate);
|
||||||
|
main.set("alerts", AlertEndpoint.getInstance().generateAlerts());
|
||||||
|
main.set("content", httpRespond(session, cookie, request));
|
||||||
|
|
||||||
|
|
||||||
|
out.print(main.compile());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
public class SymbolOverviewPage extends TraderPage {
|
public class SymbolOverviewPage extends TraderPage {
|
||||||
private static final int HISTORY_LIMIT = 200;
|
|
||||||
private static final String OVERVIEW_TEMPLATE = TraderContext.RESOURCE_WEB_ROOT + "/symbol_overview.tmpl";
|
private static final String OVERVIEW_TEMPLATE = TraderContext.RESOURCE_WEB_ROOT + "/symbol_overview.tmpl";
|
||||||
private static final String DETAIL_TEMPLATE = TraderContext.RESOURCE_WEB_ROOT + "/symbol_detail.tmpl";
|
private static final String DETAIL_TEMPLATE = TraderContext.RESOURCE_WEB_ROOT + "/symbol_detail.tmpl";
|
||||||
|
|
||||||
|
|
|
||||||
1345
src/main/resources/web/css/bootstrap-icons.css
vendored
Normal file
1345
src/main/resources/web/css/bootstrap-icons.css
vendored
Normal file
File diff suppressed because it is too large
Load diff
303
src/main/resources/web/css/bootstrap.css
vendored
303
src/main/resources/web/css/bootstrap.css
vendored
|
|
@ -1,6 +1,6 @@
|
||||||
@charset "UTF-8";
|
@charset "UTF-8";
|
||||||
/*!
|
/*!
|
||||||
* Bootstrap v5.0.0-beta2 (https://getbootstrap.com/)
|
* Bootstrap v5.0.0-beta3 (https://getbootstrap.com/)
|
||||||
* Copyright 2011-2021 The Bootstrap Authors
|
* Copyright 2011-2021 The Bootstrap Authors
|
||||||
* Copyright 2011-2021 Twitter, Inc.
|
* Copyright 2011-2021 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||||
|
|
@ -56,10 +56,6 @@ body {
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[tabindex="-1"]:focus:not(:focus-visible) {
|
|
||||||
outline: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
|
|
@ -130,7 +126,6 @@ p {
|
||||||
|
|
||||||
abbr[title],
|
abbr[title],
|
||||||
abbr[data-bs-original-title] {
|
abbr[data-bs-original-title] {
|
||||||
text-decoration: underline;
|
|
||||||
-webkit-text-decoration: underline dotted;
|
-webkit-text-decoration: underline dotted;
|
||||||
text-decoration: underline dotted;
|
text-decoration: underline dotted;
|
||||||
cursor: help;
|
cursor: help;
|
||||||
|
|
@ -336,6 +331,9 @@ select {
|
||||||
select {
|
select {
|
||||||
word-wrap: normal;
|
word-wrap: normal;
|
||||||
}
|
}
|
||||||
|
select:disabled {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
[list]::-webkit-calendar-picker-indicator {
|
[list]::-webkit-calendar-picker-indicator {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
@ -2184,10 +2182,6 @@ progress {
|
||||||
.form-control::-webkit-date-and-time-value {
|
.form-control::-webkit-date-and-time-value {
|
||||||
height: 1.5em;
|
height: 1.5em;
|
||||||
}
|
}
|
||||||
.form-control::-webkit-input-placeholder {
|
|
||||||
color: #6c757d;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
.form-control::-moz-placeholder {
|
.form-control::-moz-placeholder {
|
||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
|
@ -2359,7 +2353,6 @@ textarea.form-control-lg {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
}
|
}
|
||||||
.form-select:disabled {
|
.form-select:disabled {
|
||||||
color: #6c757d;
|
|
||||||
background-color: #e9ecef;
|
background-color: #e9ecef;
|
||||||
}
|
}
|
||||||
.form-select:-moz-focusring {
|
.form-select:-moz-focusring {
|
||||||
|
|
@ -2600,9 +2593,6 @@ textarea.form-control-lg {
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.form-floating > .form-control::-webkit-input-placeholder {
|
|
||||||
color: transparent;
|
|
||||||
}
|
|
||||||
.form-floating > .form-control::-moz-placeholder {
|
.form-floating > .form-control::-moz-placeholder {
|
||||||
color: transparent;
|
color: transparent;
|
||||||
}
|
}
|
||||||
|
|
@ -2796,6 +2786,12 @@ textarea.form-control-lg {
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.was-validated .input-group .form-control:valid, .input-group .form-control.is-valid,
|
||||||
|
.was-validated .input-group .form-select:valid,
|
||||||
|
.input-group .form-select.is-valid {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
.invalid-feedback {
|
.invalid-feedback {
|
||||||
display: none;
|
display: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -2872,6 +2868,12 @@ textarea.form-control-lg {
|
||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.was-validated .input-group .form-control:invalid, .input-group .form-control.is-invalid,
|
||||||
|
.was-validated .input-group .form-select:invalid,
|
||||||
|
.input-group .form-select.is-invalid {
|
||||||
|
z-index: 3;
|
||||||
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
@ -3546,11 +3548,9 @@ textarea.form-control-lg {
|
||||||
left: auto /* rtl:ignore */;
|
left: auto /* rtl:ignore */;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.dropup .dropdown-menu {
|
.dropup .dropdown-menu[data-bs-popper] {
|
||||||
top: auto;
|
top: auto;
|
||||||
bottom: 100%;
|
bottom: 100%;
|
||||||
}
|
|
||||||
.dropup .dropdown-menu[data-bs-popper] {
|
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-bottom: 0.125rem;
|
margin-bottom: 0.125rem;
|
||||||
}
|
}
|
||||||
|
|
@ -3887,6 +3887,11 @@ textarea.form-control-lg {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-fill .nav-item .nav-link,
|
||||||
|
.nav-justified .nav-item .nav-link {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-content > .tab-pane {
|
.tab-content > .tab-pane {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
@ -4268,7 +4273,7 @@ textarea.form-control-lg {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.card-link + .card-link {
|
.card-link + .card-link {
|
||||||
margin-left: 1rem /* rtl:ignore */;
|
margin-left: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-header {
|
.card-header {
|
||||||
|
|
@ -4381,8 +4386,8 @@ textarea.form-control-lg {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: #212529;
|
color: #212529;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
background-color: transparent;
|
background-color: #fff;
|
||||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
border: 0;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
overflow-anchor: none;
|
overflow-anchor: none;
|
||||||
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;
|
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;
|
||||||
|
|
@ -4392,12 +4397,10 @@ textarea.form-control-lg {
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.accordion-button.collapsed {
|
|
||||||
border-bottom-width: 0;
|
|
||||||
}
|
|
||||||
.accordion-button:not(.collapsed) {
|
.accordion-button:not(.collapsed) {
|
||||||
color: #0c63e4;
|
color: #0c63e4;
|
||||||
background-color: #e7f1ff;
|
background-color: #e7f1ff;
|
||||||
|
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.125);
|
||||||
}
|
}
|
||||||
.accordion-button:not(.collapsed)::after {
|
.accordion-button:not(.collapsed)::after {
|
||||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
|
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
|
||||||
|
|
@ -4433,47 +4436,53 @@ textarea.form-control-lg {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion-item:first-of-type .accordion-button {
|
.accordion-item {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||||
|
}
|
||||||
|
.accordion-item:first-of-type {
|
||||||
border-top-left-radius: 0.25rem;
|
border-top-left-radius: 0.25rem;
|
||||||
border-top-right-radius: 0.25rem;
|
border-top-right-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
.accordion-item:last-of-type .accordion-button.collapsed {
|
.accordion-item:first-of-type .accordion-button {
|
||||||
border-bottom-width: 1px;
|
border-top-left-radius: calc(0.25rem - 1px);
|
||||||
|
border-top-right-radius: calc(0.25rem - 1px);
|
||||||
|
}
|
||||||
|
.accordion-item:last-of-type {
|
||||||
|
margin-bottom: 0;
|
||||||
border-bottom-right-radius: 0.25rem;
|
border-bottom-right-radius: 0.25rem;
|
||||||
border-bottom-left-radius: 0.25rem;
|
border-bottom-left-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
.accordion-item:last-of-type .accordion-button.collapsed {
|
||||||
|
border-bottom-right-radius: calc(0.25rem - 1px);
|
||||||
|
border-bottom-left-radius: calc(0.25rem - 1px);
|
||||||
|
}
|
||||||
.accordion-item:last-of-type .accordion-collapse {
|
.accordion-item:last-of-type .accordion-collapse {
|
||||||
border-bottom-width: 1px;
|
|
||||||
border-bottom-right-radius: 0.25rem;
|
border-bottom-right-radius: 0.25rem;
|
||||||
border-bottom-left-radius: 0.25rem;
|
border-bottom-left-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion-collapse {
|
|
||||||
border: solid rgba(0, 0, 0, 0.125);
|
|
||||||
border-width: 0 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.accordion-body {
|
.accordion-body {
|
||||||
padding: 1rem 1.25rem;
|
padding: 1rem 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.accordion-flush .accordion-button {
|
.accordion-flush .accordion-collapse {
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
.accordion-flush .accordion-item {
|
||||||
border-right: 0;
|
border-right: 0;
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
.accordion-flush .accordion-collapse {
|
.accordion-flush .accordion-item:first-child {
|
||||||
border-width: 0;
|
border-top: 0;
|
||||||
}
|
}
|
||||||
.accordion-flush .accordion-item:first-of-type .accordion-button {
|
.accordion-flush .accordion-item:last-child {
|
||||||
border-top-width: 0;
|
border-bottom: 0;
|
||||||
border-top-left-radius: 0;
|
|
||||||
border-top-right-radius: 0;
|
|
||||||
}
|
}
|
||||||
.accordion-flush .accordion-item:last-of-type .accordion-button.collapsed {
|
.accordion-flush .accordion-item .accordion-button {
|
||||||
border-bottom-width: 0;
|
border-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
|
||||||
border-bottom-left-radius: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.breadcrumb {
|
.breadcrumb {
|
||||||
|
|
@ -4767,6 +4776,15 @@ textarea.form-control-lg {
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list-group-numbered {
|
||||||
|
list-style-type: none;
|
||||||
|
counter-reset: section;
|
||||||
|
}
|
||||||
|
.list-group-numbered > li::before {
|
||||||
|
content: counters(section, ".") ". ";
|
||||||
|
counter-increment: section;
|
||||||
|
}
|
||||||
|
|
||||||
.list-group-item-action {
|
.list-group-item-action {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
color: #495057;
|
color: #495057;
|
||||||
|
|
@ -4787,6 +4805,7 @@ textarea.form-control-lg {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.5rem 1rem;
|
||||||
|
color: #212529;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||||
|
|
@ -5178,7 +5197,7 @@ textarea.form-control-lg {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1050;
|
z-index: 1060;
|
||||||
display: none;
|
display: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
@ -5242,7 +5261,7 @@ textarea.form-control-lg {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 1040;
|
z-index: 1050;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
|
|
@ -5465,7 +5484,7 @@ textarea.form-control-lg {
|
||||||
}
|
}
|
||||||
.tooltip {
|
.tooltip {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1070;
|
z-index: 1080;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: var(--bs-font-sans-serif);
|
font-family: var(--bs-font-sans-serif);
|
||||||
|
|
@ -5567,7 +5586,7 @@ textarea.form-control-lg {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0 /* rtl:ignore */;
|
left: 0 /* rtl:ignore */;
|
||||||
z-index: 1060;
|
z-index: 1070;
|
||||||
display: block;
|
display: block;
|
||||||
max-width: 276px;
|
max-width: 276px;
|
||||||
font-family: var(--bs-font-sans-serif);
|
font-family: var(--bs-font-sans-serif);
|
||||||
|
|
@ -5972,6 +5991,86 @@ textarea.form-control-lg {
|
||||||
animation-duration: 1.5s;
|
animation-duration: 1.5s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.offcanvas {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 1040;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
max-width: 100%;
|
||||||
|
visibility: hidden;
|
||||||
|
background-color: #fff;
|
||||||
|
background-clip: padding-box;
|
||||||
|
outline: 0;
|
||||||
|
transition: transform 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.offcanvas {
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.offcanvas-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
}
|
||||||
|
.offcanvas-header .btn-close {
|
||||||
|
padding: 0.5rem 0.5rem;
|
||||||
|
margin: -0.5rem -0.5rem -0.5rem auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.offcanvas-title {
|
||||||
|
margin-bottom: 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.offcanvas-body {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.offcanvas-start {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 400px;
|
||||||
|
border-right: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.offcanvas-end {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 400px;
|
||||||
|
border-left: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.offcanvas-bottom {
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 30vh;
|
||||||
|
max-height: 100%;
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
|
transform: translateY(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.offcanvas.show {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.offcanvas-backdrop::before {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1039;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
content: "";
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
.clearfix::after {
|
.clearfix::after {
|
||||||
display: block;
|
display: block;
|
||||||
clear: both;
|
clear: both;
|
||||||
|
|
@ -6424,10 +6523,6 @@ textarea.form-control-lg {
|
||||||
border-color: #fff !important;
|
border-color: #fff !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.border-0 {
|
|
||||||
border-width: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-1 {
|
.border-1 {
|
||||||
border-width: 1px !important;
|
border-width: 1px !important;
|
||||||
}
|
}
|
||||||
|
|
@ -7098,6 +7193,10 @@ textarea.form-control-lg {
|
||||||
padding-left: 3rem !important;
|
padding-left: 3rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.font-monospace {
|
||||||
|
font-family: var(--bs-font-monospace) !important;
|
||||||
|
}
|
||||||
|
|
||||||
.fs-1 {
|
.fs-1 {
|
||||||
font-size: calc(1.375rem + 1.5vw) !important;
|
font-size: calc(1.375rem + 1.5vw) !important;
|
||||||
}
|
}
|
||||||
|
|
@ -7150,16 +7249,20 @@ textarea.form-control-lg {
|
||||||
font-weight: bolder !important;
|
font-weight: bolder !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-lowercase {
|
.lh-1 {
|
||||||
text-transform: lowercase !important;
|
line-height: 1 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-uppercase {
|
.lh-sm {
|
||||||
text-transform: uppercase !important;
|
line-height: 1.25 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-capitalize {
|
.lh-base {
|
||||||
text-transform: capitalize !important;
|
line-height: 1.5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lh-lg {
|
||||||
|
line-height: 2 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-start {
|
.text-start {
|
||||||
|
|
@ -7174,6 +7277,45 @@ textarea.form-control-lg {
|
||||||
text-align: center !important;
|
text-align: center !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-decoration-none {
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-decoration-underline {
|
||||||
|
text-decoration: underline !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-decoration-line-through {
|
||||||
|
text-decoration: line-through !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-lowercase {
|
||||||
|
text-transform: lowercase !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-uppercase {
|
||||||
|
text-transform: uppercase !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-capitalize {
|
||||||
|
text-transform: capitalize !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-wrap {
|
||||||
|
white-space: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-nowrap {
|
||||||
|
white-space: nowrap !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rtl:begin:remove */
|
||||||
|
.text-break {
|
||||||
|
word-wrap: break-word !important;
|
||||||
|
word-break: break-word !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* rtl:end:remove */
|
||||||
.text-primary {
|
.text-primary {
|
||||||
color: #0d6efd !important;
|
color: #0d6efd !important;
|
||||||
}
|
}
|
||||||
|
|
@ -7230,22 +7372,6 @@ textarea.form-control-lg {
|
||||||
color: inherit !important;
|
color: inherit !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.lh-1 {
|
|
||||||
line-height: 1 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lh-sm {
|
|
||||||
line-height: 1.25 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lh-base {
|
|
||||||
line-height: 1.5 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lh-lg {
|
|
||||||
line-height: 2 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bg-primary {
|
.bg-primary {
|
||||||
background-color: #0d6efd !important;
|
background-color: #0d6efd !important;
|
||||||
}
|
}
|
||||||
|
|
@ -7294,37 +7420,6 @@ textarea.form-control-lg {
|
||||||
background-image: var(--bs-gradient) !important;
|
background-image: var(--bs-gradient) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-wrap {
|
|
||||||
white-space: normal !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-nowrap {
|
|
||||||
white-space: nowrap !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-decoration-none {
|
|
||||||
text-decoration: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-decoration-underline {
|
|
||||||
text-decoration: underline !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-decoration-line-through {
|
|
||||||
text-decoration: line-through !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* rtl:begin:remove */
|
|
||||||
.text-break {
|
|
||||||
word-wrap: break-word !important;
|
|
||||||
word-break: break-word !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* rtl:end:remove */
|
|
||||||
.font-monospace {
|
|
||||||
font-family: var(--bs-font-monospace) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-select-all {
|
.user-select-all {
|
||||||
-webkit-user-select: all !important;
|
-webkit-user-select: all !important;
|
||||||
-moz-user-select: all !important;
|
-moz-user-select: all !important;
|
||||||
|
|
|
||||||
4
src/main/resources/web/css/bootstrap.min.css
vendored
4
src/main/resources/web/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
BIN
src/main/resources/web/fonts/bootstrap-icons.woff
Normal file
BIN
src/main/resources/web/fonts/bootstrap-icons.woff
Normal file
Binary file not shown.
BIN
src/main/resources/web/fonts/bootstrap-icons.woff2
Normal file
BIN
src/main/resources/web/fonts/bootstrap-icons.woff2
Normal file
Binary file not shown.
4384
src/main/resources/web/js/bootstrap.bundle.js
vendored
4384
src/main/resources/web/js/bootstrap.bundle.js
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
<!-- CSS -->
|
<!-- CSS -->
|
||||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="css/bootstrap-icons.css" rel="stylesheet">
|
||||||
<link href="css/bootstrap-switch.min.css" rel="stylesheet">
|
<link href="css/bootstrap-switch.min.css" rel="stylesheet">
|
||||||
<link href="css/trader.css" rel="stylesheet">
|
<link href="css/trader.css" rel="stylesheet">
|
||||||
|
|
||||||
|
|
@ -21,59 +22,26 @@
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
|
<main>
|
||||||
<a class="navbar-brand col-md-3 col-lg-2 me-0 px-3" href="#">Trader</a>
|
<nav class="navbar navbar-expand-md navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
|
||||||
<button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
|
<div class="container-fluid">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<a class="navbar-brand col-md-3 col-lg-2 me-0 px-3" href="#">
|
||||||
</button>
|
Trader
|
||||||
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
|
</a>
|
||||||
<ul class="navbar-nav px-3">
|
|
||||||
<li class="nav-item text-nowrap">
|
|
||||||
<a class="nav-link" href="#">Sign out</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="container-fluid">
|
{{navigation}}
|
||||||
<div class="row">
|
</div>
|
||||||
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
|
</nav>
|
||||||
<div class="position-sticky pt-3">
|
|
||||||
<ul class="nav flex-column">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link active" aria-current="page" href="#">
|
|
||||||
<span data-feather="home"></span>
|
|
||||||
Dashboard
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="#">
|
|
||||||
<span data-feather="file"></span>
|
|
||||||
Orders
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
<div class="container-fluid">
|
||||||
<span>Saved reports</span>
|
<div class="row">
|
||||||
<a class="link-secondary" href="#" aria-label="Add a new report">
|
{{sub_navigation}}
|
||||||
<span data-feather="plus-circle"></span>
|
|
||||||
</a>
|
|
||||||
</h6>
|
|
||||||
<ul class="nav flex-column mb-2">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="#">
|
|
||||||
<span data-feather="file-text"></span>
|
|
||||||
Current month
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
|
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
|
||||||
{{content}}
|
{{content}}
|
||||||
</main>
|
</main>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
50
src/main/resources/web/main_nav.tmpl
Normal file
50
src/main/resources/web/main_nav.tmpl
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarsExample04">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse navbar-collapse">
|
||||||
|
<ul class="navbar-nav me-auto mb-2 mb-md-0">
|
||||||
|
{{#rootNav}}
|
||||||
|
{{^.getSubNavs().length}}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link {{#.isActive()}}active{{/.isActive()}}" href="{{.getURL()}}" >{{.getName()}}</a>
|
||||||
|
</li>
|
||||||
|
{{/.getSubNavs().length}}
|
||||||
|
{{#.getSubNavs().length}}
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link dropdown-toggle {{#.isActive()}}active{{/.isActive()}}" href="#" data-bs-toggle="dropdown">{{.getName()}}</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
{{#.getSubNavs()}}
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" href="{{.getURL()}}">{{.getName()}}</a>
|
||||||
|
</li>
|
||||||
|
{{/.getSubNavs()}}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{{/.getSubNavs().length}}
|
||||||
|
{{/rootNav}}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<!-- User navigation -->
|
||||||
|
<ul class="navbar-nav navbar-right">
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-item dropdown-toggle" href="#" data-bs-toggle="dropdown">
|
||||||
|
<i class="bi bi-person"></i>
|
||||||
|
<strong>{{user.getUsername()}}</strong>
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li>
|
||||||
|
<div align="center">
|
||||||
|
<img src="{{user.getAvatarUrl()}}" />
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li class="divider"></li>
|
||||||
|
{{#userNav}}
|
||||||
|
<li>
|
||||||
|
<a class="dropdown-item" href="{{.getURL()}}">{{.getName()}}</a>
|
||||||
|
</li>
|
||||||
|
{{/userNav}}
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
12
src/main/resources/web/main_subnav.tmpl
Normal file
12
src/main/resources/web/main_subnav.tmpl
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!-- Sub navigation -->
|
||||||
|
<nav id="sub-navbar" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
|
||||||
|
<div class="position-sticky pt-3">
|
||||||
|
<ul class="nav flex-column">
|
||||||
|
{{#sub_navigation}}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link {{#.isActive()}}active{{/.isActive()}}" href="{{.getURL()}}">{{.getName()}}</a>
|
||||||
|
</li>
|
||||||
|
{{/sub_navigation}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<div class="panel panel-default drop-shadow">
|
<div class="panel panel-default drop-shadow">
|
||||||
<div class="panel-heading">Symbols</div>
|
<div class="panel-heading"></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
|
|
||||||
<table class="table table-hover table-condensed">
|
<table class="table table-hover table-condensed">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue