finished project pages

This commit is contained in:
Jake Potrebic 2020-08-10 14:31:56 -07:00 committed by Jake Potrebic
parent 51d9992dcb
commit b833bc0f0d
14 changed files with 87 additions and 156 deletions

View File

@ -27,7 +27,7 @@ function bindExpand(e) {
'</li>'
);
var link = childPage.find('a');
link.attr("href", '/' + namespace + '/pages/' + page.fullSlug);
link.attr("href", namespace + '/pages/' + page.fullSlug);
link.text(page.name); // this will sanitize the input
div.append(childPage);
}

View File

@ -1,25 +1,43 @@
package me.minidigger.hangar.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import me.minidigger.hangar.db.dao.HangarDao;
import me.minidigger.hangar.db.dao.UserDao;
import me.minidigger.hangar.db.model.ProjectPagesTable;
import me.minidigger.hangar.db.model.UsersTable;
import me.minidigger.hangar.model.viewhelpers.ProjectPage;
import me.minidigger.hangar.service.project.PagesSerivce;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.server.ResponseStatusException;
import me.minidigger.hangar.db.dao.HangarDao;
import me.minidigger.hangar.db.dao.UserDao;
import me.minidigger.hangar.db.model.UsersTable;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@Controller
public class Apiv1Controller extends HangarController {
private final ObjectMapper mapper;
private final PagesSerivce pagesSerivce;
private final HangarDao<UserDao> userDao;
@Autowired
public Apiv1Controller(HangarDao<UserDao> userDao) {
public Apiv1Controller(ObjectMapper mapper, PagesSerivce pagesSerivce, HangarDao<UserDao> userDao) {
this.mapper = mapper;
this.pagesSerivce = pagesSerivce;
this.userDao = userDao;
}
@ -50,9 +68,27 @@ public class Apiv1Controller extends HangarController {
return null; // TODO implement revokeKey request controller
}
@RequestMapping("/api/v1/projects/{pluginId}/pages")
public Object listPages(@PathVariable Object pluginId, @RequestParam Object parentId) {
return null; // TODO implement listPages request controller
@GetMapping(value = "/api/v1/projects/{pluginId}/pages", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ArrayNode> listPages(@PathVariable String pluginId, @RequestParam(required = false) Long parentId) {
List<ProjectPage> pages = pagesSerivce.getPages(pluginId);
ArrayNode pagesArray = mapper.createArrayNode();
pages.stream().filter(p -> {
if (parentId != null) {
return parentId.equals(p.getParentId());
} else return true;
}).forEach(page -> {
ObjectNode pageObj = mapper.createObjectNode();
pageObj.set("createdAt", mapper.valueToTree(page.getCreatedAt()));
pageObj.set("id", mapper.valueToTree(page.getId()));
pageObj.set("name", mapper.valueToTree(page.getName()));
pageObj.set("parentId", mapper.valueToTree(page.getParentId()));
String[] slug = page.getSlug().split("/");
pageObj.set("slug", mapper.valueToTree(slug[slug.length - 1]));
pageObj.set("fullSlug", mapper.valueToTree(page.getSlug()));
pagesArray.add(pageObj);
});
if (pagesArray.isEmpty()) throw new ResponseStatusException(HttpStatus.NOT_FOUND);
return ResponseEntity.ok(pagesArray);
}
@RequestMapping("/api/v1/projects/{pluginId}/versions")

View File

@ -75,12 +75,11 @@ public class PagesController extends HangarController {
String pageName = getPageName(page, subPage);
ModelAndView mav = new ModelAndView("projects/pages/view");
ProjectData projectData = projectService.getProjectData(author, slug);
ProjectPage projectPage = ProjectPage.of(pagesSerivce.getPage(projectData.getProject().getId(), pageName));
ProjectPage projectPage = pagesSerivce.getPage(projectData.getProject().getId(), pageName);
mav.addObject("p", projectData);
ScopedProjectData sp = projectService.getScopedProjectData(projectData.getProject().getId());
mav.addObject("sp", sp);
mav.addObject("page", projectPage);
mav.addObject("parentPage");
mav.addObject("projectPage", projectPage);
mav.addObject("editorOpen", false);
pagesSerivce.fillPages(mav, projectData.getProject().getId());
return fillModel(mav);
@ -148,13 +147,12 @@ public class PagesController extends HangarController {
String pageName = getPageName(page, subPage);
ModelAndView mav = new ModelAndView("projects/pages/view");
ProjectData projectData = projectService.getProjectData(author, slug);
ProjectPage projectPage = ProjectPage.of(pagesSerivce.getPage(projectData.getProject().getId(), pageName));
ProjectPage projectPage = pagesSerivce.getPage(projectData.getProject().getId(), pageName);
if (projectPage == null) throw new ResponseStatusException(HttpStatus.NOT_FOUND);
mav.addObject("p", projectData);
ScopedProjectData sp = projectService.getScopedProjectData(projectData.getProject().getId());
mav.addObject("sp", sp);
mav.addObject("page", projectPage);
mav.addObject("parentPage"); // TODO parentPage
mav.addObject("projectPage", projectPage);
mav.addObject("editorOpen", true);
pagesSerivce.fillPages(mav, projectData.getProject().getId());
return fillModel(mav);

View File

@ -187,8 +187,7 @@ public class ProjectsController extends HangarController {
mav.addObject("p", projectData);
ScopedProjectData sp = projectService.getScopedProjectData(projectData.getProject().getId());
mav.addObject("sp", sp);
mav.addObject("page", ProjectPage.of(pagesSerivce.getPage(projectData.getProject().getId(), hangarConfig.pages.home.getName())));
mav.addObject("parentPage"); // TODO parent page
mav.addObject("projectPage", pagesSerivce.getPage(projectData.getProject().getId(), hangarConfig.pages.home.getName()));
mav.addObject("editorOpen", false);
pagesSerivce.fillPages(mav, projectData.getProject().getId());
return fillModel(mav);

View File

@ -13,10 +13,10 @@ import org.springframework.stereotype.Repository;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Repository
@RegisterBeanMapper(ProjectPagesTable.class)
@RegisterBeanMapper(ProjectPage.class)
public interface ProjectPageDao {
@SqlUpdate("INSERT INTO project_pages (created_at, project_id, name, slug, contents, is_deletable, parent_id) VALUES (:now, :projectId, :name, :slug, :contents, :isDeletable, :parentId)")
@ -32,10 +32,13 @@ public interface ProjectPageDao {
void delete(@BindBean ProjectPagesTable projectPagesTable);
@SqlQuery("SELECT * FROM project_pages WHERE project_id = :projectId AND (lower(slug) = lower(:pageName) OR id = :pageId)")
ProjectPagesTable getPage(long projectId, String pageName, Long pageId);
ProjectPage getPage(long projectId, String pageName, Long pageId);
@SqlQuery("SELECT pp.* FROM project_pages pp JOIN projects p ON pp.project_id = p.id WHERE p.plugin_id = :pluginId")
List<ProjectPage> getPages(String pluginId);
@SqlQuery("WITH RECURSIVE parents AS (SELECT * FROM project_pages WHERE project_id = :projectId AND (name = :pageName OR id = :pageId) UNION SELECT pp.* FROM project_pages pp INNER JOIN parents par ON par.id = pp.parent_id) SELECT * FROM parents")
List<ProjectPagesTable> getPageParents(long projectId, String pageName, Long pageId);
List<ProjectPage> getPageParents(long projectId, String pageName, Long pageId);
@RegisterBeanMapper(ProjectPage.class)
@KeyColumn("id")

View File

@ -1,8 +1,5 @@
package me.minidigger.hangar.db.model;
import org.springframework.lang.Nullable;
import java.time.OffsetDateTime;
public class ProjectPagesTable {
@ -14,12 +11,9 @@ public class ProjectPagesTable {
private String slug;
private String contents;
private boolean isDeletable;
@Nullable
private Long parentId;
public ProjectPagesTable(long id, OffsetDateTime createdAt, long projectId, String name, String slug, String contents, boolean isDeletable, Long parentId) {
this.id = id;
this.createdAt = createdAt;
public ProjectPagesTable(long projectId, String name, String slug, String contents, boolean isDeletable, Long parentId) {
this.projectId = projectId;
this.name = name;
this.slug = slug;

View File

@ -1,108 +1,16 @@
package me.minidigger.hangar.model.viewhelpers;
import me.minidigger.hangar.db.model.ProjectPagesTable;
import org.jdbi.v3.core.annotation.Unmappable;
import org.springframework.lang.Nullable;
import java.time.OffsetDateTime;
public class ProjectPage extends ProjectPagesTable {
public class ProjectPage {
private ProjectPagesTable table;
private long id;
private OffsetDateTime createdAt;
private String name;
private String slug;
private String contents;
private boolean isDeletable;
@Nullable
private Long parentId;
public ProjectPage(long id, OffsetDateTime createdAt, String name, String slug, String contents, boolean isDeletable, @Nullable Long parentId, ProjectPagesTable table) {
this.createdAt = createdAt;
this.name = name;
this.slug = slug;
this.contents = contents;
this.isDeletable = isDeletable;
this.parentId = parentId;
this.table = table;
public ProjectPage(long projectId, String name, String slug, String contents, boolean isDeletable, Long parentId) {
super(projectId, name, slug, contents, isDeletable, parentId);
}
public ProjectPage() {
//
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public OffsetDateTime getCreatedAt() {
return createdAt;
}
public void setCreatedAt(OffsetDateTime createdAt) {
this.createdAt = createdAt;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getContents() {
return contents;
}
public void setContents(String contents) {
this.contents = contents;
}
public boolean isDeletable() {
return isDeletable;
}
public void setDeletable(boolean deletable) {
isDeletable = deletable;
}
@Nullable
public Long getParentId() {
return parentId;
}
public void setParentId(@Nullable Long parentId) {
this.parentId = parentId;
}
public ProjectPage() { }
public boolean isHome() {
return name.equals("Home") && parentId == null; // TODO check against config default
}
// public String getFullSlug(ProjectPage parent) {
// if (parent != null) {
// return parent.table.getSlug() + "/" + slug;
// }
// return slug;
// }
public static ProjectPage of(ProjectPagesTable pagesTable) {
if (pagesTable == null) return null;
return new ProjectPage(pagesTable.getId(), pagesTable.getCreatedAt(), pagesTable.getName(), pagesTable.getSlug(), pagesTable.getContents(), pagesTable.getIsDeletable(), pagesTable.getParentId(), pagesTable);
return this.getName().equals("Home") && this.getParentId() == null; // TODO check against config default
}
}

View File

@ -22,6 +22,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Service
public class UserActionLogService {
@ -54,8 +55,8 @@ public class UserActionLogService {
loggedActionType.getValue(),
loggedActionType.getActionContext().getProjectId(),
loggedActionType.getActionContext().getPageId(),
newState,
oldState
Objects.toString(newState, ""),
Objects.toString(oldState, "")
);
actionsDao.get().insertProjectPageLog(log);
}
@ -67,8 +68,8 @@ public class UserActionLogService {
loggedActionType.getValue(),
loggedActionType.getActionContext().getProjectId(),
loggedActionType.getActionContext().getVersionId(),
newState,
oldState
Objects.toString(newState, ""),
Objects.toString(oldState, "")
);
actionsDao.get().insertVersionLog(log);
}
@ -79,8 +80,8 @@ public class UserActionLogService {
getInetAddress(request),
loggedActionType.getValue(),
loggedActionType.getActionContext().getUserId(),
newState,
oldState
Objects.toString(newState, ""),
Objects.toString(oldState, "")
);
actionsDao.get().insertUserLog(log);
}
@ -91,8 +92,8 @@ public class UserActionLogService {
getInetAddress(request),
loggedActionType.getValue(),
loggedActionType.getActionContext().getOrganizationLog(),
newState,
oldState
Objects.toString(newState, ""),
Objects.toString(oldState, "")
);
actionsDao.get().insertOrganizationLog(log);
}

View File

@ -13,7 +13,6 @@ import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import java.time.OffsetDateTime;
import java.util.Map;
@Component
@ -40,9 +39,7 @@ public class PagesFactory {
throw new HangarException("error.minLength");
}
ProjectPagesTable table = new ProjectPagesTable(
-1,
OffsetDateTime.now(),
ProjectPagesTable table = new ProjectPage(
projectId,
name,
StringUtils.slugify(slug),

View File

@ -29,11 +29,13 @@ public class PagesSerivce {
this.projectPageDao = projectPageDao;
}
public ProjectPagesTable getPage(long projectId, String pageName) {
ProjectPagesTable projectPagesTable = projectPageDao.get().getPage(projectId, StringUtils.slugify(pageName), null);
return projectPagesTable;
public ProjectPage getPage(long projectId, String pageName) {
return projectPageDao.get().getPage(projectId, StringUtils.slugify(pageName), null);
}
public List<ProjectPage> getPages(String pluginId) {
return projectPageDao.get().getPages(pluginId);
}
/**
* Gets a page parents. Must specified either pageName or pageId
@ -42,7 +44,7 @@ public class PagesSerivce {
* @param pageId page id
* @return List of page parents
*/
public List<ProjectPagesTable> getPageParents(long projectId, @Nullable String pageName, @Nullable Long pageId) {
public List<ProjectPage> getPageParents(long projectId, @Nullable String pageName, @Nullable Long pageId) {
Preconditions.checkArgument(pageName == null && pageId == null, "One of (pageName, pageId) must be nonnull!");
return projectPageDao.get().getPageParents(projectId, pageName, pageId);
}

View File

@ -9,6 +9,7 @@ import me.minidigger.hangar.db.model.ProjectPagesTable;
import me.minidigger.hangar.db.model.ProjectVersionsTable;
import me.minidigger.hangar.model.Platform;
import me.minidigger.hangar.model.generated.Dependency;
import me.minidigger.hangar.model.viewhelpers.ProjectPage;
import me.minidigger.hangar.model.viewhelpers.VersionData;
import me.minidigger.hangar.service.UserActionLogService;
import me.minidigger.hangar.service.VersionService;
@ -96,7 +97,7 @@ public class ProjectFactory {
ProjectChannelsTable channelsTable = new ProjectChannelsTable(hangarConfig.channels.getNameDefault(), hangarConfig.channels.getColorDefault(), -1);
String content = "# " + name + "\n\n" + hangarConfig.pages.home.getMessage();
ProjectPagesTable pagesTable = new ProjectPagesTable(-1, OffsetDateTime.now(), -1, hangarConfig.pages.home.getName(), StringUtils.slugify(hangarConfig.pages.home.getName()), content, false, null);
ProjectPagesTable pagesTable = new ProjectPage( -1, hangarConfig.pages.home.getName(), StringUtils.slugify(hangarConfig.pages.home.getName()), content, false, null);
checkProjectAvailability(ownerUser, name, pluginId);

View File

@ -182,10 +182,6 @@ public class ProjectService {
return project;
}
public long getIdByPluginId(String pluginId) {
return projectDao.get().getByPluginId(pluginId).getId();
}
public List<ProjectApprovalData> getProjectsNeedingApproval() {
return projectDao.get().getVisibilityNeedsApproval();
}

View File

@ -1,8 +1,5 @@
package me.minidigger.hangar.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class StringUtils {
/**

View File

@ -35,16 +35,15 @@ Documentation page within Project overview.
<div class="col-md-9">
<div class="row">
<div class="col-md-12">
<#-- @ftlvariable name="page" type="me.minidigger.hangar.model.viewhelpers.ProjectPage" -->
<@editor.editor
saveCall=routes.getRouteUrl("pages.save", p.project.ownerName, p.project.slug, page.slug)
deleteCall=routes.getRouteUrl("pages.delete", p.project.ownerName, p.project.slug, page.slug)
deletable=page.deletable
saveCall=routes.getRouteUrl("pages.save", p.project.ownerName, p.project.slug, projectPage.slug)
deleteCall=routes.getRouteUrl("pages.delete", p.project.ownerName, p.project.slug, projectPage.slug)
deletable=projectPage.isDeletable
enabled=canEditPages()
raw=page.contents
cooked=markdownService.render(page.contents)
raw=projectPage.contents
cooked=markdownService.render(projectPage.contents)
subject="Page"
extraFormValue=page.name />
extraFormValue=projectPage.name />
</div>
</div>
</div>
@ -96,7 +95,7 @@ Documentation page within Project overview.
<#list rootPages as pg, children>
<li class="list-group-item">
<#if children?size gt 0>
<#if page.parentId?? && page.parentId = pg.id>
<#if projectPage.parentId?? && projectPage.parentId = pg.id>
<a class="page-collapse" data-page-id="${pg.id}">
<i class="far fa-minus-square"></i>
</a>
@ -110,7 +109,7 @@ Documentation page within Project overview.
${pg.name}
</a>
</li>
<#if page.parentId?? && page.parentId = pg.id>
<#if projectPage.parentId?? && projectPage.parentId = pg.id>
<div class="page-children" data-page-id="${pg.id}">
<#-- @ftlvariable name="childPage" type="me.minidigger.hangar.model.viewhelpers.ProjectPage" -->
<#list children as childPage>