diff --git a/marko/components/modal/style.less b/marko/components/modal/style.less index 54ee9b2..e833695 100644 --- a/marko/components/modal/style.less +++ b/marko/components/modal/style.less @@ -39,9 +39,33 @@ div.overlay { } input.big { font-size: 1.5em; - padding: 0 0.3333ch; + padding: 0 0.3336ch; } - + + + select { + display: block; + width: 100%; + padding: 0 0ch; + + border: none; + font-family: inherit; + background: none; + outline: none; + opacity: 0.5; + + option { + background-color: black; + } + } + select.big { + font-size: 1.5em; + margin: 0; + } + select:focus { + opacity: 1; + } + textarea { display: block; width: 100%; diff --git a/marko/global/colors.less b/marko/global/colors.less index 2959901..df96e0d 100644 --- a/marko/global/colors.less +++ b/marko/global/colors.less @@ -8,10 +8,10 @@ body.theme-story { .menu-link:hover, .menu > .head-menu > a:hover { background-color: rgba(17, 187, 255, 0.25); } - .color-primary, button, input:focus, textarea:focus, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { + .color-primary, button, input:focus, textarea:focus, select:focus, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { color: #4BF; } - .color-text, input, textarea { + .color-text, input, textarea, select { color: #ABC; } .color-highlight-primary { @@ -33,10 +33,10 @@ body.theme-logs { .menu-link:hover, .Menu > .head-menu > a:hover { background-color: rgba(255, 187, 17, 0.25); } - .color-primary, button, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { + .color-primary, button, input:focus, textarea:focus, select:focus, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { color: #DA1; } - .color-text, input, textarea { + .color-text, input, textarea, select { color: #AAA; } .color-highlight-dark { @@ -58,10 +58,10 @@ body.theme-logs { .menu-link:hover, .menu > .head-menu > a:hover { background-color: rgba(35, 255, 128, 0.25); } - .color-primary, button, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { + .color-primary, button, input:focus, textarea:focus, select:focus, .modal h1, .modal h2, .modal label, .markdown-content h1, .markdown-content h2, .markdown-content h3, .markdown-content h4, .markdown-content hr, .markdown-content a { color: #1F8; } - .color-text, input, textarea { + .color-text, input, textarea, select { color: #ACB; } } diff --git a/marko/page/story-content/components/edit-story-tags-modal/component.js b/marko/page/story-content/components/edit-story-tags-modal/component.js new file mode 100644 index 0000000..7603a35 --- /dev/null +++ b/marko/page/story-content/components/edit-story-tags-modal/component.js @@ -0,0 +1,40 @@ +const moment = require("moment") + +const {storyApi} = require("../../../../../rpdata/api/Story") + +module.exports = class { + onCreate(input) { + this.state = { + error: null, + loading: false, + } + } + + change(key, ev) { + this.state.values[key] = ev.target.value + } + + close() { + this.emit("close") + } + + addTag(tag) { + this.state.error = null + + storyApi.addTag({id: this.input.story.id, tag}).then(({tags}) => { + this.emit("tags", tags) + }).catch(errs => { + this.state.error = errs.message || errs[0].message || "Add tag failed" + }) + } + + removeTag(tag) { + this.state.error = null + + storyApi.removeTag({id: this.input.story.id, tag}).then(({tags}) => { + this.emit("tags", tags) + }).catch(errs => { + this.state.error = errs.message || errs[0].message || "Remove tag failed" + }) + } +} \ No newline at end of file diff --git a/marko/page/story-content/components/edit-story-tags-modal/index.marko b/marko/page/story-content/components/edit-story-tags-modal/index.marko new file mode 100644 index 0000000..12b5e66 --- /dev/null +++ b/marko/page/story-content/components/edit-story-tags-modal/index.marko @@ -0,0 +1,7 @@ + +

Edit Tags

+ +

${state.error}

+ + +
\ No newline at end of file diff --git a/marko/page/story-content/components/page/component.js b/marko/page/story-content/components/page/component.js index 89b7ec6..6d837f8 100644 --- a/marko/page/story-content/components/page/component.js +++ b/marko/page/story-content/components/page/component.js @@ -48,8 +48,6 @@ module.exports = class { } menuSelect(kind, id) { - console.log(kind, id) - switch (kind) { case "add": this.open("chapter.add") @@ -57,6 +55,11 @@ module.exports = class { } } + updateStoryTags(tags) { + this.state.story.tags = tags + this.refreshStory() + } + refreshStory() { this.state.story = Object.assign({}, this.state.story) } diff --git a/marko/page/story-content/components/page/index.marko b/marko/page/story-content/components/page/index.marko index 57ca9ff..8a342bf 100644 --- a/marko/page/story-content/components/page/index.marko +++ b/marko/page/story-content/components/page/index.marko @@ -2,10 +2,10 @@

${state.story.name}

- +
- +
\ No newline at end of file diff --git a/marko/page/story-content/components/story-tag-options/component.js b/marko/page/story-content/components/story-tag-options/component.js new file mode 100644 index 0000000..3bbdd0b --- /dev/null +++ b/marko/page/story-content/components/story-tag-options/component.js @@ -0,0 +1,62 @@ +const {tagApi} = require("../../../../../rpdata/api/Tag") + +module.exports = class { + onCreate() { + this.state = { + values: { + name: "", + kind: "Event", + }, + tags: [], + suggestions: [], + } + } + + onMount() { + tagApi.list().then(list => { + this.state.tags = list + }).catch(err => {}) + + this.getEl("name").addEventListener("keydown", ev => { + setTimeout(() => { + const name = this.getEl("name").value + const kind = this.getEl("kind").value + const search = name.toLowerCase() + + this.state.values = {name, kind} + this.state.suggestions = [] + + const suggestions = this.state.tags.filter(t => t.name.toLowerCase().includes(search)) + if (suggestions.length > 0 && suggestions.length < 10) { + if (suggestions.length > 1 || suggestions[0].name !== name) { + this.state.suggestions = suggestions + } + } + }, 100) + }) + } + + add(tag) { + this.state.values = { + kind: "Event", + name: "", + } + + this.emit("add", tag) + } + + change(key, ev) { + const value = ev.target.value + + this.state.values[key] = value + } + + applySuggestion(tag) { + this.state.values = { + name: tag.name, + kind: tag.kind, + } + + this.state.suggestions = [] + } +} \ No newline at end of file diff --git a/marko/page/story-content/components/story-tag-options/index.marko b/marko/page/story-content/components/story-tag-options/index.marko new file mode 100644 index 0000000..fd60fe3 --- /dev/null +++ b/marko/page/story-content/components/story-tag-options/index.marko @@ -0,0 +1,21 @@ +
+ + +
0)> +
Suggestions:
+ ${tag.name} +
+ + + +
+
${tag.name}
+ +
+
\ No newline at end of file diff --git a/marko/page/story-content/components/story-tag-options/style.less b/marko/page/story-content/components/story-tag-options/style.less new file mode 100644 index 0000000..9148391 --- /dev/null +++ b/marko/page/story-content/components/story-tag-options/style.less @@ -0,0 +1,46 @@ +div.tag-options { + div.tag { + padding: 0.25em; + border-bottom: 1px solid rgba(0, 220, 255, 0.125); + + div.content { + width: 80%; + display: inline-block; + } + + button { + width: 20%; + display: inline-block; + margin: 0; + } + } + + div.suggestion-list { + margin-top: 1em; + + a.tag { + display: inline-block; + margin: 0.5em 0.5ch; + padding: 0.0625em 0.5ch; + + outline: 1px solid; + opacity: 0.75; + + user-select: none; + } + a.tag:hover { + opacity: 1; + cursor: pointer; + } + + div.header { + display: inline-block; + margin: 0.5em 0.5ch; + padding: 0.0625em 0.5ch; + + opacity: 0.5; + + user-select: none; + } + } +} \ No newline at end of file diff --git a/marko/page/story-content/components/story-tags/component.js b/marko/page/story-content/components/story-tags/component.js new file mode 100644 index 0000000..723b4e0 --- /dev/null +++ b/marko/page/story-content/components/story-tags/component.js @@ -0,0 +1,5 @@ +module.exports = class { + select(kind) { + this.emit("select", kind) + } +} \ No newline at end of file diff --git a/marko/page/story-content/components/story-tags/index.marko b/marko/page/story-content/components/story-tags/index.marko index 4d7c456..103701d 100644 --- a/marko/page/story-content/components/story-tags/index.marko +++ b/marko/page/story-content/components/story-tags/index.marko @@ -1,3 +1,4 @@
${tag.name} + Edit
\ No newline at end of file diff --git a/marko/page/story-content/components/story-tags/style.less b/marko/page/story-content/components/story-tags/style.less index 449d696..a38a201 100644 --- a/marko/page/story-content/components/story-tags/style.less +++ b/marko/page/story-content/components/story-tags/style.less @@ -17,4 +17,18 @@ div.story-tags { opacity: 1; cursor: pointer; } + + a.option { + display: inline-block; + margin: 0.5em 0.5ch; + padding: 0.0625em 0.5ch; + + opacity: 0.5; + + user-select: none; + } + a.option:hover { + opacity: 1; + cursor: pointer; + } } \ No newline at end of file diff --git a/rpdata/api/Story.js b/rpdata/api/Story.js index 15f7fa5..2196e47 100644 --- a/rpdata/api/Story.js +++ b/rpdata/api/Story.js @@ -142,6 +142,48 @@ const storyApi = { return data.categories }) }, + + /** + * Call `addStoryTag(input)` mutation, returns the new tag list. + * + * @param {{id:string, tag:Tag}} input + * @returns {Promise<{tags: Tag[]}>} + */ + addTag(input) { + return query(` + mutation AddStoryTag($input: StoryTagAddInput!) { + addStoryTag(input:$input) { + tags { + kind + name + } + } + } + `, {input}, {permissions: ["member", "story.edit"]}).then(({addStoryTag}) => { + return addStoryTag + }) + }, + + /** + * Call `removeStoryTag(input)` mutation, returns the new tag list. + * + * @param {{id:string, tag:Tag}} input + * @returns {Promise<{tags: Tag[]}>} + */ + removeTag(input) { + return query(` + mutation RemoveStoryTag($input: StoryTagRemoveInput!) { + removeStoryTag(input:$input) { + tags { + kind + name + } + } + } + `, {input}, {permissions: ["member", "story.edit"]}).then(({removeStoryTag}) => { + return removeStoryTag + }) + }, } module.exports = {storyApi, Story} \ No newline at end of file diff --git a/rpdata/api/Tag.js b/rpdata/api/Tag.js index 9fac33d..d69ab8b 100644 --- a/rpdata/api/Tag.js +++ b/rpdata/api/Tag.js @@ -26,7 +26,7 @@ const tagApi = { } } `, {}).then(({tags}) => { - return tags.map(d => new Tag(d)) + return tags.map(d => new Tag(d.kind, d.name)) }) }, }