Merge pull request '1-db' (#2) from 1-db into master
Reviewed-on: http://git.athene.tech/romanov73/seminar/pulls/2
This commit is contained in:
commit
f8ff29e989
15
build.gradle
15
build.gradle
@ -32,12 +32,19 @@ dependencies {
|
|||||||
versionSwagger = '2.5.0'
|
versionSwagger = '2.5.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
|
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web'
|
||||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'
|
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jetty'
|
||||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
|
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf'
|
||||||
implementation group: 'org.slf4j', name: 'slf4j-api', version: versionSLF4J
|
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation'
|
||||||
|
implementation group: 'org.springframework.boot', name:'spring-boot-starter-data-jpa'
|
||||||
|
//implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security'
|
||||||
|
implementation group: 'org.slf4j', name: 'slf4j-api', version: versionSLF4J
|
||||||
implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect'
|
implementation group: 'nz.net.ultraq.thymeleaf', name: 'thymeleaf-layout-dialect'
|
||||||
implementation group: 'org.javassist', name: 'javassist', version: '3.25.0-GA'
|
//implementation group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-springsecurity5'
|
||||||
|
implementation group: 'com.h2database', name:'h2'
|
||||||
|
implementation group: 'javax.xml.bind', name:'jaxb-api'
|
||||||
|
implementation group: 'org.javassist', name:'javassist'
|
||||||
|
|
||||||
implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: versionJetty
|
implementation group: 'org.eclipse.jetty', name: 'jetty-servlet', version: versionJetty
|
||||||
|
|
||||||
implementation group: 'org.webjars', name: 'jquery', version: '3.6.0'
|
implementation group: 'org.webjars', name: 'jquery', version: '3.6.0'
|
||||||
|
BIN
data/db.mv.db
Normal file
BIN
data/db.mv.db
Normal file
Binary file not shown.
@ -20,7 +20,9 @@ import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
|||||||
public class MvcConfiguration implements WebMvcConfigurer {
|
public class MvcConfiguration implements WebMvcConfigurer {
|
||||||
@Override
|
@Override
|
||||||
public void addViewControllers(ViewControllerRegistry registry) {
|
public void addViewControllers(ViewControllerRegistry registry) {
|
||||||
registry.addViewController("/{articlename:\\w+}");
|
registry.addViewController("/index");
|
||||||
|
registry.addViewController("/admin");
|
||||||
|
registry.addViewController("/editNews");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -9,20 +9,20 @@ package ru.ulstu.controller;
|
|||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import ru.ulstu.model.News;
|
import ru.ulstu.service.NewsService;
|
||||||
|
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class IndexController {
|
public class IndexController {
|
||||||
|
|
||||||
|
private final NewsService newsService;
|
||||||
|
|
||||||
|
public IndexController(NewsService newsService) {
|
||||||
|
this.newsService = newsService;
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public String index(Model model) {
|
public String index(Model model) {
|
||||||
model.addAttribute("news", List.of(new News("Открытие семинара", new GregorianCalendar(2022, 4, 1).getTime(),
|
model.addAttribute("news", newsService.getAll());
|
||||||
"На кафере \"Информационные системы\" Ульяновского государственного технического университета состоится открытие постоянно действующего семинара \"Анализ данных и процессов\". Семинар планируется проводить ежемесячно."),
|
|
||||||
new News("Открытие семинара", new GregorianCalendar(2022, 4, 1).getTime(),
|
|
||||||
"На кафере \"Информационные системы\" Ульяновского государственного технического университета состоится открытие постоянно действующего семинара \"Анализ данных и процессов\". Семинар планируется проводить ежемесячно.")));
|
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
56
src/main/java/ru/ulstu/controller/NewsController.java
Normal file
56
src/main/java/ru/ulstu/controller/NewsController.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||||
|
* You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ru.ulstu.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import ru.ulstu.model.News;
|
||||||
|
import ru.ulstu.service.NewsService;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class NewsController {
|
||||||
|
private final NewsService newsService;
|
||||||
|
|
||||||
|
public NewsController(NewsService newsService) {
|
||||||
|
this.newsService = newsService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/editNews/{newsId}")
|
||||||
|
public String editNews(@PathVariable(value = "newsId") Integer id, Model model) {
|
||||||
|
model.addAttribute("news", (id != null && id != 0) ? newsService.getById(id) : new News());
|
||||||
|
return "editNews";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/news/{newsId}")
|
||||||
|
public String viewNews(@PathVariable(value = "newsId") Integer id, Model model) {
|
||||||
|
model.addAttribute("news", id != null ? newsService.getById(id) : new News());
|
||||||
|
return "news";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("saveNews")
|
||||||
|
public String saveNews(@Valid @ModelAttribute News news, BindingResult result) {
|
||||||
|
if (result.hasErrors()) {
|
||||||
|
return "editNews";
|
||||||
|
}
|
||||||
|
newsService.save(news);
|
||||||
|
|
||||||
|
return "redirect:/";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("deleteNews/{newsId}")
|
||||||
|
public String delete(@PathVariable(value = "newsId") Integer id) {
|
||||||
|
newsService.delete(id);
|
||||||
|
return "redirect:/";
|
||||||
|
}
|
||||||
|
}
|
83
src/main/java/ru/ulstu/model/BaseEntity.java
Normal file
83
src/main/java/ru/ulstu/model/BaseEntity.java
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package ru.ulstu.model;
|
||||||
|
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.MappedSuperclass;
|
||||||
|
import javax.persistence.Version;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@MappedSuperclass
|
||||||
|
public abstract class BaseEntity implements Serializable, Comparable<BaseEntity> {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.TABLE)
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
@Version
|
||||||
|
private Integer version;
|
||||||
|
|
||||||
|
public Integer getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Integer id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVersion(Integer version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getClass().isAssignableFrom(obj.getClass())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
BaseEntity other = (BaseEntity) obj;
|
||||||
|
if (id == null) {
|
||||||
|
if (other.id != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!id.equals(other.id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + (id == null ? 0 : id.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getSimpleName() + "{" +
|
||||||
|
"id=" + id +
|
||||||
|
", version=" + version +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(@NotNull BaseEntity o) {
|
||||||
|
return id != null ? id.compareTo(o.getId()) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
this.id = null;
|
||||||
|
this.version = null;
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,28 @@
|
|||||||
package ru.ulstu.model;
|
package ru.ulstu.model;
|
||||||
|
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
public class News {
|
@Entity
|
||||||
private final static int MAX_NEWS_TEXT_PREVIEW_LENGTH = 200;
|
public class News extends BaseEntity {
|
||||||
private final String title;
|
private final static int MAX_NEWS_TEXT_PREVIEW_LENGTH = 800;
|
||||||
private final Date date;
|
|
||||||
private final String text;
|
@NotEmpty(message = "Заголовок не может быть пустым")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
|
||||||
|
private Date date;
|
||||||
|
|
||||||
|
@Lob
|
||||||
|
@NotEmpty(message = "Текст новости не может быть пустым")
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
public News() {
|
||||||
|
}
|
||||||
|
|
||||||
public News(String title, Date date, String text) {
|
public News(String title, Date date, String text) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
@ -22,12 +38,24 @@ public class News {
|
|||||||
return date;
|
return date;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDate(Date date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
public String getText() {
|
public String getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPreview() {
|
public String getPreview() {
|
||||||
return text.length() > MAX_NEWS_TEXT_PREVIEW_LENGTH
|
return text != null && text.length() > MAX_NEWS_TEXT_PREVIEW_LENGTH
|
||||||
? text.substring(0, MAX_NEWS_TEXT_PREVIEW_LENGTH) + "..."
|
? text.substring(0, MAX_NEWS_TEXT_PREVIEW_LENGTH) + "..."
|
||||||
: text;
|
: text;
|
||||||
}
|
}
|
||||||
|
7
src/main/java/ru/ulstu/repository/NewsRepository.java
Normal file
7
src/main/java/ru/ulstu/repository/NewsRepository.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package ru.ulstu.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import ru.ulstu.model.News;
|
||||||
|
|
||||||
|
public interface NewsRepository extends JpaRepository<News, Integer> {
|
||||||
|
}
|
49
src/main/java/ru/ulstu/service/NewsService.java
Normal file
49
src/main/java/ru/ulstu/service/NewsService.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package ru.ulstu.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.model.News;
|
||||||
|
import ru.ulstu.repository.NewsRepository;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class NewsService {
|
||||||
|
private final NewsRepository newsRepository;
|
||||||
|
|
||||||
|
public NewsService(NewsRepository newsRepository) {
|
||||||
|
this.newsRepository = newsRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create(String title, String text) {
|
||||||
|
newsRepository.save(new News(title, new Date(), text));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void create(News news) {
|
||||||
|
news.setDate(new Date());
|
||||||
|
newsRepository.save(news);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(News news) {
|
||||||
|
if (news.getId() != null && (news.getId() != 0)) {
|
||||||
|
newsRepository.save(news);
|
||||||
|
} else {
|
||||||
|
create(news);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public News getById(@NotNull Integer id) {
|
||||||
|
return newsRepository
|
||||||
|
.findById(id)
|
||||||
|
.orElseThrow(() -> new RuntimeException("Новость не найдена"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<News> getAll() {
|
||||||
|
return newsRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(Integer id) {
|
||||||
|
newsRepository.deleteById(id);
|
||||||
|
}
|
||||||
|
}
|
@ -8,3 +8,11 @@ spring.main.banner-mode=off
|
|||||||
logging.level.tech.athene=DEBUG
|
logging.level.tech.athene=DEBUG
|
||||||
server.port=8080
|
server.port=8080
|
||||||
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
|
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
|
||||||
|
# go to http://localhost:8080/h2-console
|
||||||
|
spring.datasource.url=jdbc:h2:file:./data/db
|
||||||
|
spring.datasource.driverClassName=org.h2.Driver
|
||||||
|
spring.datasource.username=sa
|
||||||
|
spring.datasource.password=password
|
||||||
|
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
|
||||||
|
spring.h2.console.enabled=true
|
||||||
|
spring.jpa.hibernate.ddl-auto=update
|
||||||
|
@ -9,18 +9,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.news-item {
|
.news-item {
|
||||||
margin: 20px;
|
|
||||||
position: relative;
|
|
||||||
text-align: justify;
|
text-align: justify;
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-date {
|
.news-date {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
position: absolute;
|
text-align: right;
|
||||||
bottom: 0;
|
|
||||||
right: 25px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.news-image {
|
.news-image {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-dark, .link-dark:visited, .link-dark:focus {
|
||||||
|
color: black;
|
||||||
}
|
}
|
BIN
src/main/resources/static/favicon.ico
Normal file
BIN
src/main/resources/static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
16
src/main/resources/templates/admin.html
Normal file
16
src/main/resources/templates/admin.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||||
|
~ You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
|
||||||
|
<html
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<div class="container" layout:fragment="content">
|
||||||
|
<a href="/editNews/0" class="btn btn-outline-dark">
|
||||||
|
<i class="fa fa-plus-square" aria-hidden="true"> Добавить новость</i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</html>
|
@ -17,12 +17,12 @@
|
|||||||
<link rel="stylesheet" href="/webjars/bootstrap/4.6.0/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="/webjars/bootstrap/4.6.0/css/bootstrap.min.css"/>
|
||||||
<link rel="stylesheet" href="/webjars/bootstrap-select/1.13.8/css/bootstrap-select.min.css"/>
|
<link rel="stylesheet" href="/webjars/bootstrap-select/1.13.8/css/bootstrap-select.min.css"/>
|
||||||
<link rel="stylesheet" href="/webjars/font-awesome/4.7.0/css/font-awesome.min.css"/>
|
<link rel="stylesheet" href="/webjars/font-awesome/4.7.0/css/font-awesome.min.css"/>
|
||||||
<link rel="stylesheet" href="css/main.css"/>
|
<link rel="stylesheet" href="/css/main.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<nav class="navbar navbar-expand-md navbar-light bg-white">
|
<nav class="navbar navbar-expand-md navbar-light bg-white">
|
||||||
<a class="navbar-brand" href="/">
|
<a class="navbar-brand" href="/">
|
||||||
<img src="img/logo.svg" width="50px">
|
<img src="/img/logo.svg" width="50px">
|
||||||
<div class="navbar-text" th:text="#{messages.logo-title}" style="font-size: 16px"></div>
|
<div class="navbar-text" th:text="#{messages.logo-title}" style="font-size: 16px"></div>
|
||||||
</a>
|
</a>
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
|
||||||
@ -32,13 +32,16 @@
|
|||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
<ul class="navbar-nav mr-auto">
|
<ul class="navbar-nav mr-auto">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="news">Новости</a>
|
<a class="nav-link" href="/news">Новости</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="news">Заседания</a>
|
<a class="nav-link" href="/news">Заседания</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="news">Отчеты</a>
|
<a class="nav-link" href="/news">Отчеты</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="/admin">Администратору</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
34
src/main/resources/templates/editNews.html
Normal file
34
src/main/resources/templates/editNews.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||||
|
~ You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
|
||||||
|
<html
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<div class="container" layout:fragment="content">
|
||||||
|
<h3>Редактирование новости:</h3>
|
||||||
|
<form action="#" th:action="@{/saveNews}" th:object="${news}" method="post">
|
||||||
|
<input type="hidden" th:field="*{id}">
|
||||||
|
<input type="hidden" th:field="*{date}">
|
||||||
|
<input type="hidden" th:field="*{version}">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="title">Заголовок</label>
|
||||||
|
<input type="text" class="form-control" id="title" th:field="*{title}" placeholder="Заголовок новости">
|
||||||
|
<p th:if="${#fields.hasErrors('title')}" th:class="${#fields.hasErrors('title')}? error">
|
||||||
|
Не может быть пустым</p>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="text">Текст новости</label>
|
||||||
|
<textarea class="form-control" id="text" th:field="*{text}" placeholder="Текст новости"
|
||||||
|
style="height: 300px"></textarea>
|
||||||
|
<p th:if="${#fields.hasErrors('text')}" th:class="${#fields.hasErrors('text')}? error">
|
||||||
|
Не может быть пустым</p>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-outline-dark">Сохранить</button>
|
||||||
|
<a href="javascript:history.back()" class="btn btn-outline-dark">Отмена</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</html>
|
@ -8,23 +8,32 @@
|
|||||||
<html
|
<html
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
|
||||||
layout:decorate="~{default}">
|
layout:decorate="~{default}">
|
||||||
<head>
|
|
||||||
<title>Time series smoothing</title>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
||||||
</head>
|
|
||||||
<div class="container" layout:fragment="content">
|
<div class="container" layout:fragment="content">
|
||||||
<div th:each="n : ${news}" class="news">
|
<div th:each="n : ${news}" class="news">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<img class="news-image" src="img/logo.svg"/>
|
<img class="news-image" src="/img/logo.svg"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<h5 th:text="${n.title}"/>
|
<div class="row">
|
||||||
|
<div class="col-md-10">
|
||||||
|
<a th:href="@{'/news/' + ${n.id}}" class="link-dark"><h5 th:text="${n.title}"/></a>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2" style="text-align: right">
|
||||||
|
<a th:href="@{'/editNews/' + ${n.id}}" class="link-dark">
|
||||||
|
<i class="fa fa-pencil" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
<a th:href="@{'/deleteNews/' + ${n.id}}" class="link-dark"
|
||||||
|
onclick="return confirm('Удалить новость?')">
|
||||||
|
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div th:text="${n.preview}" class="news-item"></div>
|
<div th:text="${n.preview}" class="news-item"></div>
|
||||||
<div th:text="${'Опубликовано: ' + #calendars.format(n.date, 'dd.MM.yyyy HH:mm')}"
|
|
||||||
class="news-date"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div th:text="${'Опубликовано: ' + #calendars.format(n.date, 'dd.MM.yyyy HH:mm')}"
|
||||||
|
class="news-date"></div>
|
||||||
<hr/>
|
<hr/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
25
src/main/resources/templates/news.html
Normal file
25
src/main/resources/templates/news.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright (C) 2021 Anton Romanov - All Rights Reserved
|
||||||
|
~ You may use, distribute and modify this code, please write to: romanov73@gmail.com.
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
|
||||||
|
<html
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
|
||||||
|
layout:decorate="~{default}">
|
||||||
|
<div class="container" layout:fragment="content">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<img class="news-image" src="/img/logo.svg"/>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h5 th:text="${news.title}"/>
|
||||||
|
<div th:text="${news.text}" class="news-item"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:text="${'Опубликовано: ' + #calendars.format(news.date, 'dd.MM.yyyy HH:mm')}"
|
||||||
|
class="news-date"></div>
|
||||||
|
<a href="javascript:history.back()" class="btn btn-outline-dark" style="text-align: right">Назад</a>
|
||||||
|
</div>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user