Gisle Aune
6 years ago
14 changed files with 278 additions and 13 deletions
-
28marko/components/modal/style.less
-
12marko/global/colors.less
-
40marko/page/story-content/components/edit-story-tags-modal/component.js
-
7marko/page/story-content/components/edit-story-tags-modal/index.marko
-
7marko/page/story-content/components/page/component.js
-
4marko/page/story-content/components/page/index.marko
-
62marko/page/story-content/components/story-tag-options/component.js
-
21marko/page/story-content/components/story-tag-options/index.marko
-
46marko/page/story-content/components/story-tag-options/style.less
-
5marko/page/story-content/components/story-tags/component.js
-
1marko/page/story-content/components/story-tags/index.marko
-
14marko/page/story-content/components/story-tags/style.less
-
42rpdata/api/Story.js
-
2rpdata/api/Tag.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" |
|||
}) |
|||
} |
|||
} |
@ -0,0 +1,7 @@ |
|||
<modal class="modal color-text nolabel" key="modal2" enabled=(input.enabled) closable on-close("close") > |
|||
<h1>Edit Tags</h1> |
|||
|
|||
<p key="error" class="color-error">${state.error}</p> |
|||
|
|||
<story-tag-options tags=input.story.tags loading=state.loading on-remove("removeTag") on-add("addTag") /> |
|||
</modal> |
@ -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 = [] |
|||
} |
|||
} |
@ -0,0 +1,21 @@ |
|||
<div class="tag-options"> |
|||
<input key="name" placeholder="Name" class="big" on-change("change", "name") value=state.values.name /> |
|||
<select key="kind" placeholder="Kind" class="big" on-change("change", "kind") value=state.values.kind> |
|||
<option value="Character" selected=(state.values.kind === "Character")>Character</option> |
|||
<option value="Event" selected=(state.values.kind === "Event")>Event</option> |
|||
<option value="Location" selected=(state.values.kind === "Location")>Location</option> |
|||
<option value="Organization" selected=(state.values.kind === "Organization")>Organization</option> |
|||
<option value="Series" selected=(state.values.kind === "Series")>Series</option> |
|||
</select> |
|||
<div class="suggestion-list" if(state.suggestions.length > 0)> |
|||
<div class="header color-menu">Suggestions:</div> |
|||
<a for(tag in state.suggestions) on-click("applySuggestion", tag) class=["tag", "color-tag-" + tag.kind.toLowerCase()]>${tag.name}</a> |
|||
</div> |
|||
|
|||
<button disabled=(input.loading) on-click("add", state.values)>Add</button> |
|||
|
|||
<div for(tag in (input.tags || [])) class="tag" key=(tag.kind+":"+tag.name)> |
|||
<div class=("content color-tag-"+tag.kind.toLowerCase())>${tag.name}</div> |
|||
<button on-click("emit", "remove", tag)>Remove</button> |
|||
</div> |
|||
</div> |
@ -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; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,5 @@ |
|||
module.exports = class { |
|||
select(kind) { |
|||
this.emit("select", kind) |
|||
} |
|||
} |
@ -1,3 +1,4 @@ |
|||
<div class="story-tags"> |
|||
<a for(tag in input.tags) href=("/story/by-tag/" + tag.kind + "/" + encodeURIComponent(tag.name)) class=["tag", "color-tag-" + tag.kind.toLowerCase()]>${tag.name}</a> |
|||
<a on-click("select", "edit") class="option color-menu">Edit</a> |
|||
</div> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue