mirror of
https://github.com/Damillora/Shioriko.git
synced 2024-12-05 00:53:45 +00:00
Compare commits
6 Commits
e79b033c59
...
2cc9705845
Author | SHA1 | Date | |
---|---|---|---|
2cc9705845 | |||
16c9f998d5 | |||
63b19dcf0f | |||
1a0a0a7c83 | |||
45d4278a52 | |||
a420b50877 |
@ -1 +1,2 @@
|
||||
Dockerfile
|
||||
web/app/node_modules
|
||||
|
@ -3,7 +3,6 @@ package app
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/Damillora/Shioriko/pkg/models"
|
||||
"github.com/Damillora/Shioriko/pkg/services"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@ -12,18 +11,16 @@ func InitializeTagRoutes(g *gin.Engine) {
|
||||
unprotected := g.Group("/api/tag")
|
||||
{
|
||||
unprotected.GET("/", tagGet)
|
||||
unprotected.GET("/autocomplete", tagAutocomplete)
|
||||
}
|
||||
}
|
||||
|
||||
func tagGet(c *gin.Context) {
|
||||
tags := services.GetTagAll()
|
||||
var tagResult []models.TagListItem
|
||||
for _, tag := range tags {
|
||||
tagResult = append(tagResult, models.TagListItem{
|
||||
ID: tag.ID,
|
||||
Name: tag.Name,
|
||||
TagType: tag.TagType.Name,
|
||||
})
|
||||
}
|
||||
c.JSON(http.StatusOK, tagResult)
|
||||
c.JSON(http.StatusOK, tags)
|
||||
}
|
||||
|
||||
func tagAutocomplete(c *gin.Context) {
|
||||
tags := services.GetTagAutocomplete()
|
||||
c.JSON(http.StatusOK, tags)
|
||||
}
|
||||
|
@ -6,9 +6,14 @@ type TagTypeListItem struct {
|
||||
}
|
||||
|
||||
type TagListItem struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
TagType string `json:"tagType"`
|
||||
TagID string `json:"tagId"`
|
||||
TagName string `json:"tagName"`
|
||||
TagType string `json:"tagType"`
|
||||
PostCount int `json:"postCount"`
|
||||
}
|
||||
|
||||
type TagAutocompleteListItem struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type PostListItem struct {
|
||||
|
@ -5,12 +5,31 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/Damillora/Shioriko/pkg/database"
|
||||
"github.com/Damillora/Shioriko/pkg/models"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
func GetTagAll() []database.Tag {
|
||||
var tags []database.Tag
|
||||
database.DB.Joins("TagType").Find(&tags)
|
||||
func GetTagAll() []models.TagListItem {
|
||||
var tags []models.TagListItem
|
||||
database.DB.Model(&database.Tag{}).
|
||||
Joins("join tag_types on tag_types.id = tags.tag_type_id").
|
||||
Joins("left join post_tags on post_tags.tag_id = tags.id").
|
||||
Select("tags.id as tag_id, tags.name as tag_name, tag_types.name as tag_type, count(post_tags.post_id) as post_count").
|
||||
Group("tags.id, tags.name, tag_types.name").
|
||||
Order("post_count DESC").
|
||||
Find(&tags)
|
||||
return tags
|
||||
}
|
||||
|
||||
func GetTagAutocomplete() []string {
|
||||
var tags []string
|
||||
result := database.DB.Model(&database.Tag{}).
|
||||
Joins("join tag_types on tag_types.id = tags.tag_type_id").
|
||||
Select("concat(tag_types.name,':',tags.name) as name").
|
||||
Find(&tags)
|
||||
if result.Error != nil {
|
||||
return []string{}
|
||||
}
|
||||
return tags
|
||||
}
|
||||
|
||||
|
@ -49,4 +49,13 @@
|
||||
font-size: 13.3333px;
|
||||
}
|
||||
}
|
||||
#tags .svelte-tags-input-matchs {
|
||||
z-index: 200;
|
||||
&-parent {
|
||||
z-index: 200;
|
||||
}
|
||||
& li:hover {
|
||||
background: $primary;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -35,6 +35,7 @@
|
||||
<div class="navbar-menu" class:is-active={menu_shown}>
|
||||
<div class="navbar-start">
|
||||
<Link class="navbar-item" to="/posts">Posts</Link>
|
||||
<Link class="navbar-item" to="/tags">Tags</Link>
|
||||
{#if loggedIn}
|
||||
<Link class="navbar-item" to="/upload">Upload</Link>
|
||||
{/if}
|
||||
|
@ -41,6 +41,11 @@ export async function getTags() {
|
||||
const response = await axios.get(endpoint);
|
||||
return response.data;
|
||||
}
|
||||
export async function getTagAutocomplete() {
|
||||
const endpoint = url + "/api/tag/autocomplete";
|
||||
const response = await axios.get(endpoint);
|
||||
return response.data;
|
||||
}
|
||||
export async function getPosts({ page }) {
|
||||
const endpoint = url + "/api/post?page=" + page;
|
||||
const response = await axios.get(endpoint);
|
||||
|
@ -10,4 +10,7 @@
|
||||
.tile.is-multiline {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
|
||||
.svelte-tags-input-matchs-parent {
|
||||
z-index: 200;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import { getPost, postUpdate } from "../api.js";
|
||||
import { getPost, postUpdate, getTagAutocomplete } from "../api.js";
|
||||
import { navigate } from "svelte-routing";
|
||||
import Tags from "svelte-tags-input";
|
||||
import { onMount } from "svelte";
|
||||
@ -26,6 +26,11 @@
|
||||
form.tags = value.detail.tags;
|
||||
};
|
||||
|
||||
const onAutocomplete = async () => {
|
||||
const list = await getTagAutocomplete();
|
||||
return list;
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
const response = await postUpdate(id, form);
|
||||
navigate(`/post/${response.id}`);
|
||||
@ -71,6 +76,7 @@
|
||||
tags={form.tags}
|
||||
addKeys={[9, 32]}
|
||||
on:tags={onTagChange}
|
||||
autoComplete={onAutocomplete}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import { getPostSearchTag } from "../api.js";
|
||||
import { getPostSearchTag, getTagAutocomplete } from "../api.js";
|
||||
import { Link, navigate } from "svelte-routing";
|
||||
import InfiniteScroll from "svelte-infinite-scroll";
|
||||
import TagLink from "../TagLink.svelte";
|
||||
@ -51,6 +51,11 @@
|
||||
searchTerms = value.detail.tags;
|
||||
};
|
||||
|
||||
const onAutocomplete = async () => {
|
||||
const list = await getTagAutocomplete();
|
||||
return list;
|
||||
};
|
||||
|
||||
$: {
|
||||
queryParams = queryString.parse(location.search);
|
||||
if (queryParams.tags) {
|
||||
@ -88,6 +93,7 @@
|
||||
tags={searchTerms}
|
||||
addKeys={[9, 32]}
|
||||
on:tags={onTagChange}
|
||||
autoComplete={onAutocomplete}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script>
|
||||
import { getTags } from "../api";
|
||||
|
||||
import { getTags } from "../api";
|
||||
import { Link } from "svelte-routing";
|
||||
|
||||
let tags = [];
|
||||
|
||||
@ -25,15 +25,19 @@ import { getTags } from "../api";
|
||||
<table class="table is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tag</th>
|
||||
<th>Tag Type</th>
|
||||
<th >Tag</th>
|
||||
<th style="width: 30%;">Tag Type</th>
|
||||
<th style="width: 10%;">Post Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each tags as tag}
|
||||
<tr>
|
||||
<td>{tag.name}</td>
|
||||
<td>
|
||||
<Link to="/posts?tags={tag.tagType}:{tag.tagName}">{tag.tagName}</Link>
|
||||
</td>
|
||||
<td>{tag.tagType}</td>
|
||||
<td>{tag.postCount}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import { uploadBlob, postCreate } from "../api.js";
|
||||
import { uploadBlob, postCreate, getTagAutocomplete } from "../api.js";
|
||||
import { navigate, Link } from "svelte-routing";
|
||||
import Tags from "svelte-tags-input";
|
||||
import AuthRequired from "../AuthRequired.svelte";
|
||||
@ -38,6 +38,11 @@
|
||||
form.tags = value.detail.tags;
|
||||
};
|
||||
|
||||
const onAutocomplete = async () => {
|
||||
const list = await getTagAutocomplete();
|
||||
return list;
|
||||
};
|
||||
|
||||
const onSubmit = async () => {
|
||||
const response = await postCreate(form);
|
||||
navigate(`/post/${response.id}`);
|
||||
@ -107,7 +112,7 @@
|
||||
<div class="field">
|
||||
<label for="tags" class="label">Tags</label>
|
||||
<div class="control" id="tags">
|
||||
<Tags addKeys={[9, 32]} on:tags={onTagChange} />
|
||||
<Tags addKeys={[9, 32]} on:tags={onTagChange} autoComplete={onAutocomplete} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control">
|
||||
|
Loading…
Reference in New Issue
Block a user