Add header as fragment

This commit is contained in:
Dmitry Isaenko 2023-12-29 19:59:49 +03:00
parent 6318e14bc8
commit 5b03cf8367
25 changed files with 371 additions and 99 deletions

View file

@ -58,6 +58,14 @@
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/org.thymeleaf.extras/thymeleaf-extras-springsecurity6 -->
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.h2database</groupId>
<artifactId>h2</artifactId> <artifactId>h2</artifactId>

View file

@ -16,6 +16,7 @@ import jakarta.persistence.Table;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.val;
import ru.redrise.marinesco.security.UserRole; import ru.redrise.marinesco.security.UserRole;
@Data @Data
@ -69,4 +70,8 @@ public class User implements UserDetails{
public void setRole(UserRole role){ // TODO public void setRole(UserRole role){ // TODO
this.authorities.add(role); this.authorities.add(role);
} }
public boolean isAdmin(){
return authorities.get(0).getAuthority().equals("ROLE_ADMIN");
}
} }

View file

@ -35,6 +35,11 @@ public class ManageUsersController {
return new UserGenerified(); return new UserGenerified();
} }
@ModelAttribute
public void addTitle(Model model){
model.addAttribute("header_text", "Manage users");
}
@ModelAttribute @ModelAttribute
public void addUsers(Model model){ public void addUsers(Model model){
Iterable<User> users = userRepository.findAll(); Iterable<User> users = userRepository.findAll();

View file

@ -50,7 +50,7 @@ public class SecurityConfig {
.requestMatchers(mvc.pattern("/styles/**")).permitAll() .requestMatchers(mvc.pattern("/styles/**")).permitAll()
.requestMatchers(mvc.pattern("/images/*")).permitAll() .requestMatchers(mvc.pattern("/images/*")).permitAll()
.requestMatchers(mvc.pattern("/register")).permitAll() .requestMatchers(mvc.pattern("/register")).permitAll()
.requestMatchers(mvc.pattern("/login")).permitAll() .requestMatchers(mvc.pattern("/login")).anonymous()
.requestMatchers(mvc.pattern("/error")).permitAll() .requestMatchers(mvc.pattern("/error")).permitAll()
.requestMatchers(PathRequest.toH2Console()).permitAll() .requestMatchers(PathRequest.toH2Console()).permitAll()
.requestMatchers(mvc.pattern("/")).hasAnyRole("ADMIN", "USER") .requestMatchers(mvc.pattern("/")).hasAnyRole("ADMIN", "USER")

View file

@ -1,16 +0,0 @@
package ru.redrise.marinesco.security;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/usersmanagment")
public class UserManagment {
@GetMapping
public String getPage(){
return "/usersmanagment";
}
}

View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="7.3839998mm"
height="9.467mm"
viewBox="0 0 7.3839995 9.467"
version="1.1"
id="svg5"
sodipodi:docname="s_logo.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#a535aa"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="1"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="22.627417"
inkscape:cx="28.704116"
inkscape:cy="30.383494"
inkscape:window-width="3755"
inkscape:window-height="2123"
inkscape:window-x="1165"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showguides="false"
inkscape:lockguides="true" />
<defs
id="defs2" />
<g
inkscape:label="Слой 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="rect2675"
style="opacity:1;fill:#00b185;fill-opacity:1;stroke:#ffffff;stroke-width:0.818015;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 0.4987411,2.6910294 6.8852589,0.40803435 c 0.047902,-0.017123 0.089733,0.0438099 0.089733,0.0982098 V 8.9576038 c 0,0.0544 -0.040032,0.09821 -0.089733,0.09821 0,0 -3.2433058,-2.0452477 -3.2433058,-3.8408636 0,-0.06402 0,-0.06402 0,0 0,1.7946379 -3.143212,3.8409356 -3.143212,3.8409356 -0.0383515,0.03461 -0.0897335,-0.04381 -0.0897335,-0.09821 V 2.7892412 c 0,-0.05441 0.0897335,-0.097032 0.0897335,-0.09821 z"
sodipodi:nodetypes="sssssssssscs" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -6,8 +6,8 @@
body { body {
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
margin-right: 1%; margin-right: 0;
margin-left: 1%; margin-left: 0;
font-family: Terminus; font-family: Terminus;
background-color: #212121; background-color: #212121;
color: #cfcfcf; color: #cfcfcf;
@ -19,7 +19,6 @@ body {
.header-container { .header-container {
text-align: left; text-align: left;
position: relative; position: relative;
color: white;
} }
.header-container .header-bar { .header-container .header-bar {
position: absolute; position: absolute;
@ -46,3 +45,79 @@ a:hover {
a:visited { a:visited {
color: #949494; color: #949494;
} }
ul{
list-style-type: none;
}
header{
display: block;
}
.header_wrapper{
background:#323833;
color: #a7a691;
vertical-align: top;
width:100%;
padding:0px;
margin-bottom: 20px;
display: inline-block;
}
.container{
width: 100%;
max-width: 1280px;
margin: 0 auto;
}
.header_branding{
float: left;
}
#header_right_block{
list-style-type: none;
list-style-image: none;
font-family: sans-serif;
height: 100%;
margin-right: 0;
right: 0;
float: right;
padding: 0%;
font-size: 0.9em;
}
.ul_right_block{
margin: 0 !important;
padding: 0 !important;
}
.li_right_block{
height: 100%;
}
.header_entry{
height: 65px;
line-height: 65px;
display: block;
border-left: 0;
border-top: 0;
text-decoration: none;
font-variant: small-caps;
text-shadow: -1px -1px 0 #1e1e1e, 1px -1px 0 #1e1e1e, -1px 1px 0 #1e1e1e, 1px 1px 0 #1e1e1e;
color:#74bfbd;
}
.header_entry_link:hover{
color: #b6a795;
}
.block{
display: block;
}
.block_inner{
margin-left: 10px;
margin-right: 10px;
}
a.entry{
text-decoration: none;
}
.header_title{
font-size: 1.5em;
}
hr{
border: 0;
border-bottom: 1px dashed;
background: none;
}

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head></head>
<body>
<div th:fragment="header" class="header_wrapper" >
<div class="container" >
<header>
<div class="header_branding block_inner">
<a href="/">
<img height="65px" th:src="@{/images/s_logo.svg}" alt="Marinesco">
</a>
</div>
<nav id="header_right_block" class="block">
<div class="block_inner">
<ul class="ul_right_block">
<li class="li_right_block" th:if="${#authorization.expression('!isAuthenticated()')}">
<a class="entry" href="/login" th:href="@{/login}">
<span class="header_entry header_entry_link">Sign in</span>
</a>
</li>
<li class="li_right_block" th:if="${#authorization.expression('isAuthenticated()')}">
<a class="entry" href="/logout">
<span class="header_entry header_entry_link">Logout</span>
</a>
<form style="visibility: hidden" id="form" method="post" action="#" th:action="@{/logout}"></form>
</li>
</ul>
</div>
</nav>
<div class="header_entry header_title">
Marinesco
</div>
<!--
<div th:replace="~{fragments/header :: ${#authentication.principal.isAdmin()} ? 'header-admin' : 'header'}"></div>
-->
</header>
</div>
</div>
</body>
</html>

View file

@ -8,7 +8,7 @@
</head> </head>
<body> <body>
<h1>FUCKING BRILLIANT LOGIN PAGE</h1> <div th:replace="~{fragments/header :: 'header'}"></div>
<img th:src="@{/images/logo.svg}" /> <img th:src="@{/images/logo.svg}" />
</body> </body>
<div class="container"> <div class="container">

View file

@ -8,8 +8,8 @@
</head> </head>
<body> <body>
<h1 th:text="${header_text}">Manage users</h1> <div th:replace="~{fragments/header :: 'header'}"></div>
<br /><a href="/">go back</a> <h1 th:text="${header_text}"></h1>
<p> <p>
<div th:each="user : ${USR}"> <div th:each="user : ${USR}">
<span th:text="${user.id+' '+user.name+' '+user.displayName}+' ROLES: '">user</span> <span th:text="${user.id+' '+user.name+' '+user.displayName}+' ROLES: '">user</span>
@ -28,20 +28,5 @@
</form> </form>
<br /> <br />
</div> </div>
<!--
<form method="POST" th:action="@{/profile/settings}" th:object="${userSettingsForm}">
<span class="validationError" th:if="${#fields.hasErrors('displayname')}" th:errors="*{displayname}">Error</span>
<br />
<label for="displayname">Displayed name: </label>
<input type="text" name="displayname" id="displayname" th:value="${userSettingsForm.displayname}" /><br />
<span class="validationError" th:if="${password_incorrect} != null" th:text="${password_incorrect}">false</span>
<br />
<label for="password">New password: </label>
<input type="password" name="newPassword" id="newPassword" /><br />
<input type="submit" value="Save Changes" />
</form>
-->
</body> </body>
</html> </html>

View file

@ -8,13 +8,11 @@
</head> </head>
<body> <body>
<h1>Welcome to Marinesco</h1> <div th:replace="~{fragments/header :: 'header'}"></div>
<img th:src="@{/images/logo.svg}" /> <img th:src="@{/images/logo.svg}" />
<br /><a href="/login">Login</a> <br /><a href="/login">Login</a>
<br /><a href="/profile">/profile</a> <br /><a href="/profile">/profile</a>
<br /><a href="/manage_users">/manage_users</a> <br /><a href="/manage_users">/manage_users</a>
<br />
<br /><a href="/logout">Log out</a>
</body> </body>
</html> </html>

View file

@ -8,6 +8,7 @@
</head> </head>
<body> <body>
<div th:replace="~{fragments/header :: 'header'}"></div>
<h1 th:text="${header_text}">welcome</h1> <h1 th:text="${header_text}">welcome</h1>
<form method="POST" th:action="@{/profile/settings}" th:object="${userSettingsForm}"> <!-- --> <form method="POST" th:action="@{/profile/settings}" th:object="${userSettingsForm}"> <!-- -->
<span class="validationError" th:if="${#fields.hasErrors('displayname')}" th:errors="*{displayname}">Error</span> <span class="validationError" th:if="${#fields.hasErrors('displayname')}" th:errors="*{displayname}">Error</span>

View file

@ -1,17 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>User managment</title>
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="stylesheet" th:href="@{/styles/styles.css}" />
</head>
<body>
<h1>User managment</h1>
<img th:src="@{/images/logo.svg}" />
<br /><a href="/logout">Log out</a>
</body>
</html>

View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="7.3839998mm"
height="9.467mm"
viewBox="0 0 7.3839995 9.467"
version="1.1"
id="svg5"
sodipodi:docname="s_logo.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#a535aa"
bordercolor="#eeeeee"
borderopacity="1"
inkscape:showpageshadow="0"
inkscape:pageopacity="1"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#505050"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="22.627417"
inkscape:cx="28.704116"
inkscape:cy="30.383494"
inkscape:window-width="3755"
inkscape:window-height="2123"
inkscape:window-x="1165"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
showguides="false"
inkscape:lockguides="true" />
<defs
id="defs2" />
<g
inkscape:label="Слой 1"
inkscape:groupmode="layer"
id="layer1">
<path
id="rect2675"
style="opacity:1;fill:#00b185;fill-opacity:1;stroke:#ffffff;stroke-width:0.818015;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 0.4987411,2.6910294 6.8852589,0.40803435 c 0.047902,-0.017123 0.089733,0.0438099 0.089733,0.0982098 V 8.9576038 c 0,0.0544 -0.040032,0.09821 -0.089733,0.09821 0,0 -3.2433058,-2.0452477 -3.2433058,-3.8408636 0,-0.06402 0,-0.06402 0,0 0,1.7946379 -3.143212,3.8409356 -3.143212,3.8409356 -0.0383515,0.03461 -0.0897335,-0.04381 -0.0897335,-0.09821 V 2.7892412 c 0,-0.05441 0.0897335,-0.097032 0.0897335,-0.09821 z"
sodipodi:nodetypes="sssssssssscs" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -6,8 +6,8 @@
body { body {
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
margin-right: 1%; margin-right: 0;
margin-left: 1%; margin-left: 0;
font-family: Terminus; font-family: Terminus;
background-color: #212121; background-color: #212121;
color: #cfcfcf; color: #cfcfcf;
@ -19,7 +19,6 @@ body {
.header-container { .header-container {
text-align: left; text-align: left;
position: relative; position: relative;
color: white;
} }
.header-container .header-bar { .header-container .header-bar {
position: absolute; position: absolute;
@ -46,3 +45,79 @@ a:hover {
a:visited { a:visited {
color: #949494; color: #949494;
} }
ul{
list-style-type: none;
}
header{
display: block;
}
.header_wrapper{
background:#323833;
color: #a7a691;
vertical-align: top;
width:100%;
padding:0px;
margin-bottom: 20px;
display: inline-block;
}
.container{
width: 100%;
max-width: 1280px;
margin: 0 auto;
}
.header_branding{
float: left;
}
#header_right_block{
list-style-type: none;
list-style-image: none;
font-family: sans-serif;
height: 100%;
margin-right: 0;
right: 0;
float: right;
padding: 0%;
font-size: 0.9em;
}
.ul_right_block{
margin: 0 !important;
padding: 0 !important;
}
.li_right_block{
height: 100%;
}
.header_entry{
height: 65px;
line-height: 65px;
display: block;
border-left: 0;
border-top: 0;
text-decoration: none;
font-variant: small-caps;
text-shadow: -1px -1px 0 #1e1e1e, 1px -1px 0 #1e1e1e, -1px 1px 0 #1e1e1e, 1px 1px 0 #1e1e1e;
color:#74bfbd;
}
.header_entry_link:hover{
color: #b6a795;
}
.block{
display: block;
}
.block_inner{
margin-left: 10px;
margin-right: 10px;
}
a.entry{
text-decoration: none;
}
.header_title{
font-size: 1.5em;
}
hr{
border: 0;
border-bottom: 1px dashed;
background: none;
}

View file

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>
<head></head>
<body>
<div th:fragment="header" class="header_wrapper" >
<div class="container" >
<header>
<div class="header_branding block_inner">
<a href="/">
<img height="65px" th:src="@{/images/s_logo.svg}" alt="Marinesco">
</a>
</div>
<nav id="header_right_block" class="block">
<div class="block_inner">
<ul class="ul_right_block">
<li class="li_right_block" th:if="${#authorization.expression('!isAuthenticated()')}">
<a class="entry" href="/login" th:href="@{/login}">
<span class="header_entry header_entry_link">Sign in</span>
</a>
</li>
<li class="li_right_block" th:if="${#authorization.expression('isAuthenticated()')}">
<a class="entry" href="/logout">
<span class="header_entry header_entry_link">Logout</span>
</a>
<form style="visibility: hidden" id="form" method="post" action="#" th:action="@{/logout}"></form>
</li>
</ul>
</div>
</nav>
<div class="header_entry header_title">
Marinesco
</div>
<!--
<div th:replace="~{fragments/header :: ${#authentication.principal.isAdmin()} ? 'header-admin' : 'header'}"></div>
-->
</header>
</div>
</div>
</body>
</html>

View file

@ -8,7 +8,7 @@
</head> </head>
<body> <body>
<h1>FUCKING BRILLIANT LOGIN PAGE</h1> <div th:replace="~{fragments/header :: 'header'}"></div>
<img th:src="@{/images/logo.svg}" /> <img th:src="@{/images/logo.svg}" />
</body> </body>
<div class="container"> <div class="container">

View file

@ -8,8 +8,8 @@
</head> </head>
<body> <body>
<h1 th:text="${header_text}">Manage users</h1> <div th:replace="~{fragments/header :: 'header'}"></div>
<br /><a href="/">go back</a> <h1 th:text="${header_text}"></h1>
<p> <p>
<div th:each="user : ${USR}"> <div th:each="user : ${USR}">
<span th:text="${user.id+' '+user.name+' '+user.displayName}+' ROLES: '">user</span> <span th:text="${user.id+' '+user.name+' '+user.displayName}+' ROLES: '">user</span>
@ -28,20 +28,5 @@
</form> </form>
<br /> <br />
</div> </div>
<!--
<form method="POST" th:action="@{/profile/settings}" th:object="${userSettingsForm}">
<span class="validationError" th:if="${#fields.hasErrors('displayname')}" th:errors="*{displayname}">Error</span>
<br />
<label for="displayname">Displayed name: </label>
<input type="text" name="displayname" id="displayname" th:value="${userSettingsForm.displayname}" /><br />
<span class="validationError" th:if="${password_incorrect} != null" th:text="${password_incorrect}">false</span>
<br />
<label for="password">New password: </label>
<input type="password" name="newPassword" id="newPassword" /><br />
<input type="submit" value="Save Changes" />
</form>
-->
</body> </body>
</html> </html>

View file

@ -8,13 +8,11 @@
</head> </head>
<body> <body>
<h1>Welcome to Marinesco</h1> <div th:replace="~{fragments/header :: 'header'}"></div>
<img th:src="@{/images/logo.svg}" /> <img th:src="@{/images/logo.svg}" />
<br /><a href="/login">Login</a> <br /><a href="/login">Login</a>
<br /><a href="/profile">/profile</a> <br /><a href="/profile">/profile</a>
<br /><a href="/manage_users">/manage_users</a> <br /><a href="/manage_users">/manage_users</a>
<br />
<br /><a href="/logout">Log out</a>
</body> </body>
</html> </html>

View file

@ -8,6 +8,7 @@
</head> </head>
<body> <body>
<div th:replace="~{fragments/header :: 'header'}"></div>
<h1 th:text="${header_text}">welcome</h1> <h1 th:text="${header_text}">welcome</h1>
<form method="POST" th:action="@{/profile/settings}" th:object="${userSettingsForm}"> <!-- --> <form method="POST" th:action="@{/profile/settings}" th:object="${userSettingsForm}"> <!-- -->
<span class="validationError" th:if="${#fields.hasErrors('displayname')}" th:errors="*{displayname}">Error</span> <span class="validationError" th:if="${#fields.hasErrors('displayname')}" th:errors="*{displayname}">Error</span>

View file

@ -1,17 +0,0 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>User managment</title>
<link rel="icon" type="image/x-icon" href="/favicon.ico">
<link rel="stylesheet" th:href="@{/styles/styles.css}" />
</head>
<body>
<h1>User managment</h1>
<img th:src="@{/images/logo.svg}" />
<br /><a href="/logout">Log out</a>
</body>
</html>