From 8e0dc433704044fccce7f579c024d4b1b2af7dbd Mon Sep 17 00:00:00 2001 From: jinia91 Date: Wed, 10 Nov 2021 19:09:14 +0900 Subject: [PATCH] =?UTF-8?q?211110=20=EB=A9=94=EC=9D=B8=ED=99=94=EB=A9=B4?= =?UTF-8?q?=20=EA=B0=9C=EB=B0=9C=EC=A4=91=201.=20=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=97=90=20=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20=EB=A1=9C=EC=A7=81=EA=B3=BC=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EB=A0=8C=EB=8D=94=EB=A7=81=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?2.=20=EC=A1=B0=ED=9A=8C=EC=88=98=EC=88=9C=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=ED=99=94=EB=A9=B4=20=EB=85=B8=EC=B6=9C?= =?UTF-8?q?=EA=B3=BC=20=EC=B5=9C=EC=8B=A0=20=EC=97=85=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EC=88=9C=20=EA=B2=8C=EC=8B=9C=EB=AC=BC=20=EB=85=B8=EC=B6=9C=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=EB=B6=84=203.=20=EB=AC=B4?= =?UTF-8?q?=ED=95=9C=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EA=B5=AC=ED=98=84=204.?= =?UTF-8?q?=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=ED=99=94=EC=82=B4=ED=91=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=205.=20=EA=B3=84=EC=B8=B5=ED=98=95=20?= =?UTF-8?q?=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EA=B0=9C=EB=B0=9C?= =?UTF-8?q?=EA=B3=BC=20=ED=99=94=EB=A9=B4=20=EB=A0=8C=EB=8D=94=EB=A7=81=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20=20=20=20-=20=EB=A1=A4=EC=97=85=ED=95=A8?= =?UTF-8?q?=EC=88=98=EC=99=80=20=EB=B0=B1=ED=8A=B8=EB=9E=98=ED=82=B9?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 6 + node_modules/@yaireo/tagify/LICENSE | 19 + node_modules/@yaireo/tagify/README.md | 995 ++++++++++++++++++ .../@yaireo/tagify/dist/jQuery.tagify.min.js | 32 + .../@yaireo/tagify/dist/react.tagify.js | 8 + node_modules/@yaireo/tagify/dist/tagify.css | 1 + .../@yaireo/tagify/dist/tagify.min.js | 8 + .../tagify/dist/tagify.polyfills.min.js | 10 + node_modules/@yaireo/tagify/dist/tagify.vue | 27 + node_modules/@yaireo/tagify/package.json | 124 +++ node_modules/@yaireo/tagify/src/tagify.scss | 693 ++++++++++++ package-lock.json | 11 + .../article/controller/ArticleController.java | 32 +- .../myblog/blog/article/domain/Article.java | 19 +- .../blog/article/dto/ArticleForMainView.java | 19 + .../blog/article/dto/NewArticleDto.java | 10 + .../repository/ArticlePagingRepository.java | 12 + .../article/repository/ArticleRepository.java | 7 + .../blog/article/service/ArticleService.java | 51 +- .../myblog/blog/base/config/AppConfig.java | 13 + .../blog/base/config/SecurityConfig.java | 6 + .../myblog/blog/category/domain/Category.java | 51 + .../dto/CategoryCountForRepository.java | 14 + .../category/dto/CategoryForMainView.java | 53 + .../repository/CategoryRepository.java | 11 + .../repository/NaCategoryRepository.java | 27 + .../category/service/CategoryService.java | 47 + .../img/controller/UploadImgController.java | 28 + .../myblog/blog/img/domain/UploadedImg.java | 1 - .../myblog/blog/img/dto/UploadImgDto.java | 13 + ...{ImgService.java => UploadImgService.java} | 13 +- .../java/myblog/blog/main/MainController.java | 25 +- .../member/controller/MemberController.java | 11 + .../member/repository/MemberRepository.java | 1 - .../member/service/Oauth2MemberService.java | 1 - .../blog/tags/domain/ArticleTagList.java | 37 + .../java/myblog/blog/tags/domain/Tags.java | 36 + .../java/myblog/blog/tags/dto/TagsDto.java | 14 + .../repository/ArticleTagListsRepository.java | 7 + .../blog/tags/repository/TagsRepository.java | 10 + .../myblog/blog/tags/service/TagsService.java | 49 + src/main/resources/application.yml | 2 +- .../resources/static/css/articleWrite.css | 20 + src/main/resources/static/css/mainCss.css | 1 + src/main/resources/static/js/arrow.js | 14 + src/main/resources/static/js/editor.js | 3 +- src/main/resources/static/js/getCsrf.js | 10 + .../resources/static/js/infinityScroll.js | 80 ++ src/main/resources/static/js/tags.js | 14 + src/main/resources/static/js/thumbnail.js | 46 + src/main/resources/static/package-lock.json | 5 + src/main/resources/static/package.json | 1 + .../{ => article}/articleWriteForm.html | 67 +- .../resources/templates/layout/layout.html | 190 +--- .../resources/templates/layout/sideBar.html | 83 ++ src/main/resources/templates/main-origin.html | 368 +++++++ src/main/resources/templates/main.html | 299 +----- .../article/service/ArticleServiceTest.java | 178 +++- 58 files changed, 3443 insertions(+), 490 deletions(-) create mode 100644 node_modules/@yaireo/tagify/LICENSE create mode 100644 node_modules/@yaireo/tagify/README.md create mode 100644 node_modules/@yaireo/tagify/dist/jQuery.tagify.min.js create mode 100644 node_modules/@yaireo/tagify/dist/react.tagify.js create mode 100644 node_modules/@yaireo/tagify/dist/tagify.css create mode 100644 node_modules/@yaireo/tagify/dist/tagify.min.js create mode 100644 node_modules/@yaireo/tagify/dist/tagify.polyfills.min.js create mode 100644 node_modules/@yaireo/tagify/dist/tagify.vue create mode 100644 node_modules/@yaireo/tagify/package.json create mode 100644 node_modules/@yaireo/tagify/src/tagify.scss create mode 100644 package-lock.json create mode 100644 src/main/java/myblog/blog/article/dto/ArticleForMainView.java create mode 100644 src/main/java/myblog/blog/article/repository/ArticlePagingRepository.java create mode 100644 src/main/java/myblog/blog/base/config/AppConfig.java create mode 100644 src/main/java/myblog/blog/category/domain/Category.java create mode 100644 src/main/java/myblog/blog/category/dto/CategoryCountForRepository.java create mode 100644 src/main/java/myblog/blog/category/dto/CategoryForMainView.java create mode 100644 src/main/java/myblog/blog/category/repository/CategoryRepository.java create mode 100644 src/main/java/myblog/blog/category/repository/NaCategoryRepository.java create mode 100644 src/main/java/myblog/blog/category/service/CategoryService.java create mode 100644 src/main/java/myblog/blog/img/controller/UploadImgController.java create mode 100644 src/main/java/myblog/blog/img/dto/UploadImgDto.java rename src/main/java/myblog/blog/img/service/{ImgService.java => UploadImgService.java} (85%) create mode 100644 src/main/java/myblog/blog/tags/domain/ArticleTagList.java create mode 100644 src/main/java/myblog/blog/tags/domain/Tags.java create mode 100644 src/main/java/myblog/blog/tags/dto/TagsDto.java create mode 100644 src/main/java/myblog/blog/tags/repository/ArticleTagListsRepository.java create mode 100644 src/main/java/myblog/blog/tags/repository/TagsRepository.java create mode 100644 src/main/java/myblog/blog/tags/service/TagsService.java create mode 100644 src/main/resources/static/css/articleWrite.css create mode 100644 src/main/resources/static/js/arrow.js create mode 100644 src/main/resources/static/js/getCsrf.js create mode 100644 src/main/resources/static/js/infinityScroll.js create mode 100644 src/main/resources/static/js/tags.js create mode 100644 src/main/resources/static/js/thumbnail.js rename src/main/resources/templates/{ => article}/articleWriteForm.html (56%) create mode 100644 src/main/resources/templates/layout/sideBar.html create mode 100644 src/main/resources/templates/main-origin.html diff --git a/build.gradle b/build.gradle index 38123b0..4a6fbfd 100644 --- a/build.gradle +++ b/build.gradle @@ -30,6 +30,11 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' + implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.9' + implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.7.1' + implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.2.0' + + implementation 'com.querydsl:querydsl-jpa' implementation 'com.github.node-gradle:gradle-node-plugin:3.1.0' @@ -44,6 +49,7 @@ dependencies { annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' + testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:2.2.0' } test { diff --git a/node_modules/@yaireo/tagify/LICENSE b/node_modules/@yaireo/tagify/LICENSE new file mode 100644 index 0000000..4110d3c --- /dev/null +++ b/node_modules/@yaireo/tagify/LICENSE @@ -0,0 +1,19 @@ +Copyright 2019 Yair Even-Or + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/node_modules/@yaireo/tagify/README.md b/node_modules/@yaireo/tagify/README.md new file mode 100644 index 0000000..36febc0 --- /dev/null +++ b/node_modules/@yaireo/tagify/README.md @@ -0,0 +1,995 @@ +

+ +

+
Tagify - tags input component +

+ +

+ Transforms an input field or a textarea into a Tags component, in an easy, customizable way, + with great performance and small code footprint, exploded with features. +
+ VanillaReactVueAngular +

+ +

+ 👉 See Demos 👈 +

+ +

+ + + + + + + + +

+ +

+ + +

+ +## Table of Contents + + +- [Table of Contents](#table-of-contents) +- [Installation](#installation) + - [Option 1 - import from CDN:](#option-1---import-from-cdn) + - [option 2 - import as a *Node module*:](#option-2---import-as-a-node-module) + - [Usage (in your bundle):](#usage-in-your-bundle) +- [Features](#features) +- [Building the project](#building-the-project) +- [Adding tags dynamically](#adding-tags-dynamically) +- [Output value](#output-value) + - [Modify original input value format](#modify-original-input-value-format) +- [Ajax whitelist](#ajax-whitelist) +- [Edit tags](#edit-tags) +- [Validations](#validations) +- [Drag & Sort](#drag--sort) + - [Integration example:](#integration-example) +- [DOM Templates](#dom-templates) + - [Example of overriding the `tag` template:](#example-of-overriding-the-tag-template) +- [Suggestions list](#suggestions-list) + - [Example for a suggestion item alias](#example-for-a-suggestion-item-alias) + - [Example whitelist:](#example-whitelist) +- [Mixed-Content](#mixed-content) +- [Single-Value](#single-value) +- [React](#react) + - [Update regarding `onChange` prop:](#update-regarding-onchange-prop) + - [Updating the component's state](#updating-the-components-state) +- [jQuery version](#jquery-version) +- [CSS Variables](#css-variables) + - [Full list of Tagify's SCSS variables](#full-list-of-tagifys-scss-variables) +- [Methods](#methods) +- [Events](#events) +- [Hooks](#hooks) +- [Settings](#settings) + + +## Installation + +### Option 1 - import from CDN: + +Place these lines before any other code which is (or will be) using *Tagify* ([Example here](https://jsbin.com/jekuqap/edit?html)) +```html + + + +``` + +`Tagify` will then be available globally. +To load specific version use `@` - for example: `unpkg.com/@yaireo/tagify@3.1.0` + +### option 2 - import as a *Node module*: +```sh +npm i @yaireo/tagify --save +``` + +#### Usage (in your bundle): + +[live demo using Parcel as bundler](https://codesandbox.io/s/simple-tagify-setup-6pfi2) + +```js +import Tagify from '@yaireo/tagify' + +var tagify = new Tagify(...) +``` + +> Don't forget to **include `tagify.css`** file in your project. +> CSS location: `@yaireo/tagify/dist/tagify.css` +> SCSS location: `@yaireo/tagify/src/tagify.scss` +> [See SCSS usecase & example](https://github.com/yairEO/tagify/pull/282) + +## Features +* Can be applied on input & textarea elements +* Supports [mix content](#mixed-content) (text and tags together) +* Supports [single-value](#single-value) mode (like ` +``` + + +## Validations +For "regular" tags (not *mix-mode* or *select-mode*) the easiest way is to use the `pattern` setting and use a Regex, or +apply the `pattern` attribute directly on the `input` which will be "transformed" into a *Tagify* component (for vanilla code where the `input` tag is fully accessible to develops). + +If the `pattern` setting does not meet your needs, use the [`validate` setting](#settings), which recieves a *tag data object* as an argument and should return `true` if validaiton is passing, or `false`/`string` of not. +A *string* may be returned as the reason of the validation failure so it would be printed as the `title` attribute of the invalid tag. + +Note - there is a setting to keep invalid tags ([`keepInvalidTags`](#settings)) and if it's set to `true`, the user can see the reason for the invalidation by +hovering the tag and see the browser's native tooltip via the `title` attribute: + +```js +{ + empty : "empty", + exceed : "number of tags exceeded", + pattern : "pattern mismatch", + duplicate : "already exists", + notAllowed : "not allowed" +} +``` + +The texts for those (invalid tags) *titles* can be customized from the settings: + +```js +new Tagify(inputElement, { + texts: { + duplicate: "Duplicates are not allowed" + } +}) +``` + +Or by directly manipulating the *Tagify* function *prototype*: + +```js +Tagify.prototype.TEXTS = {...Tagify.prototype.TEXTS, {duplicate: "Duplicates are not allowed"}} +``` + +## Drag & Sort + +To be able to sort tags by draging, a 3rd-party script is needed. + +I have made a very simple *drag & drop* (~`11kb` *unminified*) script which uses [HTML5 native API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API) and +it is available to download via [NPM](https://www.npmjs.com/package/@yaireo/dragsort) or [Github](https://github.com/yairEO/dragsort) +but any other *drag & drop* script may possibly work. I could not find in the whole internet a decent lightweight script. + +### [Integration example](https://codepen.io/vsync/pen/jOqYOVJ): + +```js +var tagify = new Tagify(inputElement) + +// bind "DragSort" to Tagify's main element and tell +// it that all the items with the below "selector" are "draggable" +var dragsort = new DragSort(tagify.DOM.scope, { + selector: '.'+tagify.settings.classNames.tag, + callbacks: { + dragEnd: onDragEnd + } +}) + +// must update Tagify's value according to the re-ordered nodes in the DOM +function onDragEnd(elm){ + tagify.updateValueByDOMTags() +} +``` + + +## DOM Templates +It's possible to control the templates for some of the HTML elements tagify is using by +modifying the `settings.templates` Object with your own custom functions which **must return** an *HTML string*. + +Available templates are: `wrapper`, `tag`, `dropdown`, `dropdownItem` and the optional `dropdownItemNoMatch` +which is a special template for rendering a suggestion item (in the dropdown list) only if there were no matches found for the typed input. + +[View templates](https://github.com/yairEO/tagify/blob/master/src/parts/templates.js) + +### Example of overriding the `tag` template: + +Each template function automaticaly gets binded with `this` pointing to the current *Tagify* instance. +It is imperative to preserve the class names and also the `this.getAttributes(tagData)` for proper functionality. + +```js +new Tagify(inputElem, { + templates: { + tag(tagData, tagify){ + return ` + +
+ ${tagData[this.settings.tagTextProp] || tagData.value} +
+
` + } +}) +``` + +## Suggestions list + +

+ suggestions list dropdown +

+ +The suggestions list is a *whitelist Array* of *Strings* or *Objects* which was set in the [settings](#settings) Object when the Tagify instance was created, and can be set latet directly on the instance: `tagifyInstance.whitelist = ["tag1", "tag2", ...]`. + +The suggestions dropdown will be appended to the document's `` element and will be rendered by default in a position below (bottom of) the Tagify element. +Using the keyboard arrows up/down will highlight an option from the list, and hitting the Enter key to select. + +It is possible to tweak the list dropdown via 2 settings: + + - `enabled` - this is a numeral value which tells Tagify when to show the suggestions dropdown, when a minimum of N characters were typed. + - `maxItems` - Limits the number of items the suggestions list will render + +```javascript +var input = document.querySelector('input'), + tagify = new Tagify(input, { + whitelist : ['aaa', 'aaab', 'aaabb', 'aaabc', 'aaabd', 'aaabe', 'aaac', 'aaacc'], + dropdown : { + classname : "color-blue", + enabled : 0, // show the dropdown immediately on focus + maxItems : 5, + position : "text", // place the dropdown near the typed text + closeOnSelect : false, // keep the dropdown open after selecting a suggestion + highlightFirst: true + } + }); +``` + +

Will render

+ +```html +
+
+
aaab
+
aaabb
+
aaabc
+
aaabd
+
aaabe
+
+
+``` + +By default searching the suggestions is using [fuzzy-search](https://en.wikipedia.org/wiki/Approximate_string_matching) (see [settings](#settings)). + +If you wish to assign *alias* to items (in your suggestion list), add the `searchBy` property to *whitelist* items you wish +to have an *alias* for. + +In the below example, typing a part of a string which is included in the `searchBy` property, for example *`land midd"`* - +the suggested item which match the value "Israel" will be rendered in the suggestions (dropdown) list. + +### [Example](https://yaireo.github.io/tagify/#section-extra-properties) for a suggestion item alias + +```javascript +whitelist = [ + ... + { value:'Israel', code:'IL', searchBy:'holy land, desert, middle east' }, + ... +] +``` + +Another handy setting is `dropdown.searchKeys` which, like the above `dropdown.searchBy` setting, allows +expanding the search of any typed terms to more than the `value` property of the whitelist items (if items are a *Collection*). + +### Example whitelist: + +```javascript +[ + { + value : 123456, + nickname : "foo", + email : "foo@mail.com" + }, + { + value : 987654, + nickname : "bar", + email : "bar@mail.com" + }, + ...more.. +] +``` + +// setting to search in other keys: +```javascript +{ + dropdown: { + searchKeys: ["nickname", "email"] // fuzzy-search matching for those whitelist items' properties + } +} +``` + +## Mixed-Content + +[See demo here](https://yaireo.github.io/tagify/#section-mix) + +This feature must be toggled using these [settings](#settings): + +```js +{ + // mixTagsInterpolator: ["{{", "}}"], // optional: interpolation before & after string + mode: 'mix', // <-- Enable mixed-content + pattern: /@|#/ // <-- Text starting with @ or # (if single, String can be used here instead of Regex) +} +``` + +When mixing text with tags, the original textarea (or input) element will have a value as follows: + + [[cartman]]⁠ and [[kyle]]⁠ do not know [[Homer simpson]]⁠ + +If the inital value of the textarea or input is formatted as the above example, tagify will try to +automatically convert everything between `[[` & `]]` to a tag, if tag exists in the *whitelist*, so make +sure when the Tagify instance is initialized, that it has tags with the correct `value` property that match +the same values that appear between `[[` & `]]`. + +Applying the setting `dropdown.position:"text"` is encouraged for mixed-content tags, because the suggestions list +weird when there is already a lot of content at multiple lines. + +If a tag does not exists in the *whitelist*, it may be created by the user and all you should do is listen to the `add` event and update your local/remote state. + +## Single-Value + +Similar to native ``'s element `name` attribute +value | String/Array | ✔ | Initial value. +defaultValue | String/Array | | Same as `value prop +placeholder | String | ✔ | placeholder text for the component +readOnly | Boolean | ✔ | Toggles `readonly` state. With capital `O`. +tagifyRef | Object | | `useRef` hook refference for the component inner instance of vailla *Tagify* (for methods access) +showFilteredDropdown | Boolean/String | ✔ | if `true` shows the suggestions dropdown. if assigned a String, show the dropdown pre-filtered. +loading | Boolean | ✔ | Toggles `loading` state for the whole component +whitelist | Array | ✔ | Sets the `whitelist` which is the basis for the suggestions dropdown & autocomplete +className | String | | Component's optional class name to be added +InputMode | String | | `"textarea"` will create a ` + +
+
+
+ +
+
+ +
+
+
+
+
+
+
+ + + +
+ +
+ + -
- -
-
-
-
-
-
-
- -
+
@@ -86,8 +119,12 @@
+ + + + diff --git a/src/main/resources/templates/layout/layout.html b/src/main/resources/templates/layout/layout.html index 1392dc6..2999497 100644 --- a/src/main/resources/templates/layout/layout.html +++ b/src/main/resources/templates/layout/layout.html @@ -7,6 +7,7 @@ +
- diff --git a/src/main/resources/templates/layout/sideBar.html b/src/main/resources/templates/layout/sideBar.html new file mode 100644 index 0000000..dfe4c1c --- /dev/null +++ b/src/main/resources/templates/layout/sideBar.html @@ -0,0 +1,83 @@ + + + +
+ + + + + + + +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/main-origin.html b/src/main/resources/templates/main-origin.html new file mode 100644 index 0000000..6568d51 --- /dev/null +++ b/src/main/resources/templates/main-origin.html @@ -0,0 +1,368 @@ + + + + + + + Jinia's Log + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ +
+ +
+

최신 포스팅

+
+ + + + + + + + + + + +
+
+
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/main.html b/src/main/resources/templates/main.html index 6568d51..85264a3 100644 --- a/src/main/resources/templates/main.html +++ b/src/main/resources/templates/main.html @@ -51,86 +51,31 @@